Exemplo n.º 1
0
    def test_tdb_copy(self):
        src_ldb_file = os.path.join(self.tempdir, "source.ldb")
        dst_ldb_file = os.path.join(self.tempdir, "destination.ldb")

        # Create LDB source file with some content
        src_ldb = Ldb(src_ldb_file)
        src_ldb.add({"dn": "f=dc", "b": "bla"})

        # Copy source file to destination file and check return status
        self.assertIsNone(tdb_copy(src_ldb_file, dst_ldb_file))

        # Load copied file as LDB object
        dst_ldb = Ldb(dst_ldb_file)

        # Copmare contents of files
        self.assertEqual(
            src_ldb.searchone(basedn=ldb.Dn(src_ldb, "f=dc"), attribute="b"),
            dst_ldb.searchone(basedn=ldb.Dn(dst_ldb, "f=dc"), attribute="b")
        )

        # Clean up
        del src_ldb
        del dst_ldb
        os.unlink(src_ldb_file)
        os.unlink(dst_ldb_file)
Exemplo n.º 2
0
def delta_update_basesamdb(refsampath, sampath, creds, session, lp, message):
    """Update the provision container db: sam.ldb
    This function is aimed for alpha9 and newer;

    :param refsampath: Path to the samdb in the reference provision
    :param sampath: Path to the samdb in the upgraded provision
    :param creds: Credential used for openning LDB files
    :param session: Session to use for openning LDB files
    :param lp: A loadparam object
    :return: A msg_diff object with the difference between the @ATTRIBUTES
             of the current provision and the reference provision
    """

    message(SIMPLE,
            "Update base samdb by searching difference with reference one")
    refsam = Ldb(refsampath,
                 session_info=session,
                 credentials=creds,
                 lp=lp,
                 options=["modules:"])
    sam = Ldb(sampath,
              session_info=session,
              credentials=creds,
              lp=lp,
              options=["modules:"])

    empty = ldb.Message()
    deltaattr = None
    reference = refsam.search(expression="")

    for refentry in reference:
        entry = sam.search(expression="distinguishedName=%s" % refentry["dn"],
                           scope=SCOPE_SUBTREE)
        if not len(entry):
            delta = sam.msg_diff(empty, refentry)
            message(CHANGE, "Adding %s to sam db" % str(refentry.dn))
            if str(refentry.dn) == "@PROVISION" and\
                    delta.get(samba.provision.LAST_PROVISION_USN_ATTRIBUTE):
                delta.remove(samba.provision.LAST_PROVISION_USN_ATTRIBUTE)
            delta.dn = refentry.dn
            sam.add(delta)
        else:
            delta = sam.msg_diff(entry[0], refentry)
            if str(refentry.dn) == "@ATTRIBUTES":
                deltaattr = sam.msg_diff(refentry, entry[0])
            if str(refentry.dn) == "@PROVISION" and\
                    delta.get(samba.provision.LAST_PROVISION_USN_ATTRIBUTE):
                delta.remove(samba.provision.LAST_PROVISION_USN_ATTRIBUTE)
            if len(delta.items()) > 1:
                delta.dn = refentry.dn
                sam.modify(delta)

    return deltaattr
Exemplo n.º 3
0
def delta_update_basesamdb(refsampath, sampath, creds, session, lp, message):
    """Update the provision container db: sam.ldb
    This function is aimed for alpha9 and newer;

    :param refsampath: Path to the samdb in the reference provision
    :param sampath: Path to the samdb in the upgraded provision
    :param creds: Credential used for openning LDB files
    :param session: Session to use for openning LDB files
    :param lp: A loadparam object
    :return: A msg_diff object with the difference between the @ATTRIBUTES
             of the current provision and the reference provision
    """

    message(SIMPLE,
            "Update base samdb by searching difference with reference one")
    refsam = Ldb(refsampath, session_info=session, credentials=creds,
                    lp=lp, options=["modules:"])
    sam = Ldb(sampath, session_info=session, credentials=creds, lp=lp,
                options=["modules:"])

    empty = ldb.Message()
    deltaattr = None
    reference = refsam.search(expression="")

    for refentry in reference:
        entry = sam.search(expression="distinguishedName=%s" % refentry["dn"],
                            scope=SCOPE_SUBTREE)
        if not len(entry):
            delta = sam.msg_diff(empty, refentry)
            message(CHANGE, "Adding %s to sam db" % str(refentry.dn))
            if str(refentry.dn) == "@PROVISION" and\
                delta.get(samba.provision.LAST_PROVISION_USN_ATTRIBUTE):
                delta.remove(samba.provision.LAST_PROVISION_USN_ATTRIBUTE)
            delta.dn = refentry.dn
            sam.add(delta)
        else:
            delta = sam.msg_diff(entry[0], refentry)
            if str(refentry.dn) == "@ATTRIBUTES":
                deltaattr = sam.msg_diff(refentry, entry[0])
            if str(refentry.dn) == "@PROVISION" and\
                delta.get(samba.provision.LAST_PROVISION_USN_ATTRIBUTE):
                delta.remove(samba.provision.LAST_PROVISION_USN_ATTRIBUTE)
            if len(delta.items()) > 1:
                delta.dn = refentry.dn
                sam.modify(delta)

    return deltaattr
Exemplo n.º 4
0
    def test_tdb_copy(self):
        src_ldb_file = os.path.join(self.tempdir, "source.ldb")
        dst_ldb_file = os.path.join(self.tempdir, "destination.ldb")

        # Create LDB source file with some content
        src_ldb = Ldb(src_ldb_file)
        src_ldb.add({"dn": "f=dc", "b": "bla"})

        # Copy source file to destination file and check return status
        self.assertIsNone(tdb_copy(src_ldb_file, dst_ldb_file))

        # Load copied file as LDB object
        dst_ldb = Ldb(dst_ldb_file)

        # Copmare contents of files
        self.assertEqual(
            src_ldb.searchone(basedn=ldb.Dn(src_ldb, "f=dc"), attribute="b"),
            dst_ldb.searchone(basedn=ldb.Dn(dst_ldb, "f=dc"), attribute="b"))

        # Clean up
        del src_ldb
        del dst_ldb
        os.unlink(src_ldb_file)
        os.unlink(dst_ldb_file)
Exemplo n.º 5
0
class MapTestCase(MapBaseTestCase):
    def setUp(self):
        super(MapTestCase, self).setUp()
        ldb = Ldb(self.ldburl, lp=self.lp, session_info=system_session())
        ldb.set_opaque("skip_allocate_sids", "true")
        ldif = read_datafile("provision_samba3sam.ldif")
        ldb.add_ldif(self.samba4.subst(ldif))
        self.setup_modules(ldb, self.samba3, self.samba4)
        del ldb
        self.ldb = Ldb(self.ldburl, lp=self.lp, session_info=system_session())
        self.ldb.set_opaque("skip_allocate_sids", "true")

    def test_map_search(self):
        """Running search tests on mapped data."""
        self.samba3.db.add({
            "dn": "sambaDomainName=TESTS," + self.samba3.basedn,
            "objectclass": ["sambaDomain", "top"],
            "sambaSID": "S-1-5-21-4231626423-2410014848-2360679739",
            "sambaNextRid": "2000",
            "sambaDomainName": "TESTS"
        })

        # Add a set of split records
        self.ldb.add_ldif("""
dn: """ + self.samba4.dn("cn=Domain Users") + """
objectClass: group
cn: Domain Users
objectSid: S-1-5-21-4231626423-2410014848-2360679739-513
""")

        # Add a set of split records
        self.ldb.add_ldif("""
dn: """ + self.samba4.dn("cn=X") + """
objectClass: user
cn: X
codePage: x
revision: x
dnsHostName: x
nextRid: y
lastLogon: x
description: x
objectSid: S-1-5-21-4231626423-2410014848-2360679739-1052
""")

        self.ldb.add({
            "dn": self.samba4.dn("cn=Y"),
            "objectClass": "top",
            "cn": "Y",
            "codePage": "x",
            "revision": "x",
            "dnsHostName": "y",
            "nextRid": "y",
            "lastLogon": "y",
            "description": "x"
        })

        self.ldb.add({
            "dn": self.samba4.dn("cn=Z"),
            "objectClass": "top",
            "cn": "Z",
            "codePage": "x",
            "revision": "y",
            "dnsHostName": "z",
            "nextRid": "y",
            "lastLogon": "z",
            "description": "y"
        })

        # Add a set of remote records

        self.samba3.db.add({
            "dn":
            self.samba3.dn("cn=A"),
            "objectClass":
            "posixAccount",
            "cn":
            "A",
            "sambaNextRid":
            "x",
            "sambaBadPasswordCount":
            "x",
            "sambaLogonTime":
            "x",
            "description":
            "x",
            "sambaSID":
            "S-1-5-21-4231626423-2410014848-2360679739-1052",
            "sambaPrimaryGroupSID":
            "S-1-5-21-4231626423-2410014848-2360679739-512"
        })

        self.samba3.db.add({
            "dn": self.samba3.dn("cn=B"),
            "objectClass": "top",
            "cn": "B",
            "sambaNextRid": "x",
            "sambaBadPasswordCount": "x",
            "sambaLogonTime": "y",
            "description": "x"
        })

        self.samba3.db.add({
            "dn": self.samba3.dn("cn=C"),
            "objectClass": "top",
            "cn": "C",
            "sambaNextRid": "x",
            "sambaBadPasswordCount": "y",
            "sambaLogonTime": "z",
            "description": "y"
        })

        # Testing search by DN

        # Search remote record by local DN
        dn = self.samba4.dn("cn=A")
        res = self.ldb.search(dn,
                              scope=SCOPE_BASE,
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "x")

        # Search remote record by remote DN
        dn = self.samba3.dn("cn=A")
        res = self.samba3.db.search(
            dn,
            scope=SCOPE_BASE,
            attrs=["dnsHostName", "lastLogon", "sambaLogonTime"])
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertTrue(not "lastLogon" in res[0])
        self.assertEquals(str(res[0]["sambaLogonTime"]), "x")

        # Search split record by local DN
        dn = self.samba4.dn("cn=X")
        res = self.ldb.search(dn,
                              scope=SCOPE_BASE,
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertEquals(str(res[0]["dnsHostName"]), "x")
        self.assertEquals(str(res[0]["lastLogon"]), "x")

        # Search split record by remote DN
        dn = self.samba3.dn("cn=X")
        res = self.samba3.db.search(
            dn,
            scope=SCOPE_BASE,
            attrs=["dnsHostName", "lastLogon", "sambaLogonTime"])
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertTrue(not "lastLogon" in res[0])
        self.assertEquals(str(res[0]["sambaLogonTime"]), "x")

        # Testing search by attribute

        # Search by ignored attribute
        res = self.ldb.search(expression="(revision=x)",
                              scope=SCOPE_DEFAULT,
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 2)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=X"))
        self.assertEquals(str(res[0]["dnsHostName"]), "x")
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=Y"))
        self.assertEquals(str(res[1]["dnsHostName"]), "y")
        self.assertEquals(str(res[1]["lastLogon"]), "y")

        # Search by kept attribute
        res = self.ldb.search(expression="(description=y)",
                              scope=SCOPE_DEFAULT,
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 2)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=C"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "z")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=Z"))
        self.assertEquals(str(res[1]["dnsHostName"]), "z")
        self.assertEquals(str(res[1]["lastLogon"]), "z")

        # Search by renamed attribute
        res = self.ldb.search(expression="(badPwdCount=x)",
                              scope=SCOPE_DEFAULT,
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 2)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B"))
        self.assertTrue(not "dnsHostName" in res[1])
        self.assertEquals(str(res[1]["lastLogon"]), "y")

        # Search by converted attribute
        # TODO:
        #   Using the SID directly in the parse tree leads to conversion
        #   errors, letting the search fail with no results.
        #res = self.ldb.search("(objectSid=S-1-5-21-4231626423-2410014848-2360679739-1052)", scope=SCOPE_DEFAULT, attrs)
        res = self.ldb.search(expression="(objectSid=*)",
                              base=None,
                              scope=SCOPE_DEFAULT,
                              attrs=["dnsHostName", "lastLogon", "objectSid"])
        self.assertEquals(len(res), 4)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=X"))
        self.assertEquals(str(res[1]["dnsHostName"]), "x")
        self.assertEquals(str(res[1]["lastLogon"]), "x")
        self.assertSidEquals("S-1-5-21-4231626423-2410014848-2360679739-1052",
                             res[1]["objectSid"])
        self.assertTrue("objectSid" in res[1])
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertSidEquals("S-1-5-21-4231626423-2410014848-2360679739-1052",
                             res[0]["objectSid"])
        self.assertTrue("objectSid" in res[0])

        # Search by generated attribute
        # In most cases, this even works when the mapping is missing
        # a `convert_operator' by enumerating the remote db.
        res = self.ldb.search(
            expression="(primaryGroupID=512)",
            attrs=["dnsHostName", "lastLogon", "primaryGroupID"])
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(str(res[0]["primaryGroupID"]), "512")

        # Note that Xs "objectSid" seems to be fine in the previous search for
        # "objectSid"...
        #res = ldb.search(expression="(primaryGroupID=*)", NULL, ldb. SCOPE_DEFAULT, attrs)
        #print len(res) + " results found"
        #for i in range(len(res)):
        #    for (obj in res[i]) {
        #        print obj + ": " + res[i][obj]
        #    }
        #    print "---"
        #

        # Search by remote name of renamed attribute */
        res = self.ldb.search(expression="(sambaBadPasswordCount=*)",
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 0)

        # Search by objectClass
        attrs = ["dnsHostName", "lastLogon", "objectClass"]
        res = self.ldb.search(expression="(objectClass=user)", attrs=attrs)
        self.assertEquals(len(res), 2)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(str(res[0]["objectClass"][0]), "user")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=X"))
        self.assertEquals(str(res[1]["dnsHostName"]), "x")
        self.assertEquals(str(res[1]["lastLogon"]), "x")
        self.assertEquals(str(res[1]["objectClass"][0]), "user")

        # Prove that the objectClass is actually used for the search
        res = self.ldb.search(
            expression="(|(objectClass=user)(badPwdCount=x))", attrs=attrs)
        self.assertEquals(len(res), 3)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(res[0]["objectClass"][0], "user")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B"))
        self.assertTrue(not "dnsHostName" in res[1])
        self.assertEquals(str(res[1]["lastLogon"]), "y")
        self.assertEquals(set(res[1]["objectClass"]), set(["top"]))
        self.assertEquals(str(res[2].dn), self.samba4.dn("cn=X"))
        self.assertEquals(str(res[2]["dnsHostName"]), "x")
        self.assertEquals(str(res[2]["lastLogon"]), "x")
        self.assertEquals(str(res[2]["objectClass"][0]), "user")

        # Testing search by parse tree

        # Search by conjunction of local attributes
        res = self.ldb.search(expression="(&(codePage=x)(revision=x))",
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 2)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=X"))
        self.assertEquals(str(res[0]["dnsHostName"]), "x")
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=Y"))
        self.assertEquals(str(res[1]["dnsHostName"]), "y")
        self.assertEquals(str(res[1]["lastLogon"]), "y")

        # Search by conjunction of remote attributes
        res = self.ldb.search(expression="(&(lastLogon=x)(description=x))",
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 2)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=X"))
        self.assertEquals(str(res[1]["dnsHostName"]), "x")
        self.assertEquals(str(res[1]["lastLogon"]), "x")

        # Search by conjunction of local and remote attribute
        res = self.ldb.search(expression="(&(codePage=x)(description=x))",
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 2)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=X"))
        self.assertEquals(str(res[0]["dnsHostName"]), "x")
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=Y"))
        self.assertEquals(str(res[1]["dnsHostName"]), "y")
        self.assertEquals(str(res[1]["lastLogon"]), "y")

        # Search by conjunction of local and remote attribute w/o match
        attrs = ["dnsHostName", "lastLogon"]
        res = self.ldb.search(expression="(&(codePage=x)(nextRid=x))",
                              attrs=attrs)
        self.assertEquals(len(res), 0)
        res = self.ldb.search(expression="(&(revision=x)(lastLogon=z))",
                              attrs=attrs)
        self.assertEquals(len(res), 0)

        # Search by disjunction of local attributes
        res = self.ldb.search(expression="(|(revision=x)(dnsHostName=x))",
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 2)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=X"))
        self.assertEquals(str(res[0]["dnsHostName"]), "x")
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=Y"))
        self.assertEquals(str(res[1]["dnsHostName"]), "y")
        self.assertEquals(str(res[1]["lastLogon"]), "y")

        # Search by disjunction of remote attributes
        res = self.ldb.search(expression="(|(badPwdCount=x)(lastLogon=x))",
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 3)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A"))
        self.assertFalse("dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B"))
        self.assertFalse("dnsHostName" in res[1])
        self.assertEquals(str(res[1]["lastLogon"]), "y")
        self.assertEquals(str(res[2].dn), self.samba4.dn("cn=X"))
        self.assertEquals(str(res[2]["dnsHostName"]), "x")
        self.assertEquals(str(res[2]["lastLogon"]), "x")

        # Search by disjunction of local and remote attribute
        res = self.ldb.search(expression="(|(revision=x)(lastLogon=y))",
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 3)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B"))
        self.assertFalse("dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "y")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=X"))
        self.assertEquals(str(res[1]["dnsHostName"]), "x")
        self.assertEquals(str(res[1]["lastLogon"]), "x")
        self.assertEquals(str(res[2].dn), self.samba4.dn("cn=Y"))
        self.assertEquals(str(res[2]["dnsHostName"]), "y")
        self.assertEquals(str(res[2]["lastLogon"]), "y")

        # Search by disjunction of local and remote attribute w/o match
        res = self.ldb.search(expression="(|(codePage=y)(nextRid=z))",
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 0)

        # Search by negated local attribute
        res = self.ldb.search(expression="(!(revision=x))",
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 6)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B"))
        self.assertTrue(not "dnsHostName" in res[1])
        self.assertEquals(str(res[1]["lastLogon"]), "y")
        self.assertEquals(str(res[2].dn), self.samba4.dn("cn=C"))
        self.assertTrue(not "dnsHostName" in res[2])
        self.assertEquals(str(res[2]["lastLogon"]), "z")
        self.assertEquals(str(res[3].dn), self.samba4.dn("cn=Z"))
        self.assertEquals(str(res[3]["dnsHostName"]), "z")
        self.assertEquals(str(res[3]["lastLogon"]), "z")

        # Search by negated remote attribute
        res = self.ldb.search(expression="(!(description=x))",
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 4)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=C"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "z")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=Z"))
        self.assertEquals(str(res[1]["dnsHostName"]), "z")
        self.assertEquals(str(res[1]["lastLogon"]), "z")

        # Search by negated conjunction of local attributes
        res = self.ldb.search(expression="(!(&(codePage=x)(revision=x)))",
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 6)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B"))
        self.assertTrue(not "dnsHostName" in res[1])
        self.assertEquals(str(res[1]["lastLogon"]), "y")
        self.assertEquals(str(res[2].dn), self.samba4.dn("cn=C"))
        self.assertTrue(not "dnsHostName" in res[2])
        self.assertEquals(str(res[2]["lastLogon"]), "z")
        self.assertEquals(str(res[3].dn), self.samba4.dn("cn=Z"))
        self.assertEquals(str(res[3]["dnsHostName"]), "z")
        self.assertEquals(str(res[3]["lastLogon"]), "z")

        # Search by negated conjunction of remote attributes
        res = self.ldb.search(expression="(!(&(lastLogon=x)(description=x)))",
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 6)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "y")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=C"))
        self.assertTrue(not "dnsHostName" in res[1])
        self.assertEquals(str(res[1]["lastLogon"]), "z")
        self.assertEquals(str(res[2].dn), self.samba4.dn("cn=Y"))
        self.assertEquals(str(res[2]["dnsHostName"]), "y")
        self.assertEquals(str(res[2]["lastLogon"]), "y")
        self.assertEquals(str(res[3].dn), self.samba4.dn("cn=Z"))
        self.assertEquals(str(res[3]["dnsHostName"]), "z")
        self.assertEquals(str(res[3]["lastLogon"]), "z")

        # Search by negated conjunction of local and remote attribute
        res = self.ldb.search(expression="(!(&(codePage=x)(description=x)))",
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 6)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B"))
        self.assertTrue(not "dnsHostName" in res[1])
        self.assertEquals(str(res[1]["lastLogon"]), "y")
        self.assertEquals(str(res[2].dn), self.samba4.dn("cn=C"))
        self.assertTrue(not "dnsHostName" in res[2])
        self.assertEquals(str(res[2]["lastLogon"]), "z")
        self.assertEquals(str(res[3].dn), self.samba4.dn("cn=Z"))
        self.assertEquals(str(res[3]["dnsHostName"]), "z")
        self.assertEquals(str(res[3]["lastLogon"]), "z")

        # Search by negated disjunction of local attributes
        res = self.ldb.search(expression="(!(|(revision=x)(dnsHostName=x)))",
                              attrs=["dnsHostName", "lastLogon"])
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B"))
        self.assertTrue(not "dnsHostName" in res[1])
        self.assertEquals(str(res[1]["lastLogon"]), "y")
        self.assertEquals(str(res[2].dn), self.samba4.dn("cn=C"))
        self.assertTrue(not "dnsHostName" in res[2])
        self.assertEquals(str(res[2]["lastLogon"]), "z")
        self.assertEquals(str(res[3].dn), self.samba4.dn("cn=Z"))
        self.assertEquals(str(res[3]["dnsHostName"]), "z")
        self.assertEquals(str(res[3]["lastLogon"]), "z")

        # Search by negated disjunction of remote attributes
        res = self.ldb.search(expression="(!(|(badPwdCount=x)(lastLogon=x)))",
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 5)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=C"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "z")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=Y"))
        self.assertEquals(str(res[1]["dnsHostName"]), "y")
        self.assertEquals(str(res[1]["lastLogon"]), "y")
        self.assertEquals(str(res[2].dn), self.samba4.dn("cn=Z"))
        self.assertEquals(str(res[2]["dnsHostName"]), "z")
        self.assertEquals(str(res[2]["lastLogon"]), "z")

        # Search by negated disjunction of local and remote attribute
        res = self.ldb.search(expression="(!(|(revision=x)(lastLogon=y)))",
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 5)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=C"))
        self.assertTrue(not "dnsHostName" in res[1])
        self.assertEquals(str(res[1]["lastLogon"]), "z")
        self.assertEquals(str(res[2].dn), self.samba4.dn("cn=Z"))
        self.assertEquals(str(res[2]["dnsHostName"]), "z")
        self.assertEquals(str(res[2]["lastLogon"]), "z")

        # Search by complex parse tree
        res = self.ldb.search(
            expression=
            "(|(&(revision=x)(dnsHostName=x))(!(&(description=x)(nextRid=y)))(badPwdCount=y))",
            attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 7)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B"))
        self.assertTrue(not "dnsHostName" in res[1])
        self.assertEquals(str(res[1]["lastLogon"]), "y")
        self.assertEquals(str(res[2].dn), self.samba4.dn("cn=C"))
        self.assertTrue(not "dnsHostName" in res[2])
        self.assertEquals(str(res[2]["lastLogon"]), "z")
        self.assertEquals(str(res[3].dn), self.samba4.dn("cn=X"))
        self.assertEquals(str(res[3]["dnsHostName"]), "x")
        self.assertEquals(str(res[3]["lastLogon"]), "x")
        self.assertEquals(str(res[4].dn), self.samba4.dn("cn=Z"))
        self.assertEquals(str(res[4]["dnsHostName"]), "z")
        self.assertEquals(str(res[4]["lastLogon"]), "z")

        # Clean up
        dns = [
            self.samba4.dn("cn=%s" % n)
            for n in ["A", "B", "C", "X", "Y", "Z"]
        ]
        for dn in dns:
            self.ldb.delete(dn)

    def test_map_modify_local(self):
        """Modification of local records."""
        # Add local record
        dn = "cn=test,dc=idealx,dc=org"
        self.ldb.add({
            "dn": dn,
            "cn": "test",
            "foo": "bar",
            "revision": "1",
            "description": "test"
        })
        # Check it's there
        attrs = ["foo", "revision", "description"]
        res = self.ldb.search(dn, scope=SCOPE_BASE, attrs=attrs)
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertEquals(str(res[0]["foo"]), "bar")
        self.assertEquals(str(res[0]["revision"]), "1")
        self.assertEquals(str(res[0]["description"]), "test")
        # Check it's not in the local db
        res = self.samba4.db.search(expression="(cn=test)",
                                    scope=SCOPE_DEFAULT,
                                    attrs=attrs)
        self.assertEquals(len(res), 0)
        # Check it's not in the remote db
        res = self.samba3.db.search(expression="(cn=test)",
                                    scope=SCOPE_DEFAULT,
                                    attrs=attrs)
        self.assertEquals(len(res), 0)

        # Modify local record
        ldif = """
dn: """ + dn + """
replace: foo
foo: baz
replace: description
description: foo
"""
        self.ldb.modify_ldif(ldif)
        # Check in local db
        res = self.ldb.search(dn, scope=SCOPE_BASE, attrs=attrs)
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertEquals(str(res[0]["foo"]), "baz")
        self.assertEquals(str(res[0]["revision"]), "1")
        self.assertEquals(str(res[0]["description"]), "foo")

        # Rename local record
        dn2 = "cn=toast,dc=idealx,dc=org"
        self.ldb.rename(dn, dn2)
        # Check in local db
        res = self.ldb.search(dn2, scope=SCOPE_BASE, attrs=attrs)
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn2)
        self.assertEquals(str(res[0]["foo"]), "baz")
        self.assertEquals(str(res[0]["revision"]), "1")
        self.assertEquals(str(res[0]["description"]), "foo")

        # Delete local record
        self.ldb.delete(dn2)
        # Check it's gone
        res = self.ldb.search(dn2, scope=SCOPE_BASE)
        self.assertEquals(len(res), 0)

    def test_map_modify_remote_remote(self):
        """Modification of remote data of remote records"""
        # Add remote record
        dn = self.samba4.dn("cn=test")
        dn2 = self.samba3.dn("cn=test")
        self.samba3.db.add({
            "dn": dn2,
            "cn": "test",
            "description": "foo",
            "sambaBadPasswordCount": "3",
            "sambaNextRid": "1001"
        })
        # Check it's there
        res = self.samba3.db.search(
            dn2,
            scope=SCOPE_BASE,
            attrs=["description", "sambaBadPasswordCount", "sambaNextRid"])
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn2)
        self.assertEquals(str(res[0]["description"]), "foo")
        self.assertEquals(str(res[0]["sambaBadPasswordCount"]), "3")
        self.assertEquals(str(res[0]["sambaNextRid"]), "1001")
        # Check in mapped db
        attrs = ["description", "badPwdCount", "nextRid"]
        res = self.ldb.search(dn, scope=SCOPE_BASE, attrs=attrs, expression="")
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertEquals(str(res[0]["description"]), "foo")
        self.assertEquals(str(res[0]["badPwdCount"]), "3")
        self.assertEquals(str(res[0]["nextRid"]), "1001")
        # Check in local db
        res = self.samba4.db.search(dn, scope=SCOPE_BASE, attrs=attrs)
        self.assertEquals(len(res), 0)

        # Modify remote data of remote record
        ldif = """
dn: """ + dn + """
replace: description
description: test
replace: badPwdCount
badPwdCount: 4
"""
        self.ldb.modify_ldif(ldif)
        # Check in mapped db
        res = self.ldb.search(dn,
                              scope=SCOPE_BASE,
                              attrs=["description", "badPwdCount", "nextRid"])
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertEquals(str(res[0]["description"]), "test")
        self.assertEquals(str(res[0]["badPwdCount"]), "4")
        self.assertEquals(str(res[0]["nextRid"]), "1001")
        # Check in remote db
        res = self.samba3.db.search(
            dn2,
            scope=SCOPE_BASE,
            attrs=["description", "sambaBadPasswordCount", "sambaNextRid"])
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn2)
        self.assertEquals(str(res[0]["description"]), "test")
        self.assertEquals(str(res[0]["sambaBadPasswordCount"]), "4")
        self.assertEquals(str(res[0]["sambaNextRid"]), "1001")

        # Rename remote record
        dn2 = self.samba4.dn("cn=toast")
        self.ldb.rename(dn, dn2)
        # Check in mapped db
        dn = dn2
        res = self.ldb.search(dn,
                              scope=SCOPE_BASE,
                              attrs=["description", "badPwdCount", "nextRid"])
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertEquals(str(res[0]["description"]), "test")
        self.assertEquals(str(res[0]["badPwdCount"]), "4")
        self.assertEquals(str(res[0]["nextRid"]), "1001")
        # Check in remote db
        dn2 = self.samba3.dn("cn=toast")
        res = self.samba3.db.search(
            dn2,
            scope=SCOPE_BASE,
            attrs=["description", "sambaBadPasswordCount", "sambaNextRid"])
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn2)
        self.assertEquals(str(res[0]["description"]), "test")
        self.assertEquals(str(res[0]["sambaBadPasswordCount"]), "4")
        self.assertEquals(str(res[0]["sambaNextRid"]), "1001")

        # Delete remote record
        self.ldb.delete(dn)
        # Check in mapped db that it's removed
        res = self.ldb.search(dn, scope=SCOPE_BASE)
        self.assertEquals(len(res), 0)
        # Check in remote db
        res = self.samba3.db.search(dn2, scope=SCOPE_BASE)
        self.assertEquals(len(res), 0)

    def test_map_modify_remote_local(self):
        """Modification of local data of remote records"""
        # Add remote record (same as before)
        dn = self.samba4.dn("cn=test")
        dn2 = self.samba3.dn("cn=test")
        self.samba3.db.add({
            "dn": dn2,
            "cn": "test",
            "description": "foo",
            "sambaBadPasswordCount": "3",
            "sambaNextRid": "1001"
        })

        # Modify local data of remote record
        ldif = """
dn: """ + dn + """
add: revision
revision: 1
replace: description
description: test

"""
        self.ldb.modify_ldif(ldif)
        # Check in mapped db
        attrs = ["revision", "description"]
        res = self.ldb.search(dn, scope=SCOPE_BASE, attrs=attrs)
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertEquals(str(res[0]["description"]), "test")
        self.assertEquals(str(res[0]["revision"]), "1")
        # Check in remote db
        res = self.samba3.db.search(dn2, scope=SCOPE_BASE, attrs=attrs)
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn2)
        self.assertEquals(str(res[0]["description"]), "test")
        self.assertTrue(not "revision" in res[0])
        # Check in local db
        res = self.samba4.db.search(dn, scope=SCOPE_BASE, attrs=attrs)
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertTrue(not "description" in res[0])
        self.assertEquals(str(res[0]["revision"]), "1")

        # Delete (newly) split record
        self.ldb.delete(dn)

    def test_map_modify_split(self):
        """Testing modification of split records"""
        # Add split record
        dn = self.samba4.dn("cn=test")
        dn2 = self.samba3.dn("cn=test")
        self.ldb.add({
            "dn": dn,
            "cn": "test",
            "description": "foo",
            "badPwdCount": "3",
            "nextRid": "1001",
            "revision": "1"
        })
        # Check it's there
        attrs = ["description", "badPwdCount", "nextRid", "revision"]
        res = self.ldb.search(dn, scope=SCOPE_BASE, attrs=attrs)
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertEquals(str(res[0]["description"]), "foo")
        self.assertEquals(str(res[0]["badPwdCount"]), "3")
        self.assertEquals(str(res[0]["nextRid"]), "1001")
        self.assertEquals(str(res[0]["revision"]), "1")
        # Check in local db
        res = self.samba4.db.search(dn, scope=SCOPE_BASE, attrs=attrs)
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertTrue(not "description" in res[0])
        self.assertTrue(not "badPwdCount" in res[0])
        self.assertTrue(not "nextRid" in res[0])
        self.assertEquals(str(res[0]["revision"]), "1")
        # Check in remote db
        attrs = [
            "description", "sambaBadPasswordCount", "sambaNextRid", "revision"
        ]
        res = self.samba3.db.search(dn2, scope=SCOPE_BASE, attrs=attrs)
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn2)
        self.assertEquals(str(res[0]["description"]), "foo")
        self.assertEquals(str(res[0]["sambaBadPasswordCount"]), "3")
        self.assertEquals(str(res[0]["sambaNextRid"]), "1001")
        self.assertTrue(not "revision" in res[0])

        # Modify of split record
        ldif = """
dn: """ + dn + """
replace: description
description: test
replace: badPwdCount
badPwdCount: 4
replace: revision
revision: 2
"""
        self.ldb.modify_ldif(ldif)
        # Check in mapped db
        attrs = ["description", "badPwdCount", "nextRid", "revision"]
        res = self.ldb.search(dn, scope=SCOPE_BASE, attrs=attrs)
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertEquals(str(res[0]["description"]), "test")
        self.assertEquals(str(res[0]["badPwdCount"]), "4")
        self.assertEquals(str(res[0]["nextRid"]), "1001")
        self.assertEquals(str(res[0]["revision"]), "2")
        # Check in local db
        res = self.samba4.db.search(dn, scope=SCOPE_BASE, attrs=attrs)
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertTrue(not "description" in res[0])
        self.assertTrue(not "badPwdCount" in res[0])
        self.assertTrue(not "nextRid" in res[0])
        self.assertEquals(str(res[0]["revision"]), "2")
        # Check in remote db
        attrs = [
            "description", "sambaBadPasswordCount", "sambaNextRid", "revision"
        ]
        res = self.samba3.db.search(dn2, scope=SCOPE_BASE, attrs=attrs)
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn2)
        self.assertEquals(str(res[0]["description"]), "test")
        self.assertEquals(str(res[0]["sambaBadPasswordCount"]), "4")
        self.assertEquals(str(res[0]["sambaNextRid"]), "1001")
        self.assertTrue(not "revision" in res[0])

        # Rename split record
        dn2 = self.samba4.dn("cn=toast")
        self.ldb.rename(dn, dn2)
        # Check in mapped db
        dn = dn2
        attrs = ["description", "badPwdCount", "nextRid", "revision"]
        res = self.ldb.search(dn, scope=SCOPE_BASE, attrs=attrs)
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertEquals(str(res[0]["description"]), "test")
        self.assertEquals(str(res[0]["badPwdCount"]), "4")
        self.assertEquals(str(res[0]["nextRid"]), "1001")
        self.assertEquals(str(res[0]["revision"]), "2")
        # Check in local db
        res = self.samba4.db.search(dn, scope=SCOPE_BASE, attrs=attrs)
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertTrue(not "description" in res[0])
        self.assertTrue(not "badPwdCount" in res[0])
        self.assertTrue(not "nextRid" in res[0])
        self.assertEquals(str(res[0]["revision"]), "2")
        # Check in remote db
        dn2 = self.samba3.dn("cn=toast")
        res = self.samba3.db.search(dn2,
                                    scope=SCOPE_BASE,
                                    attrs=[
                                        "description", "sambaBadPasswordCount",
                                        "sambaNextRid", "revision"
                                    ])
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn2)
        self.assertEquals(str(res[0]["description"]), "test")
        self.assertEquals(str(res[0]["sambaBadPasswordCount"]), "4")
        self.assertEquals(str(res[0]["sambaNextRid"]), "1001")
        self.assertTrue(not "revision" in res[0])

        # Delete split record
        self.ldb.delete(dn)
        # Check in mapped db
        res = self.ldb.search(dn, scope=SCOPE_BASE)
        self.assertEquals(len(res), 0)
        # Check in local db
        res = self.samba4.db.search(dn, scope=SCOPE_BASE)
        self.assertEquals(len(res), 0)
        # Check in remote db
        res = self.samba3.db.search(dn2, scope=SCOPE_BASE)
        self.assertEquals(len(res), 0)
Exemplo n.º 6
0
class Samba3SamTestCase(MapBaseTestCase):
    def setUp(self):
        super(Samba3SamTestCase, self).setUp()
        ldb = Ldb(self.ldburl, lp=self.lp, session_info=system_session())
        ldb.set_opaque("skip_allocate_sids", "true")
        self.samba3.setup_data("samba3.ldif")
        ldif = read_datafile("provision_samba3sam.ldif")
        ldb.add_ldif(self.samba4.subst(ldif))
        self.setup_modules(ldb, self.samba3, self.samba4)
        del ldb
        self.ldb = Ldb(self.ldburl, lp=self.lp, session_info=system_session())
        self.ldb.set_opaque("skip_allocate_sids", "true")

    def test_search_non_mapped(self):
        """Looking up by non-mapped attribute"""
        msg = self.ldb.search(expression="(cn=Administrator)")
        self.assertEquals(len(msg), 1)
        self.assertEquals(msg[0]["cn"], "Administrator")

    def test_search_non_mapped(self):
        """Looking up by mapped attribute"""
        msg = self.ldb.search(expression="(name=Backup Operators)")
        self.assertEquals(len(msg), 1)
        self.assertEquals(str(msg[0]["name"]), "Backup Operators")

    def test_old_name_of_renamed(self):
        """Looking up by old name of renamed attribute"""
        msg = self.ldb.search(expression="(displayName=Backup Operators)")
        self.assertEquals(len(msg), 0)

    def test_mapped_containing_sid(self):
        """Looking up mapped entry containing SID"""
        msg = self.ldb.search(expression="(cn=Replicator)")
        self.assertEquals(len(msg), 1)
        self.assertEquals(str(msg[0].dn),
                          "cn=Replicator,ou=Groups,dc=vernstok,dc=nl")
        self.assertTrue("objectSid" in msg[0])
        self.assertSidEquals("S-1-5-21-4231626423-2410014848-2360679739-1052",
                             msg[0]["objectSid"])
        oc = set(msg[0]["objectClass"])
        self.assertEquals(oc, set(["group"]))

    def test_search_by_objclass(self):
        """Looking up by objectClass"""
        msg = self.ldb.search(
            expression="(|(objectClass=user)(cn=Administrator))")
        self.assertEquals(
            set([str(m.dn) for m in msg]),
            set([
                "unixName=Administrator,ou=Users,dc=vernstok,dc=nl",
                "unixName=nobody,ou=Users,dc=vernstok,dc=nl"
            ]))

    def test_s3sam_modify(self):
        # Adding a record that will be fallbacked
        self.ldb.add({
            "dn": "cn=Foo",
            "foo": "bar",
            "blah": "Blie",
            "cn": "Foo",
            "showInAdvancedViewOnly": "TRUE"
        })

        # Checking for existence of record (local)
        # TODO: This record must be searched in the local database, which is
        # currently only supported for base searches
        # msg = ldb.search(expression="(cn=Foo)", ['foo','blah','cn','showInAdvancedViewOnly')]
        # TODO: Actually, this version should work as well but doesn't...
        #
        #
        msg = self.ldb.search(
            expression="(cn=Foo)",
            base="cn=Foo",
            scope=SCOPE_BASE,
            attrs=['foo', 'blah', 'cn', 'showInAdvancedViewOnly'])
        self.assertEquals(len(msg), 1)
        self.assertEquals(str(msg[0]["showInAdvancedViewOnly"]), "TRUE")
        self.assertEquals(str(msg[0]["foo"]), "bar")
        self.assertEquals(str(msg[0]["blah"]), "Blie")

        # Adding record that will be mapped
        self.ldb.add({
            "dn": "cn=Niemand,cn=Users,dc=vernstok,dc=nl",
            "objectClass": "user",
            "unixName": "bin",
            "sambaUnicodePwd": "geheim",
            "cn": "Niemand"
        })

        # Checking for existence of record (remote)
        msg = self.ldb.search(
            expression="(unixName=bin)",
            attrs=['unixName', 'cn', 'dn', 'sambaUnicodePwd'])
        self.assertEquals(len(msg), 1)
        self.assertEquals(str(msg[0]["cn"]), "Niemand")
        self.assertEquals(str(msg[0]["sambaUnicodePwd"]), "geheim")

        # Checking for existence of record (local && remote)
        msg = self.ldb.search(
            expression="(&(unixName=bin)(sambaUnicodePwd=geheim))",
            attrs=['unixName', 'cn', 'dn', 'sambaUnicodePwd'])
        self.assertEquals(len(msg), 1)  # TODO: should check with more records
        self.assertEquals(str(msg[0]["cn"]), "Niemand")
        self.assertEquals(str(msg[0]["unixName"]), "bin")
        self.assertEquals(str(msg[0]["sambaUnicodePwd"]), "geheim")

        # Checking for existence of record (local || remote)
        msg = self.ldb.search(
            expression="(|(unixName=bin)(sambaUnicodePwd=geheim))",
            attrs=['unixName', 'cn', 'dn', 'sambaUnicodePwd'])
        #print "got %d replies" % len(msg)
        self.assertEquals(len(msg), 1)  # TODO: should check with more records
        self.assertEquals(str(msg[0]["cn"]), "Niemand")
        self.assertEquals(str(msg[0]["unixName"]), "bin")
        self.assertEquals(str(msg[0]["sambaUnicodePwd"]), "geheim")

        # Checking for data in destination database
        msg = self.samba3.db.search(expression="(cn=Niemand)")
        self.assertTrue(len(msg) >= 1)
        self.assertEquals(str(msg[0]["sambaSID"]),
                          "S-1-5-21-4231626423-2410014848-2360679739-2001")
        self.assertEquals(str(msg[0]["displayName"]), "Niemand")

        # Adding attribute...
        self.ldb.modify_ldif("""
dn: cn=Niemand,cn=Users,dc=vernstok,dc=nl
changetype: modify
add: description
description: Blah
""")

        # Checking whether changes are still there...
        msg = self.ldb.search(expression="(cn=Niemand)")
        self.assertTrue(len(msg) >= 1)
        self.assertEquals(str(msg[0]["cn"]), "Niemand")
        self.assertEquals(str(msg[0]["description"]), "Blah")

        # Modifying attribute...
        self.ldb.modify_ldif("""
dn: cn=Niemand,cn=Users,dc=vernstok,dc=nl
changetype: modify
replace: description
description: Blie
""")

        # Checking whether changes are still there...
        msg = self.ldb.search(expression="(cn=Niemand)")
        self.assertTrue(len(msg) >= 1)
        self.assertEquals(str(msg[0]["description"]), "Blie")

        # Deleting attribute...
        self.ldb.modify_ldif("""
dn: cn=Niemand,cn=Users,dc=vernstok,dc=nl
changetype: modify
delete: description
""")

        # Checking whether changes are no longer there...
        msg = self.ldb.search(expression="(cn=Niemand)")
        self.assertTrue(len(msg) >= 1)
        self.assertTrue(not "description" in msg[0])

        # Renaming record...
        self.ldb.rename("cn=Niemand,cn=Users,dc=vernstok,dc=nl",
                        "cn=Niemand2,cn=Users,dc=vernstok,dc=nl")

        # Checking whether DN has changed...
        msg = self.ldb.search(expression="(cn=Niemand2)")
        self.assertEquals(len(msg), 1)
        self.assertEquals(str(msg[0].dn),
                          "cn=Niemand2,cn=Users,dc=vernstok,dc=nl")

        # Deleting record...
        self.ldb.delete("cn=Niemand2,cn=Users,dc=vernstok,dc=nl")

        # Checking whether record is gone...
        msg = self.ldb.search(expression="(cn=Niemand2)")
        self.assertEquals(len(msg), 0)
Exemplo n.º 7
0
class MapTestCase(MapBaseTestCase):

    def setUp(self):
        super(MapTestCase, self).setUp()
        ldb = Ldb(self.ldburl, lp=self.lp, session_info=system_session())
        ldb.set_opaque("skip_allocate_sids", "true");
        ldif = read_datafile("provision_samba3sam.ldif")
        ldb.add_ldif(self.samba4.subst(ldif))
        self.setup_modules(ldb, self.samba3, self.samba4)
        del ldb
        self.ldb = Ldb(self.ldburl, lp=self.lp, session_info=system_session())
        self.ldb.set_opaque("skip_allocate_sids", "true");

    def test_map_search(self):
        """Running search tests on mapped data."""
        self.samba3.db.add({
            "dn": "sambaDomainName=TESTS," + self.samba3.basedn,
            "objectclass": ["sambaDomain", "top"],
            "sambaSID": "S-1-5-21-4231626423-2410014848-2360679739",
            "sambaNextRid": "2000",
            "sambaDomainName": "TESTS"
            })

        # Add a set of split records
        self.ldb.add_ldif("""
dn: """+ self.samba4.dn("cn=Domain Users") + """
objectClass: group
cn: Domain Users
objectSid: S-1-5-21-4231626423-2410014848-2360679739-513
""")

        # Add a set of split records
        self.ldb.add_ldif("""
dn: """+ self.samba4.dn("cn=X") + """
objectClass: user
cn: X
codePage: x
revision: x
dnsHostName: x
nextRid: y
lastLogon: x
description: x
objectSid: S-1-5-21-4231626423-2410014848-2360679739-1052
""")

        self.ldb.add({
            "dn": self.samba4.dn("cn=Y"),
            "objectClass": "top",
            "cn": "Y",
            "codePage": "x",
            "revision": "x",
            "dnsHostName": "y",
            "nextRid": "y",
            "lastLogon": "y",
            "description": "x"})

        self.ldb.add({
            "dn": self.samba4.dn("cn=Z"),
            "objectClass": "top",
            "cn": "Z",
            "codePage": "x",
            "revision": "y",
            "dnsHostName": "z",
            "nextRid": "y",
            "lastLogon": "z",
            "description": "y"})

        # Add a set of remote records

        self.samba3.db.add({
            "dn": self.samba3.dn("cn=A"),
            "objectClass": "posixAccount",
            "cn": "A",
            "sambaNextRid": "x",
            "sambaBadPasswordCount": "x",
            "sambaLogonTime": "x",
            "description": "x",
            "sambaSID": "S-1-5-21-4231626423-2410014848-2360679739-1052",
            "sambaPrimaryGroupSID": "S-1-5-21-4231626423-2410014848-2360679739-512"})

        self.samba3.db.add({
            "dn": self.samba3.dn("cn=B"),
            "objectClass": "top",
            "cn": "B",
            "sambaNextRid": "x",
            "sambaBadPasswordCount": "x",
            "sambaLogonTime": "y",
            "description": "x"})

        self.samba3.db.add({
            "dn": self.samba3.dn("cn=C"),
            "objectClass": "top",
            "cn": "C",
            "sambaNextRid": "x",
            "sambaBadPasswordCount": "y",
            "sambaLogonTime": "z",
            "description": "y"})

        # Testing search by DN

        # Search remote record by local DN
        dn = self.samba4.dn("cn=A")
        res = self.ldb.search(dn, scope=SCOPE_BASE,
                attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "x")

        # Search remote record by remote DN
        dn = self.samba3.dn("cn=A")
        res = self.samba3.db.search(dn, scope=SCOPE_BASE,
                attrs=["dnsHostName", "lastLogon", "sambaLogonTime"])
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertTrue(not "lastLogon" in res[0])
        self.assertEquals(str(res[0]["sambaLogonTime"]), "x")

        # Search split record by local DN
        dn = self.samba4.dn("cn=X")
        res = self.ldb.search(dn, scope=SCOPE_BASE,
                attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertEquals(str(res[0]["dnsHostName"]), "x")
        self.assertEquals(str(res[0]["lastLogon"]), "x")

        # Search split record by remote DN
        dn = self.samba3.dn("cn=X")
        res = self.samba3.db.search(dn, scope=SCOPE_BASE,
                attrs=["dnsHostName", "lastLogon", "sambaLogonTime"])
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertTrue(not "lastLogon" in res[0])
        self.assertEquals(str(res[0]["sambaLogonTime"]), "x")

        # Testing search by attribute

        # Search by ignored attribute
        res = self.ldb.search(expression="(revision=x)", scope=SCOPE_DEFAULT,
                attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 2)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=X"))
        self.assertEquals(str(res[0]["dnsHostName"]), "x")
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=Y"))
        self.assertEquals(str(res[1]["dnsHostName"]), "y")
        self.assertEquals(str(res[1]["lastLogon"]), "y")

        # Search by kept attribute
        res = self.ldb.search(expression="(description=y)",
                scope=SCOPE_DEFAULT, attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 2)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=C"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "z")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=Z"))
        self.assertEquals(str(res[1]["dnsHostName"]), "z")
        self.assertEquals(str(res[1]["lastLogon"]), "z")

        # Search by renamed attribute
        res = self.ldb.search(expression="(badPwdCount=x)", scope=SCOPE_DEFAULT,
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 2)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B"))
        self.assertTrue(not "dnsHostName" in res[1])
        self.assertEquals(str(res[1]["lastLogon"]), "y")

        # Search by converted attribute
        # TODO:
        #   Using the SID directly in the parse tree leads to conversion
        #   errors, letting the search fail with no results.
        #res = self.ldb.search("(objectSid=S-1-5-21-4231626423-2410014848-2360679739-1052)", scope=SCOPE_DEFAULT, attrs)
        res = self.ldb.search(expression="(objectSid=*)", base=None, scope=SCOPE_DEFAULT, attrs=["dnsHostName", "lastLogon", "objectSid"])
        self.assertEquals(len(res), 4)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=X"))
        self.assertEquals(str(res[1]["dnsHostName"]), "x")
        self.assertEquals(str(res[1]["lastLogon"]), "x")
        self.assertSidEquals("S-1-5-21-4231626423-2410014848-2360679739-1052",
                             res[1]["objectSid"])
        self.assertTrue("objectSid" in res[1])
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertSidEquals("S-1-5-21-4231626423-2410014848-2360679739-1052",
                             res[0]["objectSid"])
        self.assertTrue("objectSid" in res[0])

        # Search by generated attribute
        # In most cases, this even works when the mapping is missing
        # a `convert_operator' by enumerating the remote db.
        res = self.ldb.search(expression="(primaryGroupID=512)",
                           attrs=["dnsHostName", "lastLogon", "primaryGroupID"])
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(str(res[0]["primaryGroupID"]), "512")

        # Note that Xs "objectSid" seems to be fine in the previous search for
        # "objectSid"...
        #res = ldb.search(expression="(primaryGroupID=*)", NULL, ldb. SCOPE_DEFAULT, attrs)
        #print len(res) + " results found"
        #for i in range(len(res)):
        #    for (obj in res[i]) {
        #        print obj + ": " + res[i][obj]
        #    }
        #    print "---"
        #

        # Search by remote name of renamed attribute */
        res = self.ldb.search(expression="(sambaBadPasswordCount=*)",
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 0)

        # Search by objectClass
        attrs = ["dnsHostName", "lastLogon", "objectClass"]
        res = self.ldb.search(expression="(objectClass=user)", attrs=attrs)
        self.assertEquals(len(res), 2)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(str(res[0]["objectClass"][0]), "user")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=X"))
        self.assertEquals(str(res[1]["dnsHostName"]), "x")
        self.assertEquals(str(res[1]["lastLogon"]), "x")
        self.assertEquals(str(res[1]["objectClass"][0]), "user")

        # Prove that the objectClass is actually used for the search
        res = self.ldb.search(expression="(|(objectClass=user)(badPwdCount=x))",
                              attrs=attrs)
        self.assertEquals(len(res), 3)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(res[0]["objectClass"][0], "user")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B"))
        self.assertTrue(not "dnsHostName" in res[1])
        self.assertEquals(str(res[1]["lastLogon"]), "y")
        self.assertEquals(set(res[1]["objectClass"]), set(["top"]))
        self.assertEquals(str(res[2].dn), self.samba4.dn("cn=X"))
        self.assertEquals(str(res[2]["dnsHostName"]), "x")
        self.assertEquals(str(res[2]["lastLogon"]), "x")
        self.assertEquals(str(res[2]["objectClass"][0]), "user")

        # Testing search by parse tree

        # Search by conjunction of local attributes
        res = self.ldb.search(expression="(&(codePage=x)(revision=x))",
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 2)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=X"))
        self.assertEquals(str(res[0]["dnsHostName"]), "x")
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=Y"))
        self.assertEquals(str(res[1]["dnsHostName"]), "y")
        self.assertEquals(str(res[1]["lastLogon"]), "y")

        # Search by conjunction of remote attributes
        res = self.ldb.search(expression="(&(lastLogon=x)(description=x))",
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 2)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=X"))
        self.assertEquals(str(res[1]["dnsHostName"]), "x")
        self.assertEquals(str(res[1]["lastLogon"]), "x")

        # Search by conjunction of local and remote attribute
        res = self.ldb.search(expression="(&(codePage=x)(description=x))",
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 2)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=X"))
        self.assertEquals(str(res[0]["dnsHostName"]), "x")
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=Y"))
        self.assertEquals(str(res[1]["dnsHostName"]), "y")
        self.assertEquals(str(res[1]["lastLogon"]), "y")

        # Search by conjunction of local and remote attribute w/o match
        attrs = ["dnsHostName", "lastLogon"]
        res = self.ldb.search(expression="(&(codePage=x)(nextRid=x))",
                              attrs=attrs)
        self.assertEquals(len(res), 0)
        res = self.ldb.search(expression="(&(revision=x)(lastLogon=z))",
                              attrs=attrs)
        self.assertEquals(len(res), 0)

        # Search by disjunction of local attributes
        res = self.ldb.search(expression="(|(revision=x)(dnsHostName=x))",
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 2)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=X"))
        self.assertEquals(str(res[0]["dnsHostName"]), "x")
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=Y"))
        self.assertEquals(str(res[1]["dnsHostName"]), "y")
        self.assertEquals(str(res[1]["lastLogon"]), "y")

        # Search by disjunction of remote attributes
        res = self.ldb.search(expression="(|(badPwdCount=x)(lastLogon=x))",
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 3)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A"))
        self.assertFalse("dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B"))
        self.assertFalse("dnsHostName" in res[1])
        self.assertEquals(str(res[1]["lastLogon"]), "y")
        self.assertEquals(str(res[2].dn), self.samba4.dn("cn=X"))
        self.assertEquals(str(res[2]["dnsHostName"]), "x")
        self.assertEquals(str(res[2]["lastLogon"]), "x")

        # Search by disjunction of local and remote attribute
        res = self.ldb.search(expression="(|(revision=x)(lastLogon=y))",
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 3)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B"))
        self.assertFalse("dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "y")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=X"))
        self.assertEquals(str(res[1]["dnsHostName"]), "x")
        self.assertEquals(str(res[1]["lastLogon"]), "x")
        self.assertEquals(str(res[2].dn), self.samba4.dn("cn=Y"))
        self.assertEquals(str(res[2]["dnsHostName"]), "y")
        self.assertEquals(str(res[2]["lastLogon"]), "y")

        # Search by disjunction of local and remote attribute w/o match
        res = self.ldb.search(expression="(|(codePage=y)(nextRid=z))",
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 0)

        # Search by negated local attribute
        res = self.ldb.search(expression="(!(revision=x))",
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 6)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B"))
        self.assertTrue(not "dnsHostName" in res[1])
        self.assertEquals(str(res[1]["lastLogon"]), "y")
        self.assertEquals(str(res[2].dn), self.samba4.dn("cn=C"))
        self.assertTrue(not "dnsHostName" in res[2])
        self.assertEquals(str(res[2]["lastLogon"]), "z")
        self.assertEquals(str(res[3].dn), self.samba4.dn("cn=Z"))
        self.assertEquals(str(res[3]["dnsHostName"]), "z")
        self.assertEquals(str(res[3]["lastLogon"]), "z")

        # Search by negated remote attribute
        res = self.ldb.search(expression="(!(description=x))",
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 4)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=C"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "z")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=Z"))
        self.assertEquals(str(res[1]["dnsHostName"]), "z")
        self.assertEquals(str(res[1]["lastLogon"]), "z")

        # Search by negated conjunction of local attributes
        res = self.ldb.search(expression="(!(&(codePage=x)(revision=x)))",
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 6)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B"))
        self.assertTrue(not "dnsHostName" in res[1])
        self.assertEquals(str(res[1]["lastLogon"]), "y")
        self.assertEquals(str(res[2].dn), self.samba4.dn("cn=C"))
        self.assertTrue(not "dnsHostName" in res[2])
        self.assertEquals(str(res[2]["lastLogon"]), "z")
        self.assertEquals(str(res[3].dn), self.samba4.dn("cn=Z"))
        self.assertEquals(str(res[3]["dnsHostName"]), "z")
        self.assertEquals(str(res[3]["lastLogon"]), "z")

        # Search by negated conjunction of remote attributes
        res = self.ldb.search(expression="(!(&(lastLogon=x)(description=x)))",
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 6)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "y")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=C"))
        self.assertTrue(not "dnsHostName" in res[1])
        self.assertEquals(str(res[1]["lastLogon"]), "z")
        self.assertEquals(str(res[2].dn), self.samba4.dn("cn=Y"))
        self.assertEquals(str(res[2]["dnsHostName"]), "y")
        self.assertEquals(str(res[2]["lastLogon"]), "y")
        self.assertEquals(str(res[3].dn), self.samba4.dn("cn=Z"))
        self.assertEquals(str(res[3]["dnsHostName"]), "z")
        self.assertEquals(str(res[3]["lastLogon"]), "z")

        # Search by negated conjunction of local and remote attribute
        res = self.ldb.search(expression="(!(&(codePage=x)(description=x)))",
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 6)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B"))
        self.assertTrue(not "dnsHostName" in res[1])
        self.assertEquals(str(res[1]["lastLogon"]), "y")
        self.assertEquals(str(res[2].dn), self.samba4.dn("cn=C"))
        self.assertTrue(not "dnsHostName" in res[2])
        self.assertEquals(str(res[2]["lastLogon"]), "z")
        self.assertEquals(str(res[3].dn), self.samba4.dn("cn=Z"))
        self.assertEquals(str(res[3]["dnsHostName"]), "z")
        self.assertEquals(str(res[3]["lastLogon"]), "z")

        # Search by negated disjunction of local attributes
        res = self.ldb.search(expression="(!(|(revision=x)(dnsHostName=x)))",
                              attrs=["dnsHostName", "lastLogon"])
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B"))
        self.assertTrue(not "dnsHostName" in res[1])
        self.assertEquals(str(res[1]["lastLogon"]), "y")
        self.assertEquals(str(res[2].dn), self.samba4.dn("cn=C"))
        self.assertTrue(not "dnsHostName" in res[2])
        self.assertEquals(str(res[2]["lastLogon"]), "z")
        self.assertEquals(str(res[3].dn), self.samba4.dn("cn=Z"))
        self.assertEquals(str(res[3]["dnsHostName"]), "z")
        self.assertEquals(str(res[3]["lastLogon"]), "z")

        # Search by negated disjunction of remote attributes
        res = self.ldb.search(expression="(!(|(badPwdCount=x)(lastLogon=x)))",
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 5)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=C"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "z")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=Y"))
        self.assertEquals(str(res[1]["dnsHostName"]), "y")
        self.assertEquals(str(res[1]["lastLogon"]), "y")
        self.assertEquals(str(res[2].dn), self.samba4.dn("cn=Z"))
        self.assertEquals(str(res[2]["dnsHostName"]), "z")
        self.assertEquals(str(res[2]["lastLogon"]), "z")

        # Search by negated disjunction of local and remote attribute
        res = self.ldb.search(expression="(!(|(revision=x)(lastLogon=y)))",
                              attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 5)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=C"))
        self.assertTrue(not "dnsHostName" in res[1])
        self.assertEquals(str(res[1]["lastLogon"]), "z")
        self.assertEquals(str(res[2].dn), self.samba4.dn("cn=Z"))
        self.assertEquals(str(res[2]["dnsHostName"]), "z")
        self.assertEquals(str(res[2]["lastLogon"]), "z")

        # Search by complex parse tree
        res = self.ldb.search(expression="(|(&(revision=x)(dnsHostName=x))(!(&(description=x)(nextRid=y)))(badPwdCount=y))", attrs=["dnsHostName", "lastLogon"])
        self.assertEquals(len(res), 7)
        res = sorted(res, key=attrgetter('dn'))
        self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A"))
        self.assertTrue(not "dnsHostName" in res[0])
        self.assertEquals(str(res[0]["lastLogon"]), "x")
        self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B"))
        self.assertTrue(not "dnsHostName" in res[1])
        self.assertEquals(str(res[1]["lastLogon"]), "y")
        self.assertEquals(str(res[2].dn), self.samba4.dn("cn=C"))
        self.assertTrue(not "dnsHostName" in res[2])
        self.assertEquals(str(res[2]["lastLogon"]), "z")
        self.assertEquals(str(res[3].dn), self.samba4.dn("cn=X"))
        self.assertEquals(str(res[3]["dnsHostName"]), "x")
        self.assertEquals(str(res[3]["lastLogon"]), "x")
        self.assertEquals(str(res[4].dn), self.samba4.dn("cn=Z"))
        self.assertEquals(str(res[4]["dnsHostName"]), "z")
        self.assertEquals(str(res[4]["lastLogon"]), "z")

        # Clean up
        dns = [self.samba4.dn("cn=%s" % n) for n in ["A","B","C","X","Y","Z"]]
        for dn in dns:
            self.ldb.delete(dn)

    def test_map_modify_local(self):
        """Modification of local records."""
        # Add local record
        dn = "cn=test,dc=idealx,dc=org"
        self.ldb.add({"dn": dn,
                 "cn": "test",
                 "foo": "bar",
                 "revision": "1",
                 "description": "test"})
        # Check it's there
        attrs = ["foo", "revision", "description"]
        res = self.ldb.search(dn, scope=SCOPE_BASE, attrs=attrs)
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertEquals(str(res[0]["foo"]), "bar")
        self.assertEquals(str(res[0]["revision"]), "1")
        self.assertEquals(str(res[0]["description"]), "test")
        # Check it's not in the local db
        res = self.samba4.db.search(expression="(cn=test)",
                                    scope=SCOPE_DEFAULT, attrs=attrs)
        self.assertEquals(len(res), 0)
        # Check it's not in the remote db
        res = self.samba3.db.search(expression="(cn=test)",
                                    scope=SCOPE_DEFAULT, attrs=attrs)
        self.assertEquals(len(res), 0)

        # Modify local record
        ldif = """
dn: """ + dn + """
replace: foo
foo: baz
replace: description
description: foo
"""
        self.ldb.modify_ldif(ldif)
        # Check in local db
        res = self.ldb.search(dn, scope=SCOPE_BASE, attrs=attrs)
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertEquals(str(res[0]["foo"]), "baz")
        self.assertEquals(str(res[0]["revision"]), "1")
        self.assertEquals(str(res[0]["description"]), "foo")

        # Rename local record
        dn2 = "cn=toast,dc=idealx,dc=org"
        self.ldb.rename(dn, dn2)
        # Check in local db
        res = self.ldb.search(dn2, scope=SCOPE_BASE, attrs=attrs)
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn2)
        self.assertEquals(str(res[0]["foo"]), "baz")
        self.assertEquals(str(res[0]["revision"]), "1")
        self.assertEquals(str(res[0]["description"]), "foo")

        # Delete local record
        self.ldb.delete(dn2)
        # Check it's gone
        res = self.ldb.search(dn2, scope=SCOPE_BASE)
        self.assertEquals(len(res), 0)

    def test_map_modify_remote_remote(self):
        """Modification of remote data of remote records"""
        # Add remote record
        dn = self.samba4.dn("cn=test")
        dn2 = self.samba3.dn("cn=test")
        self.samba3.db.add({"dn": dn2,
                   "cn": "test",
                   "description": "foo",
                   "sambaBadPasswordCount": "3",
                   "sambaNextRid": "1001"})
        # Check it's there
        res = self.samba3.db.search(dn2, scope=SCOPE_BASE,
                attrs=["description", "sambaBadPasswordCount", "sambaNextRid"])
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn2)
        self.assertEquals(str(res[0]["description"]), "foo")
        self.assertEquals(str(res[0]["sambaBadPasswordCount"]), "3")
        self.assertEquals(str(res[0]["sambaNextRid"]), "1001")
        # Check in mapped db
        attrs = ["description", "badPwdCount", "nextRid"]
        res = self.ldb.search(dn, scope=SCOPE_BASE, attrs=attrs, expression="")
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertEquals(str(res[0]["description"]), "foo")
        self.assertEquals(str(res[0]["badPwdCount"]), "3")
        self.assertEquals(str(res[0]["nextRid"]), "1001")
        # Check in local db
        res = self.samba4.db.search(dn, scope=SCOPE_BASE, attrs=attrs)
        self.assertEquals(len(res), 0)

        # Modify remote data of remote record
        ldif = """
dn: """ + dn + """
replace: description
description: test
replace: badPwdCount
badPwdCount: 4
"""
        self.ldb.modify_ldif(ldif)
        # Check in mapped db
        res = self.ldb.search(dn, scope=SCOPE_BASE,
                attrs=["description", "badPwdCount", "nextRid"])
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertEquals(str(res[0]["description"]), "test")
        self.assertEquals(str(res[0]["badPwdCount"]), "4")
        self.assertEquals(str(res[0]["nextRid"]), "1001")
        # Check in remote db
        res = self.samba3.db.search(dn2, scope=SCOPE_BASE,
                attrs=["description", "sambaBadPasswordCount", "sambaNextRid"])
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn2)
        self.assertEquals(str(res[0]["description"]), "test")
        self.assertEquals(str(res[0]["sambaBadPasswordCount"]), "4")
        self.assertEquals(str(res[0]["sambaNextRid"]), "1001")

        # Rename remote record
        dn2 = self.samba4.dn("cn=toast")
        self.ldb.rename(dn, dn2)
        # Check in mapped db
        dn = dn2
        res = self.ldb.search(dn, scope=SCOPE_BASE,
                attrs=["description", "badPwdCount", "nextRid"])
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertEquals(str(res[0]["description"]), "test")
        self.assertEquals(str(res[0]["badPwdCount"]), "4")
        self.assertEquals(str(res[0]["nextRid"]), "1001")
        # Check in remote db
        dn2 = self.samba3.dn("cn=toast")
        res = self.samba3.db.search(dn2, scope=SCOPE_BASE,
                attrs=["description", "sambaBadPasswordCount", "sambaNextRid"])
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn2)
        self.assertEquals(str(res[0]["description"]), "test")
        self.assertEquals(str(res[0]["sambaBadPasswordCount"]), "4")
        self.assertEquals(str(res[0]["sambaNextRid"]), "1001")

        # Delete remote record
        self.ldb.delete(dn)
        # Check in mapped db that it's removed
        res = self.ldb.search(dn, scope=SCOPE_BASE)
        self.assertEquals(len(res), 0)
        # Check in remote db
        res = self.samba3.db.search(dn2, scope=SCOPE_BASE)
        self.assertEquals(len(res), 0)

    def test_map_modify_remote_local(self):
        """Modification of local data of remote records"""
        # Add remote record (same as before)
        dn = self.samba4.dn("cn=test")
        dn2 = self.samba3.dn("cn=test")
        self.samba3.db.add({"dn": dn2,
                   "cn": "test",
                   "description": "foo",
                   "sambaBadPasswordCount": "3",
                   "sambaNextRid": "1001"})

        # Modify local data of remote record
        ldif = """
dn: """ + dn + """
add: revision
revision: 1
replace: description
description: test

"""
        self.ldb.modify_ldif(ldif)
        # Check in mapped db
        attrs = ["revision", "description"]
        res = self.ldb.search(dn, scope=SCOPE_BASE, attrs=attrs)
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertEquals(str(res[0]["description"]), "test")
        self.assertEquals(str(res[0]["revision"]), "1")
        # Check in remote db
        res = self.samba3.db.search(dn2, scope=SCOPE_BASE, attrs=attrs)
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn2)
        self.assertEquals(str(res[0]["description"]), "test")
        self.assertTrue(not "revision" in res[0])
        # Check in local db
        res = self.samba4.db.search(dn, scope=SCOPE_BASE, attrs=attrs)
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertTrue(not "description" in res[0])
        self.assertEquals(str(res[0]["revision"]), "1")

        # Delete (newly) split record
        self.ldb.delete(dn)

    def test_map_modify_split(self):
        """Testing modification of split records"""
        # Add split record
        dn = self.samba4.dn("cn=test")
        dn2 = self.samba3.dn("cn=test")
        self.ldb.add({
            "dn": dn,
            "cn": "test",
            "description": "foo",
            "badPwdCount": "3",
            "nextRid": "1001",
            "revision": "1"})
        # Check it's there
        attrs = ["description", "badPwdCount", "nextRid", "revision"]
        res = self.ldb.search(dn, scope=SCOPE_BASE, attrs=attrs)
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertEquals(str(res[0]["description"]), "foo")
        self.assertEquals(str(res[0]["badPwdCount"]), "3")
        self.assertEquals(str(res[0]["nextRid"]), "1001")
        self.assertEquals(str(res[0]["revision"]), "1")
        # Check in local db
        res = self.samba4.db.search(dn, scope=SCOPE_BASE, attrs=attrs)
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertTrue(not "description" in res[0])
        self.assertTrue(not "badPwdCount" in res[0])
        self.assertTrue(not "nextRid" in res[0])
        self.assertEquals(str(res[0]["revision"]), "1")
        # Check in remote db
        attrs = ["description", "sambaBadPasswordCount", "sambaNextRid",
                 "revision"]
        res = self.samba3.db.search(dn2, scope=SCOPE_BASE, attrs=attrs)
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn2)
        self.assertEquals(str(res[0]["description"]), "foo")
        self.assertEquals(str(res[0]["sambaBadPasswordCount"]), "3")
        self.assertEquals(str(res[0]["sambaNextRid"]), "1001")
        self.assertTrue(not "revision" in res[0])

        # Modify of split record
        ldif = """
dn: """ + dn + """
replace: description
description: test
replace: badPwdCount
badPwdCount: 4
replace: revision
revision: 2
"""
        self.ldb.modify_ldif(ldif)
        # Check in mapped db
        attrs = ["description", "badPwdCount", "nextRid", "revision"]
        res = self.ldb.search(dn, scope=SCOPE_BASE, attrs=attrs)
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertEquals(str(res[0]["description"]), "test")
        self.assertEquals(str(res[0]["badPwdCount"]), "4")
        self.assertEquals(str(res[0]["nextRid"]), "1001")
        self.assertEquals(str(res[0]["revision"]), "2")
        # Check in local db
        res = self.samba4.db.search(dn, scope=SCOPE_BASE, attrs=attrs)
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertTrue(not "description" in res[0])
        self.assertTrue(not "badPwdCount" in res[0])
        self.assertTrue(not "nextRid" in res[0])
        self.assertEquals(str(res[0]["revision"]), "2")
        # Check in remote db
        attrs = ["description", "sambaBadPasswordCount", "sambaNextRid",
                 "revision"]
        res = self.samba3.db.search(dn2, scope=SCOPE_BASE, attrs=attrs)
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn2)
        self.assertEquals(str(res[0]["description"]), "test")
        self.assertEquals(str(res[0]["sambaBadPasswordCount"]), "4")
        self.assertEquals(str(res[0]["sambaNextRid"]), "1001")
        self.assertTrue(not "revision" in res[0])

        # Rename split record
        dn2 = self.samba4.dn("cn=toast")
        self.ldb.rename(dn, dn2)
        # Check in mapped db
        dn = dn2
        attrs = ["description", "badPwdCount", "nextRid", "revision"]
        res = self.ldb.search(dn, scope=SCOPE_BASE, attrs=attrs)
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertEquals(str(res[0]["description"]), "test")
        self.assertEquals(str(res[0]["badPwdCount"]), "4")
        self.assertEquals(str(res[0]["nextRid"]), "1001")
        self.assertEquals(str(res[0]["revision"]), "2")
        # Check in local db
        res = self.samba4.db.search(dn, scope=SCOPE_BASE, attrs=attrs)
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn)
        self.assertTrue(not "description" in res[0])
        self.assertTrue(not "badPwdCount" in res[0])
        self.assertTrue(not "nextRid" in res[0])
        self.assertEquals(str(res[0]["revision"]), "2")
        # Check in remote db
        dn2 = self.samba3.dn("cn=toast")
        res = self.samba3.db.search(dn2, scope=SCOPE_BASE,
          attrs=["description", "sambaBadPasswordCount", "sambaNextRid",
                 "revision"])
        self.assertEquals(len(res), 1)
        self.assertEquals(str(res[0].dn), dn2)
        self.assertEquals(str(res[0]["description"]), "test")
        self.assertEquals(str(res[0]["sambaBadPasswordCount"]), "4")
        self.assertEquals(str(res[0]["sambaNextRid"]), "1001")
        self.assertTrue(not "revision" in res[0])

        # Delete split record
        self.ldb.delete(dn)
        # Check in mapped db
        res = self.ldb.search(dn, scope=SCOPE_BASE)
        self.assertEquals(len(res), 0)
        # Check in local db
        res = self.samba4.db.search(dn, scope=SCOPE_BASE)
        self.assertEquals(len(res), 0)
        # Check in remote db
        res = self.samba3.db.search(dn2, scope=SCOPE_BASE)
        self.assertEquals(len(res), 0)
Exemplo n.º 8
0
class Samba3SamTestCase(MapBaseTestCase):

    def setUp(self):
        super(Samba3SamTestCase, self).setUp()
        ldb = Ldb(self.ldburl, lp=self.lp, session_info=system_session())
        ldb.set_opaque("skip_allocate_sids", "true");
        self.samba3.setup_data("samba3.ldif")
        ldif = read_datafile("provision_samba3sam.ldif")
        ldb.add_ldif(self.samba4.subst(ldif))
        self.setup_modules(ldb, self.samba3, self.samba4)
        del ldb
        self.ldb = Ldb(self.ldburl, lp=self.lp, session_info=system_session())
        self.ldb.set_opaque("skip_allocate_sids", "true");

    def test_search_non_mapped(self):
        """Looking up by non-mapped attribute"""
        msg = self.ldb.search(expression="(cn=Administrator)")
        self.assertEquals(len(msg), 1)
        self.assertEquals(msg[0]["cn"], "Administrator")

    def test_search_non_mapped(self):
        """Looking up by mapped attribute"""
        msg = self.ldb.search(expression="(name=Backup Operators)")
        self.assertEquals(len(msg), 1)
        self.assertEquals(str(msg[0]["name"]), "Backup Operators")

    def test_old_name_of_renamed(self):
        """Looking up by old name of renamed attribute"""
        msg = self.ldb.search(expression="(displayName=Backup Operators)")
        self.assertEquals(len(msg), 0)

    def test_mapped_containing_sid(self):
        """Looking up mapped entry containing SID"""
        msg = self.ldb.search(expression="(cn=Replicator)")
        self.assertEquals(len(msg), 1)
        self.assertEquals(str(msg[0].dn),
                          "cn=Replicator,ou=Groups,dc=vernstok,dc=nl")
        self.assertTrue("objectSid" in msg[0])
        self.assertSidEquals("S-1-5-21-4231626423-2410014848-2360679739-1052",
                             msg[0]["objectSid"])
        oc = set(msg[0]["objectClass"])
        self.assertEquals(oc, set(["group"]))

    def test_search_by_objclass(self):
        """Looking up by objectClass"""
        msg = self.ldb.search(expression="(|(objectClass=user)(cn=Administrator))")
        self.assertEquals(set([str(m.dn) for m in msg]),
                set(["unixName=Administrator,ou=Users,dc=vernstok,dc=nl",
                     "unixName=nobody,ou=Users,dc=vernstok,dc=nl"]))

    def test_s3sam_modify(self):
        # Adding a record that will be fallbacked
        self.ldb.add({
            "dn": "cn=Foo",
            "foo": "bar",
            "blah": "Blie",
            "cn": "Foo",
            "showInAdvancedViewOnly": "TRUE"})

        # Checking for existence of record (local)
        # TODO: This record must be searched in the local database, which is
        # currently only supported for base searches
        # msg = ldb.search(expression="(cn=Foo)", ['foo','blah','cn','showInAdvancedViewOnly')]
        # TODO: Actually, this version should work as well but doesn't...
        #
        #
        msg = self.ldb.search(expression="(cn=Foo)", base="cn=Foo",
                scope=SCOPE_BASE,
                attrs=['foo','blah','cn','showInAdvancedViewOnly'])
        self.assertEquals(len(msg), 1)
        self.assertEquals(str(msg[0]["showInAdvancedViewOnly"]), "TRUE")
        self.assertEquals(str(msg[0]["foo"]), "bar")
        self.assertEquals(str(msg[0]["blah"]), "Blie")

        # Adding record that will be mapped
        self.ldb.add({"dn": "cn=Niemand,cn=Users,dc=vernstok,dc=nl",
                 "objectClass": "user",
                 "unixName": "bin",
                 "sambaUnicodePwd": "geheim",
                 "cn": "Niemand"})

        # Checking for existence of record (remote)
        msg = self.ldb.search(expression="(unixName=bin)",
                              attrs=['unixName','cn','dn', 'sambaUnicodePwd'])
        self.assertEquals(len(msg), 1)
        self.assertEquals(str(msg[0]["cn"]), "Niemand")
        self.assertEquals(str(msg[0]["sambaUnicodePwd"]), "geheim")

        # Checking for existence of record (local && remote)
        msg = self.ldb.search(expression="(&(unixName=bin)(sambaUnicodePwd=geheim))",
                         attrs=['unixName','cn','dn', 'sambaUnicodePwd'])
        self.assertEquals(len(msg), 1)           # TODO: should check with more records
        self.assertEquals(str(msg[0]["cn"]), "Niemand")
        self.assertEquals(str(msg[0]["unixName"]), "bin")
        self.assertEquals(str(msg[0]["sambaUnicodePwd"]), "geheim")

        # Checking for existence of record (local || remote)
        msg = self.ldb.search(expression="(|(unixName=bin)(sambaUnicodePwd=geheim))",
                         attrs=['unixName','cn','dn', 'sambaUnicodePwd'])
        #print "got %d replies" % len(msg)
        self.assertEquals(len(msg), 1)        # TODO: should check with more records
        self.assertEquals(str(msg[0]["cn"]), "Niemand")
        self.assertEquals(str(msg[0]["unixName"]), "bin")
        self.assertEquals(str(msg[0]["sambaUnicodePwd"]), "geheim")

        # Checking for data in destination database
        msg = self.samba3.db.search(expression="(cn=Niemand)")
        self.assertTrue(len(msg) >= 1)
        self.assertEquals(str(msg[0]["sambaSID"]),
                "S-1-5-21-4231626423-2410014848-2360679739-2001")
        self.assertEquals(str(msg[0]["displayName"]), "Niemand")

        # Adding attribute...
        self.ldb.modify_ldif("""
dn: cn=Niemand,cn=Users,dc=vernstok,dc=nl
changetype: modify
add: description
description: Blah
""")

        # Checking whether changes are still there...
        msg = self.ldb.search(expression="(cn=Niemand)")
        self.assertTrue(len(msg) >= 1)
        self.assertEquals(str(msg[0]["cn"]), "Niemand")
        self.assertEquals(str(msg[0]["description"]), "Blah")

        # Modifying attribute...
        self.ldb.modify_ldif("""
dn: cn=Niemand,cn=Users,dc=vernstok,dc=nl
changetype: modify
replace: description
description: Blie
""")

        # Checking whether changes are still there...
        msg = self.ldb.search(expression="(cn=Niemand)")
        self.assertTrue(len(msg) >= 1)
        self.assertEquals(str(msg[0]["description"]), "Blie")

        # Deleting attribute...
        self.ldb.modify_ldif("""
dn: cn=Niemand,cn=Users,dc=vernstok,dc=nl
changetype: modify
delete: description
""")

        # Checking whether changes are no longer there...
        msg = self.ldb.search(expression="(cn=Niemand)")
        self.assertTrue(len(msg) >= 1)
        self.assertTrue(not "description" in msg[0])

        # Renaming record...
        self.ldb.rename("cn=Niemand,cn=Users,dc=vernstok,dc=nl",
                        "cn=Niemand2,cn=Users,dc=vernstok,dc=nl")

        # Checking whether DN has changed...
        msg = self.ldb.search(expression="(cn=Niemand2)")
        self.assertEquals(len(msg), 1)
        self.assertEquals(str(msg[0].dn),
                          "cn=Niemand2,cn=Users,dc=vernstok,dc=nl")

        # Deleting record...
        self.ldb.delete("cn=Niemand2,cn=Users,dc=vernstok,dc=nl")

        # Checking whether record is gone...
        msg = self.ldb.search(expression="(cn=Niemand2)")
        self.assertEquals(len(msg), 0)
Exemplo n.º 9
0
class OpenChangeDBWithLdbBackend(object):
    """The OpenChange database."""

    def __init__(self, url):
        self.url = url
        self.ldb = Ldb(self.url)
        self.nttime = samba.unix2nttime(int(time.time()))

    def reopen(self):
        self.ldb = Ldb(self.url)

    def remove(self):
        """Remove an existing OpenChangeDB file."""
        if os.path.exists(self.url):
            os.remove(self.url)
        self.reopen()

    def setup(self, names=None):
        self.ldb.add_ldif("""
dn: @OPTIONS
checkBaseOnSearch: TRUE

dn: @INDEXLIST
@IDXATTR: cn

dn: @ATTRIBUTES
cn: CASE_INSENSITIVE
dn: CASE_INSENSITIVE

""")
        self.reopen()
        if names:
            self.add_rootDSE(names.ocserverdn, names.firstorg, names.firstou)

    def add_rootDSE(self, ocserverdn, firstorg, firstou):
        self.ldb.add({"dn": "@ROOTDSE",
                      "defaultNamingContext": "CN=%s,CN=%s,%s" % (firstou, firstorg, ocserverdn),
                      "rootDomainNamingContext": ocserverdn,
                      "vendorName": "OpenChange Team (http://www.openchange.org)"})

    def add_server(self, names):
        self.ldb.add({"dn": names.ocserverdn,
                      "objectClass": ["top", "server"],
                      "cn": names.netbiosname,
                      "GlobalCount": "1",
                      "ChangeNumber": "1",
                      "ReplicaID": "1"})
        self.ldb.add({"dn": "CN=%s,%s" % (names.firstorg, names.ocserverdn),
                      "objectClass": ["top", "org"],
                      "cn": names.firstorg})
        self.ldb.add({"dn": "CN=%s,CN=%s,%s" % (names.firstou, names.firstorg, names.ocserverdn),
                      "objectClass": ["top", "ou"],
                      "cn": names.firstou})

    def add_root_public_folder(self, dn, fid, change_num, SystemIdx, childcount):
        self.ldb.add({"dn": dn,
                      "objectClass": ["publicfolder"],
                      "cn": fid,
                      "PidTagFolderId": fid,
                      "PidTagChangeNumber": change_num,
                      "PidTagDisplayName": "Public Folder Root",
                      "PidTagCreationTime": "%d" % self.nttime,
                      "PidTagLastModificationTime": "%d" % self.nttime,
                      "PidTagSubFolders": str(childcount != 0).upper(),
                      "PidTagFolderChildCount": str(childcount),
                      "SystemIdx": str(SystemIdx)})

    def add_sub_public_folder(self, dn, parentfid, fid, change_num, name, SystemIndex, childcount):
        self.ldb.add({"dn": dn,
                      "objectClass": ["publicfolder"],
                      "cn": fid,
                      "PidTagFolderId": fid,
                      "PidTagParentFolderId": parentfid,
                      "PidTagChangeNumber": change_num,
                      "PidTagDisplayName": name,
                      "PidTagCreationTime": "%d" % self.nttime,
                      "PidTagLastModificationTime": "%d" % self.nttime,
                      "PidTagAttributeHidden": str(0),
                      "PidTagAttributeReadOnly": str(0),
                      "PidTagAttributeSystem": str(0),
                      "PidTagContainerClass": "IPF.Note (check this)",
                      "PidTagSubFolders": str(childcount != 0).upper(),
                      "PidTagFolderChildCount": str(childcount),
                      "FolderType": str(1),
                      "SystemIdx": str(SystemIndex)})

    def add_one_public_folder(self, parent_fid, path, children, SystemIndex, names, dn_prefix = None):

        name = path[-1]
        GlobalCount = self.get_message_GlobalCount(names.netbiosname)
        ChangeNumber = self.get_message_ChangeNumber(names.netbiosname)
        ReplicaID = self.get_message_ReplicaID(names.netbiosname)
        if dn_prefix is None:
            dn_prefix = "CN=publicfolders,CN=%s,CN=%s,%s" % (names.firstou, names.firstorg, names.ocserverdn)
        fid = gen_mailbox_folder_fid(GlobalCount, ReplicaID)
        dn = "CN=%s,%s" % (fid, dn_prefix)
        change_num = gen_mailbox_folder_fid(ChangeNumber, ReplicaID)
        childcount = len(children)
        print "\t* %-40s: 0x%.16x (%s)" % (name, int(fid, 10), fid)
        if parent_fid == 0:
            self.add_root_public_folder(dn, fid, change_num, SystemIndex, childcount)
        else:
            self.add_sub_public_folder(dn, parent_fid, fid, change_num, name, SystemIndex, childcount)

        GlobalCount += 1
        self.set_message_GlobalCount(names.netbiosname, GlobalCount=GlobalCount)
        ChangeNumber += 1
        self.set_message_ChangeNumber(names.netbiosname, ChangeNumber=ChangeNumber)

        for name, grandchildren in children.iteritems():
            self.add_one_public_folder(fid, path + (name,), grandchildren[0], grandchildren[1], names, dn)

    def add_public_folders(self, names):
        pfstoreGUID = str(uuid.uuid4())
        self.ldb.add({"dn": "CN=publicfolders,CN=%s,CN=%s,%s" % (names.firstou, names.firstorg, names.ocserverdn),
                      "objectClass": ["container"],
                      "cn": "publicfolders",
                      "StoreGUID": pfstoreGUID,
                      "ReplicaID": str(1)})
        public_folders = _public_folders_meta(names)
        self.add_one_public_folder(0, ("Public Folder Root",), public_folders[0], public_folders[1], names)

    def lookup_server(self, cn, attributes=[]):
        # Step 1. Search Server object
        filter = "(&(objectClass=server)(cn=%s))" % cn
        res = self.ldb.search("", scope=ldb.SCOPE_SUBTREE,
                           expression=filter, attrs=attributes)
        if len(res) != 1:
            raise NoSuchServer(cn)
        return res[0]

    def lookup_mailbox_user(self, server, username, attributes=[]):
        """Check if a user already exists in openchange database.

        :param server: Server object name
        :param username: Username object
        :return: LDB Object of the user
        """
        server_dn = self.lookup_server(server, []).dn

        # Step 2. Search User object
        filter = "(&(objectClass=mailbox)(cn=%s))" % (username)
        return self.ldb.search(server_dn, scope=ldb.SCOPE_SUBTREE,
                           expression=filter, attrs=attributes)

    def lookup_public_folder(self, server, displayname, attributes=[]):
        """Retrieve the record for a public folder matching a specific display name

        :param server: Server Object Name
        :param displayname: Display Name of the Folder
        :param attributes: Requested Attributes
        :return: LDB Object of the Folder
        """
        server_dn = self.lookup_server(server, []).dn

        filter = "(&(objectClass=publicfolder)(PidTagDisplayName=%s))" % (displayname)
        return self.ldb.search(server_dn, scope=ldb.SCOPE_SUBTREE,
                               expression=filter, attrs=attributes)

    def get_message_attribute(self, server, attribute):
        """Retrieve attribute value from given message database (server).

        :param server: Server object name
        """
        return int(self.lookup_server(server, [attribute])[attribute][0], 10)

    def get_message_ReplicaID(self, server):
        """Retrieve current mailbox Replica ID for given message database (server).

        :param server: Server object name
        """
        return self.get_message_attribute(server, "ReplicaID")

    def get_message_GlobalCount(self, server):
        """Retrieve current mailbox Global Count for given message database (server).

        :param server: Server object name
        """
        return self.get_message_attribute(server, "GlobalCount")


    def set_message_GlobalCount(self, server, GlobalCount):
        """Update current mailbox GlobalCount for given message database (server).

        :param server: Server object name
        :param index: Mailbox new GlobalCount value
        """
        server_dn = self.lookup_server(server, []).dn

        newGlobalCount = """
dn: %s
changetype: modify
replace: GlobalCount
GlobalCount: %d
""" % (server_dn, GlobalCount)

        self.ldb.transaction_start()
        try:
            self.ldb.modify_ldif(newGlobalCount)
        finally:
            self.ldb.transaction_commit()

    def get_message_ChangeNumber(self, server):
        """Retrieve current mailbox Global Count for given message database (server).

        :param server: Server object name
        """
        return self.get_message_attribute(server, "ChangeNumber")


    def set_message_ChangeNumber(self, server, ChangeNumber):
        """Update current mailbox ChangeNumber for given message database (server).

        :param server: Server object name
        :param index: Mailbox new ChangeNumber value
        """
        server_dn = self.lookup_server(server, []).dn

        newChangeNumber = """
dn: %s
changetype: modify
replace: ChangeNumber
ChangeNumber: %d
""" % (server_dn, ChangeNumber)

        self.ldb.transaction_start()
        try:
            self.ldb.modify_ldif(newChangeNumber)
        finally:
            self.ldb.transaction_commit()
Exemplo n.º 10
0
class OpenChangeDBWithLdbBackend(object):
    """The OpenChange database."""
    def __init__(self, url):
        self.url = url
        self.ldb = Ldb(self.url)
        self.nttime = samba.unix2nttime(int(time.time()))

    def reopen(self):
        self.ldb = Ldb(self.url)

    def remove(self):
        """Remove an existing OpenChangeDB file."""
        if os.path.exists(self.url):
            os.remove(self.url)
        self.reopen()

    def setup(self, names=None):
        self.ldb.add_ldif("""
dn: @OPTIONS
checkBaseOnSearch: TRUE

dn: @INDEXLIST
@IDXATTR: cn

dn: @ATTRIBUTES
cn: CASE_INSENSITIVE
dn: CASE_INSENSITIVE

""")
        self.reopen()
        if names:
            self.add_rootDSE(names.ocserverdn, names.firstorg, names.firstou)

    def add_rootDSE(self, ocserverdn, firstorg, firstou):
        self.ldb.add({
            "dn":
            "@ROOTDSE",
            "defaultNamingContext":
            "CN=%s,CN=%s,%s" % (firstou, firstorg, ocserverdn),
            "rootDomainNamingContext":
            ocserverdn,
            "vendorName":
            "OpenChange Team (http://www.openchange.org)"
        })

    def add_server(self, names):
        self.ldb.add({
            "dn": names.ocserverdn,
            "objectClass": ["top", "server"],
            "cn": names.netbiosname,
            "GlobalCount": "1",
            "ChangeNumber": "1",
            "ReplicaID": "1"
        })
        self.ldb.add({
            "dn": "CN=%s,%s" % (names.firstorg, names.ocserverdn),
            "objectClass": ["top", "org"],
            "cn": names.firstorg
        })
        self.ldb.add({
            "dn":
            "CN=%s,CN=%s,%s" %
            (names.firstou, names.firstorg, names.ocserverdn),
            "objectClass": ["top", "ou"],
            "cn":
            names.firstou
        })

    def add_root_public_folder(self, dn, fid, change_num, SystemIdx,
                               childcount):
        self.ldb.add({
            "dn": dn,
            "objectClass": ["publicfolder"],
            "cn": fid,
            "PidTagFolderId": fid,
            "PidTagChangeNumber": change_num,
            "PidTagDisplayName": "Public Folder Root",
            "PidTagCreationTime": "%d" % self.nttime,
            "PidTagLastModificationTime": "%d" % self.nttime,
            "PidTagSubFolders": str(childcount != 0).upper(),
            "PidTagFolderChildCount": str(childcount),
            "SystemIdx": str(SystemIdx)
        })

    def add_sub_public_folder(self, dn, parentfid, fid, change_num, name,
                              SystemIndex, childcount):
        self.ldb.add({
            "dn": dn,
            "objectClass": ["publicfolder"],
            "cn": fid,
            "PidTagFolderId": fid,
            "PidTagParentFolderId": parentfid,
            "PidTagChangeNumber": change_num,
            "PidTagDisplayName": name,
            "PidTagCreationTime": "%d" % self.nttime,
            "PidTagLastModificationTime": "%d" % self.nttime,
            "PidTagAttributeHidden": str(0),
            "PidTagAttributeReadOnly": str(0),
            "PidTagAttributeSystem": str(0),
            "PidTagContainerClass": "IPF.Note (check this)",
            "PidTagSubFolders": str(childcount != 0).upper(),
            "PidTagFolderChildCount": str(childcount),
            "FolderType": str(1),
            "SystemIdx": str(SystemIndex)
        })

    def add_one_public_folder(self,
                              parent_fid,
                              path,
                              children,
                              SystemIndex,
                              names,
                              dn_prefix=None):

        name = path[-1]
        GlobalCount = self.get_message_GlobalCount(names.netbiosname)
        ChangeNumber = self.get_message_ChangeNumber(names.netbiosname)
        ReplicaID = self.get_message_ReplicaID(names.netbiosname)
        if dn_prefix is None:
            dn_prefix = "CN=publicfolders,CN=%s,CN=%s,%s" % (
                names.firstou, names.firstorg, names.ocserverdn)
        fid = gen_mailbox_folder_fid(GlobalCount, ReplicaID)
        dn = "CN=%s,%s" % (fid, dn_prefix)
        change_num = gen_mailbox_folder_fid(ChangeNumber, ReplicaID)
        childcount = len(children)
        print "\t* %-40s: 0x%.16x (%s)" % (name, int(fid, 10), fid)
        if parent_fid == 0:
            self.add_root_public_folder(dn, fid, change_num, SystemIndex,
                                        childcount)
        else:
            self.add_sub_public_folder(dn, parent_fid, fid, change_num, name,
                                       SystemIndex, childcount)

        GlobalCount += 1
        self.set_message_GlobalCount(names.netbiosname,
                                     GlobalCount=GlobalCount)
        ChangeNumber += 1
        self.set_message_ChangeNumber(names.netbiosname,
                                      ChangeNumber=ChangeNumber)

        for name, grandchildren in children.iteritems():
            self.add_one_public_folder(fid, path + (name, ), grandchildren[0],
                                       grandchildren[1], names, dn)

    def add_public_folders(self, names):
        pfstoreGUID = str(uuid.uuid4())
        self.ldb.add({
            "dn":
            "CN=publicfolders,CN=%s,CN=%s,%s" %
            (names.firstou, names.firstorg, names.ocserverdn),
            "objectClass": ["container"],
            "cn":
            "publicfolders",
            "StoreGUID":
            pfstoreGUID,
            "ReplicaID":
            str(1)
        })
        public_folders = _public_folders_meta(names)
        self.add_one_public_folder(0, ("Public Folder Root", ),
                                   public_folders[0], public_folders[1], names)

    def lookup_server(self, cn, attributes=[]):
        # Step 1. Search Server object
        filter = "(&(objectClass=server)(cn=%s))" % cn
        res = self.ldb.search("",
                              scope=ldb.SCOPE_SUBTREE,
                              expression=filter,
                              attrs=attributes)
        if len(res) != 1:
            raise NoSuchServer(cn)
        return res[0]

    def lookup_mailbox_user(self, server, username, attributes=[]):
        """Check if a user already exists in openchange database.

        :param server: Server object name
        :param username: Username object
        :return: LDB Object of the user
        """
        server_dn = self.lookup_server(server, []).dn

        # Step 2. Search User object
        filter = "(&(objectClass=mailbox)(cn=%s))" % (username)
        return self.ldb.search(server_dn,
                               scope=ldb.SCOPE_SUBTREE,
                               expression=filter,
                               attrs=attributes)

    def lookup_public_folder(self, server, displayname, attributes=[]):
        """Retrieve the record for a public folder matching a specific display name

        :param server: Server Object Name
        :param displayname: Display Name of the Folder
        :param attributes: Requested Attributes
        :return: LDB Object of the Folder
        """
        server_dn = self.lookup_server(server, []).dn

        filter = "(&(objectClass=publicfolder)(PidTagDisplayName=%s))" % (
            displayname)
        return self.ldb.search(server_dn,
                               scope=ldb.SCOPE_SUBTREE,
                               expression=filter,
                               attrs=attributes)

    def get_message_attribute(self, server, attribute):
        """Retrieve attribute value from given message database (server).

        :param server: Server object name
        """
        return int(self.lookup_server(server, [attribute])[attribute][0], 10)

    def get_message_ReplicaID(self, server):
        """Retrieve current mailbox Replica ID for given message database (server).

        :param server: Server object name
        """
        return self.get_message_attribute(server, "ReplicaID")

    def get_message_GlobalCount(self, server):
        """Retrieve current mailbox Global Count for given message database (server).

        :param server: Server object name
        """
        return self.get_message_attribute(server, "GlobalCount")

    def set_message_GlobalCount(self, server, GlobalCount):
        """Update current mailbox GlobalCount for given message database (server).

        :param server: Server object name
        :param index: Mailbox new GlobalCount value
        """
        server_dn = self.lookup_server(server, []).dn

        newGlobalCount = """
dn: %s
changetype: modify
replace: GlobalCount
GlobalCount: %d
""" % (server_dn, GlobalCount)

        self.ldb.transaction_start()
        try:
            self.ldb.modify_ldif(newGlobalCount)
        finally:
            self.ldb.transaction_commit()

    def get_message_ChangeNumber(self, server):
        """Retrieve current mailbox Global Count for given message database (server).

        :param server: Server object name
        """
        return self.get_message_attribute(server, "ChangeNumber")

    def set_message_ChangeNumber(self, server, ChangeNumber):
        """Update current mailbox ChangeNumber for given message database (server).

        :param server: Server object name
        :param index: Mailbox new ChangeNumber value
        """
        server_dn = self.lookup_server(server, []).dn

        newChangeNumber = """
dn: %s
changetype: modify
replace: ChangeNumber
ChangeNumber: %d
""" % (server_dn, ChangeNumber)

        self.ldb.transaction_start()
        try:
            self.ldb.modify_ldif(newChangeNumber)
        finally:
            self.ldb.transaction_commit()
Exemplo n.º 11
0
opts = parser.parse_args()[0]
lp = sambaopts.get_loadparm()
smbconf = lp.configfile

if not opts.database:
	print "Parameter database is mandatory"
	sys.exit(1)
creds = credopts.get_credentials(lp)
creds.set_kerberos_state(DONT_USE_KERBEROS)
session = system_session()
empty = ldb.Message()
newname="%s.new"%(opts.database)
if os.path.exists(newname):
	os.remove(newname)
old_ldb = Ldb(opts.database, session_info=session, credentials=creds,lp=lp)
new_ldb = Ldb(newname,session_info=session, credentials=creds,lp=lp)

new_ldb.transaction_start()
res = old_ldb.search(expression="(dn=*)",base="", scope=SCOPE_SUBTREE)
for i in range(0,len(res)):
	if str(res[i].dn) == "@BASEINFO":
		continue
	if str(res[i].dn).startswith("@INDEX:"):
		continue
	delta = new_ldb.msg_diff(empty,res[i])
	delta.dn = res[i].dn
	delta.remove("distinguishedName")
	new_ldb.add(delta)

new_ldb.transaction_commit()
Exemplo n.º 12
0
opts = parser.parse_args()[0]
lp = sambaopts.get_loadparm()
smbconf = lp.configfile

if not opts.database:
    print "Parameter database is mandatory"
    sys.exit(1)
creds = credopts.get_credentials(lp)
creds.set_kerberos_state(DONT_USE_KERBEROS)
session = system_session()
empty = ldb.Message()
newname = "%s.new" % (opts.database)
if os.path.exists(newname):
    os.remove(newname)
old_ldb = Ldb(opts.database, session_info=session, credentials=creds, lp=lp)
new_ldb = Ldb(newname, session_info=session, credentials=creds, lp=lp)

new_ldb.transaction_start()
res = old_ldb.search(expression="(dn=*)", base="", scope=SCOPE_SUBTREE)
for i in range(0, len(res)):
    if str(res[i].dn) == "@BASEINFO":
        continue
    if str(res[i].dn).startswith("@INDEX:"):
        continue
    delta = new_ldb.msg_diff(empty, res[i])
    delta.dn = res[i].dn
    delta.remove("distinguishedName")
    new_ldb.add(delta)

new_ldb.transaction_commit()