使用 Python-LDAP 操作 LDAP
2012年11月26日 | 标签: ldap, python, python-ldap | 作者:vpsee
周末看到那些排队血拼的人们,不用走进 shopping mall、不用看到那些五颜六色的打折和视觉冲击就能感受到 “节日要到了!”。一年又快结束了,这周完成备份、升级之类的收尾工作,接下来就是6周的假期,没啥大安排,假期第1周去南非德班参加高性能计算会议,回来后和家人短途旅行,然后圣诞节在家休息学点新东西,比如修车什么的,几次痛苦经历告诉我出来玩迟早是要坏的,对于 hiking/camping/road trip/4×4 这几个关键字的爱好者来说懂点维修常识是必须的。废话留到假期再说吧,接下来六周可能没有技术方面的博客更新~
最近对 LDAP 服务器上面的数据做处理,有机会接触了一下 Python-LDAP 这个库和 LDAP/Kerberos. 去除所有打印和错误处理的代码后,用 Python-LDAP 操作 LDAP 的骨干代码其实很简单,就这么几行,唯一遇到的一个小麻烦就是折腾了一个多小时才知道 ‘TRUE’ 要大写(后面有说到)。
安装 Python-LDAP
在 Ubuntu/Debian 下安装 python-ldap 模块:
$ sudo apt-get install python-ldap
在 CentOS/RHEL 下安装 python-ldap 模块:
# yum install python-ldap
创建
创建一条 LDAP 新纪录。有个要注意的地方,我们的 LDAP 有个属性 active,用来判断用户帐号是否是激活的 attrs[‘active’] = ‘TRUE’,这里的 ‘TRUE’ 不能用小写的 ‘true’,刚开始被 LDAP 管理工具上的小写 ‘true’ 误导,老以为 Python 程序里也应该用小写,结果总报错。
def ldap_add(firstname, lastname, username): l = ldap.open(LDAP_HOST) l.protocol_version = ldap.VERSION3 l.simple_bind(LDAP_BIND, LDAP_PASS) cn = firstname + ' ' + lastname addDN = "cn=%s,ou=People,dc=vpsee,dc=com" % cn attrs = {} attrs['objectclass'] = ['top','person','inetOrgPerson','posixAccount','vpseeAccount'] attrs['cn'] = cn attrs['givenName'] = firstname attrs['homeDirectory'] = '/home/people/%s' % username attrs['loginShell'] = '/bin/bash' attrs['sn'] = lastname attrs['uid'] = username attrs['uidNumber'] = ldap_newuid() attrs['gidNumber'] = ldap_getgid() attrs['active'] = 'TRUE' ldif = modlist.addModlist(attrs) l.add_s(addDN, ldif) l.unbind_s()
查找和读取
查找和读取一条 LDAP 纪录,比如根据 username 查找出 cn:
def ldap_getcn(username): try: l = ldap.open(LDAP_HOST) l.protocol_version = ldap.VERSION3 l.simple_bind(LDAP_BIND, LDAP_PASS) searchScope = ldap.SCOPE_SUBTREE searchFilter = "uid=*" + username + "*" resultID = l.search(LDAP_BASE, searchScope, searchFilter, None) result_set = [] while 1: result_type, result_data = l.result(resultID, 0) if (result_data == []): break else: if result_type == ldap.RES_SEARCH_ENTRY: result_set.append(result_data) return result_set[0][0][1]['cn'][0] except ldap.LDAPError, e: print e
更新
更新一条 LDAP 纪录,比如更新用户状态 active 为 false:
def ldap_deactive(username): try: l = ldap.open(LDAP_HOST) l.protocol_version = ldap.VERSION3 l.simple_bind(LDAP_BIND, LDAP_PASS) deactiveDN = ("cn=%s," + LDAP_BASE) % ldap_getcn(username) old = {'active':'TRUE'} new = {'active':'FALSE'} ldif = modlist.modifyModlist(old, new) l.modify_s(deactiveDN, ldif) l.unbind_s() except ldap.LDAPError, e: print e
删除
删除一条 LDAP 纪录:
def ldap_delete(username): try: l = ldap.open(LDAP_HOST) l.protocol_version = ldap.VERSION3 l.simple_bind(LDAP_BIND, LDAP_PASS) deleteDN = ("cn=%s," + LDAP_BASE) % ldap_getcn(username) l.delete_s(deleteDN) except ldap.LDAPError, e: print e
额,不知道这个请求是否冒昧~~~
是否可以出个XEN PV的VPS安装配置sendmail然后可以让WordPress正常发送邮件的教程?
看了一下你的博客,收藏了很多文章,总算可以说下建议了^_^
第一印象是网站够简洁,我喜欢,哈哈;
而第二印象则是看的比较繁琐.
每一页都是那么长,我看文章喜欢只看标题,觉得比较好的直接点进去,不好的越过.
一个好的标题加上丰富的内容,足以吸引人进入内页.
而vpsee的内容,都是长篇的-_-,所以,我觉得首页显示摘要比较好,比较适合阅读.
当然我不是视图改变别人的想法,而是提一个建议:)
@花舞花落泪
只显示标题适合新闻类网站,大部分读者都喜欢在首页直接阅读文章,不喜欢看了标题还要点击才能看文章(多点击一次多麻烦一次,我们和读者都喜欢简单。)
请问博主你的这个wp主题叫什么名字,还有你的代码插件叫什么名字啊!嘿嘿,挺好看的,求教了啊!谢谢阿
请问博主,ldap dn的active属性,是哪个objectClass包含的?
博主给出一下
LDAP_HOST
LDAP_BIND
LDAP_PASS
LDAP_BASE
啊…
LDAP获取数据最多返回1000行,在python下有解决方法吗?
#!/bin/env python
import sys
import ldap
ldapconn = ldap.initialize(‘ldap://domain.adserve.com’)
print ldapconn
print ldapconn.simple_bind(‘cn=xixi,dc=adserve,dc=com’, ‘123456Zz’)
ldapconn.protocal_version = ldap.VERSION3
searchScope = ldap.SCOPE_SUBTREE
retrieveAttributes = None
searchFilter = “cn=” + ‘xixi’
ldap_result_id=ldapconn.search(‘dc=adserve,dc=com’, searchScope, searchFilter, retrieveAttributes)
print ldap_result_id
result_type, result_data = ldapconn.result(ldap_result_id, 0)
if result_type == ldap.RES_SEARCH_ENTRY:
a=result_data[0][0]
ldapconn.simple_bind_s(a,’123456Zz’)
ldapconn.passwd_s(a,’123456Zz’,’123456Zyy’)
ldapconn.unbind()
运行结果:
1
2
Traceback (most recent call last):
File “change_passwd.py”, line 18, in
result_type, result_data = ldapconn.result(ldap_result_id, 0)
File “/usr/local/lib/python2.7/site-packages/python_ldap-2.4.25-py2.7-linux-x86_64.egg/ldap/ldapobject.py”, line 504, in result
resp_type, resp_data, resp_msgid = self.result2(msgid,all,timeout)
File “/usr/local/lib/python2.7/site-packages/python_ldap-2.4.25-py2.7-linux-x86_64.egg/ldap/ldapobject.py”, line 508, in result2
resp_type, resp_data, resp_msgid, resp_ctrls = self.result3(msgid,all,timeout)
File “/usr/local/lib/python2.7/site-packages/python_ldap-2.4.25-py2.7-linux-x86_64.egg/ldap/ldapobject.py”, line 515, in result3
resp_ctrl_classes=resp_ctrl_classes
File “/usr/local/lib/python2.7/site-packages/python_ldap-2.4.25-py2.7-linux-x86_64.egg/ldap/ldapobject.py”, line 522, in result4
ldap_result = self._ldap_call(self._l.result4,msgid,all,timeout,add_ctrls,add_intermediates,add_extop)
File “/usr/local/lib/python2.7/site-packages/python_ldap-2.4.25-py2.7-linux-x86_64.egg/ldap/ldapobject.py”, line 107, in _ldap_call
result = func(*args,**kwargs)
ldap.OPERATIONS_ERROR: {‘info’: ‘000004DC: LdapErr: DSID-0C0906E8, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, v1db1’, ‘desc’: ‘Operations error’}
请问一下出错原因是什么?谢谢~ 查了很多相关的也没有解决
您好,我想问下您的 ldap_newuid 是自己写的模块吗
我遇见了和你相似的报错
请问你现在解决了吗,如果解决了,请指导一下
谢谢
您好,请教一下,为什么的导入的python-ldap库里没有modlist.modifyModlist(old, new)方法,找了很多资料没有介绍的
您好,能请教一下怎么使用modlist方法吗,我导入python-ldap库之后用不了这个,谢谢
ldap 没有active这个属性,是通过userAccountControl属性控制的
请问modlist方法怎么用呢