使用 ldap python 更新 Active Directory 密码
问题描述
基本上尝试使用 LDAP python 重置用户的密码.我在这里浏览了各种帖子,但没有运气:(.
Basically trying to reset the user's password using LDAP python. I've gone through various posts here but no luck :(.
尝试使用:
a) modify_s() - 每次都返回没有这样的对象".尝试使用不同的用户 DN.
a) modify_s() - returns "No such object" every time. Tried with different user DN.
{'info': "0000208D: NameErr: DSID-0310020A, issue 2001 (NO_OBJECT), data 0, best match of: 'DC=mydomain,DC=com' ", 'matched': 'DC=mydomain,DC=com', 'desc': '没有这样的对象'}
{'info': "0000208D: NameErr: DSID-0310020A, problem 2001 (NO_OBJECT), data 0, best match of: 'DC=mydomain,DC=com' ", 'matched': 'DC=mydomain,DC=com', 'desc': 'No such object'}
这里是代码片段:
def changePassword(userEmail, oldPassword, newPassword):
try:
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
ldap_client = ldap.initialize("ldap://127.0.01.1:389")
ldap_client.set_option(ldap.OPT_REFERRALS, 0)
ldap_client.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
ldap_client.set_option(ldap.OPT_X_TLS,ldap.OPT_X_TLS_DEMAND)
ldap_client.set_option( ldap.OPT_X_TLS_DEMAND, True )
ldap_client.set_option( ldap.OPT_DEBUG_LEVEL, 255 )
ldap_client.simple_bind_s(ADMIN_EMAIL, ADMIN_PASSWORD)
# Set AD password
#unicode_pass = unicode('"' + newPassword + '"', "iso-8859-1")
unicode_pass = newPassword
password_value = unicode_pass.encode("utf-16-le")
add_pass = [(ldap.MOD_REPLACE, 'unicodePwd', [password_value]),( ldap.MOD_REPLACE, 'unicodePwd', [password_value])]
# Replace password
try:
user_dn = 'CN=%s,DC=mydomain,DC=com' % username
ldap_client.modify_s(user_dn, add_pass)
print "Active Directory password for", username,
"was set successfully!"
except ldap.LDAPError, e:
sys.stderr.write('Error setting AD password for: ' + username + '
')
sys.stderr.write('Message: ' + str(e) + '
')
ldap_client.unbind_s()
return 'SOME_PROBLEM'
ldap_client.unbind_s()
return 'AUTHENTICATED'
except ldap.INVALID_CREDENTIALS:
ldap_client.unbind()
return 'INVALID_CREDENTIALS'
except ldap.SERVER_DOWN:
return 'SERVER_UNAVAILABLE'
b) passwd(userEmail, oldPassword, newPassword)
.它执行得很好,但密码没有更新.
b) passwd(userEmail, oldPassword, newPassword)
. It gets executed well but password is not updated.
在确定问题时需要帮助.
Need help in identifying the problem.
参考链接:Python+LDAP+SSL
python-ldap 和 Microsoft Active Directory:连接并删除用户
如何设置lockoutTime和Active Directory 用户的密码
如何更改密码对于使用 Python 的域用户(Windows Active Directory)?
https://groups.google.com/forum/#!topic/macromedia.coldfusion.security/Rq7xx15OeBs
http://www.grotan.com/ldap/python-ldap-samples.html#add
http://marcitland.blogspot.in/2011/02/python-active-directory-linux.html
https://snipt.net/Fotinakis/change-active-directory-password-via-ldap-modify-call/
解决方案
我遇到了同样的问题,并决定询问Server Fault.我得到的答案帮助我弄清楚我的代码出了什么问题.总而言之,更新 AD 密码有两种不同的方法:一种是普通用户更新自己的密码,另一种是管理员(或任何具有足够访问权限的帐户)为其他用户重置密码.
I had the very same issue and decided to ask on Server Fault. The answer I got helped me to figure out what was wrong in my code. To summarize, there is 2 diifferent methods to update an AD password: 1 for regular user updating his own password, and another 1 for administrator (or any account with sufficient access rights) resetting the password for another user.
方法一:用户自己更新密码
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_pa55word'
new_pwd = 'the_new_pa55word'
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
oldpwd_utf16 = '"{0}"'.format(old_pwd).encode('utf-16-le')
newpwd_utf16 = '"{0}"'.format(new_pwd).encode('utf-16-le')
mod_list = [
(ldap.MOD_DELETE, "unicodePwd", oldpwd_utf16),
(ldap.MOD_ADD, "unicodePwd", newpwd_utf16),
]
l.modify_s(ad_dn.format(username), mod_list)
方法二:管理员账号更新普通用户密码
ad_server = "ldaps://ad.xxx_domain.com"
ad_dn = "CN={0},OU=Users,OU=AF,DC=xxx_domain,DC=com"
admin_username = "i_am_the_admin"
admin_password = "admin123"
username = 'my_username'
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 (as admin user)
l.simple_bind_s(ad_dn.format(admin_username), admin_password)
# 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)
请注意,第二种方法需要绑定不同的账户(有足够的权限),但允许设置新密码而无需重新输入旧密码.
Please note that the second method needs to Bind with a different account (with sufficient rights) but allows to set the new password without re-typing the old one.
相关文章