# -*- coding: utf-8 -*-
# This is a port of the original in testprogs/ejs/ldap.js
+from __future__ import print_function
import optparse
import sys
-import time
-import base64
import os
+import time
-sys.path.append("bin/python")
+sys.path.insert(0, "bin/python")
import samba
-samba.ensure_external_module("subunit", "subunit/python")
-samba.ensure_external_module("testtools", "testtools")
+from samba.tests.subunitrun import SubunitOptions, TestProgram
import samba.getopt as options
+from samba.credentials import Credentials, DONT_USE_KERBEROS
from samba.auth import system_session
-from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError
+from ldb import SCOPE_BASE, LdbError
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_OBJECT_CLASS_VIOLATION, ERR_NOT_ALLOWED_ON_RDN
-from ldb import ERR_NAMING_VIOLATION, ERR_CONSTRAINT_VIOLATION
-from ldb import ERR_UNDEFINED_ATTRIBUTE_TYPE, ERR_INSUFFICIENT_ACCESS_RIGHTS
+from ldb import ERR_OTHER, ERR_NO_SUCH_ATTRIBUTE
+from ldb import ERR_OBJECT_CLASS_VIOLATION
+from ldb import ERR_CONSTRAINT_VIOLATION
+from ldb import ERR_UNDEFINED_ATTRIBUTE_TYPE
+from ldb import ERR_INSUFFICIENT_ACCESS_RIGHTS
+from ldb import ERR_INVALID_CREDENTIALS
+from ldb import ERR_STRONG_AUTH_REQUIRED
from ldb import Message, MessageElement, Dn
from ldb import FLAG_MOD_ADD, FLAG_MOD_REPLACE, FLAG_MOD_DELETE
-from samba import Ldb
-from samba.dsdb import (UF_NORMAL_ACCOUNT, UF_INTERDOMAIN_TRUST_ACCOUNT,
+from samba.samdb import SamDB
+from samba.dsdb import (UF_NORMAL_ACCOUNT, UF_ACCOUNTDISABLE,
UF_WORKSTATION_TRUST_ACCOUNT, UF_SERVER_TRUST_ACCOUNT,
UF_PARTIAL_SECRETS_ACCOUNT, UF_TEMP_DUPLICATE_ACCOUNT,
- UF_PASSWD_NOTREQD, UF_ACCOUNTDISABLE, ATYPE_NORMAL_ACCOUNT,
+ UF_INTERDOMAIN_TRUST_ACCOUNT, UF_SMARTCARD_REQUIRED,
+ UF_PASSWD_NOTREQD, UF_LOCKOUT, UF_PASSWORD_EXPIRED, ATYPE_NORMAL_ACCOUNT,
GTYPE_SECURITY_BUILTIN_LOCAL_GROUP, GTYPE_SECURITY_DOMAIN_LOCAL_GROUP,
GTYPE_SECURITY_GLOBAL_GROUP, GTYPE_SECURITY_UNIVERSAL_GROUP,
GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP, GTYPE_DISTRIBUTION_GLOBAL_GROUP,
ATYPE_SECURITY_GLOBAL_GROUP, ATYPE_SECURITY_UNIVERSAL_GROUP,
ATYPE_SECURITY_LOCAL_GROUP, ATYPE_DISTRIBUTION_GLOBAL_GROUP,
ATYPE_DISTRIBUTION_UNIVERSAL_GROUP, ATYPE_DISTRIBUTION_LOCAL_GROUP,
- 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)
+ ATYPE_WORKSTATION_TRUST)
+from samba.dcerpc.security import (DOMAIN_RID_USERS, DOMAIN_RID_ADMINS,
+ DOMAIN_RID_DOMAIN_MEMBERS, DOMAIN_RID_DCS, DOMAIN_RID_READONLY_DCS)
-from subunit.run import SubunitTestRunner
-import unittest
-
-from samba.ndr import ndr_pack, ndr_unpack
+from samba.ndr import ndr_unpack
+from samba.dcerpc import drsblobs
+from samba.dcerpc import drsuapi
from samba.dcerpc import security
+from samba.tests import delete_force
+from samba import gensec
+from samba import werror
parser = optparse.OptionParser("sam.py [options] <host>")
sambaopts = options.SambaOptions(parser)
# use command line creds if available
credopts = options.CredentialsOptions(parser)
parser.add_option_group(credopts)
+subunitopts = SubunitOptions(parser)
+parser.add_option_group(subunitopts)
opts, args = parser.parse_args()
if len(args) < 1:
lp = sambaopts.get_loadparm()
creds = credopts.get_credentials(lp)
+creds.set_gensec_features(creds.get_gensec_features() | gensec.FEATURE_SEAL)
-class SamTests(unittest.TestCase):
-
- def delete_force(self, ldb, dn):
- try:
- ldb.delete(dn)
- 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_domain_sid(self):
- res = self.ldb.search(base=self.base_dn, expression="(objectClass=*)", scope=SCOPE_BASE)
- return ndr_unpack( security.dom_sid,res[0]["objectSid"][0])
+class SamTests(samba.tests.TestCase):
def setUp(self):
super(SamTests, self).setUp()
self.ldb = ldb
- self.gc_ldb = gc_ldb
- self.base_dn = self.find_basedn(ldb)
- self.domain_sid = self.find_domain_sid()
+ self.base_dn = ldb.domain_dn()
- print "baseDN: %s\n" % self.base_dn
+ print("baseDN: %s\n" % self.base_dn)
- self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
- self.delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + 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)
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
+ delete_force(self.ldb, "cn=ldaptest\,specialuser,cn=users," + self.base_dn)
+ delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+ delete_force(self.ldb, "cn=ldaptestgroup2,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"
+ print("Testing users and groups behaviour\n")
ldb.add({
"dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
try:
ldb.add({
"dn": "cn=ldaptestuser,cn=users," + self.base_dn,
- "objectclass": ["user", "person"],
+ "objectclass": "user",
"sAMAccountName": "administrator"})
self.fail()
- except LdbError, (num, _):
+ except LdbError as e9:
+ (num, _) = e9.args
self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
- self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+
+ # Try to create a user with an invalid account name
+ try:
+ ldb.add({
+ "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
+ "objectclass": "user",
+ "sAMAccountName": []})
+ self.fail()
+ except LdbError as e10:
+ (num, _) = e10.args
+ self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
# Try to create a user with an invalid primary group
try:
ldb.add({
"dn": "cn=ldaptestuser,cn=users," + self.base_dn,
- "objectclass": ["user", "person"],
+ "objectclass": "user",
"primaryGroupID": "0"})
self.fail()
- except LdbError, (num, _):
+ except LdbError as e11:
+ (num, _) = e11.args
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
- self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ 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"],
+ "objectclass": "user",
"primaryGroupID": str(group_rid_1)})
self.fail()
- except LdbError, (num, _):
+ except LdbError as e12:
+ (num, _) = e12.args
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
- self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ 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
try:
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e13:
+ (num, _) = e13.args
self.assertEquals(num, ERR_NO_SUCH_OBJECT)
# Test to see how we should behave when the account isn't a user
try:
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e14:
+ (num, _) = e14.args
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"]})
+ "objectclass": "user"})
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)
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
ldb.add({
"dn": "cn=ldaptestuser,cn=users," + self.base_dn,
- "objectclass": ["user", "person"],
+ "objectclass": "user",
"userAccountControl": str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD) })
res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
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)
+ 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"],
+ "objectclass": "computer",
"userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD) })
res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
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)
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
ldb.add({
"dn": "cn=ldaptestuser,cn=users," + self.base_dn,
- "objectclass": ["computer"],
+ "objectclass": "computer",
"userAccountControl": str(UF_SERVER_TRUST_ACCOUNT | UF_PASSWD_NOTREQD) })
res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
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)
+ 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"],
+ "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,
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)
+ 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"]})
+ "objectclass": "user"})
m = Message()
m.dn = Dn(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)
- self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
ldb.add({
"dn": "cn=ldaptestuser,cn=users," + self.base_dn,
- "objectclass": ["computer"]})
+ "objectclass": "computer"})
res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
scope=SCOPE_BASE, attrs=["primaryGroupID"])
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)
+ 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"]})
+ "objectclass": "user"})
# Try to set an invalid account name
m = Message()
try:
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e15:
+ (num, _) = e15.args
self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
# But to reset the actual "sAMAccountName" should still be possible
try:
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e16:
+ (num, _) = e16.args
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
# Try to make group 1 primary - should be denied since it is not yet
try:
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e17:
+ (num, _) = e17.args
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
# Make group 1 secondary
try:
ldb.delete("cn=ldaptestgroup,cn=users," + self.base_dn)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e18:
+ (num, _) = e18.args
self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
# Try to add group 1 also as secondary - should be denied
try:
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e19:
+ (num, _) = e19.args
self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
# 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,
+ "cn=ldaptestuser3,cn=users," + self.base_dn,
FLAG_MOD_ADD, "member")
try:
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e20:
+ (num, _) = e20.args
self.assertEquals(num, ERR_NO_SUCH_OBJECT)
# Make group 2 secondary
try:
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e21:
+ (num, _) = e21.args
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
# Delete invalid group member
try:
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e22:
+ (num, _) = e22.args
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
# Also this should be denied
try:
ldb.add({
- "dn": "cn=ldaptestuser2,cn=users," + self.base_dn,
- "objectclass": ["user", "person"],
+ "dn": "cn=ldaptestuser2,cn=users," + self.base_dn,
+ "objectclass": "user",
"primaryGroupID": "0"})
self.fail()
- except LdbError, (num, _):
+ except LdbError as e23:
+ (num, _) = e23.args
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
# Recreate user accounts
- self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
ldb.add({
"dn": "cn=ldaptestuser,cn=users," + self.base_dn,
- "objectclass": ["user", "person"]})
+ "objectclass": "user"})
ldb.add({
"dn": "cn=ldaptestuser2,cn=users," + self.base_dn,
- "objectclass": ["user", "person"]})
+ "objectclass": "user"})
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
try:
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e24:
+ (num, _) = e24.args
+ self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
+
+ # Already added, but as <SID=...>
+ res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
+ scope=SCOPE_BASE, attrs=["objectSid"])
+ self.assertTrue(len(res1) == 1)
+ sid_bin = res1[0]["objectSid"][0]
+ sid_str = ("<SID=" + ldb.schema_format_value("objectSid", sid_bin) + ">").upper()
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
+ m["member"] = MessageElement(sid_str, FLAG_MOD_ADD, "member")
+ try:
+ ldb.modify(m)
+ self.fail()
+ except LdbError as e25:
+ (num, _) = e25.args
self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
# Invalid member
try:
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e26:
+ (num, _) = e26.args
self.assertEquals(num, ERR_NO_SUCH_OBJECT)
# Invalid member
try:
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e27:
+ (num, _) = e27.args
self.assertEquals(num, ERR_NO_SUCH_OBJECT)
# Invalid member
try:
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e28:
+ (num, _) = e28.args
self.assertEquals(num, ERR_NO_SUCH_OBJECT)
m = Message()
FLAG_MOD_REPLACE, "member")
ldb.modify(m)
- self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- self.delete_force(self.ldb, "cn=ldaptestuser2,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)
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
+ delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+ delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
+
+ # Make also a small test for accounts with special DNs ("," in this case)
+ ldb.add({
+ "dn": "cn=ldaptest\,specialuser,cn=users," + self.base_dn,
+ "objectclass": "user"})
+ delete_force(self.ldb, "cn=ldaptest\,specialuser,cn=users," + self.base_dn)
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"""
+ print("Testing the behaviour of special attributes of SAM objects\n")
ldb.add({
"dn": "cn=ldaptestuser,cn=users," + self.base_dn,
- "objectclass": ["user", "person"]})
+ "objectclass": "user"})
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,
+ m["groupType"] = MessageElement(str(GTYPE_SECURITY_GLOBAL_GROUP), FLAG_MOD_ADD,
"groupType")
try:
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e29:
+ (num, _) = e29.args
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")
- try:
- ldb.modify(m)
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+ # Delete protection tests
- 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)
+ for attr in ["nTSecurityDescriptor", "objectSid", "sAMAccountType",
+ "sAMAccountName", "groupType"]:
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+ m[attr] = MessageElement([], FLAG_MOD_REPLACE, attr)
+ try:
+ ldb.modify(m)
+ self.fail()
+ except LdbError as e:
+ (num, _) = e.args
+ self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+ m[attr] = MessageElement([], FLAG_MOD_DELETE, attr)
+ try:
+ ldb.modify(m)
+ self.fail()
+ except LdbError as e1:
+ (num, _) = e1.args
+ self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- m["primaryGroupID"] = MessageElement([], FLAG_MOD_DELETE,
+ m["primaryGroupID"] = MessageElement("513", FLAG_MOD_ADD,
"primaryGroupID")
try:
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+ except LdbError as e30:
+ (num, _) = e30.args
+ self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- m["userAccountControl"] = MessageElement("0", FLAG_MOD_ADD,
+ m["userAccountControl"] = MessageElement(str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD), FLAG_MOD_ADD,
"userAccountControl")
try:
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e31:
+ (num, _) = e31.args
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")
+ m["objectSid"] = MessageElement("xxxxxxxxxxxxxxxx", FLAG_MOD_ADD,
+ "objectSid")
try:
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e32:
+ (num, _) = e32.args
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
m = Message()
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["sAMAccountType"] = MessageElement([], FLAG_MOD_REPLACE,
- "sAMAccountType")
- 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["sAMAccountType"] = MessageElement([], FLAG_MOD_DELETE,
- "sAMAccountType")
- try:
- ldb.modify(m)
- self.fail()
- except LdbError, (num, _):
+ except LdbError as e33:
+ (num, _) = e33.args
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
m = Message()
try:
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e34:
+ (num, _) = e34.args
self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- m["sAMAccountName"] = MessageElement([], FLAG_MOD_DELETE,
- "sAMAccountName")
- try:
- ldb.modify(m)
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+ # Delete protection tests
+
+ for attr in ["nTSecurityDescriptor", "objectSid", "sAMAccountType",
+ "sAMAccountName", "primaryGroupID", "userAccountControl",
+ "accountExpires", "badPasswordTime", "badPwdCount",
+ "codePage", "countryCode", "lastLogoff", "lastLogon",
+ "logonCount", "pwdLastSet"]:
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ m[attr] = MessageElement([], FLAG_MOD_REPLACE, attr)
+ try:
+ ldb.modify(m)
+ self.fail()
+ except LdbError as e2:
+ (num, _) = e2.args
+ 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 = Message()
+ m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ m[attr] = MessageElement([], FLAG_MOD_DELETE, attr)
+ try:
+ ldb.modify(m)
+ self.fail()
+ except LdbError as e3:
+ (num, _) = e3.args
+ self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
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"
+ print("Testing primary group token behaviour and other constructed attributes\n")
try:
ldb.add({
"objectclass": "group",
"primaryGroupToken": "100"})
self.fail()
- except LdbError, (num, _):
+ except LdbError as e35:
+ (num, _) = e35.args
self.assertEquals(num, ERR_UNDEFINED_ATTRIBUTE_TYPE)
- self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+ delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
ldb.add({
"dn": "cn=ldaptestuser,cn=users," + self.base_dn,
- "objectclass": ["user", "person"]})
+ "objectclass": "user"})
ldb.add({
"dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
try:
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e36:
+ (num, _) = e36.args
self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
- self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ 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"
+ 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"])
ldb.add({
"dn": "cn=ldaptestuser,cn=users," + self.base_dn,
- "objectclass": ["user", "person"]})
+ "objectclass": "user"})
# This testuser should contain at least two "tokenGroups" entries
# (exactly two on an unmodified "Domain Users" and "Users" group)
self.assertTrue(domain_users_group_found)
self.assertTrue(users_group_found)
- self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
def test_groupType(self):
"""Test the groupType behaviour"""
- print "Testing groupType behaviour\n"
+ print("Testing groupType behaviour\n")
# You can never create or change to a
# "GTYPE_SECURITY_BUILTIN_LOCAL_GROUP"
"objectclass": "group",
"groupType": "0"})
self.fail()
- except LdbError, (num, _):
+ except LdbError as e37:
+ (num, _) = e37.args
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
- self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+ delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
try:
ldb.add({
"objectclass": "group",
"groupType": str(GTYPE_SECURITY_BUILTIN_LOCAL_GROUP)})
self.fail()
- except LdbError, (num, _):
+ except LdbError as e38:
+ (num, _) = e38.args
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
- self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+ delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
ldb.add({
"dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
self.assertTrue(len(res1) == 1)
self.assertEquals(int(res1[0]["sAMAccountType"][0]),
ATYPE_SECURITY_GLOBAL_GROUP)
- self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+ delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
ldb.add({
"dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
self.assertTrue(len(res1) == 1)
self.assertEquals(int(res1[0]["sAMAccountType"][0]),
ATYPE_SECURITY_UNIVERSAL_GROUP)
- self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+ delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
ldb.add({
"dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
self.assertTrue(len(res1) == 1)
self.assertEquals(int(res1[0]["sAMAccountType"][0]),
ATYPE_SECURITY_LOCAL_GROUP)
- self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+ delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
ldb.add({
"dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
self.assertTrue(len(res1) == 1)
self.assertEquals(int(res1[0]["sAMAccountType"][0]),
ATYPE_DISTRIBUTION_GLOBAL_GROUP)
- self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+ delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
ldb.add({
"dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
self.assertTrue(len(res1) == 1)
self.assertEquals(int(res1[0]["sAMAccountType"][0]),
ATYPE_DISTRIBUTION_UNIVERSAL_GROUP)
- self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+ delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
ldb.add({
"dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
self.assertTrue(len(res1) == 1)
self.assertEquals(int(res1[0]["sAMAccountType"][0]),
ATYPE_DISTRIBUTION_LOCAL_GROUP)
- self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+ delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
# Modify operation
FLAG_MOD_REPLACE, "groupType")
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e39:
+ (num, _) = e39.args
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
# Security groups
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["groupType"] = MessageElement(
- str(GTYPE_SECURITY_GLOBAL_GROUP),
+ str(GTYPE_SECURITY_GLOBAL_GROUP),
FLAG_MOD_REPLACE, "groupType")
ldb.modify(m)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["groupType"] = MessageElement(
- str(GTYPE_SECURITY_DOMAIN_LOCAL_GROUP),
+ str(GTYPE_SECURITY_DOMAIN_LOCAL_GROUP),
FLAG_MOD_REPLACE, "groupType")
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e40:
+ (num, _) = e40.args
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
# Change to "universal"
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["groupType"] = MessageElement(
- str(GTYPE_SECURITY_UNIVERSAL_GROUP),
+ str(GTYPE_SECURITY_UNIVERSAL_GROUP),
FLAG_MOD_REPLACE, "groupType")
ldb.modify(m)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["groupType"] = MessageElement(
- str(GTYPE_SECURITY_GLOBAL_GROUP),
+ str(GTYPE_SECURITY_GLOBAL_GROUP),
FLAG_MOD_REPLACE, "groupType")
ldb.modify(m)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["groupType"] = MessageElement(
- str(GTYPE_SECURITY_UNIVERSAL_GROUP),
+ str(GTYPE_SECURITY_UNIVERSAL_GROUP),
FLAG_MOD_REPLACE, "groupType")
ldb.modify(m)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["groupType"] = MessageElement(
- str(GTYPE_SECURITY_DOMAIN_LOCAL_GROUP),
+ str(GTYPE_SECURITY_DOMAIN_LOCAL_GROUP),
FLAG_MOD_REPLACE, "groupType")
ldb.modify(m)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["groupType"] = MessageElement(
- str(GTYPE_SECURITY_GLOBAL_GROUP),
+ str(GTYPE_SECURITY_GLOBAL_GROUP),
FLAG_MOD_REPLACE, "groupType")
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e41:
+ (num, _) = e41.args
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
# Change to "builtin local" (shouldn't work)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["groupType"] = MessageElement(
- str(GTYPE_SECURITY_BUILTIN_LOCAL_GROUP),
+ str(GTYPE_SECURITY_BUILTIN_LOCAL_GROUP),
FLAG_MOD_REPLACE, "groupType")
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e42:
+ (num, _) = e42.args
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
m = Message()
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["groupType"] = MessageElement(
- str(GTYPE_SECURITY_UNIVERSAL_GROUP),
+ str(GTYPE_SECURITY_UNIVERSAL_GROUP),
FLAG_MOD_REPLACE, "groupType")
ldb.modify(m)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["groupType"] = MessageElement(
- str(GTYPE_SECURITY_BUILTIN_LOCAL_GROUP),
+ str(GTYPE_SECURITY_BUILTIN_LOCAL_GROUP),
FLAG_MOD_REPLACE, "groupType")
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e43:
+ (num, _) = e43.args
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
# Change back to "global"
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["groupType"] = MessageElement(
- str(GTYPE_SECURITY_GLOBAL_GROUP),
+ str(GTYPE_SECURITY_GLOBAL_GROUP),
FLAG_MOD_REPLACE, "groupType")
ldb.modify(m)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["groupType"] = MessageElement(
- str(GTYPE_SECURITY_BUILTIN_LOCAL_GROUP),
+ str(GTYPE_SECURITY_BUILTIN_LOCAL_GROUP),
FLAG_MOD_REPLACE, "groupType")
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e44:
+ (num, _) = e44.args
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
# Distribution groups
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["groupType"] = MessageElement(
- str(GTYPE_DISTRIBUTION_GLOBAL_GROUP),
+ str(GTYPE_DISTRIBUTION_GLOBAL_GROUP),
FLAG_MOD_REPLACE, "groupType")
ldb.modify(m)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["groupType"] = MessageElement(
- str(GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP),
+ str(GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP),
FLAG_MOD_REPLACE, "groupType")
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e45:
+ (num, _) = e45.args
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
# Change to "universal"
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["groupType"] = MessageElement(
- str(GTYPE_DISTRIBUTION_UNIVERSAL_GROUP),
+ str(GTYPE_DISTRIBUTION_UNIVERSAL_GROUP),
FLAG_MOD_REPLACE, "groupType")
ldb.modify(m)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["groupType"] = MessageElement(
- str(GTYPE_DISTRIBUTION_GLOBAL_GROUP),
+ str(GTYPE_DISTRIBUTION_GLOBAL_GROUP),
FLAG_MOD_REPLACE, "groupType")
ldb.modify(m)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["groupType"] = MessageElement(
- str(GTYPE_DISTRIBUTION_UNIVERSAL_GROUP),
+ str(GTYPE_DISTRIBUTION_UNIVERSAL_GROUP),
FLAG_MOD_REPLACE, "groupType")
ldb.modify(m)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["groupType"] = MessageElement(
- str(GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP),
+ str(GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP),
FLAG_MOD_REPLACE, "groupType")
ldb.modify(m)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["groupType"] = MessageElement(
- str(GTYPE_DISTRIBUTION_GLOBAL_GROUP),
+ str(GTYPE_DISTRIBUTION_GLOBAL_GROUP),
FLAG_MOD_REPLACE, "groupType")
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e46:
+ (num, _) = e46.args
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
# Change back to "universal"
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["member"] = MessageElement(
- "cn=ldaptestuser3,cn=users," + self.base_dn,
+ "cn=ldaptestuser3,cn=users," + self.base_dn,
FLAG_MOD_ADD, "member")
try:
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e47:
+ (num, _) = e47.args
self.assertEquals(num, ERR_NO_SUCH_OBJECT)
# Make group 2 secondary
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["groupType"] = MessageElement(
- str(GTYPE_DISTRIBUTION_UNIVERSAL_GROUP),
+ str(GTYPE_DISTRIBUTION_UNIVERSAL_GROUP),
FLAG_MOD_REPLACE, "groupType")
ldb.modify(m)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["groupType"] = MessageElement(
- str(GTYPE_DISTRIBUTION_GLOBAL_GROUP),
+ str(GTYPE_DISTRIBUTION_GLOBAL_GROUP),
FLAG_MOD_REPLACE, "groupType")
ldb.modify(m)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["groupType"] = MessageElement(
- str(GTYPE_SECURITY_GLOBAL_GROUP),
+ str(GTYPE_SECURITY_GLOBAL_GROUP),
FLAG_MOD_REPLACE, "groupType")
ldb.modify(m)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["groupType"] = MessageElement(
- str(GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP),
+ str(GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP),
FLAG_MOD_REPLACE, "groupType")
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e48:
+ (num, _) = e48.args
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
# Change to "universal"
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["groupType"] = MessageElement(
- str(GTYPE_DISTRIBUTION_UNIVERSAL_GROUP),
+ str(GTYPE_DISTRIBUTION_UNIVERSAL_GROUP),
FLAG_MOD_REPLACE, "groupType")
ldb.modify(m)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["groupType"] = MessageElement(
- str(GTYPE_SECURITY_GLOBAL_GROUP),
+ str(GTYPE_SECURITY_GLOBAL_GROUP),
FLAG_MOD_REPLACE, "groupType")
ldb.modify(m)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["groupType"] = MessageElement(
- str(GTYPE_SECURITY_UNIVERSAL_GROUP),
+ str(GTYPE_SECURITY_UNIVERSAL_GROUP),
FLAG_MOD_REPLACE, "groupType")
ldb.modify(m)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["groupType"] = MessageElement(
- str(GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP),
+ str(GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP),
FLAG_MOD_REPLACE, "groupType")
ldb.modify(m)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["groupType"] = MessageElement(
- str(GTYPE_DISTRIBUTION_GLOBAL_GROUP),
+ str(GTYPE_DISTRIBUTION_GLOBAL_GROUP),
FLAG_MOD_REPLACE, "groupType")
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e49:
+ (num, _) = e49.args
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
# Change back to "universal"
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["groupType"] = MessageElement(
- str(GTYPE_SECURITY_UNIVERSAL_GROUP),
+ str(GTYPE_SECURITY_UNIVERSAL_GROUP),
FLAG_MOD_REPLACE, "groupType")
ldb.modify(m)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
m["groupType"] = MessageElement(
- str(GTYPE_SECURITY_GLOBAL_GROUP),
+ str(GTYPE_SECURITY_GLOBAL_GROUP),
FLAG_MOD_REPLACE, "groupType")
ldb.modify(m)
self.assertEquals(int(res1[0]["sAMAccountType"][0]),
ATYPE_SECURITY_GLOBAL_GROUP)
- self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
-
- def test_userAccountControl(self):
- """Test the userAccountControl behaviour"""
- print "Testing userAccountControl behaviour\n"
-
- # With a user object
+ delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
- # Add operation
+ def test_pwdLastSet(self):
+ """Test the pwdLastSet behaviour"""
+ print("Testing pwdLastSet behaviour\n")
- # As user you can only set a normal account.
- # The UF_PASSWD_NOTREQD flag is needed since we haven't requested a
- # password yet.
- # With SYSTEM rights you can set a interdomain trust account.
+ ldb.add({
+ "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
+ "objectclass": "user",
+ "pwdLastSet": "0"})
- # Invalid attribute
- try:
- ldb.add({
- "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
- "objectclass": ["user", "person"],
- "userAccountControl": "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)
-
-# This has to wait until s4 supports it (needs a password module change)
-# try:
-# ldb.add({
-# "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
-# "objectclass": ["user", "person"],
-# "userAccountControl": str(UF_NORMAL_ACCOUNT)})
-# self.fail()
-# except LdbError, (num, _):
-# self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
-# self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["sAMAccountType", "userAccountControl", "pwdLastSet"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEqual(int(res1[0]["sAMAccountType"][0]),
+ ATYPE_NORMAL_ACCOUNT)
+ self.assertEqual(int(res1[0]["userAccountControl"][0]),
+ UF_NORMAL_ACCOUNT | UF_ACCOUNTDISABLE | UF_PASSWD_NOTREQD)
+ self.assertEqual(int(res1[0]["pwdLastSet"][0]), 0)
+ 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)})
+ "objectclass": "user",
+ "pwdLastSet": "-1"})
res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
- scope=SCOPE_BASE, attrs=["sAMAccountType"])
+ scope=SCOPE_BASE,
+ attrs=["sAMAccountType", "userAccountControl", "pwdLastSet"])
self.assertTrue(len(res1) == 1)
- self.assertEquals(int(res1[0]["sAMAccountType"][0]),
- ATYPE_NORMAL_ACCOUNT)
- self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ self.assertEqual(int(res1[0]["sAMAccountType"][0]),
+ ATYPE_NORMAL_ACCOUNT)
+ self.assertEqual(int(res1[0]["userAccountControl"][0]),
+ UF_NORMAL_ACCOUNT | UF_ACCOUNTDISABLE | UF_PASSWD_NOTREQD)
+ self.assertNotEqual(int(res1[0]["pwdLastSet"][0]), 0)
+ lastset = int(res1[0]["pwdLastSet"][0])
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
try:
ldb.add({
"dn": "cn=ldaptestuser,cn=users," + self.base_dn,
- "objectclass": ["user", "person"],
- "userAccountControl": str(UF_TEMP_DUPLICATE_ACCOUNT)})
+ "objectclass": "user",
+ "pwdLastSet": str(1)})
self.fail()
- except LdbError, (num, _):
+ except LdbError as e50:
+ (num, msg) = e50.args
self.assertEquals(num, ERR_OTHER)
- self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
-
-# This isn't supported yet in s4
-# try:
-# ldb.add({
-# "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
-# "objectclass": ["user", "person"],
-# "userAccountControl": str(UF_SERVER_TRUST_ACCOUNT)})
-# self.fail()
-# except LdbError, (num, _):
-# self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
-# self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
-#
-# try:
-# ldb.add({
-# "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
-# "objectclass": ["user", "person"],
-# "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT)})
-# except LdbError, (num, _):
-# self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
-# self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
-
-# This isn't supported yet in s4 - needs ACL module adaption
-# try:
-# ldb.add({
-# "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
-# "objectclass": ["user", "person"],
-# "userAccountControl": str(UF_INTERDOMAIN_TRUST_ACCOUNT)})
-# self.fail()
-# except LdbError, (num, _):
-# self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS)
-# self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ self.assertTrue('00000057' in msg)
- # Modify operation
+ try:
+ ldb.add({
+ "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
+ "objectclass": "user",
+ "pwdLastSet": str(lastset)})
+ self.fail()
+ except LdbError as e51:
+ (num, msg) = e51.args
+ self.assertEquals(num, ERR_OTHER)
+ self.assertTrue('00000057' in msg)
ldb.add({
"dn": "cn=ldaptestuser,cn=users," + self.base_dn,
- "objectclass": ["user", "person"]})
+ "objectclass": "user"})
- # After creation we should have a normal account
res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
- scope=SCOPE_BASE, attrs=["sAMAccountType"])
+ scope=SCOPE_BASE,
+ attrs=["sAMAccountType", "userAccountControl", "pwdLastSet"])
self.assertTrue(len(res1) == 1)
- self.assertEquals(int(res1[0]["sAMAccountType"][0]),
- ATYPE_NORMAL_ACCOUNT)
+ self.assertEqual(int(res1[0]["sAMAccountType"][0]),
+ ATYPE_NORMAL_ACCOUNT)
+ self.assertEqual(int(res1[0]["userAccountControl"][0]),
+ UF_NORMAL_ACCOUNT | UF_ACCOUNTDISABLE | UF_PASSWD_NOTREQD)
+ self.assertEqual(int(res1[0]["pwdLastSet"][0]), 0)
- # As user you can only switch from a normal account to a workstation
- # trust account and back.
- # The UF_PASSWD_NOTREQD flag is needed since we haven't requested a
- # password yet.
- # With SYSTEM rights you can switch to a interdomain trust account.
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ m["pls1"] = MessageElement(str(0),
+ FLAG_MOD_REPLACE,
+ "pwdLastSet")
+ ldb.modify(m)
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ m["pls1"] = MessageElement(str(0),
+ FLAG_MOD_DELETE,
+ "pwdLastSet")
+ m["pls2"] = MessageElement(str(0),
+ FLAG_MOD_ADD,
+ "pwdLastSet")
+ ldb.modify(m)
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ m["pls1"] = MessageElement(str(-1),
+ FLAG_MOD_REPLACE,
+ "pwdLastSet")
+ ldb.modify(m)
+ res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["sAMAccountType", "userAccountControl", "pwdLastSet"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEqual(int(res1[0]["sAMAccountType"][0]),
+ ATYPE_NORMAL_ACCOUNT)
+ self.assertEqual(int(res1[0]["userAccountControl"][0]),
+ UF_NORMAL_ACCOUNT | UF_ACCOUNTDISABLE | UF_PASSWD_NOTREQD)
+ self.assertGreater(int(res1[0]["pwdLastSet"][0]), lastset)
+ lastset = int(res1[0]["pwdLastSet"][0])
- # Invalid attribute
try:
m = Message()
m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- m["userAccountControl"] = MessageElement("0",
- FLAG_MOD_REPLACE, "userAccountControl")
+ m["pls1"] = MessageElement(str(0),
+ FLAG_MOD_DELETE,
+ "pwdLastSet")
+ m["pls2"] = MessageElement(str(0),
+ FLAG_MOD_ADD,
+ "pwdLastSet")
ldb.modify(m)
- except LdbError, (num, _):
- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+ self.fail()
+ except LdbError as e52:
+ (num, msg) = e52.args
+ self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
+ self.assertTrue('00002085' in msg)
-# This has to wait until s4 supports it (needs a password module change)
-# try:
-# m = Message()
-# m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
-# m["userAccountControl"] = MessageElement(
-# str(UF_NORMAL_ACCOUNT),
-# FLAG_MOD_REPLACE, "userAccountControl")
-# ldb.modify(m)
-# except LdbError, (num, _):
-# self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+ try:
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ m["pls1"] = MessageElement(str(-1),
+ FLAG_MOD_DELETE,
+ "pwdLastSet")
+ m["pls2"] = MessageElement(str(0),
+ FLAG_MOD_ADD,
+ "pwdLastSet")
+ ldb.modify(m)
+ self.fail()
+ except LdbError as e53:
+ (num, msg) = e53.args
+ self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
+ self.assertTrue('00002085' in msg)
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")
+ m["pls1"] = MessageElement(str(lastset),
+ FLAG_MOD_DELETE,
+ "pwdLastSet")
+ m["pls2"] = MessageElement(str(-1),
+ FLAG_MOD_ADD,
+ "pwdLastSet")
+ time.sleep(0.2)
ldb.modify(m)
-
res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
- scope=SCOPE_BASE, attrs=["sAMAccountType"])
+ scope=SCOPE_BASE,
+ attrs=["sAMAccountType", "userAccountControl", "pwdLastSet"])
self.assertTrue(len(res1) == 1)
- self.assertEquals(int(res1[0]["sAMAccountType"][0]),
- ATYPE_NORMAL_ACCOUNT)
+ self.assertEqual(int(res1[0]["sAMAccountType"][0]),
+ ATYPE_NORMAL_ACCOUNT)
+ self.assertEqual(int(res1[0]["userAccountControl"][0]),
+ UF_NORMAL_ACCOUNT | UF_ACCOUNTDISABLE | UF_PASSWD_NOTREQD)
+ self.assertEqual(int(res1[0]["pwdLastSet"][0]), lastset)
try:
m = Message()
m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- m["userAccountControl"] = MessageElement(
- str(UF_TEMP_DUPLICATE_ACCOUNT),
- FLAG_MOD_REPLACE, "userAccountControl")
+ m["pls1"] = MessageElement(str(lastset),
+ FLAG_MOD_DELETE,
+ "pwdLastSet")
+ m["pls2"] = MessageElement(str(lastset),
+ FLAG_MOD_ADD,
+ "pwdLastSet")
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e54:
+ (num, msg) = e54.args
self.assertEquals(num, ERR_OTHER)
+ self.assertTrue('00000057' in msg)
-# This isn't supported yet in s4
-# try:
-# m = Message()
-# m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
-# m["userAccountControl"] = MessageElement(
-# str(UF_SERVER_TRUST_ACCOUNT),
-# FLAG_MOD_REPLACE, "userAccountControl")
-# 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["pls1"] = MessageElement(str(lastset),
+ FLAG_MOD_DELETE,
+ "pwdLastSet")
+ m["pls2"] = MessageElement(str(0),
+ FLAG_MOD_ADD,
+ "pwdLastSet")
+ ldb.modify(m)
+ res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["sAMAccountType", "userAccountControl", "pwdLastSet"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEqual(int(res1[0]["sAMAccountType"][0]),
+ ATYPE_NORMAL_ACCOUNT)
+ self.assertEqual(int(res1[0]["userAccountControl"][0]),
+ UF_NORMAL_ACCOUNT | UF_ACCOUNTDISABLE | UF_PASSWD_NOTREQD)
+ uac = int(res1[0]["userAccountControl"][0])
+ self.assertEqual(int(res1[0]["pwdLastSet"][0]), 0)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- m["userAccountControl"] = MessageElement(
- str(UF_WORKSTATION_TRUST_ACCOUNT),
- FLAG_MOD_REPLACE, "userAccountControl")
+ m["uac1"] = MessageElement(str(uac|UF_PASSWORD_EXPIRED),
+ FLAG_MOD_REPLACE,
+ "userAccountControl")
ldb.modify(m)
+ res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["sAMAccountType", "userAccountControl", "pwdLastSet"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEqual(int(res1[0]["sAMAccountType"][0]),
+ ATYPE_NORMAL_ACCOUNT)
+ self.assertEqual(int(res1[0]["userAccountControl"][0]),
+ UF_NORMAL_ACCOUNT | UF_ACCOUNTDISABLE | UF_PASSWD_NOTREQD)
+ self.assertEqual(int(res1[0]["pwdLastSet"][0]), 0)
+
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+
+ def test_ldap_bind_must_change_pwd(self):
+ """Test the error messages for failing LDAP binds"""
+ print("Test the error messages for failing LDAP binds\n")
+
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+
+ def format_error_msg(hresult_v, dsid_v, werror_v):
+ #
+ # There are 4 lower case hex digits following 'v' at the end,
+ # but different Windows Versions return different values:
+ #
+ # Windows 2008R2 uses 'v1db1'
+ # Windows 2012R2 uses 'v2580'
+ #
+ return "%08X: LdapErr: DSID-%08X, comment: AcceptSecurityContext error, data %x, v" % (
+ hresult_v, dsid_v, werror_v)
+
+ HRES_SEC_E_LOGON_DENIED = 0x8009030C
+ HRES_SEC_E_INVALID_TOKEN = 0x80090308
+
+ sasl_bind_dsid = 0x0C0904DC
+ simple_bind_dsid = 0x0C0903A9
+
+ error_msg_sasl_wrong_pw = format_error_msg(
+ HRES_SEC_E_LOGON_DENIED,
+ sasl_bind_dsid,
+ werror.WERR_LOGON_FAILURE)
+ error_msg_sasl_must_change = format_error_msg(
+ HRES_SEC_E_LOGON_DENIED,
+ sasl_bind_dsid,
+ werror.WERR_PASSWORD_MUST_CHANGE)
+ error_msg_simple_wrong_pw = format_error_msg(
+ HRES_SEC_E_INVALID_TOKEN,
+ simple_bind_dsid,
+ werror.WERR_LOGON_FAILURE)
+ error_msg_simple_must_change = format_error_msg(
+ HRES_SEC_E_INVALID_TOKEN,
+ simple_bind_dsid,
+ werror.WERR_PASSWORD_MUST_CHANGE)
+
+ username = "ldaptestuser"
+ password = "thatsAcomplPASS2"
+ utf16pw = unicode('"' + password.encode('utf-8') + '"', 'utf-8').encode('utf-16-le')
+
+ ldb.add({
+ "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
+ "objectclass": "user",
+ "sAMAccountName": username,
+ "userAccountControl": str(UF_NORMAL_ACCOUNT),
+ "unicodePwd": utf16pw,
+ })
res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
- scope=SCOPE_BASE, attrs=["sAMAccountType"])
- self.assertTrue(len(res1) == 1)
- self.assertEquals(int(res1[0]["sAMAccountType"][0]),
- ATYPE_WORKSTATION_TRUST)
+ scope=SCOPE_BASE,
+ attrs=["sAMAccountName", "sAMAccountType", "userAccountControl", "pwdLastSet"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEqual(res1[0]["sAMAccountName"][0], username)
+ self.assertEqual(int(res1[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT)
+ self.assertEqual(int(res1[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT)
+ self.assertNotEqual(int(res1[0]["pwdLastSet"][0]), 0)
+
+ # Open a second LDB connection with the user credentials. Use the
+ # command line credentials for informations like the domain, the realm
+ # and the workstation.
+ sasl_creds = Credentials()
+ sasl_creds.set_username(username)
+ sasl_creds.set_password(password)
+ sasl_creds.set_domain(creds.get_domain())
+ sasl_creds.set_workstation(creds.get_workstation())
+ sasl_creds.set_gensec_features(creds.get_gensec_features() | gensec.FEATURE_SEAL)
+ sasl_creds.set_kerberos_state(DONT_USE_KERBEROS)
+
+ sasl_wrong_creds = Credentials()
+ sasl_wrong_creds.set_username(username)
+ sasl_wrong_creds.set_password("wrong")
+ sasl_wrong_creds.set_domain(creds.get_domain())
+ sasl_wrong_creds.set_workstation(creds.get_workstation())
+ sasl_wrong_creds.set_gensec_features(creds.get_gensec_features() | gensec.FEATURE_SEAL)
+ sasl_wrong_creds.set_kerberos_state(DONT_USE_KERBEROS)
+
+ simple_creds = Credentials()
+ simple_creds.set_bind_dn("cn=ldaptestuser,cn=users," + self.base_dn)
+ simple_creds.set_username(username)
+ simple_creds.set_password(password)
+ simple_creds.set_domain(creds.get_domain())
+ simple_creds.set_workstation(creds.get_workstation())
+ simple_creds.set_gensec_features(creds.get_gensec_features() | gensec.FEATURE_SEAL)
+ simple_creds.set_kerberos_state(DONT_USE_KERBEROS)
+
+ simple_wrong_creds = Credentials()
+ simple_wrong_creds.set_bind_dn("cn=ldaptestuser,cn=users," + self.base_dn)
+ simple_wrong_creds.set_username(username)
+ simple_wrong_creds.set_password("wrong")
+ simple_wrong_creds.set_domain(creds.get_domain())
+ simple_wrong_creds.set_workstation(creds.get_workstation())
+ simple_wrong_creds.set_gensec_features(creds.get_gensec_features() | gensec.FEATURE_SEAL)
+ simple_wrong_creds.set_kerberos_state(DONT_USE_KERBEROS)
+
+ sasl_ldb = SamDB(url=host, credentials=sasl_creds, lp=lp)
+ self.assertIsNotNone(sasl_ldb)
+ sasl_ldb = None
+
+ requires_strong_auth = False
+ try:
+ simple_ldb = SamDB(url=host, credentials=simple_creds, lp=lp)
+ self.assertIsNotNone(simple_ldb)
+ simple_ldb = None
+ except LdbError as e55:
+ (num, msg) = e55.args
+ if num != ERR_STRONG_AUTH_REQUIRED:
+ raise
+ requires_strong_auth = True
+
+ def assertLDAPErrorMsg(msg, expected_msg):
+ self.assertTrue(expected_msg in msg,
+ "msg[%s] does not contain expected[%s]" % (
+ msg, expected_msg))
+
+ try:
+ ldb_fail = SamDB(url=host, credentials=sasl_wrong_creds, lp=lp)
+ self.fail()
+ except LdbError as e56:
+ (num, msg) = e56.args
+ self.assertEquals(num, ERR_INVALID_CREDENTIALS)
+ self.assertTrue(error_msg_sasl_wrong_pw in msg)
+
+ if not requires_strong_auth:
+ try:
+ ldb_fail = SamDB(url=host, credentials=simple_wrong_creds, lp=lp)
+ self.fail()
+ except LdbError as e4:
+ (num, msg) = e4.args
+ self.assertEquals(num, ERR_INVALID_CREDENTIALS)
+ assertLDAPErrorMsg(msg, error_msg_simple_wrong_pw)
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")
+ m["pls1"] = MessageElement(str(0),
+ FLAG_MOD_REPLACE,
+ "pwdLastSet")
ldb.modify(m)
res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
- scope=SCOPE_BASE, attrs=["sAMAccountType"])
- self.assertTrue(len(res1) == 1)
- self.assertEquals(int(res1[0]["sAMAccountType"][0]),
- ATYPE_NORMAL_ACCOUNT)
+ scope=SCOPE_BASE, attrs=["pwdLastSet"])
+ self.assertEqual(int(res1[0]["pwdLastSet"][0]), 0)
-# This isn't supported yet in s4 - needs ACL module adaption
-# try:
-# m = Message()
-# m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
-# m["userAccountControl"] = MessageElement(
-# str(UF_INTERDOMAIN_TRUST_ACCOUNT),
-# FLAG_MOD_REPLACE, "userAccountControl")
-# ldb.modify(m)
-# self.fail()
-# except LdbError, (num, _):
-# self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS)
+ try:
+ ldb_fail = SamDB(url=host, credentials=sasl_wrong_creds, lp=lp)
+ self.fail()
+ except LdbError as e57:
+ (num, msg) = e57.args
+ self.assertEquals(num, ERR_INVALID_CREDENTIALS)
+ assertLDAPErrorMsg(msg, error_msg_sasl_wrong_pw)
- # With a computer object
+ try:
+ ldb_fail = SamDB(url=host, credentials=sasl_creds, lp=lp)
+ self.fail()
+ except LdbError as e58:
+ (num, msg) = e58.args
+ self.assertEquals(num, ERR_INVALID_CREDENTIALS)
+ assertLDAPErrorMsg(msg, error_msg_sasl_must_change)
+
+ if not requires_strong_auth:
+ try:
+ ldb_fail = SamDB(url=host, credentials=simple_wrong_creds, lp=lp)
+ self.fail()
+ except LdbError as e5:
+ (num, msg) = e5.args
+ self.assertEquals(num, ERR_INVALID_CREDENTIALS)
+ assertLDAPErrorMsg(msg, error_msg_simple_wrong_pw)
+
+ try:
+ ldb_fail = SamDB(url=host, credentials=simple_creds, lp=lp)
+ self.fail()
+ except LdbError as e6:
+ (num, msg) = e6.args
+ self.assertEquals(num, ERR_INVALID_CREDENTIALS)
+ assertLDAPErrorMsg(msg, error_msg_simple_must_change)
+
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+
+ def test_userAccountControl(self):
+ """Test the userAccountControl behaviour"""
+ print("Testing userAccountControl behaviour\n")
+
+ # With a user object
# Add operation
- # As computer you can set a normal account and a server trust account.
+ # As user you can only set a normal account.
# The UF_PASSWD_NOTREQD flag is needed since we haven't requested a
# password yet.
# With SYSTEM rights you can set a interdomain trust account.
- # Invalid attribute
- try:
- ldb.add({
- "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
- "objectclass": ["computer"],
- "userAccountControl": "0"})
- self.fail()
- except LdbError, (num, _):
- self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
- self.delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
-
-# This has to wait until s4 supports it (needs a password module change)
-# try:
-# ldb.add({
-# "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
-# "objectclass": ["computer"],
-# "userAccountControl": str(UF_NORMAL_ACCOUNT)})
-# self.fail()
-# except LdbError, (num, _):
-# self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
-# self.delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ ldb.add({
+ "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
+ "objectclass": "user",
+ "userAccountControl": "0"})
+
+ res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["sAMAccountType", "userAccountControl"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEquals(int(res1[0]["sAMAccountType"][0]),
+ ATYPE_NORMAL_ACCOUNT)
+ self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE == 0)
+ self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_PASSWD_NOTREQD == 0)
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
ldb.add({
- "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
- "objectclass": ["computer"],
+ "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
+ "objectclass": "user",
+ "userAccountControl": str(UF_NORMAL_ACCOUNT)})
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+
+ ldb.add({
+ "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
+ "objectclass": "user",
"userAccountControl": str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD)})
- res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
- scope=SCOPE_BASE, attrs=["sAMAccountType"])
+ res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["sAMAccountType", "userAccountControl"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEquals(int(res1[0]["sAMAccountType"][0]),
+ ATYPE_NORMAL_ACCOUNT)
+ self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE == 0)
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+
+ ldb.add({
+ "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
+ "objectclass": "user",
+ "userAccountControl": str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_LOCKOUT | UF_PASSWORD_EXPIRED)})
+
+ res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["sAMAccountType", "userAccountControl", "lockoutTime", "pwdLastSet"])
self.assertTrue(len(res1) == 1)
self.assertEquals(int(res1[0]["sAMAccountType"][0]),
ATYPE_NORMAL_ACCOUNT)
- self.delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ self.assertTrue(int(res1[0]["userAccountControl"][0]) & (UF_LOCKOUT | UF_PASSWORD_EXPIRED) == 0)
+ self.assertFalse("lockoutTime" in res1[0])
+ self.assertTrue(int(res1[0]["pwdLastSet"][0]) == 0)
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
try:
ldb.add({
- "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
- "objectclass": ["computer"],
+ "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
+ "objectclass": "user",
"userAccountControl": str(UF_TEMP_DUPLICATE_ACCOUNT)})
self.fail()
- except LdbError, (num, _):
+ except LdbError as e59:
+ (num, _) = e59.args
self.assertEquals(num, ERR_OTHER)
- self.delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
-
- ldb.add({
- "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
- "objectclass": ["computer"],
- "userAccountControl": str(UF_SERVER_TRUST_ACCOUNT)})
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
- scope=SCOPE_BASE, attrs=["sAMAccountType"])
- self.assertTrue(len(res1) == 1)
- self.assertEquals(int(res1[0]["sAMAccountType"][0]),
- ATYPE_WORKSTATION_TRUST)
- self.delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ try:
+ ldb.add({
+ "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
+ "objectclass": "user",
+ "userAccountControl": str(UF_SERVER_TRUST_ACCOUNT)})
+ self.fail()
+ except LdbError as e60:
+ (num, _) = e60.args
+ self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
try:
ldb.add({
- "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
- "objectclass": ["computer"],
+ "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
+ "objectclass": "user",
"userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT)})
- except LdbError, (num, _):
+ except LdbError as e61:
+ (num, _) = e61.args
+ self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+
+ try:
+ ldb.add({
+ "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
+ "objectclass": "user",
+ "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT)})
+ except LdbError as e62:
+ (num, _) = e62.args
self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
- self.delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
-
-# This isn't supported yet in s4 - needs ACL module adaption
-# try:
-# ldb.add({
-# "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
-# "objectclass": ["computer"],
-# "userAccountControl": str(UF_INTERDOMAIN_TRUST_ACCOUNT)})
-# self.fail()
-# except LdbError, (num, _):
-# self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS)
-# self.delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+
+ try:
+ ldb.add({
+ "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
+ "objectclass": "user",
+ "userAccountControl": str(UF_INTERDOMAIN_TRUST_ACCOUNT)})
+ self.fail()
+ except LdbError as e63:
+ (num, _) = e63.args
+ self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS)
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
# Modify operation
ldb.add({
- "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
- "objectclass": ["computer"]})
+ "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
+ "objectclass": "user"})
# After creation we should have a normal account
- res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
- scope=SCOPE_BASE, attrs=["sAMAccountType"])
+ res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["sAMAccountType", "userAccountControl"])
self.assertTrue(len(res1) == 1)
self.assertEquals(int(res1[0]["sAMAccountType"][0]),
ATYPE_NORMAL_ACCOUNT)
+ self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE != 0)
- # As computer you can switch from a normal account to a workstation
- # or server trust account and back (also swapping between trust
+ # As user you can only switch from a normal account to a workstation
+ # trust account and back.
+ # The UF_PASSWD_NOTREQD flag is needed since we haven't requested a
+ # password yet.
+ # With SYSTEM rights you can switch to a interdomain trust account.
+
+ # Invalid attribute
+ try:
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ m["userAccountControl"] = MessageElement("0",
+ FLAG_MOD_REPLACE, "userAccountControl")
+ ldb.modify(m)
+ except LdbError as e64:
+ (num, _) = e64.args
+ self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+
+ try:
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ m["userAccountControl"] = MessageElement(
+ str(UF_NORMAL_ACCOUNT),
+ FLAG_MOD_REPLACE, "userAccountControl")
+ ldb.modify(m)
+ except LdbError as e65:
+ (num, _) = e65.args
+ self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+
+ 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=["sAMAccountType", "userAccountControl"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEquals(int(res1[0]["sAMAccountType"][0]),
+ ATYPE_NORMAL_ACCOUNT)
+ self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE == 0)
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ m["userAccountControl"] = MessageElement(
+ str(UF_ACCOUNTDISABLE),
+ FLAG_MOD_REPLACE, "userAccountControl")
+ ldb.modify(m)
+
+ res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["sAMAccountType", "userAccountControl"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEquals(int(res1[0]["sAMAccountType"][0]),
+ ATYPE_NORMAL_ACCOUNT)
+ self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_NORMAL_ACCOUNT != 0)
+ self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE != 0)
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ m["lockoutTime"] = MessageElement(str(samba.unix2nttime(0)), FLAG_MOD_REPLACE, "lockoutTime")
+ m["pwdLastSet"] = MessageElement(str(samba.unix2nttime(0)), FLAG_MOD_REPLACE, "pwdLastSet")
+ ldb.modify(m)
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ m["userAccountControl"] = MessageElement(
+ str(UF_LOCKOUT | UF_PASSWORD_EXPIRED),
+ FLAG_MOD_REPLACE, "userAccountControl")
+ ldb.modify(m)
+
+ res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["sAMAccountType", "userAccountControl", "lockoutTime", "pwdLastSet"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEquals(int(res1[0]["sAMAccountType"][0]),
+ ATYPE_NORMAL_ACCOUNT)
+ self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_NORMAL_ACCOUNT != 0)
+ self.assertTrue(int(res1[0]["userAccountControl"][0]) & (UF_LOCKOUT | UF_PASSWORD_EXPIRED) == 0)
+ self.assertTrue(int(res1[0]["lockoutTime"][0]) == 0)
+ self.assertTrue(int(res1[0]["pwdLastSet"][0]) == 0)
+
+ try:
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ m["userAccountControl"] = MessageElement(
+ str(UF_TEMP_DUPLICATE_ACCOUNT),
+ FLAG_MOD_REPLACE, "userAccountControl")
+ ldb.modify(m)
+ self.fail()
+ except LdbError as e66:
+ (num, _) = e66.args
+ self.assertEquals(num, ERR_OTHER)
+
+ try:
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ m["userAccountControl"] = MessageElement(
+ str(UF_SERVER_TRUST_ACCOUNT),
+ FLAG_MOD_REPLACE, "userAccountControl")
+ ldb.modify(m)
+ self.fail()
+ except LdbError as e67:
+ (num, _) = e67.args
+ self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ m["userAccountControl"] = MessageElement(
+ str(UF_WORKSTATION_TRUST_ACCOUNT),
+ FLAG_MOD_REPLACE, "userAccountControl")
+ ldb.modify(m)
+
+ try:
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ m["userAccountControl"] = MessageElement(
+ str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT),
+ FLAG_MOD_REPLACE, "userAccountControl")
+ ldb.modify(m)
+ self.fail()
+ except LdbError as e68:
+ (num, _) = e68.args
+ self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+
+ res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
+ scope=SCOPE_BASE, attrs=["sAMAccountType"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEquals(int(res1[0]["sAMAccountType"][0]),
+ ATYPE_WORKSTATION_TRUST)
+
+ 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=["sAMAccountType"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEquals(int(res1[0]["sAMAccountType"][0]),
+ ATYPE_NORMAL_ACCOUNT)
+
+ try:
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ m["userAccountControl"] = MessageElement(
+ str(UF_INTERDOMAIN_TRUST_ACCOUNT),
+ FLAG_MOD_REPLACE, "userAccountControl")
+ ldb.modify(m)
+ self.fail()
+ except LdbError as e69:
+ (num, _) = e69.args
+ self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS)
+
+ # With a computer object
+
+ # Add operation
+
+ # As computer you can set a normal account and a server trust account.
+ # The UF_PASSWD_NOTREQD flag is needed since we haven't requested a
+ # password yet.
+ # With SYSTEM rights you can set a interdomain trust account.
+
+ ldb.add({
+ "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ "objectclass": "computer",
+ "userAccountControl": "0"})
+
+ res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["sAMAccountType", "userAccountControl"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEquals(int(res1[0]["sAMAccountType"][0]),
+ ATYPE_NORMAL_ACCOUNT)
+ self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE == 0)
+ self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_PASSWD_NOTREQD == 0)
+ delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+
+ ldb.add({
+ "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ "objectclass": "computer",
+ "userAccountControl": str(UF_NORMAL_ACCOUNT)})
+ delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+
+ ldb.add({
+ "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ "objectclass": "computer",
+ "userAccountControl": str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD)})
+
+ res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["sAMAccountType", "userAccountControl"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEquals(int(res1[0]["sAMAccountType"][0]),
+ ATYPE_NORMAL_ACCOUNT)
+ self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE == 0)
+ delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+
+ ldb.add({
+ "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ "objectclass": "computer",
+ "userAccountControl": str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_LOCKOUT | UF_PASSWORD_EXPIRED)})
+
+ res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["sAMAccountType", "userAccountControl", "lockoutTime", "pwdLastSet"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEquals(int(res1[0]["sAMAccountType"][0]),
+ ATYPE_NORMAL_ACCOUNT)
+ self.assertTrue(int(res1[0]["userAccountControl"][0]) & (UF_LOCKOUT | UF_PASSWORD_EXPIRED) == 0)
+ self.assertFalse("lockoutTime" in res1[0])
+ self.assertTrue(int(res1[0]["pwdLastSet"][0]) == 0)
+ delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+
+ try:
+ ldb.add({
+ "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ "objectclass": "computer",
+ "userAccountControl": str(UF_TEMP_DUPLICATE_ACCOUNT)})
+ self.fail()
+ except LdbError as e70:
+ (num, _) = e70.args
+ self.assertEquals(num, ERR_OTHER)
+ delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+
+ ldb.add({
+ "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ "objectclass": "computer",
+ "userAccountControl": str(UF_SERVER_TRUST_ACCOUNT)})
+
+ res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE, attrs=["sAMAccountType"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEquals(int(res1[0]["sAMAccountType"][0]),
+ ATYPE_WORKSTATION_TRUST)
+ delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+
+ try:
+ ldb.add({
+ "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ "objectclass": "computer",
+ "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT)})
+ except LdbError as e71:
+ (num, _) = e71.args
+ self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
+ delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+
+ try:
+ ldb.add({
+ "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ "objectclass": "computer",
+ "userAccountControl": str(UF_INTERDOMAIN_TRUST_ACCOUNT)})
+ self.fail()
+ except LdbError as e72:
+ (num, _) = e72.args
+ self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS)
+ delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+
+ # Modify operation
+
+ ldb.add({
+ "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ "objectclass": "computer"})
+
+ # After creation we should have a normal account
+ res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["sAMAccountType", "userAccountControl"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEquals(int(res1[0]["sAMAccountType"][0]),
+ ATYPE_NORMAL_ACCOUNT)
+ self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE != 0)
+
+ # As computer you can switch from a normal account to a workstation
+ # or server trust account and back (also swapping between trust
# accounts is allowed).
# The UF_PASSWD_NOTREQD flag is needed since we haven't requested a
# password yet.
m["userAccountControl"] = MessageElement("0",
FLAG_MOD_REPLACE, "userAccountControl")
ldb.modify(m)
- except LdbError, (num, _):
+ except LdbError as e73:
+ (num, _) = e73.args
+ self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+
+ try:
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ m["userAccountControl"] = MessageElement(
+ str(UF_NORMAL_ACCOUNT),
+ FLAG_MOD_REPLACE, "userAccountControl")
+ ldb.modify(m)
+ except LdbError as e74:
+ (num, _) = e74.args
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
-# This has to wait until s4 supports it (needs a password module change)
-# try:
-# m = Message()
-# m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
-# m["userAccountControl"] = MessageElement(
-# str(UF_NORMAL_ACCOUNT),
-# FLAG_MOD_REPLACE, "userAccountControl")
-# ldb.modify(m)
-# except LdbError, (num, _):
-# self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ m["userAccountControl"] = MessageElement(
+ str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD),
+ FLAG_MOD_REPLACE, "userAccountControl")
+ ldb.modify(m)
+
+ res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["sAMAccountType", "userAccountControl"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEquals(int(res1[0]["sAMAccountType"][0]),
+ ATYPE_NORMAL_ACCOUNT)
+ self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE == 0)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
m["userAccountControl"] = MessageElement(
- str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD),
+ str(UF_ACCOUNTDISABLE),
FLAG_MOD_REPLACE, "userAccountControl")
ldb.modify(m)
res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
- scope=SCOPE_BASE, attrs=["sAMAccountType"])
+ scope=SCOPE_BASE,
+ attrs=["sAMAccountType", "userAccountControl"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEquals(int(res1[0]["sAMAccountType"][0]),
+ ATYPE_NORMAL_ACCOUNT)
+ self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_NORMAL_ACCOUNT != 0)
+ self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE != 0)
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ m["lockoutTime"] = MessageElement(str(samba.unix2nttime(0)), FLAG_MOD_REPLACE, "lockoutTime")
+ m["pwdLastSet"] = MessageElement(str(samba.unix2nttime(0)), FLAG_MOD_REPLACE, "pwdLastSet")
+ ldb.modify(m)
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ m["userAccountControl"] = MessageElement(
+ str(UF_LOCKOUT | UF_PASSWORD_EXPIRED),
+ FLAG_MOD_REPLACE, "userAccountControl")
+ ldb.modify(m)
+
+ res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["sAMAccountType", "userAccountControl", "lockoutTime", "pwdLastSet"])
self.assertTrue(len(res1) == 1)
self.assertEquals(int(res1[0]["sAMAccountType"][0]),
ATYPE_NORMAL_ACCOUNT)
+ self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_NORMAL_ACCOUNT != 0)
+ self.assertTrue(int(res1[0]["userAccountControl"][0]) & (UF_LOCKOUT | UF_PASSWORD_EXPIRED) == 0)
+ self.assertTrue(int(res1[0]["lockoutTime"][0]) == 0)
+ self.assertTrue(int(res1[0]["pwdLastSet"][0]) == 0)
try:
m = Message()
m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
m["userAccountControl"] = MessageElement(
- str(UF_TEMP_DUPLICATE_ACCOUNT),
+ str(UF_TEMP_DUPLICATE_ACCOUNT),
FLAG_MOD_REPLACE, "userAccountControl")
ldb.modify(m)
self.fail()
- except LdbError, (num, _):
+ except LdbError as e75:
+ (num, _) = e75.args
self.assertEquals(num, ERR_OTHER)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
m["userAccountControl"] = MessageElement(
- str(UF_SERVER_TRUST_ACCOUNT),
+ str(UF_SERVER_TRUST_ACCOUNT),
FLAG_MOD_REPLACE, "userAccountControl")
ldb.modify(m)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
m["userAccountControl"] = MessageElement(
- str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD),
+ str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD),
FLAG_MOD_REPLACE, "userAccountControl")
ldb.modify(m)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
m["userAccountControl"] = MessageElement(
- str(UF_WORKSTATION_TRUST_ACCOUNT),
+ str(UF_WORKSTATION_TRUST_ACCOUNT),
FLAG_MOD_REPLACE, "userAccountControl")
ldb.modify(m)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
m["userAccountControl"] = MessageElement(
- str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD),
+ str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD),
FLAG_MOD_REPLACE, "userAccountControl")
ldb.modify(m)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
- m["userAccountControl"] = MessageElement(
- str(UF_SERVER_TRUST_ACCOUNT),
- FLAG_MOD_REPLACE, "userAccountControl")
+ m["userAccountControl"] = MessageElement(
+ str(UF_SERVER_TRUST_ACCOUNT),
+ FLAG_MOD_REPLACE, "userAccountControl")
+ ldb.modify(m)
+
+ res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE, attrs=["sAMAccountType"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEquals(int(res1[0]["sAMAccountType"][0]),
+ ATYPE_WORKSTATION_TRUST)
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ m["userAccountControl"] = MessageElement(
+ str(UF_WORKSTATION_TRUST_ACCOUNT),
+ FLAG_MOD_REPLACE, "userAccountControl")
+ ldb.modify(m)
+
+ res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE, attrs=["sAMAccountType"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEquals(int(res1[0]["sAMAccountType"][0]),
+ ATYPE_WORKSTATION_TRUST)
+
+ try:
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ m["userAccountControl"] = MessageElement(
+ str(UF_INTERDOMAIN_TRUST_ACCOUNT),
+ FLAG_MOD_REPLACE, "userAccountControl")
+ ldb.modify(m)
+ self.fail()
+ except LdbError as e76:
+ (num, _) = e76.args
+ self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS)
+
+ # "primaryGroupID" does not change if account type remains the same
+
+ # For a user account
+
+ ldb.add({
+ "dn": "cn=ldaptestuser2,cn=users," + self.base_dn,
+ "objectclass": "user",
+ "userAccountControl": str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE)})
+
+ res1 = ldb.search("cn=ldaptestuser2,cn=users," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["userAccountControl"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEquals(int(res1[0]["userAccountControl"][0]),
+ UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE)
+
+ m = Message()
+ m.dn = Dn(ldb, "<SID=" + ldb.get_domain_sid() + "-" + str(DOMAIN_RID_ADMINS) + ">")
+ m["member"] = MessageElement(
+ "cn=ldaptestuser2,cn=users," + self.base_dn, FLAG_MOD_ADD, "member")
+ ldb.modify(m)
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
+ m["primaryGroupID"] = MessageElement(str(DOMAIN_RID_ADMINS),
+ FLAG_MOD_REPLACE, "primaryGroupID")
+ ldb.modify(m)
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestuser2,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=ldaptestuser2,cn=users," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["userAccountControl", "primaryGroupID"])
+ self.assertTrue(len(res1) == 1)
+ self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE == 0)
+ self.assertEquals(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_ADMINS)
+
+ # For a workstation account
+
+ res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["primaryGroupID"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEquals(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_DOMAIN_MEMBERS)
+
+ m = Message()
+ m.dn = Dn(ldb, "<SID=" + ldb.get_domain_sid() + "-" + str(DOMAIN_RID_USERS) + ">")
+ m["member"] = MessageElement(
+ "cn=ldaptestcomputer,cn=computers," + self.base_dn, FLAG_MOD_ADD, "member")
+ ldb.modify(m)
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ m["primaryGroupID"] = MessageElement(str(DOMAIN_RID_USERS),
+ FLAG_MOD_REPLACE, "primaryGroupID")
+ ldb.modify(m)
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ m["userAccountControl"] = MessageElement(
+ str(UF_WORKSTATION_TRUST_ACCOUNT),
+ FLAG_MOD_REPLACE, "userAccountControl")
+ ldb.modify(m)
+
+ res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["primaryGroupID"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEquals(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_USERS)
+
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
+ delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+
+ def find_repl_meta_data(self, rpmd, attid):
+ for i in range(0, rpmd.ctr.count):
+ m = rpmd.ctr.array[i]
+ if m.attid == attid:
+ return m
+ return None
+
+ def test_smartcard_required1(self):
+ """Test the UF_SMARTCARD_REQUIRED behaviour"""
+ print("Testing UF_SMARTCARD_REQUIRED behaviour\n")
+
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+
+ ldb.add({
+ "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
+ "objectclass": "user",
+ "userAccountControl": str(UF_NORMAL_ACCOUNT),
+ "unicodePwd": "\"thatsAcomplPASS2\"".encode('utf-16-le')
+ })
+
+ res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["sAMAccountType", "userAccountControl",
+ "pwdLastSet", "msDS-KeyVersionNumber",
+ "replPropertyMetaData"])
+ self.assertTrue(len(res) == 1)
+ self.assertEqual(int(res[0]["sAMAccountType"][0]),
+ ATYPE_NORMAL_ACCOUNT)
+ self.assertEqual(int(res[0]["userAccountControl"][0]),
+ UF_NORMAL_ACCOUNT)
+ self.assertNotEqual(int(res[0]["pwdLastSet"][0]), 0)
+ lastset = int(res[0]["pwdLastSet"][0])
+ self.assertEqual(int(res[0]["msDS-KeyVersionNumber"][0]), 1)
+ self.assertTrue(len(res[0]["replPropertyMetaData"]) == 1)
+ rpmd = ndr_unpack(drsblobs.replPropertyMetaDataBlob,
+ res[0]["replPropertyMetaData"][0])
+ lastsetmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_pwdLastSet)
+ self.assertIsNotNone(lastsetmd)
+ self.assertEqual(lastsetmd.version, 1)
+ nthashmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_unicodePwd)
+ self.assertIsNotNone(nthashmd)
+ self.assertEqual(nthashmd.version, 1)
+ nthistmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_ntPwdHistory)
+ self.assertIsNotNone(nthistmd)
+ self.assertEqual(nthistmd.version, 1)
+ lmhashmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_dBCSPwd)
+ self.assertIsNotNone(lmhashmd)
+ self.assertEqual(lmhashmd.version, 1)
+ lmhistmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_lmPwdHistory)
+ self.assertIsNotNone(lmhistmd)
+ self.assertEqual(lmhistmd.version, 1)
+ spcbmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_supplementalCredentials)
+ self.assertIsNotNone(spcbmd)
+ self.assertEqual(spcbmd.version, 1)
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ m["userAccountControl"] = MessageElement(
+ str(UF_NORMAL_ACCOUNT|UF_SMARTCARD_REQUIRED),
+ FLAG_MOD_REPLACE, "userAccountControl")
+ ldb.modify(m)
+
+ res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["sAMAccountType", "userAccountControl",
+ "pwdLastSet", "msDS-KeyVersionNumber",
+ "replPropertyMetaData"])
+ self.assertTrue(len(res) == 1)
+ self.assertEqual(int(res[0]["sAMAccountType"][0]),
+ ATYPE_NORMAL_ACCOUNT)
+ self.assertEqual(int(res[0]["userAccountControl"][0]),
+ UF_NORMAL_ACCOUNT|UF_SMARTCARD_REQUIRED)
+ self.assertEqual(int(res[0]["pwdLastSet"][0]), lastset)
+ lastset1 = int(res[0]["pwdLastSet"][0])
+ self.assertEqual(int(res[0]["msDS-KeyVersionNumber"][0]), 2)
+ self.assertTrue(len(res[0]["replPropertyMetaData"]) == 1)
+ rpmd = ndr_unpack(drsblobs.replPropertyMetaDataBlob,
+ res[0]["replPropertyMetaData"][0])
+ lastsetmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_pwdLastSet)
+ self.assertIsNotNone(lastsetmd)
+ self.assertEqual(lastsetmd.version, 1)
+ nthashmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_unicodePwd)
+ self.assertIsNotNone(nthashmd)
+ self.assertEqual(nthashmd.version, 2)
+ nthistmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_ntPwdHistory)
+ self.assertIsNotNone(nthistmd)
+ self.assertEqual(nthistmd.version, 2)
+ lmhashmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_dBCSPwd)
+ self.assertIsNotNone(lmhashmd)
+ self.assertEqual(lmhashmd.version, 2)
+ lmhistmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_lmPwdHistory)
+ self.assertIsNotNone(lmhistmd)
+ self.assertEqual(lmhistmd.version, 2)
+ spcbmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_supplementalCredentials)
+ self.assertIsNotNone(spcbmd)
+ self.assertEqual(spcbmd.version, 2)
+
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+
+ def test_smartcard_required2(self):
+ """Test the UF_SMARTCARD_REQUIRED behaviour"""
+ print("Testing UF_SMARTCARD_REQUIRED behaviour\n")
+
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+
+ ldb.add({
+ "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
+ "objectclass": "user",
+ "userAccountControl": str(UF_NORMAL_ACCOUNT|UF_ACCOUNTDISABLE),
+ })
+
+ res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["sAMAccountType", "userAccountControl",
+ "pwdLastSet", "msDS-KeyVersionNumber",
+ "replPropertyMetaData"])
+ self.assertTrue(len(res) == 1)
+ self.assertEqual(int(res[0]["sAMAccountType"][0]),
+ ATYPE_NORMAL_ACCOUNT)
+ self.assertEqual(int(res[0]["userAccountControl"][0]),
+ UF_NORMAL_ACCOUNT|UF_ACCOUNTDISABLE)
+ self.assertEqual(int(res[0]["pwdLastSet"][0]), 0)
+ self.assertTrue("msDS-KeyVersionNumber" in res[0])
+ self.assertEqual(int(res[0]["msDS-KeyVersionNumber"][0]), 1)
+ self.assertTrue(len(res[0]["replPropertyMetaData"]) == 1)
+ rpmd = ndr_unpack(drsblobs.replPropertyMetaDataBlob,
+ res[0]["replPropertyMetaData"][0])
+ lastsetmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_pwdLastSet)
+ self.assertIsNotNone(lastsetmd)
+ self.assertEqual(lastsetmd.version, 1)
+ nthashmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_unicodePwd)
+ self.assertIsNotNone(nthashmd)
+ self.assertEqual(nthashmd.version, 1)
+ nthistmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_ntPwdHistory)
+ self.assertIsNotNone(nthistmd)
+ self.assertEqual(nthistmd.version, 1)
+ lmhashmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_dBCSPwd)
+ self.assertIsNotNone(lmhashmd)
+ self.assertEqual(lmhashmd.version, 1)
+ lmhistmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_lmPwdHistory)
+ self.assertIsNotNone(lmhistmd)
+ self.assertEqual(lmhistmd.version, 1)
+ spcbmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_supplementalCredentials)
+ self.assertIsNone(spcbmd)
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ m["userAccountControl"] = MessageElement(
+ str(UF_NORMAL_ACCOUNT|UF_ACCOUNTDISABLE|UF_SMARTCARD_REQUIRED),
+ FLAG_MOD_REPLACE, "userAccountControl")
+ ldb.modify(m)
+
+ res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["sAMAccountType", "userAccountControl",
+ "pwdLastSet", "msDS-KeyVersionNumber",
+ "replPropertyMetaData"])
+ self.assertTrue(len(res) == 1)
+ self.assertEqual(int(res[0]["sAMAccountType"][0]),
+ ATYPE_NORMAL_ACCOUNT)
+ self.assertEqual(int(res[0]["userAccountControl"][0]),
+ UF_NORMAL_ACCOUNT|UF_ACCOUNTDISABLE|UF_SMARTCARD_REQUIRED)
+ self.assertEqual(int(res[0]["pwdLastSet"][0]), 0)
+ self.assertEqual(int(res[0]["msDS-KeyVersionNumber"][0]), 2)
+ self.assertTrue(len(res[0]["replPropertyMetaData"]) == 1)
+ rpmd = ndr_unpack(drsblobs.replPropertyMetaDataBlob,
+ res[0]["replPropertyMetaData"][0])
+ lastsetmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_pwdLastSet)
+ self.assertIsNotNone(lastsetmd)
+ self.assertEqual(lastsetmd.version, 1)
+ nthashmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_unicodePwd)
+ self.assertIsNotNone(nthashmd)
+ self.assertEqual(nthashmd.version, 2)
+ nthistmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_ntPwdHistory)
+ self.assertIsNotNone(nthistmd)
+ self.assertEqual(nthistmd.version, 2)
+ lmhashmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_dBCSPwd)
+ self.assertIsNotNone(lmhashmd)
+ self.assertEqual(lmhashmd.version, 2)
+ lmhistmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_lmPwdHistory)
+ self.assertIsNotNone(lmhistmd)
+ self.assertEqual(lmhistmd.version, 2)
+ spcbmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_supplementalCredentials)
+ self.assertIsNotNone(spcbmd)
+ self.assertEqual(spcbmd.version, 1)
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ m["userAccountControl"] = MessageElement(
+ str(UF_NORMAL_ACCOUNT|UF_SMARTCARD_REQUIRED),
+ FLAG_MOD_REPLACE, "userAccountControl")
+ ldb.modify(m)
+
+ res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["sAMAccountType", "userAccountControl",
+ "pwdLastSet", "msDS-KeyVersionNumber",
+ "replPropertyMetaData"])
+ self.assertTrue(len(res) == 1)
+ self.assertEqual(int(res[0]["sAMAccountType"][0]),
+ ATYPE_NORMAL_ACCOUNT)
+ self.assertEqual(int(res[0]["userAccountControl"][0]),
+ UF_NORMAL_ACCOUNT|UF_SMARTCARD_REQUIRED)
+ self.assertEqual(int(res[0]["pwdLastSet"][0]), 0)
+ self.assertEqual(int(res[0]["msDS-KeyVersionNumber"][0]), 2)
+ self.assertTrue(len(res[0]["replPropertyMetaData"]) == 1)
+ rpmd = ndr_unpack(drsblobs.replPropertyMetaDataBlob,
+ res[0]["replPropertyMetaData"][0])
+ lastsetmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_pwdLastSet)
+ self.assertIsNotNone(lastsetmd)
+ self.assertEqual(lastsetmd.version, 1)
+ nthashmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_unicodePwd)
+ self.assertIsNotNone(nthashmd)
+ self.assertEqual(nthashmd.version, 2)
+ nthistmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_ntPwdHistory)
+ self.assertIsNotNone(nthistmd)
+ self.assertEqual(nthistmd.version, 2)
+ lmhashmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_dBCSPwd)
+ self.assertIsNotNone(lmhashmd)
+ self.assertEqual(lmhashmd.version, 2)
+ lmhistmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_lmPwdHistory)
+ self.assertIsNotNone(lmhistmd)
+ self.assertEqual(lmhistmd.version, 2)
+ spcbmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_supplementalCredentials)
+ self.assertIsNotNone(spcbmd)
+ self.assertEqual(spcbmd.version, 1)
+
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+
+ def test_smartcard_required3(self):
+ """Test the UF_SMARTCARD_REQUIRED behaviour"""
+ print("Testing UF_SMARTCARD_REQUIRED behaviour\n")
+
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+
+ ldb.add({
+ "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
+ "objectclass": "user",
+ "userAccountControl": str(UF_NORMAL_ACCOUNT|UF_SMARTCARD_REQUIRED|UF_ACCOUNTDISABLE),
+ })
+
+ res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["sAMAccountType", "userAccountControl",
+ "pwdLastSet", "msDS-KeyVersionNumber",
+ "replPropertyMetaData"])
+ self.assertTrue(len(res) == 1)
+ self.assertEqual(int(res[0]["sAMAccountType"][0]),
+ ATYPE_NORMAL_ACCOUNT)
+ self.assertEqual(int(res[0]["userAccountControl"][0]),
+ UF_NORMAL_ACCOUNT|UF_SMARTCARD_REQUIRED|UF_ACCOUNTDISABLE)
+ self.assertEqual(int(res[0]["pwdLastSet"][0]), 0)
+ self.assertEqual(int(res[0]["msDS-KeyVersionNumber"][0]), 1)
+ self.assertTrue(len(res[0]["replPropertyMetaData"]) == 1)
+ rpmd = ndr_unpack(drsblobs.replPropertyMetaDataBlob,
+ res[0]["replPropertyMetaData"][0])
+ lastsetmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_pwdLastSet)
+ self.assertIsNotNone(lastsetmd)
+ self.assertEqual(lastsetmd.version, 1)
+ nthashmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_unicodePwd)
+ self.assertIsNotNone(nthashmd)
+ self.assertEqual(nthashmd.version, 1)
+ nthistmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_ntPwdHistory)
+ self.assertIsNotNone(nthistmd)
+ self.assertEqual(nthistmd.version, 1)
+ lmhashmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_dBCSPwd)
+ self.assertIsNotNone(lmhashmd)
+ self.assertEqual(lmhashmd.version, 1)
+ lmhistmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_lmPwdHistory)
+ self.assertIsNotNone(lmhistmd)
+ self.assertEqual(lmhistmd.version, 1)
+ spcbmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_supplementalCredentials)
+ self.assertIsNotNone(spcbmd)
+ self.assertEqual(spcbmd.version, 1)
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+ m["userAccountControl"] = MessageElement(
+ str(UF_NORMAL_ACCOUNT|UF_SMARTCARD_REQUIRED),
+ FLAG_MOD_REPLACE, "userAccountControl")
+ ldb.modify(m)
+
+ res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["sAMAccountType", "userAccountControl",
+ "pwdLastSet", "msDS-KeyVersionNumber",
+ "replPropertyMetaData"])
+ self.assertTrue(len(res) == 1)
+ self.assertEqual(int(res[0]["sAMAccountType"][0]),
+ ATYPE_NORMAL_ACCOUNT)
+ self.assertEqual(int(res[0]["userAccountControl"][0]),
+ UF_NORMAL_ACCOUNT|UF_SMARTCARD_REQUIRED)
+ self.assertEqual(int(res[0]["pwdLastSet"][0]), 0)
+ self.assertEqual(int(res[0]["msDS-KeyVersionNumber"][0]), 1)
+ self.assertTrue(len(res[0]["replPropertyMetaData"]) == 1)
+ rpmd = ndr_unpack(drsblobs.replPropertyMetaDataBlob,
+ res[0]["replPropertyMetaData"][0])
+ lastsetmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_pwdLastSet)
+ self.assertIsNotNone(lastsetmd)
+ self.assertEqual(lastsetmd.version, 1)
+ nthashmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_unicodePwd)
+ self.assertIsNotNone(nthashmd)
+ self.assertEqual(nthashmd.version, 1)
+ nthistmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_ntPwdHistory)
+ self.assertIsNotNone(nthistmd)
+ self.assertEqual(nthistmd.version, 1)
+ lmhashmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_dBCSPwd)
+ self.assertIsNotNone(lmhashmd)
+ self.assertEqual(lmhashmd.version, 1)
+ lmhistmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_lmPwdHistory)
+ self.assertIsNotNone(lmhistmd)
+ self.assertEqual(lmhistmd.version, 1)
+ spcbmd = self.find_repl_meta_data(rpmd,
+ drsuapi.DRSUAPI_ATTID_supplementalCredentials)
+ self.assertIsNotNone(spcbmd)
+ self.assertEqual(spcbmd.version, 1)
+
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
+
+ def test_isCriticalSystemObject(self):
+ """Test the isCriticalSystemObject behaviour"""
+ print("Testing isCriticalSystemObject behaviour\n")
+
+ # Add tests
+
+ ldb.add({
+ "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ "objectclass": "computer"})
+
+ res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["isCriticalSystemObject"])
+ self.assertTrue(len(res1) == 1)
+ self.assertTrue("isCriticalSystemObject" not in res1[0])
+
+ delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+
+ ldb.add({
+ "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ "objectclass": "computer",
+ "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT)})
+
+ res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["isCriticalSystemObject"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEquals(res1[0]["isCriticalSystemObject"][0], "FALSE")
+
+ delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+
+ ldb.add({
+ "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ "objectclass": "computer",
+ "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT)})
+
+ res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["isCriticalSystemObject"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEquals(res1[0]["isCriticalSystemObject"][0], "TRUE")
+
+ delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+
+ ldb.add({
+ "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ "objectclass": "computer",
+ "userAccountControl": str(UF_SERVER_TRUST_ACCOUNT)})
+
+ res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["isCriticalSystemObject"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEquals(res1[0]["isCriticalSystemObject"][0], "TRUE")
+
+ # Modification tests
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ m["userAccountControl"] = MessageElement(str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD),
+ FLAG_MOD_REPLACE, "userAccountControl")
+ ldb.modify(m)
+
+ res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["isCriticalSystemObject"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEquals(res1[0]["isCriticalSystemObject"][0], "TRUE")
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ m["userAccountControl"] = MessageElement(str(UF_WORKSTATION_TRUST_ACCOUNT),
+ FLAG_MOD_REPLACE, "userAccountControl")
+ ldb.modify(m)
+
+ res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["isCriticalSystemObject"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEquals(res1[0]["isCriticalSystemObject"][0], "FALSE")
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ m["userAccountControl"] = MessageElement(
+ str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT),
+ FLAG_MOD_REPLACE, "userAccountControl")
+ ldb.modify(m)
+
+ res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["isCriticalSystemObject"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEquals(res1[0]["isCriticalSystemObject"][0], "TRUE")
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ m["userAccountControl"] = MessageElement(str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD),
+ FLAG_MOD_REPLACE, "userAccountControl")
+ ldb.modify(m)
+
+ res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["isCriticalSystemObject"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEquals(res1[0]["isCriticalSystemObject"][0], "TRUE")
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ m["userAccountControl"] = MessageElement(str(UF_SERVER_TRUST_ACCOUNT),
+ FLAG_MOD_REPLACE, "userAccountControl")
+ ldb.modify(m)
+
+ res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["isCriticalSystemObject"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEquals(res1[0]["isCriticalSystemObject"][0], "TRUE")
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ m["userAccountControl"] = MessageElement(str(UF_WORKSTATION_TRUST_ACCOUNT),
+ FLAG_MOD_REPLACE, "userAccountControl")
+ ldb.modify(m)
+
+ res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["isCriticalSystemObject"])
+ self.assertTrue(len(res1) == 1)
+ self.assertEquals(res1[0]["isCriticalSystemObject"][0], "FALSE")
+
+ delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+
+ def test_service_principal_name_updates(self):
+ """Test the servicePrincipalNames update behaviour"""
+ print("Testing servicePrincipalNames update behaviour\n")
+
+ ldb.add({
+ "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ "objectclass": "computer",
+ "dNSHostName": "testname.testdom"})
+
+ res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE, attrs=["servicePrincipalName"])
+ self.assertTrue(len(res) == 1)
+ self.assertFalse("servicePrincipalName" in res[0])
+
+ delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+
+ ldb.add({
+ "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ "objectclass": "computer",
+ "servicePrincipalName": "HOST/testname.testdom"})
+
+ res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE, attrs=["dNSHostName"])
+ self.assertTrue(len(res) == 1)
+ self.assertFalse("dNSHostName" in res[0])
+
+ delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+
+ ldb.add({
+ "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ "objectclass": "computer",
+ "dNSHostName": "testname2.testdom",
+ "servicePrincipalName": "HOST/testname.testdom"})
+
+ res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE, attrs=["dNSHostName"])
+ self.assertTrue(len(res) == 1)
+ self.assertEquals(res[0]["dNSHostName"][0], "testname2.testdom")
+
+ res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE, attrs=["servicePrincipalName"])
+ self.assertTrue(len(res) == 1)
+ self.assertEquals(res[0]["servicePrincipalName"][0],
+ "HOST/testname.testdom")
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ m["dNSHostName"] = MessageElement("testname.testdoM",
+ FLAG_MOD_REPLACE, "dNSHostName")
+ ldb.modify(m)
+
+ res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE, attrs=["servicePrincipalName"])
+ self.assertTrue(len(res) == 1)
+ self.assertEquals(res[0]["servicePrincipalName"][0],
+ "HOST/testname.testdom")
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ m["dNSHostName"] = MessageElement("testname2.testdom2",
+ FLAG_MOD_REPLACE, "dNSHostName")
+ ldb.modify(m)
+
+ res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE, attrs=["servicePrincipalName"])
+ self.assertTrue(len(res) == 1)
+ self.assertEquals(res[0]["servicePrincipalName"][0],
+ "HOST/testname2.testdom2")
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ m["dNSHostName"] = MessageElement([],
+ FLAG_MOD_DELETE, "dNSHostName")
+ ldb.modify(m)
+
+ res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE, attrs=["servicePrincipalName"])
+ self.assertTrue(len(res) == 1)
+ self.assertEquals(res[0]["servicePrincipalName"][0],
+ "HOST/testname2.testdom2")
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ m["dNSHostName"] = MessageElement("testname.testdom3",
+ FLAG_MOD_REPLACE, "dNSHostName")
+ ldb.modify(m)
+
+ res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE, attrs=["servicePrincipalName"])
+ self.assertTrue(len(res) == 1)
+ self.assertEquals(res[0]["servicePrincipalName"][0],
+ "HOST/testname2.testdom2")
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ m["dNSHostName"] = MessageElement("testname2.testdom2",
+ FLAG_MOD_REPLACE, "dNSHostName")
+ ldb.modify(m)
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ m["dNSHostName"] = MessageElement("testname3.testdom3",
+ FLAG_MOD_REPLACE, "dNSHostName")
+ m["servicePrincipalName"] = MessageElement("HOST/testname2.testdom2",
+ FLAG_MOD_REPLACE,
+ "servicePrincipalName")
+ ldb.modify(m)
+
+ res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE, attrs=["servicePrincipalName"])
+ self.assertTrue(len(res) == 1)
+ self.assertEquals(res[0]["servicePrincipalName"][0],
+ "HOST/testname3.testdom3")
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ m["servicePrincipalName"] = MessageElement("HOST/testname2.testdom2",
+ FLAG_MOD_REPLACE,
+ "servicePrincipalName")
+ m["dNSHostName"] = MessageElement("testname4.testdom4",
+ FLAG_MOD_REPLACE, "dNSHostName")
+ ldb.modify(m)
+
+ res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE, attrs=["servicePrincipalName"])
+ self.assertTrue(len(res) == 1)
+ self.assertEquals(res[0]["servicePrincipalName"][0],
+ "HOST/testname2.testdom2")
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ m["servicePrincipalName"] = MessageElement([],
+ FLAG_MOD_DELETE,
+ "servicePrincipalName")
ldb.modify(m)
- res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
- scope=SCOPE_BASE, attrs=["sAMAccountType"])
- self.assertTrue(len(res1) == 1)
- self.assertEquals(int(res1[0]["sAMAccountType"][0]),
- ATYPE_WORKSTATION_TRUST)
-
m = Message()
m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
- m["userAccountControl"] = MessageElement(
- str(UF_WORKSTATION_TRUST_ACCOUNT),
- FLAG_MOD_REPLACE, "userAccountControl")
+ m["dNSHostName"] = MessageElement("testname2.testdom2",
+ FLAG_MOD_REPLACE, "dNSHostName")
ldb.modify(m)
- res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
- scope=SCOPE_BASE, attrs=["sAMAccountType"])
- self.assertTrue(len(res1) == 1)
- self.assertEquals(int(res1[0]["sAMAccountType"][0]),
- ATYPE_WORKSTATION_TRUST)
+ res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE, attrs=["servicePrincipalName"])
+ self.assertTrue(len(res) == 1)
+ self.assertFalse("servicePrincipalName" in res[0])
-# This isn't supported yet in s4 - needs ACL module adaption
-# try:
-# m = Message()
-# m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
-# m["userAccountControl"] = MessageElement(
-# str(UF_INTERDOMAIN_TRUST_ACCOUNT),
-# FLAG_MOD_REPLACE, "userAccountControl")
-# ldb.modify(m)
-# self.fail()
-# except LdbError, (num, _):
-# self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS)
-
- self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
- self.delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
-
- def test_dNSHostName(self):
- """Test the dNSHostName behaviour"""
- print "Testing dNSHostName behaviour\n"
+ delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
ldb.add({
"dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
"objectclass": "computer",
- "dNSHostName": "testname.testdom"})
+ "sAMAccountName": "testname$"})
res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
- scope=SCOPE_BASE, attrs=["servicePrincipalName"])
+ scope=SCOPE_BASE, attrs=["servicePrincipalName"])
self.assertTrue(len(res) == 1)
self.assertFalse("servicePrincipalName" in res[0])
- self.delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
ldb.add({
"dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
"objectclass": "computer",
- "servicePrincipalName": "HOST/testname.testdom"})
+ "servicePrincipalName": "HOST/testname"})
res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
- scope=SCOPE_BASE, attrs=["dNSHostName"])
+ scope=SCOPE_BASE, attrs=["sAMAccountName"])
self.assertTrue(len(res) == 1)
- self.assertFalse("dNSHostName" in res[0])
+ self.assertTrue("sAMAccountName" in res[0])
- self.delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
ldb.add({
"dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
"objectclass": "computer",
- "dNSHostName": "testname2.testdom",
- "servicePrincipalName": "HOST/testname.testdom"})
+ "sAMAccountName": "testname$",
+ "servicePrincipalName": "HOST/testname"})
res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
- scope=SCOPE_BASE, attrs=["dNSHostName"])
+ scope=SCOPE_BASE, attrs=["sAMAccountName"])
self.assertTrue(len(res) == 1)
- self.assertEquals(res[0]["dNSHostName"][0], "testname2.testdom")
+ self.assertEquals(res[0]["sAMAccountName"][0], "testname$")
res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
- scope=SCOPE_BASE, attrs=["servicePrincipalName"])
+ scope=SCOPE_BASE, attrs=["servicePrincipalName"])
self.assertTrue(len(res) == 1)
self.assertEquals(res[0]["servicePrincipalName"][0],
- "HOST/testname.testdom")
+ "HOST/testname")
m = Message()
m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
- m["dNSHostName"] = MessageElement("testname.testdoM",
- FLAG_MOD_REPLACE, "dNSHostName")
+ m["sAMAccountName"] = MessageElement("testnamE$",
+ FLAG_MOD_REPLACE, "sAMAccountName")
ldb.modify(m)
res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
- scope=SCOPE_BASE, attrs=["servicePrincipalName"])
+ scope=SCOPE_BASE, attrs=["servicePrincipalName"])
self.assertTrue(len(res) == 1)
self.assertEquals(res[0]["servicePrincipalName"][0],
- "HOST/testname.testdom")
+ "HOST/testname")
m = Message()
m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
- m["dNSHostName"] = MessageElement("testname2.testdom2",
- FLAG_MOD_REPLACE, "dNSHostName")
+ m["sAMAccountName"] = MessageElement("testname",
+ FLAG_MOD_REPLACE, "sAMAccountName")
ldb.modify(m)
res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
- scope=SCOPE_BASE, attrs=["servicePrincipalName"])
+ scope=SCOPE_BASE, attrs=["servicePrincipalName"])
self.assertTrue(len(res) == 1)
self.assertEquals(res[0]["servicePrincipalName"][0],
- "HOST/testname2.testdom2")
+ "HOST/testname")
m = Message()
m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
- m["dNSHostName"] = MessageElement([],
- FLAG_MOD_DELETE, "dNSHostName")
+ m["sAMAccountName"] = MessageElement("test$name$",
+ FLAG_MOD_REPLACE, "sAMAccountName")
ldb.modify(m)
res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
- scope=SCOPE_BASE, attrs=["servicePrincipalName"])
+ scope=SCOPE_BASE, attrs=["servicePrincipalName"])
self.assertTrue(len(res) == 1)
self.assertEquals(res[0]["servicePrincipalName"][0],
- "HOST/testname2.testdom2")
+ "HOST/test$name")
m = Message()
m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
- m["dNSHostName"] = MessageElement("testname.testdom3",
- FLAG_MOD_REPLACE, "dNSHostName")
+ m["sAMAccountName"] = MessageElement("testname2",
+ FLAG_MOD_REPLACE, "sAMAccountName")
ldb.modify(m)
res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
- scope=SCOPE_BASE, attrs=["servicePrincipalName"])
+ scope=SCOPE_BASE, attrs=["servicePrincipalName"])
self.assertTrue(len(res) == 1)
self.assertEquals(res[0]["servicePrincipalName"][0],
- "HOST/testname2.testdom2")
-
- m = Message()
- m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
- m["dNSHostName"] = MessageElement("testname2.testdom2",
- FLAG_MOD_REPLACE, "dNSHostName")
- ldb.modify(m)
+ "HOST/testname2")
m = Message()
m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
- m["dNSHostName"] = MessageElement("testname3.testdom3",
- FLAG_MOD_REPLACE, "dNSHostName")
- m["servicePrincipalName"] = MessageElement("HOST/testname2.testdom2",
+ m["sAMAccountName"] = MessageElement("testname3",
+ FLAG_MOD_REPLACE, "sAMAccountName")
+ m["servicePrincipalName"] = MessageElement("HOST/testname2",
FLAG_MOD_REPLACE,
"servicePrincipalName")
ldb.modify(m)
res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
- scope=SCOPE_BASE, attrs=["servicePrincipalName"])
+ scope=SCOPE_BASE, attrs=["servicePrincipalName"])
self.assertTrue(len(res) == 1)
self.assertEquals(res[0]["servicePrincipalName"][0],
- "HOST/testname3.testdom3")
+ "HOST/testname3")
m = Message()
m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
- m["servicePrincipalName"] = MessageElement("HOST/testname2.testdom2",
+ m["servicePrincipalName"] = MessageElement("HOST/testname2",
FLAG_MOD_REPLACE,
"servicePrincipalName")
- m["dNSHostName"] = MessageElement("testname4.testdom4",
- FLAG_MOD_REPLACE, "dNSHostName")
+ m["sAMAccountName"] = MessageElement("testname4",
+ FLAG_MOD_REPLACE, "sAMAccountName")
ldb.modify(m)
res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
- scope=SCOPE_BASE, attrs=["servicePrincipalName"])
+ scope=SCOPE_BASE, attrs=["servicePrincipalName"])
self.assertTrue(len(res) == 1)
self.assertEquals(res[0]["servicePrincipalName"][0],
- "HOST/testname2.testdom2")
+ "HOST/testname2")
m = Message()
m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
m = Message()
m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
- m["dNSHostName"] = MessageElement("testname2.testdom2",
- FLAG_MOD_REPLACE, "dNSHostName")
+ m["sAMAccountName"] = MessageElement("testname2",
+ FLAG_MOD_REPLACE, "sAMAccountName")
ldb.modify(m)
res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
- scope=SCOPE_BASE, attrs=["servicePrincipalName"])
+ scope=SCOPE_BASE, attrs=["servicePrincipalName"])
self.assertTrue(len(res) == 1)
self.assertFalse("servicePrincipalName" in res[0])
- self.delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+
+ ldb.add({
+ "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ "objectclass": "computer",
+ "dNSHostName": "testname.testdom",
+ "sAMAccountName": "testname$",
+ "servicePrincipalName": [ "HOST/testname.testdom", "HOST/testname" ]
+ })
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ m["dNSHostName"] = MessageElement("testname2.testdom",
+ FLAG_MOD_REPLACE, "dNSHostName")
+ m["sAMAccountName"] = MessageElement("testname2$",
+ FLAG_MOD_REPLACE, "sAMAccountName")
+ ldb.modify(m)
+
+ res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE, attrs=["dNSHostName", "sAMAccountName", "servicePrincipalName"])
+ self.assertTrue(len(res) == 1)
+ self.assertEquals(res[0]["dNSHostName"][0], "testname2.testdom")
+ self.assertEquals(res[0]["sAMAccountName"][0], "testname2$")
+ self.assertTrue(res[0]["servicePrincipalName"][0] == "HOST/testname2" or
+ res[0]["servicePrincipalName"][1] == "HOST/testname2")
+ self.assertTrue(res[0]["servicePrincipalName"][0] == "HOST/testname2.testdom" or
+ res[0]["servicePrincipalName"][1] == "HOST/testname2.testdom")
+
+ delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+
+ ldb.add({
+ "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ "objectclass": "computer",
+ "dNSHostName": "testname.testdom",
+ "sAMAccountName": "testname$",
+ "servicePrincipalName": [ "HOST/testname.testdom", "HOST/testname" ]
+ })
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ m["sAMAccountName"] = MessageElement("testname2$",
+ FLAG_MOD_REPLACE, "sAMAccountName")
+ m["dNSHostName"] = MessageElement("testname2.testdom",
+ FLAG_MOD_REPLACE, "dNSHostName")
+ ldb.modify(m)
+
+ res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE, attrs=["dNSHostName", "sAMAccountName", "servicePrincipalName"])
+ self.assertTrue(len(res) == 1)
+ self.assertEquals(res[0]["dNSHostName"][0], "testname2.testdom")
+ self.assertEquals(res[0]["sAMAccountName"][0], "testname2$")
+ self.assertTrue(len(res[0]["servicePrincipalName"]) == 2)
+ self.assertTrue("HOST/testname2" in res[0]["servicePrincipalName"])
+ self.assertTrue("HOST/testname2.testdom" in res[0]["servicePrincipalName"])
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ m["servicePrincipalName"] = MessageElement("HOST/testname2.testdom",
+ FLAG_MOD_ADD, "servicePrincipalName")
+ try:
+ ldb.modify(m)
+ self.fail()
+ except LdbError as e77:
+ (num, _) = e77.args
+ self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ m["servicePrincipalName"] = MessageElement("HOST/testname3",
+ FLAG_MOD_ADD, "servicePrincipalName")
+ ldb.modify(m)
+
+ res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE, attrs=["dNSHostName", "sAMAccountName", "servicePrincipalName"])
+ self.assertTrue(len(res) == 1)
+ self.assertEquals(res[0]["dNSHostName"][0], "testname2.testdom")
+ self.assertEquals(res[0]["sAMAccountName"][0], "testname2$")
+ self.assertTrue(len(res[0]["servicePrincipalName"]) == 3)
+ self.assertTrue("HOST/testname2" in res[0]["servicePrincipalName"])
+ self.assertTrue("HOST/testname3" in res[0]["servicePrincipalName"])
+ self.assertTrue("HOST/testname2.testdom" in res[0]["servicePrincipalName"])
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+ m["dNSHostName"] = MessageElement("testname3.testdom",
+ FLAG_MOD_REPLACE, "dNSHostName")
+ m["servicePrincipalName"] = MessageElement("HOST/testname3.testdom",
+ FLAG_MOD_ADD, "servicePrincipalName")
+ ldb.modify(m)
+
+ res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
+ scope=SCOPE_BASE, attrs=["dNSHostName", "sAMAccountName", "servicePrincipalName"])
+ self.assertTrue(len(res) == 1)
+ self.assertEquals(res[0]["dNSHostName"][0], "testname3.testdom")
+ self.assertEquals(res[0]["sAMAccountName"][0], "testname2$")
+ self.assertTrue(len(res[0]["servicePrincipalName"]) == 3)
+ self.assertTrue("HOST/testname2" in res[0]["servicePrincipalName"])
+ self.assertTrue("HOST/testname3" in res[0]["servicePrincipalName"])
+ self.assertTrue("HOST/testname3.testdom" in res[0]["servicePrincipalName"])
+
+ delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
+
+ def test_sam_description_attribute(self):
+ """Test SAM description attribute"""
+ print("Test SAM 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")
+
+ 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"]})
+
+ 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 as e78:
+ (num, _) = e78.args
+ 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)
+
+ 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)
+ 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")
+
+ 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 as e79:
+ (num, _) = e79.args
+ 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")
+ try:
+ ldb.modify(m)
+ self.fail()
+ except LdbError as e80:
+ (num, _) = e80.args
+ 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)
+ 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")
+ try:
+ ldb.modify(m)
+ self.fail()
+ except LdbError as e81:
+ (num, _) = e81.args
+ 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 as e82:
+ (num, _) = e82.args
+ 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")
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+ m.add(MessageElement("desc1", FLAG_MOD_DELETE, "description"))
+ m.add(MessageElement("desc2", 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], "desc2")
+
+ delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+
+
+ def test_fSMORoleOwner_attribute(self):
+ """Test fSMORoleOwner attribute"""
+ print("Test fSMORoleOwner attribute")
+
+ ds_service_name = self.ldb.get_dsServiceName()
+
+ # The "fSMORoleOwner" attribute can only be set to "nTDSDSA" entries,
+ # invalid DNs return ERR_UNWILLING_TO_PERFORM
+
+ try:
+ self.ldb.add({
+ "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
+ "objectclass": "group",
+ "fSMORoleOwner": self.base_dn})
+ self.fail()
+ except LdbError as e83:
+ (num, _) = e83.args
+ self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+
+ try:
+ self.ldb.add({
+ "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
+ "objectclass": "group",
+ "fSMORoleOwner": [] })
+ self.fail()
+ except LdbError as e84:
+ (num, _) = e84.args
+ self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
+
+ # We are able to set it to a valid "nTDSDSA" entry if the server is
+ # capable of handling the role
+
+ self.ldb.add({
+ "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
+ "objectclass": "group",
+ "fSMORoleOwner": ds_service_name })
+
+ 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)
+ m.add(MessageElement(self.base_dn, FLAG_MOD_REPLACE, "fSMORoleOwner"))
+ try:
+ ldb.modify(m)
+ self.fail()
+ except LdbError as e85:
+ (num, _) = e85.args
+ self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+ m.add(MessageElement([], FLAG_MOD_REPLACE, "fSMORoleOwner"))
+ try:
+ ldb.modify(m)
+ self.fail()
+ except LdbError as e86:
+ (num, _) = e86.args
+ self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+
+ # We are able to set it to a valid "nTDSDSA" entry if the server is
+ # capable of handling the role
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+ m.add(MessageElement(ds_service_name, FLAG_MOD_REPLACE, "fSMORoleOwner"))
+ ldb.modify(m)
+
+ # A clean-out works on plain entries, not master (schema, PDC...) DNs
+
+ m = Message()
+ m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+ m.add(MessageElement([], FLAG_MOD_DELETE, "fSMORoleOwner"))
+ ldb.modify(m)
+
+ delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
+
+ def test_protected_sid_objects(self):
+ """Test deletion of objects with RID < 1000"""
+ # a list of some well-known sids
+ # objects in Builtin are aready covered by objectclass
+ protected_list = [
+ ["CN=Domain Admins","CN=Users,"],
+ ["CN=Schema Admins","CN=Users,"],
+ ["CN=Enterprise Admins","CN=Users,"],
+ ["CN=Administrator","CN=Users,"],
+ ["CN=Domain Controllers","CN=Users,"],
+ ]
+
+
+
+ for pr_object in protected_list:
+ try:
+ self.ldb.delete(pr_object[0] + "," + pr_object[1] + self.base_dn)
+ except LdbError as e7:
+ (num, _) = e7.args
+ self.assertEquals(num, ERR_OTHER)
+ else:
+ self.fail("Deleted " + pr_object[0])
+
+ try:
+ self.ldb.rename(pr_object[0] + "," + pr_object[1] + self.base_dn,
+ pr_object[0] + "2," + pr_object[1] + self.base_dn)
+ except LdbError as e8:
+ (num, _) = e8.args
+ self.fail("Could not rename " + pr_object[0])
+
+ self.ldb.rename(pr_object[0] + "2," + pr_object[1] + self.base_dn,
+ pr_object[0] + "," + pr_object[1] + self.base_dn)
+
+ def test_new_user_default_attributes(self):
+ """Test default attributes for new user objects"""
+ print("Test default attributes for new User objects\n")
+
+ user_name = "ldaptestuser"
+ user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
+ ldb.add({
+ "dn": user_dn,
+ "objectclass": "user",
+ "sAMAccountName": user_name})
+
+ res = ldb.search(user_dn, scope=SCOPE_BASE)
+ self.assertTrue(len(res) == 1)
+ user_obj = res[0]
+
+ expected_attrs = {"primaryGroupID": MessageElement(["513"]),
+ "logonCount": MessageElement(["0"]),
+ "cn": MessageElement([user_name]),
+ "countryCode": MessageElement(["0"]),
+ "objectClass": MessageElement(["top","person","organizationalPerson","user"]),
+ "instanceType": MessageElement(["4"]),
+ "distinguishedName": MessageElement([user_dn]),
+ "sAMAccountType": MessageElement(["805306368"]),
+ "objectSid": "**SKIP**",
+ "whenCreated": "**SKIP**",
+ "uSNCreated": "**SKIP**",
+ "badPasswordTime": MessageElement(["0"]),
+ "dn": Dn(ldb, user_dn),
+ "pwdLastSet": MessageElement(["0"]),
+ "sAMAccountName": MessageElement([user_name]),
+ "objectCategory": MessageElement(["CN=Person,%s" % ldb.get_schema_basedn().get_linearized()]),
+ "objectGUID": "**SKIP**",
+ "whenChanged": "**SKIP**",
+ "badPwdCount": MessageElement(["0"]),
+ "accountExpires": MessageElement(["9223372036854775807"]),
+ "name": MessageElement([user_name]),
+ "codePage": MessageElement(["0"]),
+ "userAccountControl": MessageElement(["546"]),
+ "lastLogon": MessageElement(["0"]),
+ "uSNChanged": "**SKIP**",
+ "lastLogoff": MessageElement(["0"])}
+ # assert we have expected attribute names
+ actual_names = set(user_obj.keys())
+ # Samba does not use 'dSCorePropagationData', so skip it
+ actual_names -= set(['dSCorePropagationData'])
+ self.assertEqual(set(expected_attrs.keys()), actual_names, "Actual object does not have expected attributes")
+ # check attribute values
+ for name in expected_attrs.keys():
+ actual_val = user_obj.get(name)
+ self.assertFalse(actual_val is None, "No value for attribute '%s'" % name)
+ expected_val = expected_attrs[name]
+ if expected_val == "**SKIP**":
+ # "**ANY**" values means "any"
+ continue
+ self.assertEqual(expected_val, actual_val,
+ "Unexpected value[%r] for '%s' expected[%r]" %
+ (actual_val, name, expected_val))
+ # clean up
+ delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
if not "://" in host:
else:
host = "ldap://%s" % host
-ldb = Ldb(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)
-else:
- gc_ldb = None
-
-runner = SubunitTestRunner()
-rc = 0
-if not runner.run(unittest.makeSuite(SamTests)).wasSuccessful():
- rc = 1
-sys.exit(rc)
+ldb = SamDB(host, credentials=creds, session_info=system_session(lp), lp=lp)
+
+TestProgram(module=__name__, opts=subunitopts)