sys.path.append("bin/python")
import samba
-samba.ensure_external_module("subunit", "subunit/python")
samba.ensure_external_module("testtools", "testtools")
+samba.ensure_external_module("subunit", "subunit/python")
import samba.getopt as options
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
from ldb import Message, MessageElement, Dn
from ldb import FLAG_MOD_ADD, FLAG_MOD_REPLACE, FLAG_MOD_DELETE
+from ldb import timestring
from samba import Ldb
-from samba.dsdb import (UF_NORMAL_ACCOUNT, UF_INTERDOMAIN_TRUST_ACCOUNT,
- UF_WORKSTATION_TRUST_ACCOUNT, UF_SERVER_TRUST_ACCOUNT,
- UF_PARTIAL_SECRETS_ACCOUNT,
+from samba.samdb import SamDB
+from samba.dsdb import (UF_NORMAL_ACCOUNT,
+ UF_WORKSTATION_TRUST_ACCOUNT,
UF_PASSWD_NOTREQD, UF_ACCOUNTDISABLE, ATYPE_NORMAL_ACCOUNT,
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 subunit.run import SubunitTestRunner
import unittest
except LdbError, (num, _):
self.assertEquals(num, ERR_NO_SUCH_OBJECT)
- def find_basedn(self, ldb):
- res = ldb.search(base="", expression="", scope=SCOPE_BASE,
- attrs=["defaultNamingContext"])
- self.assertEquals(len(res), 1)
- return res[0]["defaultNamingContext"][0]
-
def find_configurationdn(self, ldb):
res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["configurationNamingContext"])
self.assertEquals(len(res), 1)
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.gc_ldb = gc_ldb
- self.base_dn = self.find_basedn(ldb)
+ self.base_dn = ldb.domain_dn()
self.configuration_dn = self.find_configurationdn(ldb)
self.schema_dn = self.find_schemadn(ldb)
self.domain_sid = self.find_domain_sid()
except LdbError, (num, _):
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+ # Invalid objectclass specified
+ try:
+ self.ldb.add({
+ "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
+ "objectClass": [] })
+ self.fail()
+ except LdbError, (num, _):
+ self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
+
# Invalid objectclass specified
try:
self.ldb.add({
except LdbError, (num, _):
self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
+ # More than one change operation is allowed
+ ldb.modify_ldif("""
+dn: cn=ldaptestuser,cn=users, """ + self.base_dn + """
+changetype: modify
+delete: objectClass
+objectClass: bootableDevice
+add: objectClass
+objectClass: bootableDevice
+""")
+
+ # We cannot remove all object classes by an empty replace
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ m["objectClass"] = MessageElement([], FLAG_MOD_REPLACE, "objectClass")
+ try:
+ ldb.modify(m)
+ self.fail()
+ except LdbError, (num, _):
+ self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
+
m = Message()
m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
m["objectClass"] = MessageElement(["top", "computer"], FLAG_MOD_REPLACE,
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"""
+ def test_attribute_ranges(self):
+ """Test attribute ranges"""
+ print "Test attribute ranges"""
-# 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)
-
- self.ldb.add({
- "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
- "description": "desc2",
- "objectclass": "group",
- "description": "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"]})
+ # 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)
-# m = Message()
-# m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
-# m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_REPLACE,
-# "description")
+ # 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)
-
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
- m["description"] = MessageElement("desc1", FLAG_MOD_REPLACE,
- "description")
- ldb.modify(m)
+# 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")
-# 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": "person" })
+ # Too short (min. 1)
m = Message()
- m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
- m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_DELETE,
- "description")
+ 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_NO_SUCH_ATTRIBUTE)
-
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
- m["description"] = MessageElement("desc1", FLAG_MOD_DELETE,
- "description")
- ldb.modify(m)
-
-# 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)
+ 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"""
"""Tests the 'distinguishedName' attribute"""
print "Tests the 'distinguishedName' attribute"""
+ # The "dn" shortcut isn't supported
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+ m["objectClass"] = MessageElement("group", 0, "objectClass")
+ m["dn"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn, 0,
+ "dn")
+ try:
+ ldb.add(m)
+ self.fail()
+ except LdbError, (num, _):
+ self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
+
# a wrong "distinguishedName" attribute is obviously tolerated
self.ldb.add({
"dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
self.assertTrue(Dn(ldb, res[0]["distinguishedName"][0])
== Dn(ldb, "cn=ldaptestgroup, cn=users," + self.base_dn))
+ # The "dn" shortcut isn't supported
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+ m["dn"] = MessageElement(
+ "cn=ldaptestgroup,cn=users," + self.base_dn, FLAG_MOD_REPLACE,
+ "dn")
+ try:
+ ldb.modify(m)
+ self.fail()
+ except LdbError, (num, _):
+ self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
+
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["distinguishedName"] = MessageElement(
self.ldb.add({
"dn": "cn=ldaptestuser2,cn=users," + self.base_dn,
- "objectclass": ["user", "person"] })
+ "objectclass": "user" })
ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn)
self.ldb.add({
"dn": "cn=ldaptestuser5,cn=users," + self.base_dn,
- "objectclass": ["user", "person"] })
+ "objectclass": "user" })
ldb.rename("cn=ldaptestuser5,cn=users," + self.base_dn, "cn=ldaptestUSER5,cn=users," + self.base_dn)
self.delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
self.ldb.add({
"dn": "cn=ldaptestuser5,cn=users," + self.base_dn,
- "objectclass": ["user", "person"] })
+ "objectclass": "user" })
ldb.rename("cn=ldaptestuser5,cn=Users," + self.base_dn, "cn=ldaptestUSER5,cn=users," + self.base_dn)
res = ldb.search(expression="cn=ldaptestuser5")
print "Found %u records" % len(res)
self.assertEquals(len(res), 1, "Wrong number of hits for (&(cn=ldaptestuser5)(objectclass=user))")
self.delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
+ def test_objectGUID(self):
+ """Test objectGUID behaviour"""
+ print "Testing objectGUID behaviour\n"
+
+ # The objectGUID cannot directly be set
+ try:
+ self.ldb.add_ldif("""
+dn: cn=ldaptestcontainer,""" + self.base_dn + """
+objectClass: container
+objectGUID: bd3480c9-58af-4cd8-92df-bc4a18b6e44d
+""")
+ self.fail()
+ except LdbError, (num, _):
+ self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+
+ self.ldb.add({
+ "dn": "cn=ldaptestcontainer," + self.base_dn,
+ "objectClass": "container" })
+
+ res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["objectGUID", "uSNCreated", "uSNChanged", "whenCreated", "whenChanged"])
+ self.assertTrue(len(res) == 1)
+ self.assertTrue("objectGUID" in res[0])
+ self.assertTrue("uSNCreated" in res[0])
+ self.assertTrue("uSNChanged" in res[0])
+ self.assertTrue("whenCreated" in res[0])
+ self.assertTrue("whenChanged" in res[0])
+
+ self.delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
+
+ # All the following attributes are specificable on add operations
+ self.ldb.add({
+ "dn": "cn=ldaptestcontainer," + self.base_dn,
+ "objectClass": "container",
+ "uSNCreated" : "1",
+ "uSNChanged" : "1",
+ "whenCreated": timestring(long(time.time())),
+ "whenChanged": timestring(long(time.time())) })
+
+ res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["objectGUID", "uSNCreated", "uSNChanged", "whenCreated", "whenChanged"])
+ self.assertTrue(len(res) == 1)
+ self.assertTrue("objectGUID" in res[0])
+ self.assertTrue("uSNCreated" in res[0])
+ self.assertFalse(res[0]["uSNCreated"][0] == "1") # these are corrected
+ self.assertTrue("uSNChanged" in res[0])
+ self.assertFalse(res[0]["uSNChanged"][0] == "1") # these are corrected
+
+ self.delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
+
+ # All this attributes are specificable on add operations
+ self.ldb.add({
+ "dn": "cn=ldaptestcontainer," + self.base_dn,
+ "objectclass": "container",
+ "uSNCreated" : "1",
+ "uSNChanged" : "1",
+ "whenCreated": timestring(long(time.time())),
+ "whenChanged": timestring(long(time.time())) })
+
+ res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["objectGUID", "uSNCreated", "uSNChanged", "whenCreated", "whenChanged"])
+ self.assertTrue(len(res) == 1)
+ self.assertTrue("objectGUID" in res[0])
+ self.assertTrue("uSNCreated" in res[0])
+ self.assertFalse(res[0]["uSNCreated"][0] == "1") # these are corrected
+ self.assertTrue("uSNChanged" in res[0])
+ self.assertFalse(res[0]["uSNChanged"][0] == "1") # these are corrected
+ self.assertTrue("whenCreated" in res[0])
+ self.assertTrue("whenChanged" in res[0])
+
+ # The objectGUID cannot directly be changed
+ try:
+ self.ldb.modify_ldif("""
+dn: cn=ldaptestcontainer,""" + self.base_dn + """
+changetype: modify
+replace: objectGUID
+objectGUID: bd3480c9-58af-4cd8-92df-bc4a18b6e44d
+""")
+ self.fail()
+ except LdbError, (num, _):
+ self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
+
+ self.delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
+
def test_parentGUID(self):
"""Test parentGUID behaviour"""
print "Testing parentGUID behaviour\n"
- # TODO: This seems to fail on Windows Server. Hidden attribute?
-
self.ldb.add({
"dn": "cn=parentguidtest,cn=users," + self.base_dn,
"objectclass":"user",
try:
ldb.add({
"dn": "cn=ldaptestuser,cn=users," + self.base_dn,
- "objectclass": ["user", "person"],
+ "objectclass": "user",
"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"]})
+ "objectclass": "user"})
m = Message()
m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
res = self.ldb.search(base=("<WKGUID=ab1d30f3768811d1aded00c04fd8d5cd,%s>" % self.base_dn), scope=SCOPE_BASE, attrs=[])
self.assertEquals(len(res), 1)
-
+
res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=B:32:ab1d30f3768811d1aded00c04fd8d5cd:%s" % res[0].dn))
self.assertEquals(len(res2), 1)
ldb.add({
"dn": "cn=ldaptestuser,cn=uSers," + self.base_dn,
- "objectclass": ["user", "person"],
+ "objectclass": "user",
"cN": "LDAPtestUSER",
"givenname": "ldap",
"sn": "testy"})
self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
ldb.add({
"dn": "cn=ldaptestuser2,cn=useRs," + self.base_dn,
- "objectClass": ["person", "user"],
+ "objectClass": "user",
"cn": "LDAPtestUSER2",
"givenname": "testy",
"sn": "ldap user2"})
# ensure we cannot add it again
try:
ldb.add({"dn": "cn=ldaptestuser3,cn=userS," + self.base_dn,
- "objectClass": ["person", "user"],
+ "objectClass": "user",
"cn": "LDAPtestUSER3"})
self.fail()
except LdbError, (num, _):
# ensure can now use that name
ldb.add({"dn": "cn=ldaptestuser3,cn=users," + self.base_dn,
- "objectClass": ["person", "user"],
+ "objectClass": "user",
"cn": "LDAPtestUSER3"})
# ensure we now cannot rename
"objectClass": "container"})
ldb.add({"dn": "CN=ldaptestuser4,CN=ldaptestcontainer," + self.base_dn,
- "objectClass": ["person", "user"],
+ "objectClass": "user",
"cn": "LDAPtestUSER4"})
+ # Here we don't enforce these hard "description" constraints
+ ldb.modify_ldif("""
+dn: cn=ldaptestcontainer,""" + self.base_dn + """
+changetype: modify
+replace: description
+description: desc1
+description: desc2
+""")
+
ldb.modify_ldif("""
dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
changetype: modify
user_name = "testdescriptoruser1"
user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
#
- # Test add_ldif() with SDDL security descriptor input
+ # Test an empty security descriptor (naturally this shouldn't work)
#
self.delete_force(self.ldb, user_dn)
+ try:
+ self.ldb.add({ "dn": user_dn,
+ "objectClass": "user",
+ "sAMAccountName": user_name,
+ "nTSecurityDescriptor": [] })
+ self.fail()
+ except LdbError, (num, _):
+ self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
+ finally:
+ self.delete_force(self.ldb, user_dn)
+ #
+ # Test add_ldif() with SDDL security descriptor input
+ #
try:
sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
self.ldb.add_ldif("""
user_name = "testdescriptoruser2"
user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
#
- # Delete user object and test modify_ldif() with SDDL security descriptor input
+ # Test an empty security descriptor (naturally this shouldn't work)
+ #
+ self.delete_force(self.ldb, user_dn)
+ self.ldb.add({ "dn": user_dn,
+ "objectClass": "user",
+ "sAMAccountName": user_name })
+
+ m = Message()
+ m.dn = Dn(ldb, user_dn)
+ m["nTSecurityDescriptor"] = MessageElement([], FLAG_MOD_ADD,
+ "nTSecurityDescriptor")
+ try:
+ self.ldb.modify(m)
+ self.fail()
+ except LdbError, (num, _):
+ self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
+
+ m = Message()
+ m.dn = Dn(ldb, user_dn)
+ m["nTSecurityDescriptor"] = MessageElement([], FLAG_MOD_REPLACE,
+ "nTSecurityDescriptor")
+ try:
+ self.ldb.modify(m)
+ self.fail()
+ except LdbError, (num, _):
+ self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+
+ m = Message()
+ m.dn = Dn(ldb, user_dn)
+ m["nTSecurityDescriptor"] = MessageElement([], FLAG_MOD_DELETE,
+ "nTSecurityDescriptor")
+ try:
+ self.ldb.modify(m)
+ self.fail()
+ except LdbError, (num, _):
+ self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+
+ self.delete_force(self.ldb, user_dn)
+ #
+ # Test modify_ldif() with SDDL security descriptor input
# Add ACE to the original descriptor test
#
try:
- self.delete_force(self.ldb, user_dn)
self.ldb.add_ldif("""
dn: """ + user_dn + """
objectclass: user
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):
res = self.ldb.search("", scope=SCOPE_BASE,
attrs=["namingContexts", "defaultNamingContext", "schemaNamingContext", "configurationNamingContext"])
self.assertEquals(len(res), 1)
-
+
ncs = set([])
for nc in res[0]["namingContexts"]:
self.assertTrue(nc not in ncs)
else:
host = "ldap://%s" % host
-ldb = Ldb(host, credentials=creds, session_info=system_session(), lp=lp)
+ldb = SamDB(host, credentials=creds, session_info=system_session(), lp=lp)
if not "tdb://" in host:
gc_ldb = Ldb("%s:3268" % host, credentials=creds,
session_info=system_session(), lp=lp)