我需要在 Python Web 应用程序 (Flask) 中实现“更新密码”功能。目标是允许用户在远程 Active Directory 服务器上自行更新密码。
我以这个快速单元测试结束
import os
import ldap
def test_change_passwd():
ad_server = "ldaps://ad.xxx_domain.com"
ad_dn = "CN={0},OU=Users,OU=AF,DC=xxx_domain,DC=com"
username = 'my_username'
old_pwd = 'the_old_complicated_password'
new_pwd = 'the_new_complicated_password'
cert = os.path.join('/path', "to", 'server_cert.cer')
# LDAP connection initialization
l = ldap.initialize(ad_server)
# Set LDAP protocol version used
l.protocol_version = ldap.VERSION3
# Force cert validation
l.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_DEMAND)
# Set path name of file containing all trusted CA certificates
l.set_option(ldap.OPT_X_TLS_CACERTFILE, cert)
# Force libldap to create a new SSL context (must be last TLS option!)
l.set_option(ldap.OPT_X_TLS_NEWCTX, 0)
# Bind
l.simple_bind_s(ad_dn.format(username), old_pwd)
# Now, perform the password update
newpwd_utf16 = '"{0}"'.format(new_pwd).encode('utf-16-le')
mod_list = [(ldap.MOD_REPLACE, "unicodePwd", newpwd_utf16)]
l.modify_s(ad_dn.format(username), mod_list)
当我运行它时,它在最后一行(l.modify_s()
)失败并出现以下错误:
INSUFFICIENT_ACCESS: {'info': u'00000005: SecErr: DSID-031A11D7, problem 4003 (INSUFF_ACCESS_RIGHTS), data 0\n', 'desc': u'Insufficient access'}
我不知道问题出在我的 Python 代码上还是目录上用户配置错误。另外,我不是 AD 服务器的管理员(对此也没有任何了解)。
我是否需要对用户进行一些特殊设置以允许他自行更新密码?我是否使用正确的方法来更新密码?
注意:我也尝试过这种方法更新密码,但没有成功:
l.passwd_s(dn.format(username), old_pwd, new_pwd)
失败并出现错误:
PROTOCOL_ERROR({'info': u'0000203D: LdapErr: DSID-0C0911D4, comment: Unknown extended request OID, data 0, v3839', 'desc': u'Protocol error'},)
我到处都看到说此功能不应与 AD 服务器一起使用...
答案1
MS Active Directory 区分两种不同的用例。
注意:old_passwd_value
并且new_passwd_value
两者都必须是像您的代码片段中那样奇怪的双引号低端 UTF-16 编码。
如果管理员设置了其他用户的密码,您可以使用您的代码:
mod_list = [ (ldap0.MOD_REPLACE, 'unicodePwd', [new_passwd_value]), ]
如果用户更改了自己的密码,则必须使用:
mod_list = [ (ldap0.MOD_DELETE, 'unicodePwd', [old_passwd_value]), (ldap0.MOD_ADD, 'unicodePwd', [new_passwd_value]), ]