mirror of
https://github.com/samba-team/samba.git
synced 2025-06-25 19:17:10 +03:00
This performs checks on direct password changes over LDB/LDAP. Indirect password changes over the RPCs are already tested by some torture suite (SAMR passwords). So no need to do this again here.
580 lines
18 KiB
Python
Executable File
580 lines
18 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
# This tests the password changes over LDAP for AD implementations
|
|
#
|
|
# Copyright Matthias Dieter Wallnoefer 2010
|
|
#
|
|
# Notice: This tests will also work against Windows Server if the connection is
|
|
# secured enough (SASL with a minimum of 128 Bit encryption) - consider
|
|
# MS-ADTS 3.1.1.3.1.5
|
|
#
|
|
# Important: Make sure that the minimum password age is set to "0"!
|
|
|
|
import optparse
|
|
import sys
|
|
import time
|
|
import base64
|
|
import os
|
|
|
|
sys.path.append("bin/python")
|
|
|
|
import samba.getopt as options
|
|
|
|
from samba.auth import system_session
|
|
from samba.credentials import Credentials
|
|
from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, 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
|
|
from ldb import Message, MessageElement, Dn
|
|
from ldb import FLAG_MOD_ADD, FLAG_MOD_REPLACE, FLAG_MOD_DELETE
|
|
from samba import gensec
|
|
from samba.samdb import SamDB
|
|
from subunit.run import SubunitTestRunner
|
|
import unittest
|
|
|
|
parser = optparse.OptionParser("passwords [options] <host>")
|
|
sambaopts = options.SambaOptions(parser)
|
|
parser.add_option_group(sambaopts)
|
|
parser.add_option_group(options.VersionOptions(parser))
|
|
# use command line creds if available
|
|
credopts = options.CredentialsOptions(parser)
|
|
parser.add_option_group(credopts)
|
|
opts, args = parser.parse_args()
|
|
|
|
if len(args) < 1:
|
|
parser.print_usage()
|
|
sys.exit(1)
|
|
|
|
host = args[0]
|
|
|
|
lp = sambaopts.get_loadparm()
|
|
creds = credopts.get_credentials(lp)
|
|
|
|
# Force an encrypted connection
|
|
creds.set_gensec_features(creds.get_gensec_features() | gensec.FEATURE_SEAL)
|
|
|
|
#
|
|
# Tests start here
|
|
#
|
|
|
|
class PasswordTests(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 setUp(self):
|
|
self.ldb = ldb
|
|
self.base_dn = self.find_basedn(ldb)
|
|
|
|
# (Re)adds the test user "testuser" with the inital password
|
|
# "thatsAcomplPASS1"
|
|
self.delete_force(self.ldb, "cn=testuser,cn=users," + self.base_dn)
|
|
self.ldb.add({
|
|
"dn": "cn=testuser,cn=users," + self.base_dn,
|
|
"objectclass": ["user", "person"],
|
|
"sAMAccountName": "testuser",
|
|
"userPassword": "thatsAcomplPASS1" })
|
|
ldb.enable_account("(cn=testuser)" + self.base_dn)
|
|
|
|
# Open a second LDB connection with the user credentials. Use the
|
|
# command line credentials for informations like the domain, the realm
|
|
# and the workstation.
|
|
creds2 = Credentials()
|
|
# FIXME: Reactivate the user credentials when we have user password
|
|
# change support also on the ACL level in s4
|
|
creds2.set_username(creds.get_username())
|
|
creds2.set_password(creds.get_password())
|
|
#creds2.set_username("testuser")
|
|
#creds2.set_password("thatsAcomplPASS1")
|
|
creds2.set_domain(creds.get_domain())
|
|
creds2.set_realm(creds.get_realm())
|
|
creds2.set_workstation(creds.get_workstation())
|
|
creds2.set_gensec_features(creds2.get_gensec_features()
|
|
| gensec.FEATURE_SEAL)
|
|
self.ldb2 = SamDB(url=host, credentials=creds2, lp=lp)
|
|
|
|
def test_unicodePwd_hash_set(self):
|
|
print "Performs a password hash set operation on 'unicodePwd' which should be prevented"
|
|
# Notice: Direct hash password sets should never work
|
|
|
|
m = Message()
|
|
m.dn = Dn(ldb, "cn=testuser,cn=users," + self.base_dn)
|
|
m["unicodePwd"] = MessageElement("XXXXXXXXXXXXXXXX", FLAG_MOD_REPLACE,
|
|
"unicodePwd")
|
|
try:
|
|
ldb.modify(m)
|
|
self.fail()
|
|
except LdbError, (num, _):
|
|
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
|
|
|
|
def test_unicodePwd_hash_change(self):
|
|
print "Performs a password hash change operation on 'unicodePwd' which should be prevented"
|
|
# Notice: Direct hash password changes should never work
|
|
|
|
# Hash password changes should never work
|
|
try:
|
|
self.ldb2.modify_ldif("""
|
|
dn: cn=testuser,cn=users,""" + self.base_dn + """
|
|
changetype: modify
|
|
delete: unicodePwd
|
|
unicodePwd: XXXXXXXXXXXXXXXX
|
|
add: unicodePwd
|
|
unicodePwd: YYYYYYYYYYYYYYYY
|
|
""")
|
|
self.fail()
|
|
except LdbError, (num, _):
|
|
self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
|
|
|
|
def test_unicodePwd_clear_set(self):
|
|
print "Performs a password cleartext set operation on 'unicodePwd'"
|
|
|
|
m = Message()
|
|
m.dn = Dn(ldb, "cn=testuser,cn=users," + self.base_dn)
|
|
m["unicodePwd"] = MessageElement("\"thatsAcomplPASS2\"".encode('utf-16-le'),
|
|
FLAG_MOD_REPLACE, "unicodePwd")
|
|
ldb.modify(m)
|
|
|
|
def test_unicodePwd_clear_change(self):
|
|
print "Performs a password cleartext change operation on 'unicodePwd'"
|
|
|
|
self.ldb2.modify_ldif("""
|
|
dn: cn=testuser,cn=users,""" + self.base_dn + """
|
|
changetype: modify
|
|
delete: unicodePwd
|
|
unicodePwd:: """ + base64.b64encode("\"thatsAcomplPASS1\"".encode('utf-16-le')) + """
|
|
add: unicodePwd
|
|
unicodePwd:: """ + base64.b64encode("\"thatsAcomplPASS2\"".encode('utf-16-le')) + """
|
|
""")
|
|
|
|
# A change to the same password again will not work (password history)
|
|
try:
|
|
self.ldb2.modify_ldif("""
|
|
dn: cn=testuser,cn=users,""" + self.base_dn + """
|
|
changetype: modify
|
|
delete: unicodePwd
|
|
unicodePwd:: """ + base64.b64encode("\"thatsAcomplPASS2\"".encode('utf-16-le')) + """
|
|
add: unicodePwd
|
|
unicodePwd:: """ + base64.b64encode("\"thatsAcomplPASS2\"".encode('utf-16-le')) + """
|
|
""")
|
|
self.fail()
|
|
except LdbError, (num, _):
|
|
self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
|
|
|
|
def test_dBCSPwd_hash_set(self):
|
|
print "Performs a password hash set operation on 'dBCSPwd' which should be prevented"
|
|
# Notice: Direct hash password sets should never work
|
|
|
|
m = Message()
|
|
m.dn = Dn(ldb, "cn=testuser,cn=users," + self.base_dn)
|
|
m["dBCSPwd"] = MessageElement("XXXXXXXXXXXXXXXX", FLAG_MOD_REPLACE,
|
|
"dBCSPwd")
|
|
try:
|
|
ldb.modify(m)
|
|
self.fail()
|
|
except LdbError, (num, _):
|
|
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
|
|
|
|
def test_dBCSPwd_hash_change(self):
|
|
print "Performs a password hash change operation on 'dBCSPwd' which should be prevented"
|
|
# Notice: Direct hash password changes should never work
|
|
|
|
try:
|
|
self.ldb2.modify_ldif("""
|
|
dn: cn=testuser,cn=users,""" + self.base_dn + """
|
|
changetype: modify
|
|
delete: dBCSPwd
|
|
dBCSPwd: XXXXXXXXXXXXXXXX
|
|
add: dBCSPwd
|
|
dBCSPwd: YYYYYYYYYYYYYYYY
|
|
""")
|
|
self.fail()
|
|
except LdbError, (num, _):
|
|
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
|
|
|
|
def test_userPassword_clear_set(self):
|
|
print "Performs a password cleartext set operation on 'userPassword'"
|
|
# Notice: This works only against Windows if "dSHeuristics" has been set
|
|
# properly
|
|
|
|
m = Message()
|
|
m.dn = Dn(ldb, "cn=testuser,cn=users," + self.base_dn)
|
|
m["userPassword"] = MessageElement("thatsAcomplPASS2", FLAG_MOD_REPLACE,
|
|
"userPassword")
|
|
ldb.modify(m)
|
|
|
|
def test_userPassword_clear_change(self):
|
|
print "Performs a password cleartext change operation on 'userPassword'"
|
|
# Notice: This works only against Windows if "dSHeuristics" has been set
|
|
# properly
|
|
|
|
self.ldb2.modify_ldif("""
|
|
dn: cn=testuser,cn=users,""" + self.base_dn + """
|
|
changetype: modify
|
|
delete: userPassword
|
|
userPassword: thatsAcomplPASS1
|
|
add: userPassword
|
|
userPassword: thatsAcomplPASS2
|
|
""")
|
|
|
|
# A change to the same password again will not work (password history)
|
|
try:
|
|
self.ldb2.modify_ldif("""
|
|
dn: cn=testuser,cn=users,""" + self.base_dn + """
|
|
changetype: modify
|
|
delete: userPassword
|
|
userPassword: thatsAcomplPASS2
|
|
add: userPassword
|
|
userPassword: thatsAcomplPASS2
|
|
""")
|
|
self.fail()
|
|
except LdbError, (num, _):
|
|
self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
|
|
|
|
def test_clearTextPassword_clear_set(self):
|
|
print "Performs a password cleartext set operation on 'clearTextPassword'"
|
|
# Notice: This never works against Windows - only supported by us
|
|
|
|
try:
|
|
m = Message()
|
|
m.dn = Dn(ldb, "cn=testuser,cn=users," + self.base_dn)
|
|
m["clearTextPassword"] = MessageElement("thatsAcomplPASS2".encode('utf-16-le'),
|
|
FLAG_MOD_REPLACE, "clearTextPassword")
|
|
ldb.modify(m)
|
|
# this passes against s4
|
|
except LdbError, (num, msg):
|
|
# "NO_SUCH_ATTRIBUTE" is returned by Windows -> ignore it
|
|
if num != ERR_NO_SUCH_ATTRIBUTE:
|
|
raise LdbError(num, msg)
|
|
|
|
def test_clearTextPassword_clear_change(self):
|
|
print "Performs a password cleartext change operation on 'clearTextPassword'"
|
|
# Notice: This never works against Windows - only supported by us
|
|
|
|
try:
|
|
self.ldb2.modify_ldif("""
|
|
dn: cn=testuser,cn=users,""" + self.base_dn + """
|
|
changetype: modify
|
|
delete: clearTextPassword
|
|
clearTextPassword:: """ + base64.b64encode("thatsAcomplPASS1".encode('utf-16-le')) + """
|
|
add: clearTextPassword
|
|
clearTextPassword:: """ + base64.b64encode("thatsAcomplPASS2".encode('utf-16-le')) + """
|
|
""")
|
|
# this passes against s4
|
|
except LdbError, (num, msg):
|
|
# "NO_SUCH_ATTRIBUTE" is returned by Windows -> ignore it
|
|
if num != ERR_NO_SUCH_ATTRIBUTE:
|
|
raise LdbError(num, msg)
|
|
|
|
# A change to the same password again will not work (password history)
|
|
try:
|
|
self.ldb2.modify_ldif("""
|
|
dn: cn=testuser,cn=users,""" + self.base_dn + """
|
|
changetype: modify
|
|
delete: clearTextPassword
|
|
clearTextPassword:: """ + base64.b64encode("thatsAcomplPASS2".encode('utf-16-le')) + """
|
|
add: clearTextPassword
|
|
clearTextPassword:: """ + base64.b64encode("thatsAcomplPASS2".encode('utf-16-le')) + """
|
|
""")
|
|
self.fail()
|
|
except LdbError, (num, _):
|
|
# "NO_SUCH_ATTRIBUTE" is returned by Windows -> ignore it
|
|
if num != ERR_NO_SUCH_ATTRIBUTE:
|
|
self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
|
|
|
|
def test_failures(self):
|
|
print "Performs some failure testing"
|
|
|
|
try:
|
|
ldb.modify_ldif("""
|
|
dn: cn=testuser,cn=users,""" + self.base_dn + """
|
|
changetype: modify
|
|
delete: userPassword
|
|
userPassword: thatsAcomplPASS1
|
|
""")
|
|
self.fail()
|
|
except LdbError, (num, _):
|
|
self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
|
|
|
|
try:
|
|
self.ldb2.modify_ldif("""
|
|
dn: cn=testuser,cn=users,""" + self.base_dn + """
|
|
changetype: modify
|
|
delete: userPassword
|
|
""")
|
|
self.fail()
|
|
except LdbError, (num, _):
|
|
self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
|
|
|
|
try:
|
|
ldb.modify_ldif("""
|
|
dn: cn=testuser,cn=users,""" + self.base_dn + """
|
|
changetype: modify
|
|
add: userPassword
|
|
userPassword: thatsAcomplPASS1
|
|
""")
|
|
self.fail()
|
|
except LdbError, (num, _):
|
|
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
|
|
|
|
try:
|
|
self.ldb2.modify_ldif("""
|
|
dn: cn=testuser,cn=users,""" + self.base_dn + """
|
|
changetype: modify
|
|
add: userPassword
|
|
userPassword: thatsAcomplPASS1
|
|
""")
|
|
self.fail()
|
|
except LdbError, (num, _):
|
|
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
|
|
|
|
try:
|
|
ldb.modify_ldif("""
|
|
dn: cn=testuser,cn=users,""" + self.base_dn + """
|
|
changetype: modify
|
|
delete: userPassword
|
|
userPassword: thatsAcomplPASS1
|
|
add: userPassword
|
|
userPassword: thatsAcomplPASS2
|
|
userPassword: thatsAcomplPASS2
|
|
""")
|
|
self.fail()
|
|
except LdbError, (num, _):
|
|
self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
|
|
|
|
try:
|
|
self.ldb2.modify_ldif("""
|
|
dn: cn=testuser,cn=users,""" + self.base_dn + """
|
|
changetype: modify
|
|
delete: userPassword
|
|
userPassword: thatsAcomplPASS1
|
|
add: userPassword
|
|
userPassword: thatsAcomplPASS2
|
|
userPassword: thatsAcomplPASS2
|
|
""")
|
|
self.fail()
|
|
except LdbError, (num, _):
|
|
self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
|
|
|
|
try:
|
|
ldb.modify_ldif("""
|
|
dn: cn=testuser,cn=users,""" + self.base_dn + """
|
|
changetype: modify
|
|
delete: userPassword
|
|
userPassword: thatsAcomplPASS1
|
|
userPassword: thatsAcomplPASS1
|
|
add: userPassword
|
|
userPassword: thatsAcomplPASS2
|
|
""")
|
|
self.fail()
|
|
except LdbError, (num, _):
|
|
self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
|
|
|
|
try:
|
|
self.ldb2.modify_ldif("""
|
|
dn: cn=testuser,cn=users,""" + self.base_dn + """
|
|
changetype: modify
|
|
delete: userPassword
|
|
userPassword: thatsAcomplPASS1
|
|
userPassword: thatsAcomplPASS1
|
|
add: userPassword
|
|
userPassword: thatsAcomplPASS2
|
|
""")
|
|
self.fail()
|
|
except LdbError, (num, _):
|
|
self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
|
|
|
|
try:
|
|
ldb.modify_ldif("""
|
|
dn: cn=testuser,cn=users,""" + self.base_dn + """
|
|
changetype: modify
|
|
delete: userPassword
|
|
userPassword: thatsAcomplPASS1
|
|
add: userPassword
|
|
userPassword: thatsAcomplPASS2
|
|
add: userPassword
|
|
userPassword: thatsAcomplPASS2
|
|
""")
|
|
self.fail()
|
|
except LdbError, (num, _):
|
|
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
|
|
|
|
try:
|
|
self.ldb2.modify_ldif("""
|
|
dn: cn=testuser,cn=users,""" + self.base_dn + """
|
|
changetype: modify
|
|
delete: userPassword
|
|
userPassword: thatsAcomplPASS1
|
|
add: userPassword
|
|
userPassword: thatsAcomplPASS2
|
|
add: userPassword
|
|
userPassword: thatsAcomplPASS2
|
|
""")
|
|
self.fail()
|
|
except LdbError, (num, _):
|
|
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
|
|
|
|
try:
|
|
ldb.modify_ldif("""
|
|
dn: cn=testuser,cn=users,""" + self.base_dn + """
|
|
changetype: modify
|
|
delete: userPassword
|
|
userPassword: thatsAcomplPASS1
|
|
delete: userPassword
|
|
userPassword: thatsAcomplPASS1
|
|
add: userPassword
|
|
userPassword: thatsAcomplPASS2
|
|
""")
|
|
self.fail()
|
|
except LdbError, (num, _):
|
|
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
|
|
|
|
try:
|
|
self.ldb2.modify_ldif("""
|
|
dn: cn=testuser,cn=users,""" + self.base_dn + """
|
|
changetype: modify
|
|
delete: userPassword
|
|
userPassword: thatsAcomplPASS1
|
|
delete: userPassword
|
|
userPassword: thatsAcomplPASS1
|
|
add: userPassword
|
|
userPassword: thatsAcomplPASS2
|
|
""")
|
|
self.fail()
|
|
except LdbError, (num, _):
|
|
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
|
|
|
|
try:
|
|
ldb.modify_ldif("""
|
|
dn: cn=testuser,cn=users,""" + self.base_dn + """
|
|
changetype: modify
|
|
delete: userPassword
|
|
userPassword: thatsAcomplPASS1
|
|
add: userPassword
|
|
userPassword: thatsAcomplPASS2
|
|
replace: userPassword
|
|
userPassword: thatsAcomplPASS3
|
|
""")
|
|
self.fail()
|
|
except LdbError, (num, _):
|
|
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
|
|
|
|
try:
|
|
self.ldb2.modify_ldif("""
|
|
dn: cn=testuser,cn=users,""" + self.base_dn + """
|
|
changetype: modify
|
|
delete: userPassword
|
|
userPassword: thatsAcomplPASS1
|
|
add: userPassword
|
|
userPassword: thatsAcomplPASS2
|
|
replace: userPassword
|
|
userPassword: thatsAcomplPASS3
|
|
""")
|
|
self.fail()
|
|
except LdbError, (num, _):
|
|
self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
|
|
|
|
# Reverse order does work
|
|
self.ldb2.modify_ldif("""
|
|
dn: cn=testuser,cn=users,""" + self.base_dn + """
|
|
changetype: modify
|
|
add: userPassword
|
|
userPassword: thatsAcomplPASS2
|
|
delete: userPassword
|
|
userPassword: thatsAcomplPASS1
|
|
""")
|
|
|
|
try:
|
|
self.ldb2.modify_ldif("""
|
|
dn: cn=testuser,cn=users,""" + self.base_dn + """
|
|
changetype: modify
|
|
delete: userPassword
|
|
userPassword: thatsAcomplPASS2
|
|
add: unicodePwd
|
|
unicodePwd:: """ + base64.b64encode("\"thatsAcomplPASS3\"".encode('utf-16-le')) + """
|
|
""")
|
|
# this passes against s4
|
|
except LdbError, (num, _):
|
|
self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
|
|
|
|
try:
|
|
self.ldb2.modify_ldif("""
|
|
dn: cn=testuser,cn=users,""" + self.base_dn + """
|
|
changetype: modify
|
|
delete: unicodePwd
|
|
unicodePwd:: """ + base64.b64encode("\"thatsAcomplPASS3\"".encode('utf-16-le')) + """
|
|
add: userPassword
|
|
userPassword: thatsAcomplPASS4
|
|
""")
|
|
# this passes against s4
|
|
except LdbError, (num, _):
|
|
self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
|
|
|
|
# Several password changes at once are allowed
|
|
ldb.modify_ldif("""
|
|
dn: cn=testuser,cn=users,""" + self.base_dn + """
|
|
changetype: modify
|
|
replace: userPassword
|
|
userPassword: thatsAcomplPASS1
|
|
userPassword: thatsAcomplPASS2
|
|
""")
|
|
|
|
# Several password changes at once are allowed
|
|
ldb.modify_ldif("""
|
|
dn: cn=testuser,cn=users,""" + self.base_dn + """
|
|
changetype: modify
|
|
replace: userPassword
|
|
userPassword: thatsAcomplPASS1
|
|
userPassword: thatsAcomplPASS2
|
|
replace: userPassword
|
|
userPassword: thatsAcomplPASS3
|
|
replace: userPassword
|
|
userPassword: thatsAcomplPASS4
|
|
""")
|
|
|
|
# This surprisingly should work
|
|
self.delete_force(self.ldb, "cn=testuser2,cn=users," + self.base_dn)
|
|
self.ldb.add({
|
|
"dn": "cn=testuser2,cn=users," + self.base_dn,
|
|
"objectclass": ["user", "person"],
|
|
"userPassword": ["thatsAcomplPASS1", "thatsAcomplPASS2"] })
|
|
|
|
# This surprisingly should work
|
|
self.delete_force(self.ldb, "cn=testuser2,cn=users," + self.base_dn)
|
|
self.ldb.add({
|
|
"dn": "cn=testuser2,cn=users," + self.base_dn,
|
|
"objectclass": ["user", "person"],
|
|
"userPassword": ["thatsAcomplPASS1", "thatsAcomplPASS1"] })
|
|
|
|
def tearDown(self):
|
|
self.delete_force(self.ldb, "cn=testuser,cn=users," + self.base_dn)
|
|
self.delete_force(self.ldb, "cn=testuser2,cn=users," + self.base_dn)
|
|
# Close the second LDB connection (with the user credentials)
|
|
self.ldb2 = None
|
|
|
|
if not "://" in host:
|
|
if os.path.isfile(host):
|
|
host = "tdb://%s" % host
|
|
else:
|
|
host = "ldap://%s" % host
|
|
|
|
ldb = SamDB(url=host, session_info=system_session(), credentials=creds, lp=lp)
|
|
|
|
runner = SubunitTestRunner()
|
|
rc = 0
|
|
if not runner.run(unittest.makeSuite(PasswordTests)).wasSuccessful():
|
|
rc = 1
|
|
sys.exit(rc)
|