【发布时间】:2015-04-01 18:34:09
【问题描述】:
背景: 我正在开发一个 API 来集中用户创建和管理多个资源(例如 Google Apps、Dropbox 等)。 在 Linux VM 上,我开发了一个 API 和 Web 界面,允许我(和我的共同管理员)对这些服务的用户帐户进行身份验证和管理。 接下来我需要集成的是我们的 Active Directory,它托管在远程 Windows Server 2008 上。
我一直在尝试使用 python-ldap 连接并检索/修改信息,但遇到了 DIR_ERROR 操作错误(尝试查询用户时)和 NAMING_VIOLATION 错误(尝试添加用户时)的问题。
*基于http://www.grotan.com/ldap/python-ldap-samples.html、stackoverflow 问题和 python-ldap 文档的代码 我认为有效的绑定代码:
import ldap
try:
l = ldap.open("serverip")
l.protocol_version = ldap.VERSION3
username = "myUserName@adtest.local"
password = "secret"
result = l.simple_bind(username, password)
print result
except ldap.LDAPError, e:
print e
打印: (97, [], 1, [])
查询用户脚本: (按照文章的建议尝试不绑定,但收到“为了执行此操作,必须在连接上完成成功的绑定。”)
import ldap
try:
l = ldap.open("serverIp", port=389)
l.protocol_version = ldap.VERSION3
username = "myUserName@adtest.local"
password = "secret"
result = l.simple_bind(username, password)
print result
except ldap.LDAPError, e:
print e
# handle error however you like
baseDN = "ou=Users, o=adtest.local"
searchScope = ldap.SCOPE_SUBTREE
retrieveAttributes = None
searchFilter = "cn=*myUserName*"
try:
ldap_result_id = l.search(baseDN, searchScope, searchFilter, retrieveAttributes)
result_set = []
while 1:
result_type, result_data = l.result(ldap_result_id, 0)
if (result_data == []):
break
else:
if result_type == ldap.RES_SEARCH_ENTRY:
result_set.append(result_data)
print result_set
except ldap.LDAPError, e:
print e
结果如下: (97, [], 1, []) {'info': '000020D6: SvcErr: DSID-031007DB, 问题 5012 (DIR_ERROR), data 0\n','desc':'操作错误'}
添加用户脚本:(使用 ldaps)
import ldap
import ldap.modlist as modlist
# Open a connection
l = ldap.initialize("ldaps://serverIp:636/")
# Bind/authenticate with a user with apropriate rights to add objects
l.simple_bind_s("myUserName@adtest.local","secret")
# The dn of our new entry/object
dn="cn=test,dc=adtest,dc=local"
# A dict to help build the "body" of the object
attrs = {}
attrs['objectclass'] = ['top','organizationalRole','simpleSecurityObject']
attrs['cn'] = 'test'
attrs['userPassword'] = 'aDifferentSecret'
attrs['description'] = 'test user'
# Convert our dict to nice syntax for the add-function using modlist-module
ldif = modlist.addModlist(attrs)
# Do the add-operation to the ldapserver
l.add_s(dn,ldif)
# Disconnect and free resources when done
l.unbind_s()
这会导致: ldap.SERVER_DOWN: {'info': '收到了意外长度的 TLS 数据包。','desc': "Can't contact LDAP server"}
*这让我觉得端口可能是问题,所以我将初始化行更改为l = ldap.initialize("ldap://serverIp:389/"),类似于其他两个脚本。
现在我得到: ldap.NAMING_VIOLATION: {'info': "00002099: NameErr: DSID-0305109C, 问题 2005 (NAMING_VIOLATION), 数据 0, 最佳匹配:\n\t'dc=adtest, dc=local'\n", 'desc ': '命名违规'}
此外,我已经将 ou 和 uid 添加到 attrs 但没有发生错误变化。
我做错了什么或者我可以尝试做些什么不同的事情? 感谢您的任何帮助/建议!
编辑:我检查了我的服务器,并且端口 636 被正确设置为允许安全 LDAP 流量,所以我不知道为什么这给了我与普通 LDAP 不同的错误。 edit2:我尝试在我的添加脚本中更改以下行 dn="cn=test,dc=adtest.local"
我拥有的新输出(堆栈跟踪)是(我在其中添加了 print 语句以显示绑定实际上是在错误之前发生的):
(97, [], 1, [])
回溯(最近一次通话最后一次):
文件“test2.py”,第 21 行,<module>
l.add_s(dn,ldif)
文件“/usr/local/lib/python2.7/dist-packages/ldap/ldapobject.py”,第 202 行,在 add_s
返回 self.result(msgid,all=1,timeout=self.timeout)
结果中的文件“/usr/local/lib/python2.7/dist-packages/ldap/ldapobject.py”,第 465 行
resp_type, resp_data, resp_msgid = self.result2(msgid,all,timeout)
结果2中的文件“/usr/local/lib/python2.7/dist-packages/ldap/ldapobject.py”,第469行
resp_type, resp_data, resp_msgid, resp_ctrls = self.result3(msgid,all,timeout)
结果3中的文件“/usr/local/lib/python2.7/dist-packages/ldap/ldapobject.py”,第476行
resp_ctrl_classes=resp_ctrl_classes
结果4中的文件“/usr/local/lib/python2.7/dist-packages/ldap/ldapobject.py”,第483行
ldap_result = self._ldap_call(self._l.result4,msgid,all,timeout,add_ctrls,add_intermediates,add_extop)
文件“/usr/local/lib/python2.7/dist-packages/ldap/ldapobject.py”,第 106 行,在 _ldap_call
结果 = func(*args,**kwargs)
ldap.REFERRAL: {'info': '推荐:\nldap://adtest.local/cn=test,dc=adtest.local', 'desc': '推荐'}
【问题讨论】:
标签: python active-directory python-ldap