文章目录

  • 模块作用
  • 模块安装
  • 代码示例
  • 参考文档

模块作用

python操作ldap的库, 可以对ldap的数据进行增删改查,官方文档地址:https://www.python-ldap.org/en/latest/index.html

模块安装

pip install python-ldap

代码示例

  • 不断完善中……
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @File  : testldap.py
# @Author: xxx.xxxxx
# @Date  : 2022/3/3 16:34
# @Desc  :
import ldap
import ldap.modlist as modlistLDAP_CONFIG = {"HOST": "ldap://127.0.0.1:389","USERNAME": "cn=admin,dc=example,dc=org","PASSWORD": "admin","BASE_DN": "dc=example,dc=org"
}class LDAPBackend(object):"""Authenticates with ldap."""_connection = None_connection_bound = Falsedef authenticate(self, username=None, passwd=None, **kwargs):if not username or not passwd:return Noneif self._authenticate_user_dn(username, passwd):# user = self._get_or_create_user(username, passwd)# return userreturn "pass"else:return None@propertydef connection(self):if not self._connection_bound:self._bind()return self._get_connection()def _bind(self):self._bind_as(LDAP_CONFIG['USERNAME'], LDAP_CONFIG['PASSWORD'], True)def _bind_as(self, bind_dn, bind_password, sticky=False):self._get_connection().simple_bind_s(bind_dn, bind_password)self._connection_bound = stickydef _get_connection(self):if not self._connection:self._connection = ldap.initialize(LDAP_CONFIG['HOST'])return self._connectiondef _authenticate_user_dn(self, username, passwd):bind_dn = 'cn=%s,%s' % (username, LDAP_CONFIG['BASE_DN'])try:self._bind_as(bind_dn, passwd, False)return Trueexcept ldap.INVALID_CREDENTIALS:return Falsedef _get_or_create_user(self, username, passwd):# 获取或者新建Userpass# return userdef create_ldap_user(self, username, password, ou):l = self.connectionuser = {}try:user['objectclass'] = ["top", "person", "organizationalPerson", "inetOrgPerson"]user['cn'] = usernameuser['sn'] = user['cn']user['userPassword'] = passworduser_dn = 'cn=%s,cn=%s,%s' % (username, ou, LDAP_CONFIG["BASE_DN"])# 用户的属性值转化为bytesuser = {key: [v.encode("utf-8") if type(v) == str else v for v in values] if type(values) == list else values.encode("utf-8") for key, values in user.items()}ldif = modlist.addModlist(user)ret = l.add_s(user_dn, ldif)if ret:print(f"dn={user_dn} is successfully created.")return retexcept TypeError as e:print(e)except ldap.ALREADY_EXISTS as e:print(f"dn={user_dn} is Already exists")except Exception as e:print(e)def create_ldap_ou(self, ou):""":param ou::return:"""l = self.connectionattrs = {}attrs['objectclass'] = ["top", "organizationalUnit"]attrs['ou'] = ouou_dn = 'ou=%s,%s' % (ou, LDAP_CONFIG["BASE_DN"])# 字符换转化为字节attrs = {key: [v.encode("utf-8") if type(v) == str else v for v in values] if type(values) == list else values.encode("utf-8") for key, values in attrs.items()}ldif = modlist.addModlist(attrs)ret = l.add_s(ou_dn, ldif)print(f"dn={ou_dn} is successfully created.")return retdef create_ldap_group(self, ou, gpname):""":return:"""l = self.connectionattrs = {}attrs['objectclass'] = ["top", "groupOfNames"]attrs['cn'] = gpname# 必须有member属性attrs['member'] = "cn=luonan,cn=Users,dc=example,dc=org"group_dn = 'cn=%s,ou=%s,%s' % (gpname, ou, LDAP_CONFIG["BASE_DN"])# 字符换转化为字节user = {key: [v.encode("utf-8") if type(v) == str else v for v in values] if type(values) == list else values.encode("utf-8") for key, values in attrs.items()}ldif = modlist.addModlist(user)ret = l.add_s(group_dn, ldif)print(f"group:{group_dn} successfully created!")return retdef get_ldap_users_dn(self, org_dn=''):""":param org_dn::return: [dn]"""l = self.connectionfilter_str = '(&(objectclass=person))'usr_dn=[]if org_dn:ret = l.search_s(org_dn, ldap.SCOPE_SUBTREE, filter_str)else:ret = l.search_s(LDAP_CONFIG["BASE_DN"], ldap.SCOPE_SUBTREE, filter_str)# 只获取用户的dnfor dn in ret:# print(type(dn), dn)usr_dn.append(dn[0])return usr_dndef add_users_to_group(self, ou, group_name):""":param group_name: 组名,字符串类型如"groupname";:return:注函数中定义的参数modlist可以接受多个参数列表,其中:MOD_ADD: 如果属性存在,这个属性可以有多个值,那么新值加进去,旧值保留MOD_DELETE :如果属性的值存在,值将被删除MOD_REPLACE :这个属性所有的旧值将会被删除,这个值被加进去举例:[( ldap.MOD_ADD, 'memberUid', 'user1' ),( ldap.MOD_DELETE, 'memberUid', 'user3')]"""users = self.get_ldap_users_dn()modlist = []if users:for us in users:modlist.append((ldap.MOD_ADD, 'member', us.encode("utf-8")))try:l = self.connectiongroup_dn = "cn=%s,ou=%s,%s" % (group_name, ou, LDAP_CONFIG["BASE_DN"])l.modify_s(group_dn, modlist)l.unbind_s()return Trueexcept ldap.LDAPError as e:print("%s update users failed,reason: %s" % (group_dn, str(e)))return Falsedef add_user_to_group(self, ou, group_name):""":param group_name: 组名,字符串类型如"groupname";:return:注函数中定义的参数modlist可以接受多个参数列表,其中:MOD_ADD: 如果属性存在,这个属性可以有多个值,那么新值加进去,旧值保留MOD_DELETE :如果属性的值存在,值将被删除MOD_REPLACE :这个属性所有的旧值将会被删除,这个值被加进去举例:[( ldap.MOD_ADD, 'memberUid', 'user1' ),( ldap.MOD_DELETE, 'memberUid', 'user3')]"""try:l = self.connectiongroup_dn = "cn=%s,ou=%s,%s" % (group_name, ou, LDAP_CONFIG["BASE_DN"])users = self.get_ldap_users_dn()if users:for us in users:data = []try:data.append((ldap.MOD_ADD, 'member', us.encode("utf-8")))l.modify_s(group_dn, data)print(f"{group_dn} successfully added user:{us}")except ldap.TYPE_OR_VALUE_EXISTS as e:print("%s update users failed,reason: %s" % (group_dn, str(e)))continuel.unbind_s()return Trueexcept ldap.LDAPError as e:print("%s update users failed,reason: %s" % (group_dn, str(e)))return Falseif __name__ == "__main__":ld = LDAPBackend()# 用户鉴权# users = ld.authenticate('admin', 'admin')# 创建用户# ld.create_ldap_user(username="ln05", password="example123", ou="Users")# 创建ou# ld.create_ldap_ou(ou='MGroups')# 在ou 下创建组# ld.create_ldap_group(ou='MGroups', gpname="gp004")# 查询ldap下的所有用户,默认查询全部# users = ld.get_ldap_users_dn()# for u in users:#     print(type(u), u)# 给用户组批量添加用户# ld.add_users_to_group(ou='MGroups',  group_name='gp001')# 给用户组逐个添加用户ld.add_user_to_group(ou='MGroups',  group_name='gp003')

参考文档

  1. https://www.cnblogs.com/linxiyue/p/10250243.html
  2. https://codingdict.com/sources/py/ldap/18943.html #开源实例
  3. https://blog.51cto.com/u_14207158/2352634 #AD/LDAP
  4. https://www.cnblogs.com/huiyichanmian/p/12600710.html #用户认证
  5. https://my.oschina.net/shawnplaying/blog/733338 #LDAP3

python-ldap模块相关推荐

  1. Python Re 模块超全解读!详细

    内行必看!Python Re 模块超全解读! 2019.08.08 18:59:45字数 953阅读 121 re模块下的函数 compile(pattern):创建模式对象 > import ...

  2. python argparse模块_Python argparse模块应用实例解析

    这篇文章主要介绍了Python argparse模块应用实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 简介 argparse是python ...

  3. 关于使用python logging模块的几点总结

    关于使用python logging模块的几点总结 使用python的标准日志模块logging可以非常方便地记录日志.Python日志系统非常丰富.添加结构化或非结构化日志输出到python代码,写 ...

  4. python高级-模块(14)

    一.python中的模块 有过C语言编程经验的朋友都知道在C语言中如果要引用sqrt函数,必须用语句#include <math.h>引入math.h这个头文件,否则是无法正常进行调用的. ...

  5. 转载: Python os 模块的功能以及子函数介绍

    原文链接: python之os模块 - 程序生(Codey) - 博客园 https://www.cnblogs.com/cxscode/p/8085326.html 一.Python OS模块介绍 ...

  6. 简单介绍python process模块

    在python中大部分情况需要使用多进程,python提供了multiprocessing模块.multiprocessing模块的功能众多:支持子进程.通信和共享数据.执行不同形式的同步,提供了Pr ...

  7. python io模块_python中的StringIO模块

    原博文 2015-10-23 15:21 − # python中的StringIO模块 标签:python StringIO --- > 此模块主要用于在内存缓冲区中读写数据.模块是用类编写的, ...

  8. python正则表达式需要模块_使用Python正则表达式模块,让操作更加简单

    处理文本数据的一个主要任务就是创建许多以文本为基础的特性. 人们可能想要在文本中找出特定格式的内容,比如找出存在于文本中的电子邮件,或者大型文本中的电话号码. 虽然想要实现上述功能听起来很繁琐,但是如 ...

  9. python导入模块有同名_Python:导入与函数同名的模块

    背景:第一次在SE上提问.我在 Python方面还很陌生,而且在编程方面也不是很有经验.我已经四处寻找,但我没有找到这个问题的答案,我非常感谢你的帮助. 我的问题是:如何导入与函数同名的模块? 具体来 ...

  10. python第三方模块—psutil模块

    系统基础信息采集模块作为监控模块的重要组成部分,能够帮助运维人员了解当前系统的健康程度,同时也是衡量业务的服务质量的依据,比如系统资源吃紧,会直接影响业务的服务质量及用户体验,另外获取设备的流量信息, ...

最新文章

  1. 神奇的 SQL,Group By 真扎心,原来是这样!
  2. python大牛 关东升_《Python从小白到大牛》第4章 Python语法基础
  3. MySQL存储过程_创建-调用
  4. Essential C++中文版 前言
  5. 学习面向对象和设计模式的好地方
  6. 转观念 变架构 补短板——析科华恒盛向数据中心方案商转型
  7. 进程调度算法 C++实现
  8. Python PIP Mysql-python 报错 ERROR: Command errored out with exit status 1: python setup.py egg_info C
  9. 网页设计中时尚​​的下拉菜单案例
  10. bokeh python_Python Bokeh数据可视化教程
  11. [javascript] Promise API
  12. 关于去除Eclipse对JavaScript的验证
  13. 小学计算机属于数学与科学吗,我是计算机专业,想考小学信息技术教师资格证没有,那我是报科学还是...
  14. java 序列化,流,二进制的区别和联系
  15. spring quartz 表达式在线生成器
  16. 截止失真放大电路_反馈/反馈电路/反馈类型的判别方法
  17. 9. 成功解决:Driver class ‘org.gjt.mm.mysql.Driver‘ could not be found
  18. Android Studio项目编码设置为GBK或UTF-8  中文乱码 和 Eclipse项目编码设置
  19. [网络安全学习篇1]:windowsxp、windows2003、windows7、windows2008系统部署(千峰网络安全视频笔记)
  20. 很火的《脱口秀大会》里的他们竟然都是程序员

热门文章

  1. Redux入门0x101: 简介及`redux`简单实现
  2. Ethernet(以太网)之二 物理介质(10Base、100Base-T、100Base-TX等)
  3. 点击箭头 切图 html,项目切图规范 css精灵图 css小箭头代码 BFC (Block Formatting Context) 块级格式化上下文...
  4. java 查找关键字_java实现简单的关键字查找
  5. 国泰君安国际获“最佳金融公司”等多项大奖
  6. 人脸识别常用的性能评价指标
  7. 钉钉对接U8 - 报销单
  8. 纺织行业MES系统解决方案
  9. 云计算终结传统密码体系?“密码云”重塑密码基础设施
  10. 免费的天气API接口 获取今日, 未来3天, 未来7天天气预报数据