python使用ldap3模块操作windows2012域
脚本
#!/usr/bin/python3 # -*- coding: utf-8 -*- # 注意:ldap3库如果要使用tls(安全连接),需要ad服务先安装并配置好证书服务,才能通过tls连接,否则连接测试时会报LDAPSocketOpenError('unable to open socket' # 如果是进行账号密码修改及账户激活时,会报错:“WILL_NOT_PERFORM” import json from ldap3 import ALL_ATTRIBUTES,ALL from ldap3 import Connection, NTLM, Server,ServerPool,SUBTREE from ldap3 import MODIFY_REPLACE server1 = Server("172.18.188.7", port=636, use_ssl=True, get_info=ALL, connect_timeout=5) LDAP_SERVER_POOL = [server1] SERVER_USER = 'southpark\\administrator' SERVER_PASSWORD = "xxxxxxx" class AD(object): ''' AD用户操作 ''' def __init__(self): '''初始化''' self.conn = Connection( # 配置服务器连接参数 server=LDAP_SERVER_POOL, auto_bind=True, authentication=NTLM, # 连接Windows AD需要配置此项 read_only=False, # 禁止修改数据:True user=SERVER_USER, # 管理员账户 password=SERVER_PASSWORD, ) self.active_base_dn = 'ou=south,dc=southpark,dc=com' # 正式员工账户所在OU self.search_filter = '(objectclass=user)' # 只获取【用户】对象 self.ou_search_filter = '(objectclass=organizationalUnit)' # 只获取【OU】对象 def users_get(self): '''获取所有的用户''' self.conn.search(search_base=self.active_base_dn, search_filter=self.search_filter, attributes=ALL_ATTRIBUTES) res = self.conn.response_to_json() res = json.loads(res)['entries'] return res def OU_get(self): '''获取所有的OU''' self.conn.search(search_base=self.active_base_dn, search_filter=self.ou_search_filter, attributes=ALL_ATTRIBUTES) res = self.conn.response_to_json() res = json.loads(res)['entries'] return res def create_obj(self, dn, type, attr=None): ''' 新建用户or部门,User需要设置密码,激活账户 :param dn: dn = "ou=人事部3,ou=罗辑实验室,dc=adtest,dc=intra" #创建的OU的完整路径 dn = "cn=张三,ou=人事部3,ou=罗辑实验室,dc=adtest,dc=intra" #创建的User的完整路径 :param type:选项:ou or user :param attr = {#User 属性表,需要设置什么属性,增加对应的键值对 "SamAccountName": "zhangsan", # 账号 "EmployeeID":"1", # 员工编号 "Sn": "张", # 姓 "name": "张三", "telephoneNumber": "12345678933", "mobile": "12345678933", "UserPrincipalName":"zhangsan@adtest.com", "Mail":"zhangsan@adtest.com", "Displayname": "张三", "Manager":"CN=李四,OU=人事部,DC=adtest,DC=com",#需要使用用户的DN路径 } attr = {#OU属性表 'name':'人事部', 'managedBy':"CN=张三,OU=IT组,OU=罗辑实验室,DC=adtest,DC=intra", #部分负责人 } :return:True and success 是创建成功了 (True, {'result': 0, 'description': 'success', 'dn': '', 'message': '', 'referrals': None, 'type': 'addResponse'}) ''' object_class = {'user': ['user', 'posixGroup', 'top'], 'ou': ['organizationalUnit', 'posixGroup', 'top'], } res = self.conn.add(dn=dn, object_class=object_class[type], attributes=attr) if type == "user": # 如果是用户时,我们需要给账户设置密码,并把账户激活 self.conn.extend.microsoft.modify_password(dn, "123456") # 设置用户密码为123456 print(self.conn.result) self.conn.modify(dn, {'userAccountControl': [(MODIFY_REPLACE, ['66048'])]}) # 激活用户 self.conn.unbind() return res, self.conn.result def del_obj(self, DN): ''' 删除用户 or 部门 :param DN: :return:True ''' res = self.conn.delete(dn=DN) return res def __rename_obj(self, dn, newname): ''' OU or User 重命名方法 :param dn:需要修改的object的完整dn路径 :param newname: 新的名字,User格式:"cn=新名字";OU格式:"OU=新名字" :return:返回中有:'description': 'success', 表示操作成功 {'result': 0, 'description': 'success', 'dn': '', 'message': '', 'referrals': None, 'type': 'modDNResponse'} ''' self.conn.modify_dn(dn, newname) return self.conn.result def clock_unclock(self,dn,clock): """ 启用帐号:66048 为密码永不过期及启用帐号,单启用帐号为 512 self.conn.modify(CN, {'userAccountControl': [('MODIFY_REPLACE', ['66048'])]}) 禁用帐号:66050 为密码永不过期及禁用帐号,单禁用帐号为 514 self.conn.modify(CN, {'userAccountControl': [('MODIFY_REPLACE', ['66050'])]}) :param dn: 'CN=李四,OU=south,DC=southpark,DC=com' :param clock: true为解锁账号,false为禁用账号 :return: """ if clock: self.conn.modify(dn, {'userAccountControl': [('MODIFY_REPLACE', ['66048'])]}) self.conn.unbind() return self.conn.result else: self.conn.modify(dn, {'userAccountControl': [('MODIFY_REPLACE', ['66050'])]}) self.conn.unbind() return self.conn.result def auth(self,username,password): """ 用户认证接口 # """ ldap_user = '\\{}@southpark.com'.format(username) server = Server('172.18.188.7', use_ssl=False) connection = Connection(server, user=ldap_user, password=password, authentication=NTLM) connection.bind() res = connection.search( search_base="ou=south,dc=southpark,dc=com", search_filter='(sAMAccountName={})'.format(username), search_scope=SUBTREE, attributes=['cn', 'givenName', 'mail', 'sAMAccountName', 'memberOf'], paged_size=5 ) if res: entry = connection.response[0] attr_dict = entry['attributes'] print(attr_dict) print("username:%s ;res: %s" %(username,connection.bind())) connection.closed return (True, attr_dict.get('cn'), None) else: connection.closed return (False, None, '账号已锁定或密码错误') if __name__ == '__main__': # attr={ # 'cn': '李四', # 'displayName': '李, 四', # 'distinguishedName': 'CN=李四,OU=south,DC=southpark,DC=com', # 'givenName': '四', # 'name': '李四', # 'objectCategory': 'CN=Person,CN=Schema,CN=Configuration,DC=southpark,DC=com', # 'userPrincipalName': 'lisi@southpark.com', # 'sAMAccountName': 'lisi', #登陆用户名 # 'sn': '李', # 'telephoneNumber': 'xxxxxxxxxxx', # 'mail': 'lisi@163.com', # 'description': '['运维工程师']', # } # rest=AD().create_obj('CN=李四,OU=south,DC=southpark,DC=com','user',attr) # print(rest) res=AD().auth('ls','123456') # AD().clock_unclock('CN=李四,OU=south,DC=southpark,DC=com',False) print(res)
备注:
windows server 2012域只需要搭建好证书服务器就能使用ldaps://x.x.x.x:636连接了,可以搜索ldp打开客户端测试
参考链接:
https://cloud.tencent.com/developer/article/1623867 #ldap3模块使用方法
https://blog.wlzs.cn/python%E4%BD%BF%E7%94%A8ldap3%E8%BF%9B%E8%A1%8Cwindows-ad%E5%9F%9F%E7%AE%A1%E7%90%86/ #Python使用Ldap3进行Windows AD域管理
https://techexpert.tips/zh-hans/windows-zh-hans/%E9%80%9A%E8%BF%87-ssl-%E5%8A%9F%E8%83%BD%E5%90%AF%E7%94%A8%E6%B4%BB%E5%8A%A8%E7%9B%AE%E5%BD%95-ldap/ #活动目录-通过SSL启用LDAP
https://www.cnblogs.com/haiya2019/p/10627730.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通