2018-12-12 03:40:43 +03:00
#!/usr/bin/env python3
2010-04-10 22:04:13 +04:00
# -*- 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
import optparse
import sys
import base64
2010-11-09 17:04:47 +03:00
import time
2010-04-10 22:04:13 +04:00
import os
2011-02-01 06:43:34 +03:00
sys . path . insert ( 0 , " bin/python " )
2014-11-02 20:13:06 +03:00
from samba . tests . subunitrun import SubunitOptions , TestProgram
2018-05-11 02:03:03 +03:00
from samba . tests . password_test import PasswordTestCase
2010-04-10 22:04:13 +04:00
import samba . getopt as options
from samba . auth import system_session
from samba . credentials import Credentials
2022-09-16 02:42:48 +03:00
from samba . dcerpc import security
2024-01-11 06:23:55 +03:00
from samba . hresult import HRES_SEC_E_INVALID_TOKEN
2010-06-19 19:48:37 +04:00
from ldb import SCOPE_BASE , LdbError
2011-01-06 14:40:07 +03:00
from ldb import ERR_ATTRIBUTE_OR_VALUE_EXISTS
2010-07-01 19:23:01 +04:00
from ldb import ERR_UNWILLING_TO_PERFORM , ERR_INSUFFICIENT_ACCESS_RIGHTS
2010-04-10 22:04:13 +04:00
from ldb import ERR_NO_SUCH_ATTRIBUTE
2010-06-19 19:48:37 +04:00
from ldb import ERR_CONSTRAINT_VIOLATION
2022-04-11 07:43:42 +03:00
from ldb import ERR_INVALID_CREDENTIALS
2010-04-10 22:04:13 +04:00
from ldb import Message , MessageElement , Dn
2010-11-01 21:54:07 +03:00
from ldb import FLAG_MOD_ADD , FLAG_MOD_REPLACE , FLAG_MOD_DELETE
2022-09-16 02:42:48 +03:00
from samba import gensec , werror
2010-04-10 22:04:13 +04:00
from samba . samdb import SamDB
2010-11-25 02:13:47 +03:00
from samba . tests import delete_force
2010-04-10 22:04:13 +04:00
2010-11-10 15:35:30 +03:00
parser = optparse . OptionParser ( " passwords.py [options] <host> " )
2010-04-10 22:04:13 +04:00
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 )
2014-11-02 20:13:06 +03:00
subunitopts = SubunitOptions ( parser )
parser . add_option_group ( subunitopts )
2010-04-10 22:04:13 +04:00
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
#
2018-07-30 09:20:39 +03:00
2018-05-11 02:03:03 +03:00
class PasswordTests ( PasswordTestCase ) :
2010-06-19 19:48:37 +04:00
2010-04-10 22:04:13 +04:00
def setUp ( self ) :
2010-06-19 20:58:18 +04:00
super ( PasswordTests , self ) . setUp ( )
2014-11-02 20:13:06 +03:00
self . ldb = SamDB ( url = host , session_info = system_session ( lp ) , credentials = creds , lp = lp )
2018-05-11 02:03:03 +03:00
# permit password changes during this test
self . allow_password_changes ( )
2014-11-02 20:13:06 +03:00
self . base_dn = self . ldb . domain_dn ( )
2010-08-14 13:59:47 +04:00
# (Re)adds the test user "testuser" with no password atm
2010-11-25 02:13:47 +03:00
delete_force ( self . ldb , " cn=testuser,cn=users, " + self . base_dn )
2010-04-10 22:04:13 +04:00
self . ldb . add ( {
" dn " : " cn=testuser,cn=users, " + self . base_dn ,
2010-11-01 19:23:34 +03:00
" objectclass " : " user " ,
2010-08-14 13:59:47 +04:00
" sAMAccountName " : " testuser " } )
2010-08-15 12:02:43 +04:00
# Tests a password change when we don't have any password yet with a
# wrong old password
2010-08-14 13:59:47 +04:00
try :
self . ldb . modify_ldif ( """
dn : cn = testuser , cn = users , """ + self.base_dn + """
changetype : modify
delete : userPassword
2010-08-15 20:19:52 +04:00
userPassword : noPassword
2010-08-14 13:59:47 +04:00
add : userPassword
userPassword : thatsAcomplPASS2
""" )
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e :
( num , msg ) = e . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_CONSTRAINT_VIOLATION )
2010-08-15 20:19:52 +04:00
# Windows (2008 at least) seems to have some small bug here: it
# returns "0000056A" on longer (always wrong) previous passwords.
self . assertTrue ( ' 00000056 ' in msg )
2010-08-14 13:59:47 +04:00
2010-08-15 12:02:43 +04:00
# Sets the initial user password with a "special" password change
# I think that this internally is a password set operation and it can
# only be performed by someone which has password set privileges on the
# account (at least in s4 we do handle it like that).
2010-08-14 13:59:47 +04:00
self . ldb . modify_ldif ( """
dn : cn = testuser , cn = users , """ + self.base_dn + """
changetype : modify
2010-08-15 12:02:43 +04:00
delete : userPassword
add : userPassword
2010-08-14 13:59:47 +04:00
userPassword : thatsAcomplPASS1
""" )
2010-08-15 12:02:43 +04:00
# But in the other way around this special syntax doesn't work
try :
self . ldb . modify_ldif ( """
dn : cn = testuser , cn = users , """ + self.base_dn + """
changetype : modify
delete : userPassword
userPassword : thatsAcomplPASS1
add : userPassword
""" )
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e1 :
( num , _ ) = e1 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_CONSTRAINT_VIOLATION )
2010-08-15 12:02:43 +04:00
# Enables the user account
2010-06-11 12:04:19 +04:00
self . ldb . enable_account ( " (sAMAccountName=testuser) " )
2010-04-10 22:04:13 +04:00
# Open a second LDB connection with the user credentials. Use the
2019-03-25 17:02:45 +03:00
# command line credentials for information like the domain, the realm
2010-04-10 22:04:13 +04:00
# and the workstation.
creds2 = Credentials ( )
2010-07-05 01:20:37 +04:00
creds2 . set_username ( " testuser " )
creds2 . set_password ( " thatsAcomplPASS1 " )
2010-04-10 22:04:13 +04:00
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 ( )
2018-07-30 09:15:34 +03:00
| gensec . FEATURE_SEAL )
2010-04-10 22:04:13 +04:00
self . ldb2 = SamDB ( url = host , credentials = creds2 , lp = lp )
2022-04-11 07:43:42 +03:00
self . creds = creds2
2010-04-10 22:04:13 +04:00
def test_unicodePwd_hash_set ( self ) :
2014-11-02 20:13:06 +03:00
""" Performs a password hash set operation on ' unicodePwd ' which should be prevented """
2010-04-10 22:04:13 +04:00
# Notice: Direct hash password sets should never work
m = Message ( )
2014-11-02 20:13:06 +03:00
m . dn = Dn ( self . ldb , " cn=testuser,cn=users, " + self . base_dn )
2010-04-10 22:04:13 +04:00
m [ " unicodePwd " ] = MessageElement ( " XXXXXXXXXXXXXXXX " , FLAG_MOD_REPLACE ,
2018-07-30 09:16:12 +03:00
" unicodePwd " )
2010-04-10 22:04:13 +04:00
try :
2014-11-02 20:13:06 +03:00
self . ldb . modify ( m )
2010-04-10 22:04:13 +04:00
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e2 :
( num , _ ) = e2 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_UNWILLING_TO_PERFORM )
2010-04-10 22:04:13 +04:00
def test_unicodePwd_hash_change ( self ) :
2014-11-02 20:13:06 +03:00
""" Performs a password hash change operation on ' unicodePwd ' which should be prevented """
2010-04-10 22:04:13 +04:00
# 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 ( )
2018-02-23 17:34:23 +03:00
except LdbError as e3 :
( num , _ ) = e3 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_CONSTRAINT_VIOLATION )
2010-04-10 22:04:13 +04:00
def test_unicodePwd_clear_set ( self ) :
2014-11-02 20:13:06 +03:00
""" Performs a password cleartext set operation on ' unicodePwd ' """
2010-04-10 22:04:13 +04:00
m = Message ( )
2014-11-02 20:13:06 +03:00
m . dn = Dn ( self . ldb , " cn=testuser,cn=users, " + self . base_dn )
2010-04-10 22:04:13 +04:00
m [ " unicodePwd " ] = MessageElement ( " \" thatsAcomplPASS2 \" " . encode ( ' utf-16-le ' ) ,
2018-07-30 09:16:12 +03:00
FLAG_MOD_REPLACE , " unicodePwd " )
2014-11-02 20:13:06 +03:00
self . ldb . modify ( m )
2010-04-10 22:04:13 +04:00
def test_unicodePwd_clear_change ( self ) :
2014-11-02 20:13:06 +03:00
""" Performs a password cleartext change operation on ' unicodePwd ' """
2010-04-10 22:04:13 +04:00
self . ldb2 . modify_ldif ( """
dn : cn = testuser , cn = users , """ + self.base_dn + """
changetype : modify
delete : unicodePwd
2018-05-04 17:27:12 +03:00
unicodePwd : : """ + base64.b64encode( " \" thatsAcomplPASS1 \" " .encode( ' utf-16-le ' )).decode( ' utf8 ' ) + """
2010-04-10 22:04:13 +04:00
add : unicodePwd
2018-05-04 17:27:12 +03:00
unicodePwd : : """ + base64.b64encode( " \" thatsAcomplPASS2 \" " .encode( ' utf-16-le ' )).decode( ' utf8 ' ) + """
2010-04-10 22:04:13 +04:00
""" )
2010-08-14 12:46:38 +04:00
# Wrong old password
try :
self . ldb2 . modify_ldif ( """
dn : cn = testuser , cn = users , """ + self.base_dn + """
changetype : modify
delete : unicodePwd
2018-05-04 17:27:12 +03:00
unicodePwd : : """ + base64.b64encode( " \" thatsAcomplPASS3 \" " .encode( ' utf-16-le ' )).decode( ' utf8 ' ) + """
2010-08-14 12:46:38 +04:00
add : unicodePwd
2018-05-04 17:27:12 +03:00
unicodePwd : : """ + base64.b64encode( " \" thatsAcomplPASS4 \" " .encode( ' utf-16-le ' )).decode( ' utf8 ' ) + """
2010-08-14 12:46:38 +04:00
""" )
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e4 :
( num , msg ) = e4 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_CONSTRAINT_VIOLATION )
2010-08-15 20:19:52 +04:00
self . assertTrue ( ' 00000056 ' in msg )
2010-08-14 12:46:38 +04:00
2010-04-10 22:04:13 +04:00
# 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
2018-05-04 17:27:12 +03:00
unicodePwd : : """ + base64.b64encode( " \" thatsAcomplPASS2 \" " .encode( ' utf-16-le ' )).decode( ' utf8 ' ) + """
2010-04-10 22:04:13 +04:00
add : unicodePwd
2018-05-04 17:27:12 +03:00
unicodePwd : : """ + base64.b64encode( " \" thatsAcomplPASS2 \" " .encode( ' utf-16-le ' )).decode( ' utf8 ' ) + """
2010-04-10 22:04:13 +04:00
""" )
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e5 :
( num , msg ) = e5 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_CONSTRAINT_VIOLATION )
2010-08-15 20:19:52 +04:00
self . assertTrue ( ' 0000052D ' in msg )
2010-04-10 22:04:13 +04:00
2022-04-11 07:43:42 +03:00
def test_old_password_simple_bind ( self ) :
2023-11-28 05:11:12 +03:00
""" Shows that we can log in with the immediate previous password, but not any earlier passwords. """
2022-04-11 07:43:42 +03:00
user_dn_str = f ' CN=testuser,CN=Users, { self . base_dn } '
user_dn = Dn ( self . ldb , user_dn_str )
# Change the account password.
m = Message ( user_dn )
m [ ' 0 ' ] = MessageElement ( self . creds . get_password ( ) ,
FLAG_MOD_DELETE , ' userPassword ' )
m [ ' 1 ' ] = MessageElement ( ' Password#2 ' ,
FLAG_MOD_ADD , ' userPassword ' )
self . ldb . modify ( m )
# Show we can still log in using the previous password.
self . creds . set_bind_dn ( user_dn_str )
try :
SamDB ( url = host_ldaps ,
credentials = self . creds , lp = lp )
except LdbError :
self . fail ( ' failed to login with previous password! ' )
# Change the account password a second time.
m = Message ( user_dn )
m [ ' 0 ' ] = MessageElement ( ' Password#2 ' ,
FLAG_MOD_DELETE , ' userPassword ' )
m [ ' 1 ' ] = MessageElement ( ' Password#3 ' ,
FLAG_MOD_ADD , ' userPassword ' )
self . ldb . modify ( m )
# Show we can no longer log in using the original password.
try :
SamDB ( url = host_ldaps ,
credentials = self . creds , lp = lp )
except LdbError as err :
num , estr = err . args
self . assertEqual ( ERR_INVALID_CREDENTIALS , num )
2023-11-29 06:00:13 +03:00
self . assertIn ( f " { HRES_SEC_E_INVALID_TOKEN : 08X } " , estr )
2022-04-11 07:43:42 +03:00
else :
self . fail ( ' should have failed to login with previous password! ' )
def test_old_password_attempt_reuse ( self ) :
2023-11-28 05:11:12 +03:00
""" Shows that we cannot reuse the original password after changing the password twice. """
2022-04-11 07:43:42 +03:00
res = self . ldb . search ( self . ldb . domain_dn ( ) , scope = SCOPE_BASE ,
attrs = [ ' pwdHistoryLength ' ] )
history_len = int ( res [ 0 ] . get ( ' pwdHistoryLength ' , idx = 0 ) )
self . assertGreaterEqual ( history_len , 3 )
user_dn_str = f ' CN=testuser,CN=Users, { self . base_dn } '
user_dn = Dn ( self . ldb , user_dn_str )
first_pwd = self . creds . get_password ( )
previous_pwd = first_pwd
for new_pwd in [ ' Password#0 ' , ' Password#1 ' ] :
# Change the account password.
m = Message ( user_dn )
m [ ' 0 ' ] = MessageElement ( previous_pwd ,
FLAG_MOD_DELETE , ' userPassword ' )
m [ ' 1 ' ] = MessageElement ( new_pwd ,
FLAG_MOD_ADD , ' userPassword ' )
self . ldb . modify ( m )
# Show that the original password is in the history by trying to
# set it as our new password.
m = Message ( user_dn )
m [ ' 0 ' ] = MessageElement ( new_pwd ,
FLAG_MOD_DELETE , ' userPassword ' )
m [ ' 1 ' ] = MessageElement ( first_pwd ,
FLAG_MOD_ADD , ' userPassword ' )
try :
self . ldb . modify ( m )
except LdbError as err :
num , estr = err . args
self . assertEqual ( ERR_CONSTRAINT_VIOLATION , num )
self . assertIn ( f ' { werror . WERR_PASSWORD_RESTRICTION : 08X } ' , estr )
else :
self . fail ( ' should not have been able to reuse password! ' )
previous_pwd = new_pwd
def test_old_password_rename_simple_bind ( self ) :
2023-11-28 05:11:12 +03:00
""" Shows that we can log in with the previous password after renaming the account. """
2022-04-11 07:43:42 +03:00
user_dn_str = f ' CN=testuser,CN=Users, { self . base_dn } '
user_dn = Dn ( self . ldb , user_dn_str )
# Change the account password.
m = Message ( user_dn )
m [ ' 0 ' ] = MessageElement ( self . creds . get_password ( ) ,
FLAG_MOD_DELETE , ' userPassword ' )
m [ ' 1 ' ] = MessageElement ( ' Password#2 ' ,
FLAG_MOD_ADD , ' userPassword ' )
self . ldb . modify ( m )
# Show we can still log in using the previous password.
self . creds . set_bind_dn ( user_dn_str )
try :
SamDB ( url = host_ldaps ,
credentials = self . creds , lp = lp )
except LdbError :
self . fail ( ' failed to login with previous password! ' )
# Rename the account, causing the salt to change.
m = Message ( user_dn )
m [ ' 1 ' ] = MessageElement ( ' testuser_2 ' ,
FLAG_MOD_REPLACE , ' sAMAccountName ' )
self . ldb . modify ( m )
# Show that a simple bind can still be performed using the previous
# password.
self . creds . set_username ( ' testuser_2 ' )
try :
SamDB ( url = host_ldaps ,
credentials = self . creds , lp = lp )
except LdbError :
self . fail ( ' failed to login with previous password! ' )
def test_old_password_rename_simple_bind_2 ( self ) :
2023-11-28 05:11:12 +03:00
""" Shows that we can rename the account, change the password and log in with the previous password. """
2022-04-11 07:43:42 +03:00
user_dn_str = f ' CN=testuser,CN=Users, { self . base_dn } '
user_dn = Dn ( self . ldb , user_dn_str )
# Rename the account, causing the salt to change.
m = Message ( user_dn )
m [ ' 1 ' ] = MessageElement ( ' testuser_2 ' ,
FLAG_MOD_REPLACE , ' sAMAccountName ' )
self . ldb . modify ( m )
# Change the account password, causing the new salt to be stored.
m = Message ( user_dn )
m [ ' 0 ' ] = MessageElement ( self . creds . get_password ( ) ,
FLAG_MOD_DELETE , ' userPassword ' )
m [ ' 1 ' ] = MessageElement ( ' Password#2 ' ,
FLAG_MOD_ADD , ' userPassword ' )
self . ldb . modify ( m )
# Show that a simple bind can still be performed using the previous
# password.
self . creds . set_bind_dn ( user_dn_str )
self . creds . set_username ( ' testuser_2 ' )
try :
SamDB ( url = host_ldaps ,
credentials = self . creds , lp = lp )
except LdbError :
self . fail ( ' failed to login with previous password! ' )
def test_old_password_rename_attempt_reuse ( self ) :
2023-11-28 05:11:12 +03:00
""" Shows that we cannot reuse the original password after renaming the account. """
2022-04-11 07:43:42 +03:00
user_dn_str = f ' CN=testuser,CN=Users, { self . base_dn } '
user_dn = Dn ( self . ldb , user_dn_str )
# Change the account password.
m = Message ( user_dn )
m [ ' 0 ' ] = MessageElement ( self . creds . get_password ( ) ,
FLAG_MOD_DELETE , ' userPassword ' )
m [ ' 1 ' ] = MessageElement ( ' Password#2 ' ,
FLAG_MOD_ADD , ' userPassword ' )
self . ldb . modify ( m )
# Show that the previous password is in the history by trying to set it
# as our new password.
m = Message ( user_dn )
m [ ' 0 ' ] = MessageElement ( ' Password#2 ' ,
FLAG_MOD_DELETE , ' userPassword ' )
m [ ' 1 ' ] = MessageElement ( self . creds . get_password ( ) ,
FLAG_MOD_ADD , ' userPassword ' )
try :
self . ldb . modify ( m )
except LdbError as err :
num , estr = err . args
self . assertEqual ( ERR_CONSTRAINT_VIOLATION , num )
self . assertIn ( f ' { werror . WERR_PASSWORD_RESTRICTION : 08X } ' , estr )
else :
self . fail ( ' should not have been able to reuse password! ' )
# Rename the account, causing the salt to change.
m = Message ( user_dn )
m [ ' 1 ' ] = MessageElement ( ' testuser_2 ' ,
FLAG_MOD_REPLACE , ' sAMAccountName ' )
self . ldb . modify ( m )
# Show that the previous password is still in the history by trying to
# set it as our new password.
m = Message ( user_dn )
m [ ' 0 ' ] = MessageElement ( ' Password#2 ' ,
FLAG_MOD_DELETE , ' userPassword ' )
m [ ' 1 ' ] = MessageElement ( self . creds . get_password ( ) ,
FLAG_MOD_ADD , ' userPassword ' )
try :
self . ldb . modify ( m )
except LdbError as err :
num , estr = err . args
self . assertEqual ( ERR_CONSTRAINT_VIOLATION , num )
self . assertIn ( f ' { werror . WERR_PASSWORD_RESTRICTION : 08X } ' , estr )
else :
self . fail ( ' should not have been able to reuse password! ' )
def test_old_password_rename_attempt_reuse_2 ( self ) :
2023-11-28 05:11:12 +03:00
""" Shows that we cannot reuse the original password after renaming the account and changing the password. """
2022-04-11 07:43:42 +03:00
user_dn_str = f ' CN=testuser,CN=Users, { self . base_dn } '
user_dn = Dn ( self . ldb , user_dn_str )
# Rename the account, causing the salt to change.
m = Message ( user_dn )
m [ ' 1 ' ] = MessageElement ( ' testuser_2 ' ,
FLAG_MOD_REPLACE , ' sAMAccountName ' )
self . ldb . modify ( m )
# Change the account password, causing the new salt to be stored.
m = Message ( user_dn )
m [ ' 0 ' ] = MessageElement ( self . creds . get_password ( ) ,
FLAG_MOD_DELETE , ' userPassword ' )
m [ ' 1 ' ] = MessageElement ( ' Password#2 ' ,
FLAG_MOD_ADD , ' userPassword ' )
self . ldb . modify ( m )
# Show that the previous password is in the history by trying to set it
# as our new password.
m = Message ( user_dn )
m [ ' 0 ' ] = MessageElement ( ' Password#2 ' ,
FLAG_MOD_DELETE , ' userPassword ' )
m [ ' 1 ' ] = MessageElement ( self . creds . get_password ( ) ,
FLAG_MOD_ADD , ' userPassword ' )
try :
self . ldb . modify ( m )
except LdbError as err :
num , estr = err . args
self . assertEqual ( ERR_CONSTRAINT_VIOLATION , num )
self . assertIn ( f ' { werror . WERR_PASSWORD_RESTRICTION : 08X } ' , estr )
else :
self . fail ( ' should not have been able to reuse password! ' )
2022-02-09 03:57:47 +03:00
def test_protected_unicodePwd_clear_set ( self ) :
""" Performs a password cleartext set operation on ' unicodePwd ' with the user in
the Protected Users group """
user_dn = f ' cn=testuser,cn=users, { self . base_dn } '
# Add the user to the Protected Users group.
# Search for the Protected Users group.
group_dn = Dn ( self . ldb ,
f ' <SID= { self . ldb . get_domain_sid ( ) } - '
f ' { security . DOMAIN_RID_PROTECTED_USERS } > ' )
try :
group_res = self . ldb . search ( base = group_dn ,
scope = SCOPE_BASE ,
attrs = [ ' member ' ] )
except LdbError as err :
self . fail ( err )
# Add the user to the list of members.
members = list ( group_res [ 0 ] . get ( ' member ' , ( ) ) )
members . append ( user_dn )
m = Message ( group_dn )
m [ ' member ' ] = MessageElement ( members ,
FLAG_MOD_REPLACE ,
' member ' )
self . ldb . modify ( m )
m = Message ( )
m . dn = Dn ( self . ldb , user_dn )
m [ ' unicodePwd ' ] = MessageElement (
' " thatsAcomplPASS2 " ' . encode ( ' utf-16-le ' ) ,
FLAG_MOD_REPLACE , ' unicodePwd ' )
self . ldb . modify ( m )
def test_protected_unicodePwd_clear_change ( self ) :
""" Performs a password cleartext change operation on ' unicodePwd ' with the user
in the Protected Users group """
user_dn = f ' cn=testuser,cn=users, { self . base_dn } '
# Add the user to the Protected Users group.
# Search for the Protected Users group.
group_dn = Dn ( self . ldb ,
f ' <SID= { self . ldb . get_domain_sid ( ) } - '
f ' { security . DOMAIN_RID_PROTECTED_USERS } > ' )
try :
group_res = self . ldb . search ( base = group_dn ,
scope = SCOPE_BASE ,
attrs = [ ' member ' ] )
except LdbError as err :
self . fail ( err )
# Add the user to the list of members.
members = list ( group_res [ 0 ] . get ( ' member ' , ( ) ) )
members . append ( user_dn )
m = Message ( group_dn )
m [ ' member ' ] = MessageElement ( members ,
FLAG_MOD_REPLACE ,
' member ' )
self . ldb . modify ( m )
self . ldb2 . modify_ldif ( f """
dn : cn = testuser , cn = users , { self . base_dn }
changetype : modify
delete : unicodePwd
unicodePwd : : { base64 . b64encode ( ' " thatsAcomplPASS1 " ' . encode ( ' utf-16-le ' ) )
. decode ( ' utf8 ' ) }
add : unicodePwd
unicodePwd : : { base64 . b64encode ( ' " thatsAcomplPASS2 " ' . encode ( ' utf-16-le ' ) )
. decode ( ' utf8 ' ) }
""" )
2010-04-10 22:04:13 +04:00
def test_dBCSPwd_hash_set ( self ) :
2014-11-02 20:13:06 +03:00
""" Performs a password hash set operation on ' dBCSPwd ' which should be prevented """
2010-04-10 22:04:13 +04:00
# Notice: Direct hash password sets should never work
m = Message ( )
2014-11-02 20:13:06 +03:00
m . dn = Dn ( self . ldb , " cn=testuser,cn=users, " + self . base_dn )
2010-04-10 22:04:13 +04:00
m [ " dBCSPwd " ] = MessageElement ( " XXXXXXXXXXXXXXXX " , FLAG_MOD_REPLACE ,
2018-07-30 09:16:12 +03:00
" dBCSPwd " )
2010-04-10 22:04:13 +04:00
try :
2014-11-02 20:13:06 +03:00
self . ldb . modify ( m )
2010-04-10 22:04:13 +04:00
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e6 :
( num , _ ) = e6 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_UNWILLING_TO_PERFORM )
2010-04-10 22:04:13 +04:00
def test_dBCSPwd_hash_change ( self ) :
2014-11-02 20:13:06 +03:00
""" Performs a password hash change operation on ' dBCSPwd ' which should be prevented """
2010-04-10 22:04:13 +04:00
# 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 ( )
2018-02-23 17:34:23 +03:00
except LdbError as e7 :
( num , _ ) = e7 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_UNWILLING_TO_PERFORM )
2010-04-10 22:04:13 +04:00
def test_userPassword_clear_set ( self ) :
2014-11-02 20:13:06 +03:00
""" Performs a password cleartext set operation on ' userPassword ' """
2010-04-10 22:04:13 +04:00
# Notice: This works only against Windows if "dSHeuristics" has been set
# properly
m = Message ( )
2014-11-02 20:13:06 +03:00
m . dn = Dn ( self . ldb , " cn=testuser,cn=users, " + self . base_dn )
2010-04-10 22:04:13 +04:00
m [ " userPassword " ] = MessageElement ( " thatsAcomplPASS2 " , FLAG_MOD_REPLACE ,
2018-07-30 09:16:12 +03:00
" userPassword " )
2014-11-02 20:13:06 +03:00
self . ldb . modify ( m )
2010-04-10 22:04:13 +04:00
def test_userPassword_clear_change ( self ) :
2014-11-02 20:13:06 +03:00
""" Performs a password cleartext change operation on ' userPassword ' """
2010-04-10 22:04:13 +04:00
# 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
""" )
2010-08-14 12:46:38 +04:00
# Wrong old password
try :
self . ldb2 . modify_ldif ( """
dn : cn = testuser , cn = users , """ + self.base_dn + """
changetype : modify
delete : userPassword
userPassword : thatsAcomplPASS3
add : userPassword
userPassword : thatsAcomplPASS4
""" )
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e8 :
( num , msg ) = e8 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_CONSTRAINT_VIOLATION )
2010-08-15 20:19:52 +04:00
self . assertTrue ( ' 00000056 ' in msg )
2010-08-14 12:46:38 +04:00
2010-04-10 22:04:13 +04:00
# 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 ( )
2018-02-23 17:34:23 +03:00
except LdbError as e9 :
( num , msg ) = e9 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_CONSTRAINT_VIOLATION )
2010-08-15 20:19:52 +04:00
self . assertTrue ( ' 0000052D ' in msg )
2010-04-10 22:04:13 +04:00
def test_clearTextPassword_clear_set ( self ) :
2014-11-02 20:13:06 +03:00
""" Performs a password cleartext set operation on ' clearTextPassword ' """
2010-04-10 22:04:13 +04:00
# Notice: This never works against Windows - only supported by us
try :
m = Message ( )
2014-11-02 20:13:06 +03:00
m . dn = Dn ( self . ldb , " cn=testuser,cn=users, " + self . base_dn )
2010-04-10 22:04:13 +04:00
m [ " clearTextPassword " ] = MessageElement ( " thatsAcomplPASS2 " . encode ( ' utf-16-le ' ) ,
2018-07-30 09:16:12 +03:00
FLAG_MOD_REPLACE , " clearTextPassword " )
2014-11-02 20:13:06 +03:00
self . ldb . modify ( m )
2010-04-10 22:04:13 +04:00
# this passes against s4
2018-02-23 17:34:23 +03:00
except LdbError as e10 :
( num , msg ) = e10 . args
2010-04-10 22:04:13 +04:00
# "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 ) :
2014-11-02 20:13:06 +03:00
""" Performs a password cleartext change operation on ' clearTextPassword ' """
2010-04-10 22:04:13 +04:00
# 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
2018-05-04 17:27:12 +03:00
clearTextPassword : : """ + base64.b64encode( " thatsAcomplPASS1 " .encode( ' utf-16-le ' )).decode( ' utf8 ' ) + """
2010-04-10 22:04:13 +04:00
add : clearTextPassword
2018-05-04 17:27:12 +03:00
clearTextPassword : : """ + base64.b64encode( " thatsAcomplPASS2 " .encode( ' utf-16-le ' )).decode( ' utf8 ' ) + """
2010-04-10 22:04:13 +04:00
""" )
# this passes against s4
2018-02-23 17:34:23 +03:00
except LdbError as e11 :
( num , msg ) = e11 . args
2010-04-10 22:04:13 +04:00
# "NO_SUCH_ATTRIBUTE" is returned by Windows -> ignore it
if num != ERR_NO_SUCH_ATTRIBUTE :
raise LdbError ( num , msg )
2010-08-14 12:46:38 +04:00
# Wrong old password
try :
self . ldb2 . modify_ldif ( """
dn : cn = testuser , cn = users , """ + self.base_dn + """
changetype : modify
delete : clearTextPassword
2018-05-04 17:27:12 +03:00
clearTextPassword : : """ + base64.b64encode( " thatsAcomplPASS3 " .encode( ' utf-16-le ' )).decode( ' utf8 ' ) + """
2010-08-14 12:46:38 +04:00
add : clearTextPassword
2018-05-04 17:27:12 +03:00
clearTextPassword : : """ + base64.b64encode( " thatsAcomplPASS4 " .encode( ' utf-16-le ' )).decode( ' utf8 ' ) + """
2010-08-14 12:46:38 +04:00
""" )
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e12 :
( num , msg ) = e12 . args
2010-08-14 12:46:38 +04:00
# "NO_SUCH_ATTRIBUTE" is returned by Windows -> ignore it
if num != ERR_NO_SUCH_ATTRIBUTE :
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_CONSTRAINT_VIOLATION )
2010-08-15 20:19:52 +04:00
self . assertTrue ( ' 00000056 ' in msg )
2010-08-14 12:46:38 +04:00
2010-04-10 22:04:13 +04:00
# 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
2018-05-04 17:27:12 +03:00
clearTextPassword : : """ + base64.b64encode( " thatsAcomplPASS2 " .encode( ' utf-16-le ' )).decode( ' utf8 ' ) + """
2010-04-10 22:04:13 +04:00
add : clearTextPassword
2018-05-04 17:27:12 +03:00
clearTextPassword : : """ + base64.b64encode( " thatsAcomplPASS2 " .encode( ' utf-16-le ' )).decode( ' utf8 ' ) + """
2010-04-10 22:04:13 +04:00
""" )
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e13 :
( num , msg ) = e13 . args
2010-04-10 22:04:13 +04:00
# "NO_SUCH_ATTRIBUTE" is returned by Windows -> ignore it
if num != ERR_NO_SUCH_ATTRIBUTE :
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_CONSTRAINT_VIOLATION )
2010-08-15 20:19:52 +04:00
self . assertTrue ( ' 0000052D ' in msg )
2010-04-10 22:04:13 +04:00
def test_failures ( self ) :
2014-11-02 20:13:06 +03:00
""" Performs some failure testing """
2010-04-10 22:04:13 +04:00
try :
2014-11-02 20:13:06 +03:00
self . ldb . modify_ldif ( """
2010-04-10 22:04:13 +04:00
dn : cn = testuser , cn = users , """ + self.base_dn + """
changetype : modify
delete : userPassword
userPassword : thatsAcomplPASS1
""" )
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e14 :
( num , _ ) = e14 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_CONSTRAINT_VIOLATION )
2010-04-10 22:04:13 +04:00
try :
self . ldb2 . modify_ldif ( """
dn : cn = testuser , cn = users , """ + self.base_dn + """
changetype : modify
delete : userPassword
2010-11-08 00:35:29 +03:00
userPassword : thatsAcomplPASS1
""" )
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e15 :
( num , _ ) = e15 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_CONSTRAINT_VIOLATION )
2010-11-08 00:35:29 +03:00
try :
2014-11-02 20:13:06 +03:00
self . ldb . modify_ldif ( """
2010-11-08 00:35:29 +03:00
dn : cn = testuser , cn = users , """ + self.base_dn + """
changetype : modify
delete : userPassword
""" )
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e16 :
( num , _ ) = e16 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_CONSTRAINT_VIOLATION )
2010-11-08 00:35:29 +03:00
try :
self . ldb2 . modify_ldif ( """
dn : cn = testuser , cn = users , """ + self.base_dn + """
changetype : modify
delete : userPassword
2010-04-10 22:04:13 +04:00
""" )
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e17 :
( num , _ ) = e17 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_CONSTRAINT_VIOLATION )
2010-04-10 22:04:13 +04:00
try :
2014-11-02 20:13:06 +03:00
self . ldb . modify_ldif ( """
2010-04-10 22:04:13 +04:00
dn : cn = testuser , cn = users , """ + self.base_dn + """
changetype : modify
add : userPassword
userPassword : thatsAcomplPASS1
""" )
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e18 :
( num , _ ) = e18 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_UNWILLING_TO_PERFORM )
2010-04-10 22:04:13 +04:00
try :
self . ldb2 . modify_ldif ( """
dn : cn = testuser , cn = users , """ + self.base_dn + """
changetype : modify
add : userPassword
userPassword : thatsAcomplPASS1
""" )
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e19 :
( num , _ ) = e19 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_INSUFFICIENT_ACCESS_RIGHTS )
2010-04-10 22:04:13 +04:00
try :
2014-11-02 20:13:06 +03:00
self . ldb . modify_ldif ( """
2010-04-10 22:04:13 +04:00
dn : cn = testuser , cn = users , """ + self.base_dn + """
changetype : modify
delete : userPassword
userPassword : thatsAcomplPASS1
add : userPassword
userPassword : thatsAcomplPASS2
userPassword : thatsAcomplPASS2
""" )
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e20 :
( num , _ ) = e20 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_CONSTRAINT_VIOLATION )
2010-04-10 22:04:13 +04:00
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 ( )
2018-02-23 17:34:23 +03:00
except LdbError as e21 :
( num , _ ) = e21 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_CONSTRAINT_VIOLATION )
2010-04-10 22:04:13 +04:00
try :
2014-11-02 20:13:06 +03:00
self . ldb . modify_ldif ( """
2010-04-10 22:04:13 +04:00
dn : cn = testuser , cn = users , """ + self.base_dn + """
changetype : modify
delete : userPassword
userPassword : thatsAcomplPASS1
userPassword : thatsAcomplPASS1
add : userPassword
userPassword : thatsAcomplPASS2
""" )
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e22 :
( num , _ ) = e22 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_CONSTRAINT_VIOLATION )
2010-04-10 22:04:13 +04:00
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 ( )
2018-02-23 17:34:23 +03:00
except LdbError as e23 :
( num , _ ) = e23 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_CONSTRAINT_VIOLATION )
2010-04-10 22:04:13 +04:00
try :
2014-11-02 20:13:06 +03:00
self . ldb . modify_ldif ( """
2010-04-10 22:04:13 +04:00
dn : cn = testuser , cn = users , """ + self.base_dn + """
changetype : modify
delete : userPassword
userPassword : thatsAcomplPASS1
add : userPassword
userPassword : thatsAcomplPASS2
add : userPassword
userPassword : thatsAcomplPASS2
""" )
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e24 :
( num , _ ) = e24 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_UNWILLING_TO_PERFORM )
2010-04-10 22:04:13 +04:00
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 ( )
2018-02-23 17:34:23 +03:00
except LdbError as e25 :
( num , _ ) = e25 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_INSUFFICIENT_ACCESS_RIGHTS )
2010-04-10 22:04:13 +04:00
try :
2014-11-02 20:13:06 +03:00
self . ldb . modify_ldif ( """
2010-04-10 22:04:13 +04:00
dn : cn = testuser , cn = users , """ + self.base_dn + """
changetype : modify
delete : userPassword
userPassword : thatsAcomplPASS1
delete : userPassword
userPassword : thatsAcomplPASS1
add : userPassword
userPassword : thatsAcomplPASS2
""" )
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e26 :
( num , _ ) = e26 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_UNWILLING_TO_PERFORM )
2010-04-10 22:04:13 +04:00
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 ( )
2018-02-23 17:34:23 +03:00
except LdbError as e27 :
( num , _ ) = e27 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_INSUFFICIENT_ACCESS_RIGHTS )
2010-04-10 22:04:13 +04:00
try :
2014-11-02 20:13:06 +03:00
self . ldb . modify_ldif ( """
2010-04-10 22:04:13 +04:00
dn : cn = testuser , cn = users , """ + self.base_dn + """
changetype : modify
delete : userPassword
userPassword : thatsAcomplPASS1
add : userPassword
userPassword : thatsAcomplPASS2
replace : userPassword
userPassword : thatsAcomplPASS3
""" )
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e28 :
( num , _ ) = e28 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_UNWILLING_TO_PERFORM )
2010-04-10 22:04:13 +04:00
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 ( )
2018-02-23 17:34:23 +03:00
except LdbError as e29 :
( num , _ ) = e29 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_INSUFFICIENT_ACCESS_RIGHTS )
2010-04-10 22:04:13 +04:00
# 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
2018-05-04 17:27:12 +03:00
unicodePwd : : """ + base64.b64encode( " \" thatsAcomplPASS3 \" " .encode( ' utf-16-le ' )).decode( ' utf8 ' ) + """
2010-04-10 22:04:13 +04:00
""" )
2018-07-30 09:14:03 +03:00
# this passes against s4
2018-02-23 17:34:23 +03:00
except LdbError as e30 :
( num , _ ) = e30 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_ATTRIBUTE_OR_VALUE_EXISTS )
2010-04-10 22:04:13 +04:00
try :
self . ldb2 . modify_ldif ( """
dn : cn = testuser , cn = users , """ + self.base_dn + """
changetype : modify
delete : unicodePwd
2018-05-04 17:27:12 +03:00
unicodePwd : : """ + base64.b64encode( " \" thatsAcomplPASS3 \" " .encode( ' utf-16-le ' )).decode( ' utf8 ' ) + """
2010-04-10 22:04:13 +04:00
add : userPassword
userPassword : thatsAcomplPASS4
""" )
2018-07-30 09:14:03 +03:00
# this passes against s4
2018-02-23 17:34:23 +03:00
except LdbError as e31 :
( num , _ ) = e31 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_NO_SUCH_ATTRIBUTE )
2010-04-10 22:04:13 +04:00
# Several password changes at once are allowed
2014-11-02 20:13:06 +03:00
self . ldb . modify_ldif ( """
2010-04-10 22:04:13 +04:00
dn : cn = testuser , cn = users , """ + self.base_dn + """
changetype : modify
replace : userPassword
userPassword : thatsAcomplPASS1
userPassword : thatsAcomplPASS2
""" )
# Several password changes at once are allowed
2014-11-02 20:13:06 +03:00
self . ldb . modify_ldif ( """
2010-04-10 22:04:13 +04:00
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
2010-11-25 02:13:47 +03:00
delete_force ( self . ldb , " cn=testuser2,cn=users, " + self . base_dn )
2010-04-10 22:04:13 +04:00
self . ldb . add ( {
" dn " : " cn=testuser2,cn=users, " + self . base_dn ,
2010-11-01 19:23:34 +03:00
" objectclass " : " user " ,
2018-07-30 09:17:02 +03:00
" userPassword " : [ " thatsAcomplPASS1 " , " thatsAcomplPASS2 " ] } )
2010-04-10 22:04:13 +04:00
# This surprisingly should work
2010-11-25 02:13:47 +03:00
delete_force ( self . ldb , " cn=testuser2,cn=users, " + self . base_dn )
2010-04-10 22:04:13 +04:00
self . ldb . add ( {
" dn " : " cn=testuser2,cn=users, " + self . base_dn ,
2010-11-01 19:23:34 +03:00
" objectclass " : " user " ,
2018-07-30 09:17:02 +03:00
" userPassword " : [ " thatsAcomplPASS1 " , " thatsAcomplPASS1 " ] } )
2010-04-10 22:04:13 +04:00
2010-11-01 21:54:07 +03:00
def test_empty_passwords ( self ) :
2018-03-09 16:57:01 +03:00
print ( " Performs some empty passwords testing " )
2010-11-01 21:54:07 +03:00
try :
self . ldb . add ( {
" dn " : " cn=testuser2,cn=users, " + self . base_dn ,
" objectclass " : " user " ,
2018-07-30 09:17:02 +03:00
" unicodePwd " : [ ] } )
2010-11-01 21:54:07 +03:00
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e32 :
( num , _ ) = e32 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_CONSTRAINT_VIOLATION )
2010-11-01 21:54:07 +03:00
try :
self . ldb . add ( {
" dn " : " cn=testuser2,cn=users, " + self . base_dn ,
" objectclass " : " user " ,
2018-07-30 09:17:02 +03:00
" dBCSPwd " : [ ] } )
2010-11-01 21:54:07 +03:00
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e33 :
( num , _ ) = e33 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_CONSTRAINT_VIOLATION )
2010-11-01 21:54:07 +03:00
try :
self . ldb . add ( {
" dn " : " cn=testuser2,cn=users, " + self . base_dn ,
" objectclass " : " user " ,
2018-07-30 09:17:02 +03:00
" userPassword " : [ ] } )
2010-11-01 21:54:07 +03:00
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e34 :
( num , _ ) = e34 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_CONSTRAINT_VIOLATION )
2010-11-01 21:54:07 +03:00
try :
self . ldb . add ( {
" dn " : " cn=testuser2,cn=users, " + self . base_dn ,
" objectclass " : " user " ,
2018-07-30 09:17:02 +03:00
" clearTextPassword " : [ ] } )
2010-11-01 21:54:07 +03:00
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e35 :
( num , _ ) = e35 . args
2010-11-01 21:54:07 +03:00
self . assertTrue ( num == ERR_CONSTRAINT_VIOLATION or
2018-07-30 09:19:33 +03:00
num == ERR_NO_SUCH_ATTRIBUTE ) # for Windows
2010-11-01 21:54:07 +03:00
2010-11-25 02:13:47 +03:00
delete_force ( self . ldb , " cn=testuser2,cn=users, " + self . base_dn )
2010-11-01 21:54:07 +03:00
m = Message ( )
2014-11-02 20:13:06 +03:00
m . dn = Dn ( self . ldb , " cn=testuser,cn=users, " + self . base_dn )
2010-11-01 21:54:07 +03:00
m [ " unicodePwd " ] = MessageElement ( [ ] , FLAG_MOD_ADD , " unicodePwd " )
try :
2014-11-02 20:13:06 +03:00
self . ldb . modify ( m )
2010-11-01 21:54:07 +03:00
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e36 :
( num , _ ) = e36 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_CONSTRAINT_VIOLATION )
2010-11-01 21:54:07 +03:00
m = Message ( )
2014-11-02 20:13:06 +03:00
m . dn = Dn ( self . ldb , " cn=testuser,cn=users, " + self . base_dn )
2010-11-01 21:54:07 +03:00
m [ " dBCSPwd " ] = MessageElement ( [ ] , FLAG_MOD_ADD , " dBCSPwd " )
try :
2014-11-02 20:13:06 +03:00
self . ldb . modify ( m )
2010-11-01 21:54:07 +03:00
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e37 :
( num , _ ) = e37 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_CONSTRAINT_VIOLATION )
2010-11-01 21:54:07 +03:00
m = Message ( )
2014-11-02 20:13:06 +03:00
m . dn = Dn ( self . ldb , " cn=testuser,cn=users, " + self . base_dn )
2010-11-01 21:54:07 +03:00
m [ " userPassword " ] = MessageElement ( [ ] , FLAG_MOD_ADD , " userPassword " )
try :
2014-11-02 20:13:06 +03:00
self . ldb . modify ( m )
2010-11-01 21:54:07 +03:00
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e38 :
( num , _ ) = e38 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_CONSTRAINT_VIOLATION )
2010-11-01 21:54:07 +03:00
m = Message ( )
2014-11-02 20:13:06 +03:00
m . dn = Dn ( self . ldb , " cn=testuser,cn=users, " + self . base_dn )
2010-11-01 21:54:07 +03:00
m [ " clearTextPassword " ] = MessageElement ( [ ] , FLAG_MOD_ADD , " clearTextPassword " )
try :
2014-11-02 20:13:06 +03:00
self . ldb . modify ( m )
2010-11-01 21:54:07 +03:00
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e39 :
( num , _ ) = e39 . args
2010-11-01 21:54:07 +03:00
self . assertTrue ( num == ERR_CONSTRAINT_VIOLATION or
2018-07-30 09:19:33 +03:00
num == ERR_NO_SUCH_ATTRIBUTE ) # for Windows
2010-11-01 21:54:07 +03:00
m = Message ( )
2014-11-02 20:13:06 +03:00
m . dn = Dn ( self . ldb , " cn=testuser,cn=users, " + self . base_dn )
2010-11-01 21:54:07 +03:00
m [ " unicodePwd " ] = MessageElement ( [ ] , FLAG_MOD_REPLACE , " unicodePwd " )
try :
2014-11-02 20:13:06 +03:00
self . ldb . modify ( m )
2010-11-01 21:54:07 +03:00
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e40 :
( num , _ ) = e40 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_UNWILLING_TO_PERFORM )
2010-11-01 21:54:07 +03:00
m = Message ( )
2014-11-02 20:13:06 +03:00
m . dn = Dn ( self . ldb , " cn=testuser,cn=users, " + self . base_dn )
2010-11-01 21:54:07 +03:00
m [ " dBCSPwd " ] = MessageElement ( [ ] , FLAG_MOD_REPLACE , " dBCSPwd " )
try :
2014-11-02 20:13:06 +03:00
self . ldb . modify ( m )
2010-11-01 21:54:07 +03:00
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e41 :
( num , _ ) = e41 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_UNWILLING_TO_PERFORM )
2010-11-01 21:54:07 +03:00
m = Message ( )
2014-11-02 20:13:06 +03:00
m . dn = Dn ( self . ldb , " cn=testuser,cn=users, " + self . base_dn )
2010-11-01 21:54:07 +03:00
m [ " userPassword " ] = MessageElement ( [ ] , FLAG_MOD_REPLACE , " userPassword " )
try :
2014-11-02 20:13:06 +03:00
self . ldb . modify ( m )
2010-11-01 21:54:07 +03:00
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e42 :
( num , _ ) = e42 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_UNWILLING_TO_PERFORM )
2010-11-01 21:54:07 +03:00
m = Message ( )
2014-11-02 20:13:06 +03:00
m . dn = Dn ( self . ldb , " cn=testuser,cn=users, " + self . base_dn )
2010-11-01 21:54:07 +03:00
m [ " clearTextPassword " ] = MessageElement ( [ ] , FLAG_MOD_REPLACE , " clearTextPassword " )
try :
2014-11-02 20:13:06 +03:00
self . ldb . modify ( m )
2010-11-01 21:54:07 +03:00
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e43 :
( num , _ ) = e43 . args
2010-11-01 21:54:07 +03:00
self . assertTrue ( num == ERR_UNWILLING_TO_PERFORM or
2018-07-30 09:19:33 +03:00
num == ERR_NO_SUCH_ATTRIBUTE ) # for Windows
2010-11-01 21:54:07 +03:00
m = Message ( )
2014-11-02 20:13:06 +03:00
m . dn = Dn ( self . ldb , " cn=testuser,cn=users, " + self . base_dn )
2010-11-01 21:54:07 +03:00
m [ " unicodePwd " ] = MessageElement ( [ ] , FLAG_MOD_DELETE , " unicodePwd " )
try :
2014-11-02 20:13:06 +03:00
self . ldb . modify ( m )
2010-11-01 21:54:07 +03:00
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e44 :
( num , _ ) = e44 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_UNWILLING_TO_PERFORM )
2010-11-01 21:54:07 +03:00
m = Message ( )
2014-11-02 20:13:06 +03:00
m . dn = Dn ( self . ldb , " cn=testuser,cn=users, " + self . base_dn )
2010-11-01 21:54:07 +03:00
m [ " dBCSPwd " ] = MessageElement ( [ ] , FLAG_MOD_DELETE , " dBCSPwd " )
try :
2014-11-02 20:13:06 +03:00
self . ldb . modify ( m )
2010-11-01 21:54:07 +03:00
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e45 :
( num , _ ) = e45 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_UNWILLING_TO_PERFORM )
2010-11-01 21:54:07 +03:00
m = Message ( )
2014-11-02 20:13:06 +03:00
m . dn = Dn ( self . ldb , " cn=testuser,cn=users, " + self . base_dn )
2010-11-01 21:54:07 +03:00
m [ " userPassword " ] = MessageElement ( [ ] , FLAG_MOD_DELETE , " userPassword " )
try :
2014-11-02 20:13:06 +03:00
self . ldb . modify ( m )
2010-11-01 21:54:07 +03:00
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e46 :
( num , _ ) = e46 . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_CONSTRAINT_VIOLATION )
2010-11-01 21:54:07 +03:00
m = Message ( )
2014-11-02 20:13:06 +03:00
m . dn = Dn ( self . ldb , " cn=testuser,cn=users, " + self . base_dn )
2010-11-01 21:54:07 +03:00
m [ " clearTextPassword " ] = MessageElement ( [ ] , FLAG_MOD_DELETE , " clearTextPassword " )
try :
2014-11-02 20:13:06 +03:00
self . ldb . modify ( m )
2010-11-01 21:54:07 +03:00
self . fail ( )
2018-02-23 17:34:23 +03:00
except LdbError as e47 :
( num , _ ) = e47 . args
2010-11-01 21:54:07 +03:00
self . assertTrue ( num == ERR_CONSTRAINT_VIOLATION or
2018-07-30 09:19:33 +03:00
num == ERR_NO_SUCH_ATTRIBUTE ) # for Windows
2010-11-01 21:54:07 +03:00
2010-11-09 17:04:47 +03:00
def test_plain_userPassword ( self ) :
2018-03-09 16:57:01 +03:00
print ( " Performs testing about the standard ' userPassword ' behaviour " )
2010-11-09 17:04:47 +03:00
# Delete the "dSHeuristics"
2014-11-02 20:13:06 +03:00
self . ldb . set_dsheuristics ( None )
2010-11-09 17:04:47 +03:00
2018-07-30 09:19:33 +03:00
time . sleep ( 1 ) # This switching time is strictly needed!
2010-11-09 17:04:47 +03:00
m = Message ( )
2014-11-02 20:13:06 +03:00
m . dn = Dn ( self . ldb , " cn=testuser,cn=users, " + self . base_dn )
2010-11-09 17:04:47 +03:00
m [ " userPassword " ] = MessageElement ( " myPassword " , FLAG_MOD_ADD ,
2018-07-30 09:16:12 +03:00
" userPassword " )
2014-11-02 20:13:06 +03:00
self . ldb . modify ( m )
2010-11-09 17:04:47 +03:00
2014-11-02 20:13:06 +03:00
res = self . ldb . search ( " cn=testuser,cn=users, " + self . base_dn ,
2018-07-30 09:16:12 +03:00
scope = SCOPE_BASE , attrs = [ " userPassword " ] )
2010-11-09 17:04:47 +03:00
self . assertTrue ( len ( res ) == 1 )
self . assertTrue ( " userPassword " in res [ 0 ] )
2020-02-07 01:02:38 +03:00
self . assertEqual ( str ( res [ 0 ] [ " userPassword " ] [ 0 ] ) , " myPassword " )
2010-11-09 17:04:47 +03:00
m = Message ( )
2014-11-02 20:13:06 +03:00
m . dn = Dn ( self . ldb , " cn=testuser,cn=users, " + self . base_dn )
2010-11-09 17:04:47 +03:00
m [ " userPassword " ] = MessageElement ( " myPassword2 " , FLAG_MOD_REPLACE ,
2018-07-30 09:16:12 +03:00
" userPassword " )
2014-11-02 20:13:06 +03:00
self . ldb . modify ( m )
2010-11-09 17:04:47 +03:00
2014-11-02 20:13:06 +03:00
res = self . ldb . search ( " cn=testuser,cn=users, " + self . base_dn ,
2018-07-30 09:16:12 +03:00
scope = SCOPE_BASE , attrs = [ " userPassword " ] )
2010-11-09 17:04:47 +03:00
self . assertTrue ( len ( res ) == 1 )
self . assertTrue ( " userPassword " in res [ 0 ] )
2020-02-07 01:02:38 +03:00
self . assertEqual ( str ( res [ 0 ] [ " userPassword " ] [ 0 ] ) , " myPassword2 " )
2010-11-09 17:04:47 +03:00
m = Message ( )
2014-11-02 20:13:06 +03:00
m . dn = Dn ( self . ldb , " cn=testuser,cn=users, " + self . base_dn )
2010-11-09 17:04:47 +03:00
m [ " userPassword " ] = MessageElement ( [ ] , FLAG_MOD_DELETE ,
2018-07-30 09:16:12 +03:00
" userPassword " )
2014-11-02 20:13:06 +03:00
self . ldb . modify ( m )
2010-11-09 17:04:47 +03:00
2014-11-02 20:13:06 +03:00
res = self . ldb . search ( " cn=testuser,cn=users, " + self . base_dn ,
2018-07-30 09:16:12 +03:00
scope = SCOPE_BASE , attrs = [ " userPassword " ] )
2010-11-09 17:04:47 +03:00
self . assertTrue ( len ( res ) == 1 )
self . assertFalse ( " userPassword " in res [ 0 ] )
# Set the test "dSHeuristics" to deactivate "userPassword" pwd changes
2014-11-02 20:13:06 +03:00
self . ldb . set_dsheuristics ( " 000000000 " )
2010-11-09 17:04:47 +03:00
m = Message ( )
2014-11-02 20:13:06 +03:00
m . dn = Dn ( self . ldb , " cn=testuser,cn=users, " + self . base_dn )
2010-11-09 17:04:47 +03:00
m [ " userPassword " ] = MessageElement ( " myPassword3 " , FLAG_MOD_REPLACE ,
2018-07-30 09:16:12 +03:00
" userPassword " )
2014-11-02 20:13:06 +03:00
self . ldb . modify ( m )
2010-11-09 17:04:47 +03:00
2014-11-02 20:13:06 +03:00
res = self . ldb . search ( " cn=testuser,cn=users, " + self . base_dn ,
2018-07-30 09:16:12 +03:00
scope = SCOPE_BASE , attrs = [ " userPassword " ] )
2010-11-09 17:04:47 +03:00
self . assertTrue ( len ( res ) == 1 )
self . assertTrue ( " userPassword " in res [ 0 ] )
2020-02-07 01:02:38 +03:00
self . assertEqual ( str ( res [ 0 ] [ " userPassword " ] [ 0 ] ) , " myPassword3 " )
2010-11-09 17:04:47 +03:00
# Set the test "dSHeuristics" to deactivate "userPassword" pwd changes
2014-11-02 20:13:06 +03:00
self . ldb . set_dsheuristics ( " 000000002 " )
2010-11-09 17:04:47 +03:00
m = Message ( )
2014-11-02 20:13:06 +03:00
m . dn = Dn ( self . ldb , " cn=testuser,cn=users, " + self . base_dn )
2010-11-09 17:04:47 +03:00
m [ " userPassword " ] = MessageElement ( " myPassword4 " , FLAG_MOD_REPLACE ,
2018-07-30 09:16:12 +03:00
" userPassword " )
2014-11-02 20:13:06 +03:00
self . ldb . modify ( m )
2010-11-09 17:04:47 +03:00
2014-11-02 20:13:06 +03:00
res = self . ldb . search ( " cn=testuser,cn=users, " + self . base_dn ,
2018-07-30 09:16:12 +03:00
scope = SCOPE_BASE , attrs = [ " userPassword " ] )
2010-11-09 17:04:47 +03:00
self . assertTrue ( len ( res ) == 1 )
self . assertTrue ( " userPassword " in res [ 0 ] )
2020-02-07 01:02:38 +03:00
self . assertEqual ( str ( res [ 0 ] [ " userPassword " ] [ 0 ] ) , " myPassword4 " )
2010-11-09 17:04:47 +03:00
# Reset the test "dSHeuristics" (reactivate "userPassword" pwd changes)
2014-11-02 20:13:06 +03:00
self . ldb . set_dsheuristics ( " 000000001 " )
2010-11-09 17:04:47 +03:00
2016-02-22 03:33:01 +03:00
def test_modify_dsheuristics_userPassword ( self ) :
2018-03-09 16:57:01 +03:00
print ( " Performs testing about reading userPassword between dsHeuristic modifies " )
2016-02-22 03:33:01 +03:00
# Make sure userPassword cannot be read
self . ldb . set_dsheuristics ( " 000000000 " )
# Open a new connection (with dsHeuristic=000000000)
ldb1 = SamDB ( url = host , session_info = system_session ( lp ) ,
credentials = creds , lp = lp )
# Set userPassword to be read
# This setting only affects newer connections (ldb2)
ldb1 . set_dsheuristics ( " 000000001 " )
time . sleep ( 1 )
m = Message ( )
m . dn = Dn ( ldb1 , " cn=testuser,cn=users, " + self . base_dn )
m [ " userPassword " ] = MessageElement ( " thatsAcomplPASS1 " , FLAG_MOD_REPLACE ,
2018-07-30 09:16:12 +03:00
" userPassword " )
2016-02-22 03:33:01 +03:00
ldb1 . modify ( m )
res = ldb1 . search ( " cn=testuser,cn=users, " + self . base_dn ,
scope = SCOPE_BASE , attrs = [ " userPassword " ] )
2018-04-11 13:47:03 +03:00
# userPassword cannot be read, it wasn't set, instead the
# password was
2016-02-22 03:33:01 +03:00
self . assertTrue ( len ( res ) == 1 )
self . assertFalse ( " userPassword " in res [ 0 ] )
# Open another new connection (with dsHeuristic=000000001)
ldb2 = SamDB ( url = host , session_info = system_session ( lp ) ,
credentials = creds , lp = lp )
2018-04-11 13:47:03 +03:00
res = ldb2 . search ( " cn=testuser,cn=users, " + self . base_dn ,
scope = SCOPE_BASE , attrs = [ " userPassword " ] )
# Check on the new connection that userPassword was not stored
# from ldb1 or is not readable
self . assertTrue ( len ( res ) == 1 )
self . assertFalse ( " userPassword " in res [ 0 ] )
# Set userPassword to be readable
2016-02-22 03:33:01 +03:00
# This setting does not affect this connection
ldb2 . set_dsheuristics ( " 000000000 " )
time . sleep ( 1 )
res = ldb2 . search ( " cn=testuser,cn=users, " + self . base_dn ,
scope = SCOPE_BASE , attrs = [ " userPassword " ] )
# Check that userPassword was not stored from ldb1
self . assertTrue ( len ( res ) == 1 )
self . assertFalse ( " userPassword " in res [ 0 ] )
m = Message ( )
m . dn = Dn ( ldb2 , " cn=testuser,cn=users, " + self . base_dn )
m [ " userPassword " ] = MessageElement ( " thatsAcomplPASS2 " , FLAG_MOD_REPLACE ,
2018-07-30 09:16:12 +03:00
" userPassword " )
2016-02-22 03:33:01 +03:00
ldb2 . modify ( m )
res = ldb2 . search ( " cn=testuser,cn=users, " + self . base_dn ,
scope = SCOPE_BASE , attrs = [ " userPassword " ] )
2018-04-11 13:47:03 +03:00
# Check despite setting it with userPassword support disabled
# on this connection it should still not be readable
2016-02-22 03:33:01 +03:00
self . assertTrue ( len ( res ) == 1 )
2018-04-11 13:47:03 +03:00
self . assertFalse ( " userPassword " in res [ 0 ] )
2016-02-22 03:33:01 +03:00
# Only password from ldb1 is the user's password
creds2 = Credentials ( )
creds2 . set_username ( " testuser " )
creds2 . set_password ( " thatsAcomplPASS1 " )
creds2 . set_domain ( creds . get_domain ( ) )
creds2 . set_realm ( creds . get_realm ( ) )
creds2 . set_workstation ( creds . get_workstation ( ) )
creds2 . set_gensec_features ( creds2 . get_gensec_features ( )
| gensec . FEATURE_SEAL )
try :
SamDB ( url = host , credentials = creds2 , lp = lp )
except :
self . fail ( " testuser used the wrong password " )
ldb3 = SamDB ( url = host , session_info = system_session ( lp ) ,
credentials = creds , lp = lp )
# Check that userPassword was stored from ldb2
res = ldb3 . search ( " cn=testuser,cn=users, " + self . base_dn ,
scope = SCOPE_BASE , attrs = [ " userPassword " ] )
# userPassword can be read
self . assertTrue ( len ( res ) == 1 )
self . assertTrue ( " userPassword " in res [ 0 ] )
2020-02-07 01:02:38 +03:00
self . assertEqual ( str ( res [ 0 ] [ " userPassword " ] [ 0 ] ) , " thatsAcomplPASS2 " )
2016-02-22 03:33:01 +03:00
# Reset the test "dSHeuristics" (reactivate "userPassword" pwd changes)
self . ldb . set_dsheuristics ( " 000000001 " )
2018-04-11 13:47:03 +03:00
ldb4 = SamDB ( url = host , session_info = system_session ( lp ) ,
credentials = creds , lp = lp )
# Check that userPassword that was stored from ldb2
res = ldb4 . search ( " cn=testuser,cn=users, " + self . base_dn ,
scope = SCOPE_BASE , attrs = [ " userPassword " ] )
# userPassword can be not be read
self . assertTrue ( len ( res ) == 1 )
self . assertFalse ( " userPassword " in res [ 0 ] )
2010-12-02 11:55:56 +03:00
def test_zero_length ( self ) :
# Get the old "minPwdLength"
2014-11-02 20:13:06 +03:00
minPwdLength = self . ldb . get_minPwdLength ( )
2023-08-02 11:44:32 +03:00
# Set it temporarily to "0"
2014-11-02 20:13:06 +03:00
self . ldb . set_minPwdLength ( " 0 " )
2010-12-02 11:55:56 +03:00
# Get the old "pwdProperties"
2014-11-02 20:13:06 +03:00
pwdProperties = self . ldb . get_pwdProperties ( )
2023-08-02 11:44:32 +03:00
# Set them temporarily to "0" (to deactivate eventually the complexity)
2014-11-02 20:13:06 +03:00
self . ldb . set_pwdProperties ( " 0 " )
2010-12-02 11:55:56 +03:00
2014-11-02 20:13:06 +03:00
self . ldb . setpassword ( " (sAMAccountName=testuser) " , " " )
2010-12-02 11:55:56 +03:00
# Reset the "pwdProperties" as they were before
2014-11-02 20:13:06 +03:00
self . ldb . set_pwdProperties ( pwdProperties )
2010-12-02 11:55:56 +03:00
# Reset the "minPwdLength" as it was before
2014-11-02 20:13:06 +03:00
self . ldb . set_minPwdLength ( minPwdLength )
2010-12-02 11:55:56 +03:00
2018-02-15 14:43:09 +03:00
def test_pw_change_delete_no_value_userPassword ( self ) :
""" Test password change with userPassword where the delete attribute doesn ' t have a value """
try :
self . ldb2 . modify_ldif ( """
dn : cn = testuser , cn = users , """ + self.base_dn + """
changetype : modify
delete : userPassword
add : userPassword
userPassword : thatsAcomplPASS1
""" )
2018-10-11 06:52:14 +03:00
except LdbError as e :
2018-11-06 00:03:39 +03:00
( num , msg ) = e . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_CONSTRAINT_VIOLATION )
2018-02-15 14:43:09 +03:00
else :
self . fail ( )
def test_pw_change_delete_no_value_clearTextPassword ( self ) :
""" Test password change with clearTextPassword where the delete attribute doesn ' t have a value """
try :
self . ldb2 . modify_ldif ( """
dn : cn = testuser , cn = users , """ + self.base_dn + """
changetype : modify
delete : clearTextPassword
add : clearTextPassword
clearTextPassword : thatsAcomplPASS2
""" )
2018-10-11 06:52:14 +03:00
except LdbError as e :
2018-11-06 00:03:39 +03:00
( num , msg ) = e . args
2018-02-15 14:43:09 +03:00
self . assertTrue ( num == ERR_CONSTRAINT_VIOLATION or
2018-07-30 09:19:33 +03:00
num == ERR_NO_SUCH_ATTRIBUTE ) # for Windows
2018-02-15 14:43:09 +03:00
else :
self . fail ( )
def test_pw_change_delete_no_value_unicodePwd ( self ) :
""" Test password change with unicodePwd where the delete attribute doesn ' t have a value """
try :
self . ldb2 . modify_ldif ( """
dn : cn = testuser , cn = users , """ + self.base_dn + """
changetype : modify
delete : unicodePwd
add : unicodePwd
2018-05-04 17:27:12 +03:00
unicodePwd : : """ + base64.b64encode( " \" thatsAcomplPASS3 \" " .encode( ' utf-16-le ' )).decode( ' utf8 ' ) + """
2018-02-15 14:43:09 +03:00
""" )
2018-10-11 06:52:14 +03:00
except LdbError as e :
2018-11-06 00:03:39 +03:00
( num , msg ) = e . args
2020-02-07 01:02:38 +03:00
self . assertEqual ( num , ERR_CONSTRAINT_VIOLATION )
2018-02-15 14:43:09 +03:00
else :
self . fail ( )
2010-04-10 22:04:13 +04:00
def tearDown ( self ) :
2010-06-19 20:58:18 +04:00
super ( PasswordTests , self ) . tearDown ( )
2010-11-25 02:13:47 +03:00
delete_force ( self . ldb , " cn=testuser,cn=users, " + self . base_dn )
delete_force ( self . ldb , " cn=testuser2,cn=users, " + self . base_dn )
2010-04-10 22:04:13 +04:00
# Close the second LDB connection (with the user credentials)
self . ldb2 = None
2018-07-30 09:21:29 +03:00
2018-07-30 09:22:34 +03:00
if " :// " not in host :
2010-04-10 22:04:13 +04:00
if os . path . isfile ( host ) :
2022-04-11 07:43:42 +03:00
host_ldaps = None
2010-04-10 22:04:13 +04:00
host = " tdb:// %s " % host
else :
2022-04-11 07:43:42 +03:00
host_ldaps = " ldaps:// %s " % host
2010-04-10 22:04:13 +04:00
host = " ldap:// %s " % host
2014-11-02 20:13:06 +03:00
TestProgram ( module = __name__ , opts = subunitopts )