验证账号密码以及是否有效
Active Directory LDAP bind errors
python ldap3 设置
raise_exceptions=True
绑定ActiveDirectory
无效凭据时会抛出LDAPInvalidCredentialsResult
, 该异常message
内容如下
EX:
80090308: LdapErr: DSID-0C09030B, comment: AcceptSecurityContext error, data 525, v893
- 525 user not found
- 52e invalid credentials
- 530 not permitted to logon at this time
- 531 not permitted to logon at this workstation
- 532 password expired
- 533 account disabled
- 534 The user has not been granted the requested logon type at this machine
- 701 account expired
- 773 user must reset password
- 775 user account locked
http://www-01.ibm.com/support/docview.wss?uid=swg21290631
python ldap3实例
from ldap3 import Server, Connection, MODIFY_REPLACE
s = Server('192.168.241.135')
domain = 'TEST'
search_base = 'dc=test,dc=com'
admin_c = Connection(server=s, user=domain + '\\' + 'admin', password='adminpwd', auto_bind=True)
def auth(user, pwd):
u'''验证域账号密码是否正确'''
try:
c = Connection(server=s, user=domain + '\\' + user, password=pwd,
auto_bind=True, raise_exceptions=True)
c.unbind()
return True, ''
except LDAPInvalidCredentialsResult as e:
if '52e' in e.message:
return False, u'用户名或密码不正确!'
elif '775' in e.message:
return False, u'账号已锁定,请联系管理员或等待自动解锁!'
elif '533' in e.message:
return False, u'账号已禁用!'
elif '773' in e.message:
# 如果仅仅使用普通凭据来绑定ldap用途,请返回False, 让用户通过其他途径修改密码后再来验证登陆
# return False, u'用户登陆前必须修改密码!'
# 设置该账号下次登陆不需要更改密码,再验证一次
admin_c.search(search_base=search_base, search_filter='(SamAccountName=%s)' % user,
attributes=['pwdLastSet'])
admin_c.modify(admin_c.entries[0].entry_dn, {'pwdLastSet': [(MODIFY_REPLACE, ['-1'])]})
return auth(user, pwd)
else:
return False, u'认证失败,请联系管理员检查该账号!'
查看账号是否锁定
假设用户A在
2018/12/19 17:00
锁定,默认锁定时间是10
分钟, 到2018/12/19 17:20
域控自动解锁,在用户再次登陆一次之前
该用户的lockoutTime
不会恢复到0
,即使域控上查看到的用户没有被锁。因此使用Ldap搜索判断用户是否是锁定并不完全可靠。
from ldap3 import Server, Connection
s = Server('192.168.241.135')
domain = 'TEST'
search_base = 'dc=test,dc=com'
admin_c = Connection(server=s, user=domain + '\\' + 'admin', password='adminpwd', auto_bind=True)
admin_c.search(search_base=search_base, search_filter='(SamAccountName=%s)' % name, attributes=['lockoutTime'])
# 检查账户是否被锁定
# lockoutTime=0时候,ldap3搜索到的时间为'1601-01-01 00:00:00+00:00'
# lockoutTime为未设置时候 ldap3搜索结果值为None
if admin_c.entries[0]['lockoutTime'].value is not None and \
str(admin_c.entries[0]['lockoutTime'].value) != '1601-01-01 00:00:00+00:00':
return False
return True
(Search-ADAccount -LockedOut | Where-Object {$_.SamAccountName -eq leo}) -eq $true
修改账号下一次登陆必须
from ldap3 import Server, Connection
s = Server('192.168.241.135')
domain = 'TEST'
search_base = 'dc=test,dc=com'
admin_c = Connection(server=s, user=domain + '\\' + 'admin', password='adminpwd', auto_bind=True)
admin_c.modify('cn=leo,dc=test,dc=com', {'pwdLastSet': [(MODIFY_REPLACE, ['-1'])]})
Set-ADUser -Identity leo -ChangePasswordAtLogon $false
UserAccountControl
该属性不能完全判断账号是否锁定,不能修改密码。
比如,用户A在域控制器上显示是锁定
状态, 但是该用户UserAccountControl & 0x10
结果是0
,应该是有额外途径判断账号是否有效的依据
- ACCOUNTDISABLE 0x0002
- LOCKOUT 0x0010
- PASSWD_CANT_CHANGE
- PASSWD_CANT_CHANGE 0040
- …