Ejemplo n.º 1
0
    def test_dirsync_send_delta(self):
        """Check that dirsync return correct delta when sending the last cookie"""
        res = self.ldb_admin.search(
            self.base_dn,
            expression="(&(samaccountname=test*)(!(isDeleted=*)))",
            controls=["dirsync:1:0:10000"])
        ctl = str(res.controls[0]).split(":")
        ctl[1] = "1"
        ctl[2] = "0"
        ctl[3] = "10000"
        control = str(":".join(ctl))
        res = self.ldb_admin.search(
            self.base_dn,
            expression="(&(samaccountname=test*)(!(isDeleted=*)))",
            controls=[control])
        self.assertEqual(len(res), 0)

        res = self.ldb_admin.search(
            self.base_dn,
            expression="(&(objectClass=organizationalUnit)(!(isDeleted=*)))",
            controls=["dirsync:1:0:100000"])

        ctl = str(res.controls[0]).split(":")
        ctl[1] = "1"
        ctl[2] = "0"
        ctl[3] = "10000"
        control2 = str(":".join(ctl))

        # Let's create an OU
        ouname = "OU=testou2,%s" % self.base_dn
        self.ouname = ouname
        self.ldb_admin.create_ou(ouname)
        res = self.ldb_admin.search(
            self.base_dn,
            expression="(&(objectClass=organizationalUnit)(!(isDeleted=*)))",
            controls=[control2])
        self.assertEqual(len(res), 1)
        ctl = str(res.controls[0]).split(":")
        ctl[1] = "1"
        ctl[2] = "0"
        ctl[3] = "10000"
        control3 = str(":".join(ctl))

        delta = Message()
        delta.dn = Dn(self.ldb_admin, str(ouname))

        delta["cn"] = MessageElement("test ou", FLAG_MOD_ADD, "cn")
        self.ldb_admin.modify(delta)
        res = self.ldb_admin.search(
            self.base_dn,
            expression="(&(objectClass=organizationalUnit)(!(isDeleted=*)))",
            controls=[control3])

        self.assertEqual(len(res.msgs), 1)
        # 3 attributes: instanceType, cn and objectGUID
        self.assertEqual(len(res.msgs[0]), 3)

        delta = Message()
        delta.dn = Dn(self.ldb_admin, str(ouname))
        delta["cn"] = MessageElement([], FLAG_MOD_DELETE, "cn")
        self.ldb_admin.modify(delta)
        res = self.ldb_admin.search(
            self.base_dn,
            expression="(&(objectClass=organizationalUnit)(!(isDeleted=*)))",
            controls=[control3])

        self.assertEqual(len(res.msgs), 1)
        # So we won't have much attribute returned but instanceType and GUID
        # are.
        # 3 attributes: instanceType and objectGUID and cn but empty
        self.assertEqual(len(res.msgs[0]), 3)
        ouname = "OU=newouname,%s" % self.base_dn
        self.ldb_admin.rename(str(res[0].dn), str(Dn(self.ldb_admin, ouname)))
        self.ouname = ouname
        ctl = str(res.controls[0]).split(":")
        ctl[1] = "1"
        ctl[2] = "0"
        ctl[3] = "10000"
        control4 = str(":".join(ctl))
        res = self.ldb_admin.search(
            self.base_dn,
            expression="(&(objectClass=organizationalUnit)(!(isDeleted=*)))",
            controls=[control3])

        self.assertTrue(res[0].get("parentGUID") != None)
        self.assertTrue(res[0].get("name") != None)
        delete_force(self.ldb_admin, ouname)
Ejemplo n.º 2
0
 def _link_user_and_group(self, u, g):
     m = Message()
     m.dn = Dn(self.ldb, "CN=g%d,%s" % (g, self.ou_groups))
     m["member"] = MessageElement("cn=u%d,%s" % (u, self.ou_users),
                                  FLAG_MOD_ADD, "member")
     self.ldb.modify(m)
Ejemplo n.º 3
0
class SchemaTests_msDS_IntId(samba.tests.TestCase):
    def setUp(self):
        super(SchemaTests_msDS_IntId, self).setUp()
        self.ldb = ldb
        res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["*"])
        self.assertEquals(len(res), 1)
        self.schema_dn = res[0]["schemaNamingContext"][0]
        self.base_dn = res[0]["defaultNamingContext"][0]
        self.forest_level = int(res[0]["forestFunctionality"][0])

    def _ldap_schemaUpdateNow(self):
        ldif = """
dn:
changetype: modify
add: schemaUpdateNow
schemaUpdateNow: 1
"""
        self.ldb.modify_ldif(ldif)

    def _make_obj_names(self, prefix):
        class_name = prefix + time.strftime("%s", time.gmtime())
        class_ldap_name = class_name.replace("-", "")
        class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
        return (class_name, class_ldap_name, class_dn)

    def _is_schema_base_object(self, ldb_msg):
        """Test systemFlags for SYSTEM_FLAG_SCHEMA_BASE_OBJECT (16)"""
        systemFlags = 0
        if "systemFlags" in ldb_msg:
            systemFlags = int(ldb_msg["systemFlags"][0])
        return (systemFlags & 16) != 0

    def _make_attr_ldif(self, attr_name, attr_dn):
        ldif = """
dn: """ + attr_dn + """
objectClass: top
objectClass: attributeSchema
adminDescription: """ + attr_name + """
adminDisplayName: """ + attr_name + """
cn: """ + attr_name + """
attributeId: 1.2.840.""" + str(random.randint(1, 100000)) + """.1.5.9940
attributeSyntax: 2.5.5.12
omSyntax: 64
instanceType: 4
isSingleValued: TRUE
systemOnly: FALSE
"""
        return ldif

    def test_msDS_IntId_on_attr(self):
        """Testing msDs-IntId creation for Attributes.
        See MS-ADTS - 3.1.1.Attributes

        This test should verify that:
        - Creating attribute with 'msDS-IntId' fails with ERR_UNWILLING_TO_PERFORM
        - Adding 'msDS-IntId' on existing attribute fails with ERR_CONSTRAINT_VIOLATION
        - Creating attribute with 'msDS-IntId' set and FLAG_SCHEMA_BASE_OBJECT flag
          set fails with ERR_UNWILLING_TO_PERFORM
        - Attributes created with FLAG_SCHEMA_BASE_OBJECT not set have
          'msDS-IntId' attribute added internally
        """

        # 1. Create attribute without systemFlags
        # msDS-IntId should be created if forest functional
        # level is >= DS_DOMAIN_FUNCTION_2003
        # and missing otherwise
        (attr_name, attr_ldap_name,
         attr_dn) = self._make_obj_names("msDS-IntId-Attr-1-")
        ldif = self._make_attr_ldif(attr_name, attr_dn)

        # try to add msDS-IntId during Attribute creation
        ldif_fail = ldif + "msDS-IntId: -1993108831\n"
        try:
            self.ldb.add_ldif(ldif_fail)
            self.fail("Adding attribute with preset msDS-IntId should fail")
        except LdbError, (num, _):
            self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)

        # add the new attribute and update schema
        self.ldb.add_ldif(ldif)
        self._ldap_schemaUpdateNow()

        # Search for created attribute
        res = []
        res = self.ldb.search(attr_dn, scope=SCOPE_BASE, attrs=["*"])
        self.assertEquals(len(res), 1)
        self.assertEquals(res[0]["lDAPDisplayName"][0], attr_ldap_name)
        if self.forest_level >= DS_DOMAIN_FUNCTION_2003:
            if self._is_schema_base_object(res[0]):
                self.assertTrue("msDS-IntId" not in res[0])
            else:
                self.assertTrue("msDS-IntId" in res[0])
        else:
            self.assertTrue("msDS-IntId" not in res[0])

        msg = Message()
        msg.dn = Dn(self.ldb, attr_dn)
        msg["msDS-IntId"] = MessageElement("-1993108831", FLAG_MOD_REPLACE,
                                           "msDS-IntId")
        try:
            self.ldb.modify(msg)
            self.fail("Modifying msDS-IntId should return error")
        except LdbError, (num, _):
            self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
Ejemplo n.º 4
0
    def test_dirsync_attributes(self):
        """Check behavior with some attributes """
        res = self.ldb_admin.search(self.base_dn,
                                    expression="samaccountname=*",
                                    controls=["dirsync:1:0:1"])
        # Check that nTSecurityDescriptor is returned as it's the case when doing dirsync
        self.assertTrue(res.msgs[0].get("ntsecuritydescriptor") != None)
        # Check that non replicated attributes are not returned
        self.assertTrue(res.msgs[0].get("badPwdCount") == None)
        # Check that non forward link are not returned
        self.assertTrue(res.msgs[0].get("memberof") == None)

        # Asking for instanceType will return also objectGUID
        res = self.ldb_admin.search(self.base_dn,
                                    expression="samaccountname=Administrator",
                                    attrs=["instanceType"],
                                    controls=["dirsync:1:0:1"])
        self.assertTrue(res.msgs[0].get("objectGUID") != None)
        self.assertTrue(res.msgs[0].get("instanceType") != None)

        # We don't return an entry if asked for objectGUID
        res = self.ldb_admin.search(self.base_dn,
                                    expression="(distinguishedName=%s)" %
                                    str(self.base_dn),
                                    attrs=["objectGUID"],
                                    controls=["dirsync:1:0:1"])
        self.assertEquals(len(res.msgs), 0)

        # a request on the root of a NC didn't return parentGUID
        res = self.ldb_admin.search(self.base_dn,
                                    expression="(distinguishedName=%s)" %
                                    str(self.base_dn),
                                    attrs=["name"],
                                    controls=["dirsync:1:0:1"])
        self.assertTrue(res.msgs[0].get("objectGUID") != None)
        self.assertTrue(res.msgs[0].get("name") != None)
        self.assertTrue(res.msgs[0].get("parentGUID") == None)
        self.assertTrue(res.msgs[0].get("instanceType") != None)

        # Asking for name will return also objectGUID and parentGUID
        # and instanceType and of course name
        res = self.ldb_admin.search(self.base_dn,
                                    expression="samaccountname=Administrator",
                                    attrs=["name"],
                                    controls=["dirsync:1:0:1"])
        self.assertTrue(res.msgs[0].get("objectGUID") != None)
        self.assertTrue(res.msgs[0].get("name") != None)
        self.assertTrue(res.msgs[0].get("parentGUID") != None)
        self.assertTrue(res.msgs[0].get("instanceType") != None)

        # Asking for dn will not return not only DN but more like if attrs=*
        # parentGUID should be returned
        res = self.ldb_admin.search(self.base_dn,
                                    expression="samaccountname=Administrator",
                                    attrs=["dn"],
                                    controls=["dirsync:1:0:1"])
        count = len(res.msgs[0])
        res2 = self.ldb_admin.search(self.base_dn,
                                     expression="samaccountname=Administrator",
                                     controls=["dirsync:1:0:1"])
        count2 = len(res2.msgs[0])
        self.assertEqual(count, count2)

        # Asking for cn will return nothing on objects that have CN as RDN
        res = self.ldb_admin.search(self.base_dn,
                                    expression="samaccountname=Administrator",
                                    attrs=["cn"],
                                    controls=["dirsync:1:0:1"])
        self.assertEqual(len(res.msgs), 0)
        # Asking for parentGUID will return nothing too
        res = self.ldb_admin.search(self.base_dn,
                                    expression="samaccountname=Administrator",
                                    attrs=["parentGUID"],
                                    controls=["dirsync:1:0:1"])
        self.assertEqual(len(res.msgs), 0)
        ouname = "OU=testou,%s" % self.base_dn
        self.ouname = ouname
        self.ldb_admin.create_ou(ouname)
        delta = Message()
        delta.dn = Dn(self.ldb_admin, str(ouname))
        delta["cn"] = MessageElement("test ou", FLAG_MOD_ADD, "cn")
        self.ldb_admin.modify(delta)
        res = self.ldb_admin.search(self.base_dn,
                                    expression="name=testou",
                                    attrs=["cn"],
                                    controls=["dirsync:1:0:1"])

        self.assertEqual(len(res.msgs), 1)
        self.assertEqual(len(res.msgs[0]), 3)
        delete_force(self.ldb_admin, ouname)
Ejemplo n.º 5
0
 def add_attr(self, dn, attr, value):
     m = Message()
     m.dn = Dn(self.ldb_admin, dn)
     m[attr] = MessageElement(value, FLAG_MOD_ADD, attr)
     self.ldb_admin.modify(m)
Ejemplo n.º 6
0
        # Search for created attribute
        res = []
        res = self.ldb.search(attr_dn, scope=SCOPE_BASE, attrs=["*"])
        self.assertEquals(len(res), 1)
        self.assertEquals(res[0]["lDAPDisplayName"][0], attr_ldap_name)
        if self.forest_level >= DS_DOMAIN_FUNCTION_2003:
            if self._is_schema_base_object(res[0]):
                self.assertTrue("msDS-IntId" not in res[0])
            else:
                self.assertTrue("msDS-IntId" in res[0])
        else:
            self.assertTrue("msDS-IntId" not in res[0])

        msg = Message()
        msg.dn = Dn(self.ldb, attr_dn)
        msg["msDS-IntId"] = MessageElement("-1993108831", FLAG_MOD_REPLACE,
                                           "msDS-IntId")
        try:
            self.ldb.modify(msg)
            self.fail("Modifying msDS-IntId should return error")
        except LdbError, (num, _):
            self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)

    def _make_class_ldif(self, class_dn, class_name):
        ldif = """
dn: """ + class_dn + """
objectClass: top
objectClass: classSchema
adminDescription: """ + class_name + """
adminDisplayName: """ + class_name + """
cn: """ + class_name + """
governsId: 1.2.840.""" + str(random.randint(1, 100000)) + """.1.5.9939
Ejemplo n.º 7
0
    def test_modify_dsheuristics_userPassword(self):
        print(
            "Performs testing about reading userPassword between dsHeuristic modifies"
        )

        # Make sure userPassword cannot be read
        self.ldb.set_dsheuristics("000000000")

        # Open a new connection (with dsHeuristic=000000000)
        ldb1 = SamDB(url=host,
                     session_info=system_session(lp),
                     credentials=creds,
                     lp=lp)

        # Set userPassword to be read
        # This setting only affects newer connections (ldb2)
        ldb1.set_dsheuristics("000000001")
        time.sleep(1)

        m = Message()
        m.dn = Dn(ldb1, "cn=testuser,cn=users," + self.base_dn)
        m["userPassword"] = MessageElement("thatsAcomplPASS1",
                                           FLAG_MOD_REPLACE, "userPassword")
        ldb1.modify(m)

        res = ldb1.search("cn=testuser,cn=users," + self.base_dn,
                          scope=SCOPE_BASE,
                          attrs=["userPassword"])

        # userPassword cannot be read, it wasn't set, instead the
        # password was
        self.assertTrue(len(res) == 1)
        self.assertFalse("userPassword" in res[0])

        # Open another new connection (with dsHeuristic=000000001)
        ldb2 = SamDB(url=host,
                     session_info=system_session(lp),
                     credentials=creds,
                     lp=lp)

        res = ldb2.search("cn=testuser,cn=users," + self.base_dn,
                          scope=SCOPE_BASE,
                          attrs=["userPassword"])

        # Check on the new connection that userPassword was not stored
        # from ldb1 or is not readable
        self.assertTrue(len(res) == 1)
        self.assertFalse("userPassword" in res[0])

        # Set userPassword to be readable
        # This setting does not affect this connection
        ldb2.set_dsheuristics("000000000")
        time.sleep(1)

        res = ldb2.search("cn=testuser,cn=users," + self.base_dn,
                          scope=SCOPE_BASE,
                          attrs=["userPassword"])

        # Check that userPassword was not stored from ldb1
        self.assertTrue(len(res) == 1)
        self.assertFalse("userPassword" in res[0])

        m = Message()
        m.dn = Dn(ldb2, "cn=testuser,cn=users," + self.base_dn)
        m["userPassword"] = MessageElement("thatsAcomplPASS2",
                                           FLAG_MOD_REPLACE, "userPassword")
        ldb2.modify(m)

        res = ldb2.search("cn=testuser,cn=users," + self.base_dn,
                          scope=SCOPE_BASE,
                          attrs=["userPassword"])

        # Check despite setting it with userPassword support disabled
        # on this connection it should still not be readable
        self.assertTrue(len(res) == 1)
        self.assertFalse("userPassword" in res[0])

        # Only password from ldb1 is the user's password
        creds2 = Credentials()
        creds2.set_username("testuser")
        creds2.set_password("thatsAcomplPASS1")
        creds2.set_domain(creds.get_domain())
        creds2.set_realm(creds.get_realm())
        creds2.set_workstation(creds.get_workstation())
        creds2.set_gensec_features(creds2.get_gensec_features()
                                   | gensec.FEATURE_SEAL)

        try:
            SamDB(url=host, credentials=creds2, lp=lp)
        except:
            self.fail("testuser used the wrong password")

        ldb3 = SamDB(url=host,
                     session_info=system_session(lp),
                     credentials=creds,
                     lp=lp)

        # Check that userPassword was stored from ldb2
        res = ldb3.search("cn=testuser,cn=users," + self.base_dn,
                          scope=SCOPE_BASE,
                          attrs=["userPassword"])

        # userPassword can be read
        self.assertTrue(len(res) == 1)
        self.assertTrue("userPassword" in res[0])
        self.assertEquals(str(res[0]["userPassword"][0]), "thatsAcomplPASS2")

        # Reset the test "dSHeuristics" (reactivate "userPassword" pwd changes)
        self.ldb.set_dsheuristics("000000001")

        ldb4 = SamDB(url=host,
                     session_info=system_session(lp),
                     credentials=creds,
                     lp=lp)

        # Check that userPassword that was stored from ldb2
        res = ldb4.search("cn=testuser,cn=users," + self.base_dn,
                          scope=SCOPE_BASE,
                          attrs=["userPassword"])

        # userPassword can be not be read
        self.assertTrue(len(res) == 1)
        self.assertFalse("userPassword" in res[0])
Ejemplo n.º 8
0
    def test_plain_userPassword(self):
        print("Performs testing about the standard 'userPassword' behaviour")

        # Delete the "dSHeuristics"
        self.ldb.set_dsheuristics(None)

        time.sleep(1)  # This switching time is strictly needed!

        m = Message()
        m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn)
        m["userPassword"] = MessageElement("myPassword", FLAG_MOD_ADD,
                                           "userPassword")
        self.ldb.modify(m)

        res = self.ldb.search("cn=testuser,cn=users," + self.base_dn,
                              scope=SCOPE_BASE,
                              attrs=["userPassword"])
        self.assertTrue(len(res) == 1)
        self.assertTrue("userPassword" in res[0])
        self.assertEquals(str(res[0]["userPassword"][0]), "myPassword")

        m = Message()
        m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn)
        m["userPassword"] = MessageElement("myPassword2", FLAG_MOD_REPLACE,
                                           "userPassword")
        self.ldb.modify(m)

        res = self.ldb.search("cn=testuser,cn=users," + self.base_dn,
                              scope=SCOPE_BASE,
                              attrs=["userPassword"])
        self.assertTrue(len(res) == 1)
        self.assertTrue("userPassword" in res[0])
        self.assertEquals(str(res[0]["userPassword"][0]), "myPassword2")

        m = Message()
        m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn)
        m["userPassword"] = MessageElement([], FLAG_MOD_DELETE, "userPassword")
        self.ldb.modify(m)

        res = self.ldb.search("cn=testuser,cn=users," + self.base_dn,
                              scope=SCOPE_BASE,
                              attrs=["userPassword"])
        self.assertTrue(len(res) == 1)
        self.assertFalse("userPassword" in res[0])

        # Set the test "dSHeuristics" to deactivate "userPassword" pwd changes
        self.ldb.set_dsheuristics("000000000")

        m = Message()
        m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn)
        m["userPassword"] = MessageElement("myPassword3", FLAG_MOD_REPLACE,
                                           "userPassword")
        self.ldb.modify(m)

        res = self.ldb.search("cn=testuser,cn=users," + self.base_dn,
                              scope=SCOPE_BASE,
                              attrs=["userPassword"])
        self.assertTrue(len(res) == 1)
        self.assertTrue("userPassword" in res[0])
        self.assertEquals(str(res[0]["userPassword"][0]), "myPassword3")

        # Set the test "dSHeuristics" to deactivate "userPassword" pwd changes
        self.ldb.set_dsheuristics("000000002")

        m = Message()
        m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn)
        m["userPassword"] = MessageElement("myPassword4", FLAG_MOD_REPLACE,
                                           "userPassword")
        self.ldb.modify(m)

        res = self.ldb.search("cn=testuser,cn=users," + self.base_dn,
                              scope=SCOPE_BASE,
                              attrs=["userPassword"])
        self.assertTrue(len(res) == 1)
        self.assertTrue("userPassword" in res[0])
        self.assertEquals(str(res[0]["userPassword"][0]), "myPassword4")

        # Reset the test "dSHeuristics" (reactivate "userPassword" pwd changes)
        self.ldb.set_dsheuristics("000000001")
Ejemplo n.º 9
0
    def test_empty_passwords(self):
        print("Performs some empty passwords testing")

        try:
            self.ldb.add({
                "dn": "cn=testuser2,cn=users," + self.base_dn,
                "objectclass": "user",
                "unicodePwd": []
            })
            self.fail()
        except LdbError as e32:
            (num, _) = e32.args
            self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)

        try:
            self.ldb.add({
                "dn": "cn=testuser2,cn=users," + self.base_dn,
                "objectclass": "user",
                "dBCSPwd": []
            })
            self.fail()
        except LdbError as e33:
            (num, _) = e33.args
            self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)

        try:
            self.ldb.add({
                "dn": "cn=testuser2,cn=users," + self.base_dn,
                "objectclass": "user",
                "userPassword": []
            })
            self.fail()
        except LdbError as e34:
            (num, _) = e34.args
            self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)

        try:
            self.ldb.add({
                "dn": "cn=testuser2,cn=users," + self.base_dn,
                "objectclass": "user",
                "clearTextPassword": []
            })
            self.fail()
        except LdbError as e35:
            (num, _) = e35.args
            self.assertTrue(num == ERR_CONSTRAINT_VIOLATION
                            or num == ERR_NO_SUCH_ATTRIBUTE)  # for Windows

        delete_force(self.ldb, "cn=testuser2,cn=users," + self.base_dn)

        m = Message()
        m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn)
        m["unicodePwd"] = MessageElement([], FLAG_MOD_ADD, "unicodePwd")
        try:
            self.ldb.modify(m)
            self.fail()
        except LdbError as e36:
            (num, _) = e36.args
            self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)

        m = Message()
        m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn)
        m["dBCSPwd"] = MessageElement([], FLAG_MOD_ADD, "dBCSPwd")
        try:
            self.ldb.modify(m)
            self.fail()
        except LdbError as e37:
            (num, _) = e37.args
            self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)

        m = Message()
        m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn)
        m["userPassword"] = MessageElement([], FLAG_MOD_ADD, "userPassword")
        try:
            self.ldb.modify(m)
            self.fail()
        except LdbError as e38:
            (num, _) = e38.args
            self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)

        m = Message()
        m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn)
        m["clearTextPassword"] = MessageElement([], FLAG_MOD_ADD,
                                                "clearTextPassword")
        try:
            self.ldb.modify(m)
            self.fail()
        except LdbError as e39:
            (num, _) = e39.args
            self.assertTrue(num == ERR_CONSTRAINT_VIOLATION
                            or num == ERR_NO_SUCH_ATTRIBUTE)  # for Windows

        m = Message()
        m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn)
        m["unicodePwd"] = MessageElement([], FLAG_MOD_REPLACE, "unicodePwd")
        try:
            self.ldb.modify(m)
            self.fail()
        except LdbError as e40:
            (num, _) = e40.args
            self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)

        m = Message()
        m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn)
        m["dBCSPwd"] = MessageElement([], FLAG_MOD_REPLACE, "dBCSPwd")
        try:
            self.ldb.modify(m)
            self.fail()
        except LdbError as e41:
            (num, _) = e41.args
            self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)

        m = Message()
        m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn)
        m["userPassword"] = MessageElement([], FLAG_MOD_REPLACE,
                                           "userPassword")
        try:
            self.ldb.modify(m)
            self.fail()
        except LdbError as e42:
            (num, _) = e42.args
            self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)

        m = Message()
        m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn)
        m["clearTextPassword"] = MessageElement([], FLAG_MOD_REPLACE,
                                                "clearTextPassword")
        try:
            self.ldb.modify(m)
            self.fail()
        except LdbError as e43:
            (num, _) = e43.args
            self.assertTrue(num == ERR_UNWILLING_TO_PERFORM
                            or num == ERR_NO_SUCH_ATTRIBUTE)  # for Windows

        m = Message()
        m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn)
        m["unicodePwd"] = MessageElement([], FLAG_MOD_DELETE, "unicodePwd")
        try:
            self.ldb.modify(m)
            self.fail()
        except LdbError as e44:
            (num, _) = e44.args
            self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)

        m = Message()
        m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn)
        m["dBCSPwd"] = MessageElement([], FLAG_MOD_DELETE, "dBCSPwd")
        try:
            self.ldb.modify(m)
            self.fail()
        except LdbError as e45:
            (num, _) = e45.args
            self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)

        m = Message()
        m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn)
        m["userPassword"] = MessageElement([], FLAG_MOD_DELETE, "userPassword")
        try:
            self.ldb.modify(m)
            self.fail()
        except LdbError as e46:
            (num, _) = e46.args
            self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)

        m = Message()
        m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn)
        m["clearTextPassword"] = MessageElement([], FLAG_MOD_DELETE,
                                                "clearTextPassword")
        try:
            self.ldb.modify(m)
            self.fail()
        except LdbError as e47:
            (num, _) = e47.args
            self.assertTrue(num == ERR_CONSTRAINT_VIOLATION
                            or num == ERR_NO_SUCH_ATTRIBUTE)  # for Windows
Ejemplo n.º 10
0
    def setUp(self):
        super(MatchRulesTests, self).setUp()
        self.lp = lp
        self.ldb = SamDB(host, credentials=creds, session_info=system_session(lp), lp=lp)
        self.base_dn = self.ldb.domain_dn()
        self.ou = "ou=matchrulestest,%s" % self.base_dn
        self.ou_users = "ou=users,%s" % self.ou
        self.ou_groups = "ou=groups,%s" % self.ou
        self.ou_computers = "ou=computers,%s" % self.ou

        # Add a organizational unit to create objects
        self.ldb.add({
            "dn": self.ou,
            "objectclass": "organizationalUnit"})

	# Add the following OU hierarchy and set otherWellKnownObjects,
	# which has BinaryDN syntax:
	#
	# o1
	# |--> o2
	# |    |--> o3
	# |    |    |-->o4

	self.ldb.add({
	    "dn": "OU=o1,%s" % self.ou,
            "objectclass": "organizationalUnit"})
	self.ldb.add({
	    "dn": "OU=o2,OU=o1,%s" % self.ou,
            "objectclass": "organizationalUnit"})
	self.ldb.add({
	    "dn": "OU=o3,OU=o2,OU=o1,%s" % self.ou,
            "objectclass": "organizationalUnit"})
	self.ldb.add({
	    "dn": "OU=o4,OU=o3,OU=o2,OU=o1,%s" % self.ou,
            "objectclass": "organizationalUnit"})

        m = Message()
        m.dn = Dn(self.ldb, self.ou)
        m["otherWellKnownObjects"] = MessageElement("B:32:00000000000000000000000000000001:OU=o1,%s" % self.ou,
                                     FLAG_MOD_ADD, "otherWellKnownObjects")
        self.ldb.modify(m)

        m = Message()
        m.dn = Dn(self.ldb, "OU=o1,%s" % self.ou)
        m["otherWellKnownObjects"] = MessageElement("B:32:00000000000000000000000000000002:OU=o2,OU=o1,%s" % self.ou,
                                     FLAG_MOD_ADD, "otherWellKnownObjects")
        self.ldb.modify(m)

        m = Message()
        m.dn = Dn(self.ldb, "OU=o2,OU=o1,%s" % self.ou)
        m["otherWellKnownObjects"] = MessageElement("B:32:00000000000000000000000000000003:OU=o3,OU=o2,OU=o1,%s" % self.ou,
                                     FLAG_MOD_ADD, "otherWellKnownObjects")
        self.ldb.modify(m)

        m = Message()
        m.dn = Dn(self.ldb, "OU=o3,OU=o2,OU=o1,%s" % self.ou)
        m["otherWellKnownObjects"] = MessageElement("B:32:00000000000000000000000000000004:OU=o4,OU=o3,OU=o2,OU=o1,%s" % self.ou,
                                     FLAG_MOD_ADD, "otherWellKnownObjects")
        self.ldb.modify(m)

	# Create OU for users and groups
        self.ldb.add({
            "dn": self.ou_users,
            "objectclass": "organizationalUnit"})
        self.ldb.add({
            "dn": self.ou_groups,
            "objectclass": "organizationalUnit"})
        self.ldb.add({
            "dn": self.ou_computers,
            "objectclass": "organizationalUnit"})

        # Add four groups
        self.ldb.add({
            "dn": "cn=g1,%s" % self.ou_groups,
            "objectclass": "group" })
        self.ldb.add({
            "dn": "cn=g2,%s" % self.ou_groups,
            "objectclass": "group" })
        self.ldb.add({
            "dn": "cn=g3,%s" % self.ou_groups,
            "objectclass": "group" })
        self.ldb.add({
            "dn": "cn=g4,%s" % self.ou_groups,
            "objectclass": "group" })

        # Add four users
        self.ldb.add({
            "dn": "cn=u1,%s" % self.ou_users,
            "objectclass": "user"})
        self.ldb.add({
            "dn": "cn=u2,%s" % self.ou_users,
            "objectclass": "user"})
        self.ldb.add({
            "dn": "cn=u3,%s" % self.ou_users,
            "objectclass": "user"})
        self.ldb.add({
            "dn": "cn=u4,%s" % self.ou_users,
            "objectclass": "user"})

        # Add computers to test Object(DN-Binary) syntax
        self.ldb.add({
            "dn": "cn=c1,%s" % self.ou_computers,
            "objectclass": "computer",
            "dNSHostName": "c1.%s" % self.lp.get("realm").lower(),
            "servicePrincipalName": ["HOST/c1"],
            "sAMAccountName": "c1$",
            "userAccountControl": "83890178"})

        self.ldb.add({
            "dn": "cn=c2,%s" % self.ou_computers,
            "objectclass": "computer",
            "dNSHostName": "c2.%s" % self.lp.get("realm").lower(),
            "servicePrincipalName": ["HOST/c2"],
            "sAMAccountName": "c2$",
            "userAccountControl": "83890178"})

        self.ldb.add({
            "dn": "cn=c3,%s" % self.ou_computers,
            "objectclass": "computer",
            "dNSHostName": "c3.%s" % self.lp.get("realm").lower(),
            "servicePrincipalName": ["HOST/c3"],
            "sAMAccountName": "c3$",
            "userAccountControl": "83890178"})

        # Create the following hierarchy:
        # g4
        # |--> u4
        # |--> g3
        # |    |--> u3
        # |    |--> g2
        # |    |    |--> u2
        # |    |    |--> g1
        # |    |    |    |--> u1

        # u1 member of g1
        m = Message()
        m.dn = Dn(self.ldb, "cn=g1,%s" % self.ou_groups)
        m["member"] = MessageElement("cn=u1,%s" % self.ou_users,
                                     FLAG_MOD_ADD, "member")
        self.ldb.modify(m)

        # u2 member of g2
        m = Message()
        m.dn = Dn(self.ldb, "cn=g2,%s" % self.ou_groups)
        m["member"] = MessageElement("cn=u2,%s" % self.ou_users,
                                     FLAG_MOD_ADD, "member")
        self.ldb.modify(m)

        # u3 member of g3
        m = Message()
        m.dn = Dn(self.ldb, "cn=g3,%s" % self.ou_groups)
        m["member"] = MessageElement("cn=u3,%s" % self.ou_users,
                                     FLAG_MOD_ADD, "member")
        self.ldb.modify(m)

        # u4 member of g4
        m = Message()
        m.dn = Dn(self.ldb, "cn=g4,%s" % self.ou_groups)
        m["member"] = MessageElement("cn=u4,%s" % self.ou_users,
                                     FLAG_MOD_ADD, "member")
        self.ldb.modify(m)

        # g3 member of g4
        m = Message()
        m.dn = Dn(self.ldb, "cn=g4,%s" % self.ou_groups)
        m["member"] = MessageElement("cn=g3,%s" % self.ou_groups,
                                     FLAG_MOD_ADD, "member")
        self.ldb.modify(m)

        # g2 member of g3
        m = Message()
        m.dn = Dn(self.ldb, "cn=g3,%s" % self.ou_groups)
        m["member"] = MessageElement("cn=g2,%s" % self.ou_groups,
                                     FLAG_MOD_ADD, "member")
        self.ldb.modify(m)

        # g1 member of g2
        m = Message()
        m.dn = Dn(self.ldb, "cn=g2,%s" % self.ou_groups)
        m["member"] = MessageElement("cn=g1,%s" % self.ou_groups,
                                     FLAG_MOD_ADD, "member")
        self.ldb.modify(m)

        # The msDS-RevealedUsers is owned by system and cannot be modified
        # directly. Set the schemaUpgradeInProgress flag as workaround
        # and create this hierarchy:
        # ou=computers
        # |-> c1
        # |   |->c2
        # |   |  |->u1

        #
        # While appropriate for this test, this is NOT a good practice
        # in general.  This is only done here because the alternative
        # is to make a schema modification.
        #
        # IF/WHEN Samba protects this attribute better, this
        # particular part of the test can be removed, as the same code
        # is covered by the addressBookRoots2 case well enough.
        #
        m = Message()
        m.dn = Dn(self.ldb, "")
        m["e1"] = MessageElement("1", FLAG_MOD_REPLACE, "schemaUpgradeInProgress")
        self.ldb.modify(m)

        m = Message()
        m.dn = Dn(self.ldb, "cn=c2,%s" % self.ou_computers)
        m["e1"] = MessageElement("B:8:01010101:cn=c3,%s" % self.ou_computers,
                                 FLAG_MOD_ADD, "msDS-RevealedUsers")
        self.ldb.modify(m)

        m = Message()
        m.dn = Dn(self.ldb, "cn=c1,%s" % self.ou_computers)
        m["e1"] = MessageElement("B:8:01010101:cn=c2,%s" % self.ou_computers,
                                 FLAG_MOD_ADD, "msDS-RevealedUsers")
        self.ldb.modify(m)

        m = Message()
        m.dn = Dn(self.ldb, "")
        m["e1"] = MessageElement("0", FLAG_MOD_REPLACE, "schemaUpgradeInProgress")
        self.ldb.modify(m)

        # Add a couple of ms-Exch-Configuration-Container to test forward-link
        # attributes without backward link (addressBookRoots2)
        # e1
        # |--> e2
        # |    |--> c1
        self.ldb.add({
            "dn": "cn=e1,%s" % self.ou,
            "objectclass": "msExchConfigurationContainer"})
        self.ldb.add({
            "dn": "cn=e2,%s" % self.ou,
            "objectclass": "msExchConfigurationContainer"})

        m = Message()
        m.dn = Dn(self.ldb, "cn=e2,%s" % self.ou)
        m["e1"] = MessageElement("cn=c1,%s" % self.ou_computers,
                                 FLAG_MOD_ADD, "addressBookRoots2")
        self.ldb.modify(m)

        m = Message()
        m.dn = Dn(self.ldb, "cn=e1,%s" % self.ou)
        m["e1"] = MessageElement("cn=e2,%s" % self.ou,
                                 FLAG_MOD_ADD, "addressBookRoots2")
        self.ldb.modify(m)
Ejemplo n.º 11
0
    def setUp(self):
        super(BasePasswordTestCase, self).setUp()

        self.global_creds.set_gensec_features(self.global_creds.get_gensec_features() |
                                              gensec.FEATURE_SEAL)

        self.template_creds = Credentials()
        self.template_creds.set_username("testuser")
        self.template_creds.set_password("thatsAcomplPASS1")
        self.template_creds.set_domain(self.global_creds.get_domain())
        self.template_creds.set_realm(self.global_creds.get_realm())
        self.template_creds.set_workstation(self.global_creds.get_workstation())
        self.template_creds.set_gensec_features(self.global_creds.get_gensec_features())
        self.template_creds.set_kerberos_state(self.global_creds.get_kerberos_state())


        # Gets back the basedn
        base_dn = self.ldb.domain_dn()

        # Gets back the configuration basedn
        configuration_dn = self.ldb.get_config_basedn().get_linearized()

        # Get the old "dSHeuristics" if it was set
        dsheuristics = self.ldb.get_dsheuristics()

        # Reset the "dSHeuristics" as they were before
        self.addCleanup(self.ldb.set_dsheuristics, dsheuristics)

        res = self.ldb.search(base_dn,
                         scope=SCOPE_BASE, attrs=["lockoutDuration", "lockOutObservationWindow", "lockoutThreshold"])

        if "lockoutDuration" in res[0]:
            lockoutDuration = res[0]["lockoutDuration"][0]
        else:
            lockoutDuration = 0

        if "lockoutObservationWindow" in res[0]:
            lockoutObservationWindow = res[0]["lockoutObservationWindow"][0]
        else:
            lockoutObservationWindow = 0

        if "lockoutThreshold" in res[0]:
            lockoutThreshold = res[0]["lockoutThreshold"][0]
        else:
            lockoutTreshold = 0

        self.addCleanup(self.ldb.modify_ldif, """
dn: """ + base_dn + """
changetype: modify
replace: lockoutDuration
lockoutDuration: """ + str(lockoutDuration) + """
replace: lockoutObservationWindow
lockoutObservationWindow: """ + str(lockoutObservationWindow) + """
replace: lockoutThreshold
lockoutThreshold: """ + str(lockoutThreshold) + """
""")

        m = Message()
        m.dn = Dn(self.ldb, base_dn)

        self.account_lockout_duration = 2
        account_lockout_duration_ticks = -int(self.account_lockout_duration * (1e7))

        m["lockoutDuration"] = MessageElement(str(account_lockout_duration_ticks),
                                              FLAG_MOD_REPLACE, "lockoutDuration")

        account_lockout_threshold = 3
        m["lockoutThreshold"] = MessageElement(str(account_lockout_threshold),
                                               FLAG_MOD_REPLACE, "lockoutThreshold")

        self.lockout_observation_window = 2
        lockout_observation_window_ticks = -int(self.lockout_observation_window * (1e7))

        m["lockOutObservationWindow"] = MessageElement(str(lockout_observation_window_ticks),
                                                       FLAG_MOD_REPLACE, "lockOutObservationWindow")

        self.ldb.modify(m)

        # Set the "dSHeuristics" to activate the correct "userPassword" behaviour
        self.ldb.set_dsheuristics("000000001")

        # Get the old "minPwdAge"
        minPwdAge = self.ldb.get_minPwdAge()

        # Reset the "minPwdAge" as it was before
        self.addCleanup(self.ldb.set_minPwdAge, minPwdAge)

        # Set it temporarely to "0"
        self.ldb.set_minPwdAge("0")

        self.base_dn = self.ldb.domain_dn()

        self.domain_sid = security.dom_sid(self.ldb.get_domain_sid())
        self.samr = samr.samr("ncacn_ip_tcp:%s[seal]" % self.host, self.lp, self.global_creds)
        self.samr_handle = self.samr.Connect2(None, security.SEC_FLAG_MAXIMUM_ALLOWED)
        self.samr_domain = self.samr.OpenDomain(self.samr_handle, security.SEC_FLAG_MAXIMUM_ALLOWED, self.domain_sid)

        self.addCleanup(self.delete_ldb_connections)

        # (Re)adds the test user accounts
        self.lockout1krb5_creds = self.insta_creds(self.template_creds,
                                                   username="******",
                                                   userpass="******",
                                                   kerberos_state=MUST_USE_KERBEROS)
        self.lockout1krb5_ldb = self._readd_user(self.lockout1krb5_creds)
        self.lockout1ntlm_creds = self.insta_creds(self.template_creds,
                                                   username="******",
                                                   userpass="******",
                                                   kerberos_state=DONT_USE_KERBEROS)
        self.lockout1ntlm_ldb = self._readd_user(self.lockout1ntlm_creds)