from ldb import ERR_NO_SUCH_OBJECT, ERR_ATTRIBUTE_OR_VALUE_EXISTS
from ldb import ERR_ENTRY_ALREADY_EXISTS, ERR_UNWILLING_TO_PERFORM
from ldb import ERR_NOT_ALLOWED_ON_NON_LEAF, ERR_OTHER, ERR_INVALID_DN_SYNTAX
-from ldb import ERR_NO_SUCH_ATTRIBUTE
+from ldb import ERR_NO_SUCH_ATTRIBUTE, ERR_INVALID_ATTRIBUTE_SYNTAX
from ldb import ERR_OBJECT_CLASS_VIOLATION, ERR_NOT_ALLOWED_ON_RDN
from ldb import ERR_NAMING_VIOLATION, ERR_CONSTRAINT_VIOLATION
from ldb import ERR_UNDEFINED_ATTRIBUTE_TYPE
UF_WORKSTATION_TRUST_ACCOUNT, UF_SERVER_TRUST_ACCOUNT,
UF_PARTIAL_SECRETS_ACCOUNT,
UF_PASSWD_NOTREQD, UF_ACCOUNTDISABLE, ATYPE_NORMAL_ACCOUNT,
- ATYPE_WORKSTATION_TRUST, SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE)
+ ATYPE_WORKSTATION_TRUST, SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE,
+ SYSTEM_FLAG_CONFIG_ALLOW_RENAME, SYSTEM_FLAG_CONFIG_ALLOW_MOVE,
+ SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE)
from samba.dcerpc.security import (DOMAIN_RID_USERS, DOMAIN_RID_DOMAIN_MEMBERS,
DOMAIN_RID_DCS, DOMAIN_RID_READONLY_DCS)
from samba.ndr import ndr_pack, ndr_unpack
from samba.dcerpc import security
-parser = optparse.OptionParser("ldap [options] <host>")
+parser = optparse.OptionParser("ldap.py [options] <host>")
sambaopts = options.SambaOptions(parser)
parser.add_option_group(sambaopts)
parser.add_option_group(options.VersionOptions(parser))
res = self.ldb.search(base=self.base_dn, expression="(objectClass=*)", scope=SCOPE_BASE)
return ndr_unpack( security.dom_sid,res[0]["objectSid"][0])
+ def set_dsheuristics(self, dsheuristics):
+ m = Message()
+ m.dn = Dn(self.ldb, "CN=Directory Service, CN=Windows NT, CN=Services, "
+ + self.configuration_dn)
+ if dsheuristics is not None:
+ m["dSHeuristics"] = MessageElement(dsheuristics, FLAG_MOD_REPLACE,
+ "dSHeuristics")
+ else:
+ m["dSHeuristics"] = MessageElement([], FLAG_MOD_DELETE, "dsHeuristics")
+ self.ldb.modify(m)
+
def setUp(self):
super(BasicTests, self).setUp()
self.ldb = ldb
self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
self.delete_force(self.ldb, "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn)
self.delete_force(self.ldb, "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn)
- self.delete_force(self.ldb, "cn=entry1,cn=ldaptestcontainer," + self.base_dn)
- self.delete_force(self.ldb, "cn=entry2,cn=ldaptestcontainer," + self.base_dn)
self.delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
self.delete_force(self.ldb, "cn=ldaptestcontainer2," + self.base_dn)
self.delete_force(self.ldb, "cn=parentguidtest,cn=users," + self.base_dn)
except LdbError, (num, _):
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+ # Test allowed system flags
+ self.ldb.add({
+ "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
+ "objectClass": "person",
+ "systemFlags": str(~(SYSTEM_FLAG_CONFIG_ALLOW_RENAME | SYSTEM_FLAG_CONFIG_ALLOW_MOVE | SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE)) })
+
+ res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
+ scope=SCOPE_BASE, attrs=["systemFlags"])
+ self.assertTrue(len(res) == 1)
+ self.assertEquals(res[0]["systemFlags"][0], "0")
+
+ self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+
self.ldb.add({
"dn": "cn=ldaptestuser,cn=users," + self.base_dn,
"objectClass": "person" })
"objectClass")
ldb.modify(m)
- self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
+ self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
def test_system_only(self):
"""Test systemOnly objects"""
except LdbError, (num, _):
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+ try:
+ self.ldb.add({
+ "dn": "cn=testsecret,cn=system," + self.base_dn,
+ "objectclass": "secret"})
+ self.fail()
+ except LdbError, (num, _):
+ self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+
self.delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn)
self.delete_force(self.ldb, "cn=testsecret,cn=system," + self.base_dn)
+ try:
+ self.ldb.add({
+ "dn": "cn=ldaptestcontainer," + self.base_dn,
+ "objectclass": "container",
+ "isCriticalSystemObject": "TRUE"})
+ self.fail()
+ except LdbError, (num, _):
+ self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+
+ self.ldb.add({
+ "dn": "cn=ldaptestcontainer," + self.base_dn,
+ "objectclass": "container"})
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestcontainer," + self.base_dn)
+ m["isCriticalSystemObject"] = MessageElement("TRUE", FLAG_MOD_REPLACE,
+ "isCriticalSystemObject")
+ try:
+ ldb.modify(m)
+ self.fail()
+ except LdbError, (num, _):
+ self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+
+ self.delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
+
+ # Proof if DC SAM object has "isCriticalSystemObject" set
+ res = self.ldb.search("", scope=SCOPE_BASE, attrs=["serverName"])
+ self.assertTrue(len(res) == 1)
+ self.assertTrue("serverName" in res[0])
+ res = self.ldb.search(res[0]["serverName"][0], scope=SCOPE_BASE,
+ attrs=["serverReference"])
+ self.assertTrue(len(res) == 1)
+ self.assertTrue("serverReference" in res[0])
+ res = self.ldb.search(res[0]["serverReference"][0], scope=SCOPE_BASE,
+ attrs=["isCriticalSystemObject"])
+ self.assertTrue(len(res) == 1)
+ self.assertTrue("isCriticalSystemObject" in res[0])
+ self.assertEquals(res[0]["isCriticalSystemObject"][0], "TRUE")
+
def test_invalid_parent(self):
"""Test adding an object with invalid parent"""
print "Test adding an object with invalid parent"""
self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
- def test_multi_valued_attributes(self):
- """Test multi-valued attributes"""
- print "Test multi-valued attributes"""
-
-# TODO: In this test I added some special tests where I got very unusual
-# results back from a real AD. s4 doesn't match them and I've no idea how to
-# implement those error cases (maybe there exists a special trigger for
-# "description" attributes which handle them)
+ def test_description_attribute(self):
+ """Test description attribute"""
+ print "Test description attribute"""
self.ldb.add({
"dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
"objectclass": "group",
"description": "desc1"})
+ res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
+ scope=SCOPE_BASE, attrs=["description"])
+ self.assertTrue(len(res) == 1)
+ self.assertTrue("description" in res[0])
+ self.assertTrue(len(res[0]["description"]) == 1)
+ self.assertEquals(res[0]["description"][0], "desc1")
+
self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
self.ldb.add({
"objectclass": "group",
"description": ["desc1", "desc2"]})
-# m = Message()
-# m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
-# m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_REPLACE,
-# "description")
-# try:
-# ldb.modify(m)
-# self.fail()
-# except LdbError, (num, _):
-# self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
+ res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
+ scope=SCOPE_BASE, attrs=["description"])
+ self.assertTrue(len(res) == 1)
+ self.assertTrue("description" in res[0])
+ self.assertTrue(len(res[0]["description"]) == 2)
+ self.assertTrue(res[0]["description"][0] == "desc1" or
+ res[0]["description"][1] == "desc1")
+ self.assertTrue(res[0]["description"][0] == "desc2" or
+ res[0]["description"][1] == "desc2")
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+ m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_REPLACE,
+ "description")
+ try:
+ ldb.modify(m)
+ self.fail()
+ except LdbError, (num, _):
+ self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+ m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_DELETE,
+ "description")
+ ldb.modify(m)
+
+ self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+
+ self.ldb.add({
+ "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
+ "objectclass": "group" })
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
"description")
ldb.modify(m)
-# m = Message()
-# m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
-# m["description"] = MessageElement("desc3", FLAG_MOD_ADD,
-# "description")
-# try:
-# ldb.modify(m)
-# self.fail()
-# except LdbError, (num, _):
-# self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
+ res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
+ scope=SCOPE_BASE, attrs=["description"])
+ self.assertTrue(len(res) == 1)
+ self.assertTrue("description" in res[0])
+ self.assertTrue(len(res[0]["description"]) == 1)
+ self.assertEquals(res[0]["description"][0], "desc1")
+
+ self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+
+ self.ldb.add({
+ "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
+ "objectclass": "group",
+ "description": ["desc1", "desc2"]})
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+ m["description"] = MessageElement("desc1", FLAG_MOD_REPLACE,
+ "description")
+ ldb.modify(m)
+
+ res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
+ scope=SCOPE_BASE, attrs=["description"])
+ self.assertTrue(len(res) == 1)
+ self.assertTrue("description" in res[0])
+ self.assertTrue(len(res[0]["description"]) == 1)
+ self.assertEquals(res[0]["description"][0], "desc1")
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+ m["description"] = MessageElement("desc3", FLAG_MOD_ADD,
+ "description")
+ try:
+ ldb.modify(m)
+ self.fail()
+ except LdbError, (num, _):
+ self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["description"] = MessageElement("desc1", FLAG_MOD_DELETE,
"description")
ldb.modify(m)
+ res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
+ scope=SCOPE_BASE, attrs=["description"])
+ self.assertTrue(len(res) == 1)
+ self.assertFalse("description" in res[0])
-# m = Message()
-# m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
-# m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_REPLACE,
-# "description")
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+ m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_REPLACE,
+ "description")
+ try:
+ ldb.modify(m)
+ self.fail()
+ except LdbError, (num, _):
+ self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+ m["description"] = MessageElement(["desc3", "desc4"], FLAG_MOD_ADD,
+ "description")
+ try:
+ ldb.modify(m)
+ self.fail()
+ except LdbError, (num, _):
+ self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+ m["description"] = MessageElement("desc1", FLAG_MOD_ADD,
+ "description")
+ ldb.modify(m)
+
+ res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
+ scope=SCOPE_BASE, attrs=["description"])
+ self.assertTrue(len(res) == 1)
+ self.assertTrue("description" in res[0])
+ self.assertTrue(len(res[0]["description"]) == 1)
+ self.assertEquals(res[0]["description"][0], "desc1")
+
+ self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+
+ def test_attribute_ranges(self):
+ """Test attribute ranges"""
+ print "Test attribute ranges"""
+
+ # Too short (min. 1)
+ try:
+ ldb.add({
+ "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
+ "objectClass": "person",
+ "sn": "" })
+ self.fail()
+ except LdbError, (num, _):
+ self.assertEquals(num, ERR_INVALID_ATTRIBUTE_SYNTAX)
+
+ # Too long (max. 64)
# try:
-# ldb.modify(m)
+# ldb.add({
+# "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
+# "objectClass": "person",
+# "sn": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" })
# self.fail()
# except LdbError, (num, _):
-# self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
+# self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
+
+ ldb.add({
+ "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
+ "objectClass": "person" })
+
+ # Too short (min. 1)
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ m["sn"] = MessageElement("", FLAG_MOD_REPLACE, "sn")
+ try:
+ ldb.modify(m)
+ self.fail()
+ except LdbError, (num, _):
+ self.assertEquals(num, ERR_INVALID_ATTRIBUTE_SYNTAX)
+ # Too long (max. 64)
# m = Message()
-# m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
-# m["description"] = MessageElement(["desc3", "desc4"], FLAG_MOD_ADD,
-# "description")
+# m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+# m["sn"] = MessageElement("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", FLAG_MOD_REPLACE, "sn")
# try:
# ldb.modify(m)
# self.fail()
# except LdbError, (num, _):
-# self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
+# self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
m = Message()
- m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
- m["description"] = MessageElement("desc3", FLAG_MOD_ADD,
- "description")
+ m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ m["sn"] = MessageElement("x", FLAG_MOD_REPLACE, "sn")
ldb.modify(m)
- self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+ self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
def test_empty_messages(self):
"""Test empty messages"""
for key in res1[0].keys():
if key == "sAMAccountName":
has_another_attribute = True
- break
- self.assertTrue(has_another_attribute)
- self.assertTrue(len(res1[0]["samaccountname"]) == 1)
- self.assertEquals(res1[0]["samaccountname"][0], "parentguidtest");
-
- print "Testing parentGUID behaviour on rename\n"
-
- self.ldb.add({
- "dn": "cn=testotherusers," + self.base_dn,
- "objectclass":"container"});
- res1 = ldb.search(base="cn=testotherusers," + self.base_dn,scope=SCOPE_BASE,
- attrs=["objectGUID"]);
- ldb.rename("cn=parentguidtest,cn=users," + self.base_dn,
- "cn=parentguidtest,cn=testotherusers," + self.base_dn);
- res2 = ldb.search(base="cn=parentguidtest,cn=testotherusers," + self.base_dn,
- scope=SCOPE_BASE,
- attrs=["parentGUID"]);
- self.assertEquals(res1[0]["objectGUID"], res2[0]["parentGUID"]);
-
- self.delete_force(self.ldb, "cn=parentguidtest,cn=testotherusers," + self.base_dn)
- self.delete_force(self.ldb, "cn=testotherusers," + self.base_dn)
-
- def test_groupType_int32(self):
- """Test groupType (int32) behaviour (should appear to be casted to a 32 bit signed integer before comparsion)"""
- print "Testing groupType (int32) behaviour\n"
-
- res1 = ldb.search(base=self.base_dn, scope=SCOPE_SUBTREE,
- attrs=["groupType"], expression="groupType=2147483653");
-
- res2 = ldb.search(base=self.base_dn, scope=SCOPE_SUBTREE,
- attrs=["groupType"], expression="groupType=-2147483643");
-
- self.assertEquals(len(res1), len(res2))
-
- self.assertTrue(res1.count > 0)
-
- self.assertEquals(res1[0]["groupType"][0], "-2147483643")
-
- def test_linked_attributes(self):
- """This tests the linked attribute behaviour"""
- print "Testing linked attribute behaviour\n"
-
- ldb.add({
- "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
- "objectclass": "group"})
-
- # This should not work since "memberOf" is linked to "member"
- try:
- ldb.add({
- "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
- "objectclass": ["user", "person"],
- "memberOf": "cn=ldaptestgroup,cn=users," + self.base_dn})
- except LdbError, (num, _):
- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
-
- ldb.add({
- "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
- "objectclass": ["user", "person"]})
-
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn,
- FLAG_MOD_ADD, "memberOf")
- try:
- ldb.modify(m)
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
-
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
- m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
- FLAG_MOD_ADD, "member")
- ldb.modify(m)
-
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn,
- FLAG_MOD_REPLACE, "memberOf")
- try:
- ldb.modify(m)
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
-
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn,
- FLAG_MOD_DELETE, "memberOf")
- try:
- ldb.modify(m)
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
-
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
- m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
- FLAG_MOD_DELETE, "member")
- ldb.modify(m)
-
- # This should yield no results since the member attribute for
- # "ldaptestuser" should have been deleted
- res1 = ldb.search("cn=ldaptestgroup, cn=users," + self.base_dn,
- scope=SCOPE_BASE,
- expression="(member=cn=ldaptestuser,cn=users," + self.base_dn + ")",
- attrs=[])
- self.assertTrue(len(res1) == 0)
-
- self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
-
- ldb.add({
- "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
- "objectclass": "group",
- "member": "cn=ldaptestuser,cn=users," + self.base_dn})
-
- self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
-
- # Make sure that the "member" attribute for "ldaptestuser" has been
- # removed
- res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
- scope=SCOPE_BASE, attrs=["member"])
- self.assertTrue(len(res) == 1)
- self.assertFalse("member" in res[0])
-
- self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
-
- def test_users_groups(self):
- """This tests the SAM users and groups behaviour"""
- print "Testing users and groups behaviour\n"
-
- ldb.add({
- "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
- "objectclass": "group"})
-
- ldb.add({
- "dn": "cn=ldaptestgroup2,cn=users," + self.base_dn,
- "objectclass": "group"})
-
- res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
- scope=SCOPE_BASE, attrs=["objectSID"])
- self.assertTrue(len(res1) == 1)
- group_rid_1 = security.dom_sid(ldb.schema_format_value("objectSID",
- res1[0]["objectSID"][0])).split()[1]
-
- res1 = ldb.search("cn=ldaptestgroup2,cn=users," + self.base_dn,
- scope=SCOPE_BASE, attrs=["objectSID"])
- self.assertTrue(len(res1) == 1)
- group_rid_2 = security.dom_sid(ldb.schema_format_value("objectSID",
- res1[0]["objectSID"][0])).split()[1]
-
- # Try to create a user with an invalid primary group
- try:
- ldb.add({
- "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
- "objectclass": ["user", "person"],
- "primaryGroupID": "0"})
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
- self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
-
- # Try to Create a user with a valid primary group
- try:
- ldb.add({
- "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
- "objectclass": ["user", "person"],
- "primaryGroupID": str(group_rid_1)})
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
- self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
-
- # Test to see how we should behave when the user account doesn't
- # exist
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- m["primaryGroupID"] = MessageElement("0", FLAG_MOD_REPLACE,
- "primaryGroupID")
- try:
- ldb.modify(m)
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_NO_SUCH_OBJECT)
-
- # Test to see how we should behave when the account isn't a user
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
- m["primaryGroupID"] = MessageElement("0", FLAG_MOD_REPLACE,
- "primaryGroupID")
- try:
- ldb.modify(m)
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
-
- # Test default primary groups on add operations
-
- ldb.add({
- "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
- "objectclass": ["user", "person"]})
-
- res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
- scope=SCOPE_BASE, attrs=["primaryGroupID"])
- self.assertTrue(len(res1) == 1)
- self.assertEquals(res1[0]["primaryGroupID"][0], str(DOMAIN_RID_USERS))
-
- self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
-
- ldb.add({
- "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
- "objectclass": ["user", "person"],
- "userAccountControl": str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD) })
-
- res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
- scope=SCOPE_BASE, attrs=["primaryGroupID"])
- self.assertTrue(len(res1) == 1)
- self.assertEquals(res1[0]["primaryGroupID"][0], str(DOMAIN_RID_USERS))
-
- self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
-
- # unfortunately the INTERDOMAIN_TRUST_ACCOUNT case cannot be tested
- # since such accounts aren't directly creatable (ACCESS_DENIED)
-
- ldb.add({
- "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
- "objectclass": ["computer"],
- "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD) })
-
- res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
- scope=SCOPE_BASE, attrs=["primaryGroupID"])
- self.assertTrue(len(res1) == 1)
- self.assertEquals(res1[0]["primaryGroupID"][0], str(DOMAIN_RID_DOMAIN_MEMBERS))
-
- self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
-
- ldb.add({
- "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
- "objectclass": ["computer"],
- "userAccountControl": str(UF_SERVER_TRUST_ACCOUNT | UF_PASSWD_NOTREQD) })
-
- res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
- scope=SCOPE_BASE, attrs=["primaryGroupID"])
- self.assertTrue(len(res1) == 1)
- self.assertEquals(res1[0]["primaryGroupID"][0], str(DOMAIN_RID_DCS))
-
- self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
-
- # Read-only DC accounts are only creatable by
- # UF_WORKSTATION_TRUST_ACCOUNT and work only on DCs >= 2008 (therefore
- # we have a fallback in the assertion)
- ldb.add({
- "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
- "objectclass": ["computer"],
- "userAccountControl": str(UF_PARTIAL_SECRETS_ACCOUNT | UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD) })
-
- res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
- scope=SCOPE_BASE, attrs=["primaryGroupID"])
- self.assertTrue(len(res1) == 1)
- self.assertTrue(res1[0]["primaryGroupID"][0] == str(DOMAIN_RID_READONLY_DCS) or
- res1[0]["primaryGroupID"][0] == str(DOMAIN_RID_DOMAIN_MEMBERS))
-
- self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
-
- # Test default primary groups on modify operations
-
- ldb.add({
- "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
- "objectclass": ["user", "person"]})
-
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- m["userAccountControl"] = MessageElement(str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD), FLAG_MOD_REPLACE,
- "userAccountControl")
- ldb.modify(m)
-
- res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
- scope=SCOPE_BASE, attrs=["primaryGroupID"])
- self.assertTrue(len(res1) == 1)
- self.assertEquals(res1[0]["primaryGroupID"][0], str(DOMAIN_RID_USERS))
-
- # unfortunately the INTERDOMAIN_TRUST_ACCOUNT case cannot be tested
- # since such accounts aren't directly creatable (ACCESS_DENIED)
-
- self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
-
- ldb.add({
- "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
- "objectclass": ["computer"]})
-
- res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
- scope=SCOPE_BASE, attrs=["primaryGroupID"])
- self.assertTrue(len(res1) == 1)
- self.assertEquals(res1[0]["primaryGroupID"][0], str(DOMAIN_RID_USERS))
-
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- m["userAccountControl"] = MessageElement(str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD), FLAG_MOD_REPLACE,
- "userAccountControl")
- ldb.modify(m)
-
- res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
- scope=SCOPE_BASE, attrs=["primaryGroupID"])
- self.assertTrue(len(res1) == 1)
- self.assertEquals(res1[0]["primaryGroupID"][0], str(DOMAIN_RID_DOMAIN_MEMBERS))
-
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- m["userAccountControl"] = MessageElement(str(UF_SERVER_TRUST_ACCOUNT | UF_PASSWD_NOTREQD), FLAG_MOD_REPLACE,
- "userAccountControl")
- ldb.modify(m)
-
- res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
- scope=SCOPE_BASE, attrs=["primaryGroupID"])
- self.assertTrue(len(res1) == 1)
- self.assertEquals(res1[0]["primaryGroupID"][0], str(DOMAIN_RID_DCS))
-
- # Read-only DC accounts are only creatable by
- # UF_WORKSTATION_TRUST_ACCOUNT and work only on DCs >= 2008 (therefore
- # we have a fallback in the assertion)
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- m["userAccountControl"] = MessageElement(str(UF_PARTIAL_SECRETS_ACCOUNT | UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD), FLAG_MOD_REPLACE,
- "userAccountControl")
- ldb.modify(m)
-
- res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
- scope=SCOPE_BASE, attrs=["primaryGroupID"])
- self.assertTrue(len(res1) == 1)
- self.assertTrue(res1[0]["primaryGroupID"][0] == str(DOMAIN_RID_READONLY_DCS) or
- res1[0]["primaryGroupID"][0] == str(DOMAIN_RID_DOMAIN_MEMBERS))
-
- self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
-
- # Recreate account for further tests
-
- ldb.add({
- "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
- "objectclass": ["user", "person"]})
-
- # We should be able to reset our actual primary group
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- m["primaryGroupID"] = MessageElement(str(DOMAIN_RID_USERS), FLAG_MOD_REPLACE,
- "primaryGroupID")
- ldb.modify(m)
-
- # Try to add invalid primary group
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- m["primaryGroupID"] = MessageElement("0", FLAG_MOD_REPLACE,
- "primaryGroupID")
- try:
- ldb.modify(m)
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
-
- # Try to make group 1 primary - should be denied since it is not yet
- # secondary
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- m["primaryGroupID"] = MessageElement(str(group_rid_1),
- FLAG_MOD_REPLACE, "primaryGroupID")
- try:
- ldb.modify(m)
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
-
- # Make group 1 secondary
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
- m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
- FLAG_MOD_REPLACE, "member")
- ldb.modify(m)
-
- # Make group 1 primary
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- m["primaryGroupID"] = MessageElement(str(group_rid_1),
- FLAG_MOD_REPLACE, "primaryGroupID")
- ldb.modify(m)
-
- # Try to delete group 1 - should be denied
- try:
- ldb.delete("cn=ldaptestgroup,cn=users," + self.base_dn)
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
-
- # Try to add group 1 also as secondary - should be denied
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
- m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
- FLAG_MOD_ADD, "member")
- try:
- ldb.modify(m)
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
+ break
+ self.assertTrue(has_another_attribute)
+ self.assertTrue(len(res1[0]["samaccountname"]) == 1)
+ self.assertEquals(res1[0]["samaccountname"][0], "parentguidtest");
- # Try to add invalid member to group 1 - should be denied
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
- m["member"] = MessageElement(
- "cn=ldaptestuser3,cn=users," + self.base_dn,
- FLAG_MOD_ADD, "member")
- try:
- ldb.modify(m)
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_NO_SUCH_OBJECT)
+ print "Testing parentGUID behaviour on rename\n"
- # Make group 2 secondary
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
- m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
- FLAG_MOD_ADD, "member")
- ldb.modify(m)
+ self.ldb.add({
+ "dn": "cn=testotherusers," + self.base_dn,
+ "objectclass":"container"});
+ res1 = ldb.search(base="cn=testotherusers," + self.base_dn,scope=SCOPE_BASE,
+ attrs=["objectGUID"]);
+ ldb.rename("cn=parentguidtest,cn=users," + self.base_dn,
+ "cn=parentguidtest,cn=testotherusers," + self.base_dn);
+ res2 = ldb.search(base="cn=parentguidtest,cn=testotherusers," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["parentGUID"]);
+ self.assertEquals(res1[0]["objectGUID"], res2[0]["parentGUID"]);
- # Swap the groups
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- m["primaryGroupID"] = MessageElement(str(group_rid_2),
- FLAG_MOD_REPLACE, "primaryGroupID")
- ldb.modify(m)
+ self.delete_force(self.ldb, "cn=parentguidtest,cn=testotherusers," + self.base_dn)
+ self.delete_force(self.ldb, "cn=testotherusers," + self.base_dn)
- # Old primary group should contain a "member" attribute for the user,
- # the new shouldn't contain anymore one
- res1 = ldb.search("cn=ldaptestgroup, cn=users," + self.base_dn,
- scope=SCOPE_BASE, attrs=["member"])
- self.assertTrue(len(res1) == 1)
- self.assertTrue(len(res1[0]["member"]) == 1)
- self.assertEquals(res1[0]["member"][0].lower(),
- ("cn=ldaptestuser,cn=users," + self.base_dn).lower())
+ def test_groupType_int32(self):
+ """Test groupType (int32) behaviour (should appear to be casted to a 32 bit signed integer before comparsion)"""
+ print "Testing groupType (int32) behaviour\n"
- res1 = ldb.search("cn=ldaptestgroup2, cn=users," + self.base_dn,
- scope=SCOPE_BASE, attrs=["member"])
- self.assertTrue(len(res1) == 1)
- self.assertFalse("member" in res1[0])
+ res1 = ldb.search(base=self.base_dn, scope=SCOPE_SUBTREE,
+ attrs=["groupType"], expression="groupType=2147483653");
- # Also this should be denied
- try:
- ldb.add({
- "dn": "cn=ldaptestuser1,cn=users," + self.base_dn,
- "objectclass": ["user", "person"],
- "primaryGroupID": "0"})
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+ res2 = ldb.search(base=self.base_dn, scope=SCOPE_SUBTREE,
+ attrs=["groupType"], expression="groupType=-2147483643");
- self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
- self.delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
+ self.assertEquals(len(res1), len(res2))
- def test_sam_attributes(self):
- """Test the behaviour of special attributes of SAM objects"""
- print "Testing the behaviour of special attributes of SAM objects\n"""
+ self.assertTrue(res1.count > 0)
+
+ self.assertEquals(res1[0]["groupType"][0], "-2147483643")
+
+ def test_linked_attributes(self):
+ """This tests the linked attribute behaviour"""
+ print "Testing linked attribute behaviour\n"
- ldb.add({
- "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
- "objectclass": ["user", "person"]})
ldb.add({
"dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
"objectclass": "group"})
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
- m["groupType"] = MessageElement("0", FLAG_MOD_ADD,
- "groupType")
- try:
- ldb.modify(m)
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
-
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
- m["groupType"] = MessageElement([], FLAG_MOD_DELETE,
- "groupType")
+ # This should not work since "memberOf" is linked to "member"
try:
- ldb.modify(m)
- self.fail()
+ ldb.add({
+ "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
+ "objectclass": ["user", "person"],
+ "memberOf": "cn=ldaptestgroup,cn=users," + self.base_dn})
except LdbError, (num, _):
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- m["primaryGroupID"] = MessageElement("0", FLAG_MOD_ADD,
- "primaryGroupID")
- try:
- ldb.modify(m)
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
+ ldb.add({
+ "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
+ "objectclass": ["user", "person"]})
m = Message()
m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- m["primaryGroupID"] = MessageElement([], FLAG_MOD_DELETE,
- "primaryGroupID")
+ m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn,
+ FLAG_MOD_ADD, "memberOf")
try:
ldb.modify(m)
self.fail()
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
m = Message()
- m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- m["userAccountControl"] = MessageElement("0", FLAG_MOD_ADD,
- "userAccountControl")
- try:
- ldb.modify(m)
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
-
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- m["userAccountControl"] = MessageElement([], FLAG_MOD_DELETE,
- "userAccountControl")
- try:
- ldb.modify(m)
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+ m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+ m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
+ FLAG_MOD_ADD, "member")
+ ldb.modify(m)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- m["sAMAccountType"] = MessageElement("0", FLAG_MOD_ADD,
- "sAMAccountType")
+ m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn,
+ FLAG_MOD_REPLACE, "memberOf")
try:
ldb.modify(m)
self.fail()
m = Message()
m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- m["sAMAccountType"] = MessageElement([], FLAG_MOD_REPLACE,
- "sAMAccountType")
+ m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn,
+ FLAG_MOD_DELETE, "memberOf")
try:
ldb.modify(m)
self.fail()
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
m = Message()
- m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- m["sAMAccountType"] = MessageElement([], FLAG_MOD_DELETE,
- "sAMAccountType")
- try:
- ldb.modify(m)
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
-
- self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+ m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+ m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
+ FLAG_MOD_DELETE, "member")
+ ldb.modify(m)
- def test_primary_group_token_constructed(self):
- """Test the primary group token behaviour (hidden-generated-readonly attribute on groups) and some other constructed attributes"""
- print "Testing primary group token behaviour and other constructed attributes\n"
+ # This should yield no results since the member attribute for
+ # "ldaptestuser" should have been deleted
+ res1 = ldb.search("cn=ldaptestgroup, cn=users," + self.base_dn,
+ scope=SCOPE_BASE,
+ expression="(member=cn=ldaptestuser,cn=users," + self.base_dn + ")",
+ attrs=[])
+ self.assertTrue(len(res1) == 0)
- try:
- ldb.add({
- "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
- "objectclass": "group",
- "primaryGroupToken": "100"})
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_UNDEFINED_ATTRIBUTE_TYPE)
self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
- ldb.add({
- "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
- "objectclass": ["user", "person"]})
-
ldb.add({
"dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
- "objectclass": "group"})
-
- # Testing for one invalid, and one valid operational attribute, but also the things they are built from
- res1 = ldb.search(self.base_dn,
- scope=SCOPE_BASE, attrs=["primaryGroupToken", "canonicalName", "objectClass", "objectSid"])
- self.assertTrue(len(res1) == 1)
- self.assertFalse("primaryGroupToken" in res1[0])
- self.assertTrue("canonicalName" in res1[0])
- self.assertTrue("objectClass" in res1[0])
- self.assertTrue("objectSid" in res1[0])
-
- res1 = ldb.search(self.base_dn,
- scope=SCOPE_BASE, attrs=["primaryGroupToken", "canonicalName"])
- self.assertTrue(len(res1) == 1)
- self.assertFalse("primaryGroupToken" in res1[0])
- self.assertFalse("objectSid" in res1[0])
- self.assertFalse("objectClass" in res1[0])
- self.assertTrue("canonicalName" in res1[0])
-
- res1 = ldb.search("cn=users,"+self.base_dn,
- scope=SCOPE_BASE, attrs=["primaryGroupToken"])
- self.assertTrue(len(res1) == 1)
- self.assertFalse("primaryGroupToken" in res1[0])
-
- res1 = ldb.search("cn=ldaptestuser, cn=users," + self.base_dn,
- scope=SCOPE_BASE, attrs=["primaryGroupToken"])
- self.assertTrue(len(res1) == 1)
- self.assertFalse("primaryGroupToken" in res1[0])
-
- res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
- scope=SCOPE_BASE)
- self.assertTrue(len(res1) == 1)
- self.assertFalse("primaryGroupToken" in res1[0])
-
- res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
- scope=SCOPE_BASE, attrs=["primaryGroupToken", "objectSID"])
- self.assertTrue(len(res1) == 1)
- primary_group_token = int(res1[0]["primaryGroupToken"][0])
-
- rid = security.dom_sid(ldb.schema_format_value("objectSID", res1[0]["objectSID"][0])).split()[1]
- self.assertEquals(primary_group_token, rid)
-
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
- m["primaryGroupToken"] = "100"
- try:
- ldb.modify(m)
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
+ "objectclass": "group",
+ "member": "cn=ldaptestuser,cn=users," + self.base_dn})
self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
-
- def test_tokenGroups(self):
- """Test the tokenGroups behaviour (hidden-generated-readonly attribute on SAM objects)"""
- print "Testing tokenGroups behaviour\n"
-
- # The domain object shouldn't contain any "tokenGroups" entry
- res = ldb.search(self.base_dn, scope=SCOPE_BASE, attrs=["tokenGroups"])
- self.assertTrue(len(res) == 1)
- self.assertFalse("tokenGroups" in res[0])
-
- # The domain administrator should contain "tokenGroups" entries
- # (the exact number depends on the domain/forest function level and the
- # DC software versions)
- res = ldb.search("cn=Administrator,cn=Users," + self.base_dn,
- scope=SCOPE_BASE, attrs=["tokenGroups"])
- self.assertTrue(len(res) == 1)
- self.assertTrue("tokenGroups" in res[0])
- ldb.add({
- "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
- "objectclass": ["user", "person"]})
-
- # This testuser should contain at least two "tokenGroups" entries
- # (exactly two on an unmodified "Domain Users" and "Users" group)
- res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
- scope=SCOPE_BASE, attrs=["tokenGroups"])
+ # Make sure that the "member" attribute for "ldaptestuser" has been
+ # removed
+ res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
+ scope=SCOPE_BASE, attrs=["member"])
self.assertTrue(len(res) == 1)
- self.assertTrue(len(res[0]["tokenGroups"]) >= 2)
-
- # one entry which we need to find should point to domains "Domain Users"
- # group and another entry should point to the builtin "Users"group
- domain_users_group_found = False
- users_group_found = False
- for sid in res[0]["tokenGroups"]:
- rid = security.dom_sid(ldb.schema_format_value("objectSID", sid)).split()[1]
- if rid == 513:
- domain_users_group_found = True
- if rid == 545:
- users_group_found = True
-
- self.assertTrue(domain_users_group_found)
- self.assertTrue(users_group_found)
+ self.assertFalse("member" in res[0])
- self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
def test_wkguid(self):
"""Test Well known GUID behaviours (including DN+Binary)"""
self.assertEquals(len(res), 1)
self.assertTrue("subScheamSubEntry" not in res[0])
- def test_delete(self):
- """Tests the delete operation"""
- print "Tests the delete operations"""
-
- ldb.add({
- "dn": "cn=ldaptestcontainer," + self.base_dn,
- "objectclass": "container"})
- ldb.add({
- "dn": "cn=entry1,cn=ldaptestcontainer," + self.base_dn,
- "objectclass": "container"})
- ldb.add({
- "dn": "cn=entry2,cn=ldaptestcontainer," + self.base_dn,
- "objectclass": "container"})
-
- try:
- ldb.delete("cn=ldaptestcontainer," + self.base_dn)
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_NOT_ALLOWED_ON_NON_LEAF)
-
- ldb.delete("cn=ldaptestcontainer," + self.base_dn, ["tree_delete:0"])
-
- try:
- res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
- scope=SCOPE_BASE, attrs=[])
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_NO_SUCH_OBJECT)
- try:
- res = ldb.search("cn=entry1,cn=ldaptestcontainer," + self.base_dn,
- scope=SCOPE_BASE, attrs=[])
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_NO_SUCH_OBJECT)
- try:
- res = ldb.search("cn=entry2,cn=ldaptestcontainer," + self.base_dn,
- scope=SCOPE_BASE, attrs=[])
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_NO_SUCH_OBJECT)
-
- self.delete_force(self.ldb, "cn=entry1,cn=ldaptestcontainer," + self.base_dn)
- self.delete_force(self.ldb, "cn=entry2,cn=ldaptestcontainer," + self.base_dn)
- self.delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
-
- # Performs some protected object delete testing
-
- res = ldb.search(base="", expression="", scope=SCOPE_BASE,
- attrs=["dsServiceName", "dNSHostName"])
- self.assertEquals(len(res), 1)
-
- try:
- ldb.delete(res[0]["dsServiceName"][0])
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
-
- res = ldb.search(self.base_dn, scope=SCOPE_SUBTREE,
- attrs=["rIDSetReferences"],
- expression="(&(objectClass=computer)(dNSHostName=" + res[0]["dNSHostName"][0] + "))")
- self.assertEquals(len(res), 1)
-
- try:
- ldb.delete(res[0]["rIDSetReferences"][0])
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
-
- try:
- ldb.delete("cn=Enterprise Schema,cn=Partitions," + self.configuration_dn)
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
-
-# TODO: This fails with LDB_ERR_NOT_ALLOWED_ON_NON_LEAF on Windows
-# try:
-# ldb.delete("cn=Enterprise Configuration,cn=Partitions," + self.configuration_dn)
-# self.fail()
-# except LdbError, (num, _):
-# self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
-
- # Performs some "systemFlags" testing
-
- # Delete failing since "SYSTEM_FLAG_DISALLOW_DELETE"
- try:
- ldb.delete("CN=Users," + self.base_dn)
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
-
def test_all(self):
"""Basic tests"""
finally:
self.delete_force(self.ldb, user_dn)
+ def test_dsheuristics(self):
+ """Tests the 'dSHeuristics' attribute"""
+ print "Tests the 'dSHeuristics' attribute"""
+
+ # Get the current value to restore it later
+ res = self.ldb.search("CN=Directory Service, CN=Windows NT, CN=Services, "
+ + self.configuration_dn, scope=SCOPE_BASE, attrs=["dSHeuristics"])
+ if "dSHeuristics" in res[0]:
+ dsheuristics = res[0]["dSHeuristics"][0]
+ else:
+ dsheuristics = None
+ # Should not be longer than 18 chars?
+ try:
+ self.set_dsheuristics("123ABC-+!1asdfg@#^12")
+ except LdbError, (num, _):
+ self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
+ # If it is >= 10 chars, tenthChar should be 1
+ try:
+ self.set_dsheuristics("00020000000002")
+ except LdbError, (num, _):
+ self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
+ # apart from the above, all char values are accepted
+ self.set_dsheuristics("123ABC-+!1asdfg@#^")
+ res = self.ldb.search("CN=Directory Service, CN=Windows NT, CN=Services, "
+ + self.configuration_dn, scope=SCOPE_BASE, attrs=["dSHeuristics"])
+ self.assertTrue("dSHeuristics" in res[0])
+ self.assertEquals(res[0]["dSHeuristics"][0], "123ABC-+!1asdfg@#^")
+ # restore old value
+ self.set_dsheuristics(dsheuristics)
+
class BaseDnTests(unittest.TestCase):
self.assertTrue(res[0]["configurationNamingContext"][0] in ncs)
self.assertTrue(res[0]["schemaNamingContext"][0] in ncs)
+ def test_serverPath(self):
+ """Testing the server paths in rootDSE"""
+ res = self.ldb.search("", scope=SCOPE_BASE,
+ attrs=["dsServiceName", "serverName"])
+ self.assertEquals(len(res), 1)
+
+ self.assertTrue("CN=Servers" in res[0]["dsServiceName"][0])
+ self.assertTrue("CN=Sites" in res[0]["dsServiceName"][0])
+ self.assertTrue("CN=NTDS Settings" in res[0]["dsServiceName"][0])
+ self.assertTrue("CN=Servers" in res[0]["serverName"][0])
+ self.assertTrue("CN=Sites" in res[0]["serverName"][0])
+ self.assertFalse("CN=NTDS Settings" in res[0]["serverName"][0])
+
+ def test_dnsHostname(self):
+ """Testing the DNS hostname in rootDSE"""
+ res = self.ldb.search("", scope=SCOPE_BASE,
+ attrs=["dnsHostName", "serverName"])
+ self.assertEquals(len(res), 1)
+
+ res2 = self.ldb.search(res[0]["serverName"][0], scope=SCOPE_BASE,
+ attrs=["dNSHostName"])
+ self.assertEquals(len(res2), 1)
+
+ self.assertEquals(res[0]["dnsHostName"][0], res2[0]["dNSHostName"][0])
+
+ def test_ldapServiceName(self):
+ """Testing the ldap service name in rootDSE"""
+ res = self.ldb.search("", scope=SCOPE_BASE,
+ attrs=["ldapServiceName", "dNSHostName"])
+ self.assertEquals(len(res), 1)
+
+ (hostname, _, dns_domainname) = res[0]["dNSHostName"][0].partition(".")
+ self.assertTrue(":%s$@%s" % (hostname, dns_domainname.upper())
+ in res[0]["ldapServiceName"][0])
if not "://" in host:
if os.path.isfile(host):