#!/usr/bin/env python
# coding=UTF-8
'''
https://www.cnblogs.com/haiya2019/p/10627730.html
@Author: wjx
@Description: AD域
@Date: 2018-12-23 21:23:57
@LastEditTime: 2019-03-28 23:46:56
'''
from ldap3 import Server, Connection, ALL, NTLM
class Adoper():
'''
操作AD域的类
'''
def __init__(self, domain, ip, admin='administrator', pwd=None):
'''
domain: 域名,格式为:xxx.xxx.xxx
ip: ip地址,格式为:192.168.214.1
admin: 管理员账号
pwd: 管理员密码
'''
self.domain = domain
self.DC = ','.join(['DC=' + dc for dc in domain.split('.')]) # csc.com -> DC=csc,DC=com
self.pre = domain.split('.')[0].upper() # 用户登陆的前缀
self.ip = ip
self.admin = admin
self.pwd = pwd
self.server = Server(self.ip, get_info=ALL)
self.conn = Connection(self.server, user=self.pre+'\\'+self.admin, password=self.pwd, auto_bind=True, authentication=NTLM)
def search(self, org):
'''
查询组织下的用户
org: 组织,格式为:aaa.bbb 即bbb组织下的aaa组织,不包含域地址
'''
att_list = ['displayName', 'userPrincipalName','userAccountControl','sAMAccountName','pwdLastSet']
org_base = ','.join(['OU=' + ou for ou in org.split('.')]) + ',' + self.DC
res = self.conn.search(search_base=org_base,
search_filter='(objectclass=user)', # 查询数据的类型
attributes=att_list, # 查询数据的哪些属性
paged_size=1000) # 一次查询多少数据
if res:
for user in self.conn.entries:
yield user['displayName']
else:
print('查询失败: ', self.conn.result['description'])
return None
def add_org(self, org):
'''
增加组织
oorg: 组织,格式为:aaa.bbb 即bbb组织下的aaa组织,不包含域地址
'''
org_base = ','.join(['OU=' + ou for ou in org.split('.')]) + ',' + self.DC
res = self.conn.add(org_base, object_class='OrganizationalUnit') # 成功返回True,失败返回False
if res:
print(f'增加组织[ {org} ]成功!')
else:
print(f'增加组织[ {org} ]发生错误: ', self.conn.result['description'])
def add_user(self, org, name, uid):
'''
增加用户
org:增加到该组织下
name:显示名称
uid:账号
'''
org_base = ','.join(['OU=' + ou for ou in org.split('.')]) + ',' + self.DC
user_att = {
'displayName' : name,
'userPrincipalName' : uid + '@' + self.domain, # uid@admin组成登录名
'userAccountControl': '544', # 启用账号
'sAMAccountName': uid,
'pwdLastSet': -1 # 取消下次登录需要修改密码
}
res = self.conn.add(f'CN={uid},{org_base}', object_class='user',
attributes=user_att)
if res:
print(f'增加用户[ {name} ]成功!')
else:
print(f'增加用户[ {name} ]发生错误:', self.conn.result['description'])
if __name__ == '__main__':
ad93 = Adoper(domain='test.csc.com', ip='192.168.214.93', pwd='Winhong1234@#test')
for user in ad93.search('信息科技部.总行.cibuser'):
print(user)
ad93.add_org('python02.cibuser')
ad93.add_user('python02.cibuser', 'python03类用户', 'python03')
2###########分页
from ldap3 import Server, Connection, ALL
# 配置LDAP服务器和连接信息
server = Server('ldap.example.com')
conn = Connection(server, 'username', 'password', auto_bind=True)
# 搜索基础DN
base_dn = 'dc=example,dc=com'
# 搜索过滤器,这里使用了通配符过滤所有对象
search_filter = 'objectClass=*'
# 分页大小和搜索范围
page_size = 100
search_scope = ALL
# 执行分页搜索
paged_search_control = conn.extend.standard.paged_search(
base_dn,
search_filter,
size=page_size,
paged_criticality=False,
server_controls=[search_scope]
)
# 获取分页结果
pages = 0
while True:
response = conn.result
if response:
for entry in response:
print(entry)
pages += 1
if paged_search_control.cookie:
paged_search_control.set_cookie(response)
conn.extend.standard.paged_search(
paged_search_control=paged_search_control
)
else:
break
else:
break
print(f"Total pages: {pages}")
3分页############
from ldap3 import Server, Connection, ALL
# 自定义连接方式
host = '192.168.0.1'
port = 389
user = 'cn=admin,dc=example,dc=com'
password = 'admin'
base_dn = 'dc=example,dc=com'
# 创建LDAP服务器对象
server = Server(host=host, port=port, get_info=ALL)
# 创建LDAP连接
conn = Connection(server=server, user=user, password=password, client_strategy='SYNC', auto_bind=True)
# 分页查询操作
search_base = 'ou=people,' + base_dn
search_filter = '(objectclass=person)'
# 第一页查询
pagination_control = {'paged_criticality': True, 'paged_size': 10}
conn.search(search_base=search_base, search_filter=search_filter, attributes=['cn'], controls=pagination_control)
while True:
# 打印查询结果
for entry in conn.entries:
print('CN:', entry.cn)
# 获取下一页
pagination_control_cookie = None
for control in conn.response['controls']:
if control.__class__.__name__ == 'SimplePagedResultsControl':
pagination_control_cookie = control.cookie
break
if not pagination_control_cookie:
break
pagination_control['paged_cookie'] = pagination_control_cookie
conn.search(search_base=search_base, search_filter=search_filter, attributes=['cn'], controls=pagination_control)
print('Pagination operation successful')
4分页############
from ldap3 import Server, Connection, SUBTREE
total_entries = 0
server = Server('test-server')
c = Connection(server, user='username', password='password')
c.search(search_base = 'o=test',
search_filter = '(objectClass=inetOrgPerson)',
search_scope = SUBTREE,
attributes = ['cn', 'givenName'],
paged_size = 5)
total_entries += len(c.response)
for entry in c.response:
print(entry['dn'], entry['attributes'])
cookie = c.result['controls']['1.2.840.113556.1.4.319']['value']['cookie']
while cookie:
c.search(search_base = 'o=test',
search_filter = '(objectClass=inetOrgPerson)',
search_scope = SUBTREE,
attributes = ['cn', 'givenName'],
paged_size = 5,
paged_cookie = cookie)
total_entries += len(c.response)
cookie = c.result['controls']['1.2.840.113556.1.4.319']['value']['cookie']
for entry in c.response:
print(entry['dn'], entry['attributes'])
print('Total entries retrieved:', total_entries)
5分页############
# paged search wrapped in a generator
total_entries = 0
entry_generator = c.extend.standard.paged_search(search_base = 'o=test',
search_filter = '(objectClass=inetOrgPerson)',
search_scope = SUBTREE,
attributes = ['cn', 'givenName'],
paged_size = 5,
generator=True)
for entry in entry_generator:
total_entries += 1
print(entry['dn'], entry['attributes'])
print('Total entries retrieved:', total_entries)
###################
>>> searchParameters = { 'search_base': 'dc=demo1,dc=freeipa,dc=org',
>>> 'search_filter': '(objectClass=Person)',
>>> 'attributes': ['cn', 'givenName'],
>>> 'paged_size': 5 }
>>> while True:
>>> conn.search(**searchParameters)
>>> for entry in conn.entries:
>>> print(entry)
>>> cookie = conn.result['controls']['1.2.840.113556.1.4.319']['value']['cookie']
>>> if cookie:
>>> searchParameters['paged_cookie'] = cookie
>>> else:
>>> break