通過python-ldap操作管理AD/LDAP用戶及組織結構
阿新 • • 發佈:2019-02-20
scribe 郵箱 單元 刪除 let use acc 字段 tgui
LDAP/AD是兩種應用最廣泛的認證服務器,AD是微軟基於LDAP開發而成的,應用於Windows平臺,而LDAP主要應用於Linux平臺(LDAP用在Windows平臺比較少)。既然AD是基於LDAP的擴展,則LDAP大部分協議,AD均可原生支持,這位我們操作和管理AD認證服務器提供了大大的便利。
在軟件開發過程中,很多公司都采用AD/LDAP用於自己的用戶認證體系,本文重點研究通過Python語言提供的Python-Ldap框架,來操作和管理AD/LDAP中的用戶,組織結構等,希望對大家有所幫助。
基本概念:
o– organization(組織-公司) ou – organization unit(組織單元/部門) c - countryName(國家) dc - domainComponent(域名組件) sn – suer name(真實名稱) cn - common name(常用名稱) dn - distinguished name(唯一標識)
AD和LDAP中的字段及含義:
- 用戶表字段對應關系:
字段描述 表示值 唯一標識 dn 用戶名 userPrincipalName(AD)/cn(LDAP) 密碼 userPassword 真實姓名 displayName 工作地點 physicalDeliveryOfficeName 職務 title 郵箱 mail 個人電話 telephoneNumber 公司電話 homePhone
- 組織結構表對應關系:
字段描述 表示值 唯一標識 dn 組織名稱 ou 組織描述 description
- 在AD中創建用戶
import ldap def create_ad_user(username, unicode_password, org_dn): l = ldap.initialize(‘ldap://172.16.1.163:636‘) #use secure port default:636 l.protocol_version = 3 l.set_option(ldap.OPT_REFERRALS, 0) l.simple_bind_s(‘Administrator‘, ‘P@ssword‘) user = {} user[‘objectclass‘] = [‘top‘, ‘person‘, ‘organizationalPerson‘, ‘user‘] user_dn = ‘cn=%s,%s‘ % (username,org_dn) user[‘userPrincipalName‘] = ‘%s@%s‘ % (username, domain) user[‘userAccountControl‘] = ‘66048‘ # active user account user[‘unicodePwd‘] = unicode_password ldif = modlist.addModlist(user) ret, _ = l.add_s(user_dn, ldif) print ret
- 在LDAP中創建用戶
import ldap def create_ldap_user(username, password, org_dn): l = ldap.initialize(‘ldap://172.16.1.163:389‘) l.protocol_version = 3 l.set_option(ldap.OPT_REFERRALS, 0) l.simple_bind_s(‘Administrator‘, ‘P@ssword‘) user = {} user[‘objectclass‘] = [‘top‘, ‘person‘, ‘inetOrgPerson‘] user[‘cn‘] = username user[‘sn‘] = user[‘cn‘] user[‘password‘] = password user_dn = ‘cn=%s,%s‘ % (username,org_dn) ldif = modlist.addModlist(user) ret, _ = l.add_s(user_dn, ldif) print ret
- 修改AD/LDAP用戶基本信息
import ldap def modify_user(username): firstname = ‘Abel‘ lastname = ‘Lee‘ l = ldap.initialize(‘ldap://172.16.1.163:389‘) l.protocol_version = 3 l.set_option(ldap.OPT_REFERRALS, 0) l.simple_bind_s(‘Administrator‘, ‘P@ssword‘) cn = username dn = ‘cn=%s,ou=org1,dc=testad,dc=com‘ % cn old = {‘description‘: ‘old description‘} new = {‘description‘: ‘new description‘} ldif = ldap.modifyModlist(old, new) ret = l.modify_s(dn, ldif) l.unbind_s() print ret
- 刪除AD/LDAP用戶
import ldap def delete_users(user_dn): l = ldap.initialize(‘ldap://172.16.1.163:389‘) l.protocol_version = 3 l.set_option(ldap.OPT_REFERRALS, 0) l.simple_bind_s(‘Administrator‘, ‘P@ssword‘) ret = l.delete_s(user_dn) l.unbind_s() print ret
- 查詢AD用戶信息
import ldap def describe_ad_users(org_dn=‘‘, usernames = []): l = ldap.initialize(‘ldap://172.16.1.163:389‘) l.protocol_version = 3 l.set_option(ldap.OPT_REFERRALS, 0) l.simple_bind_s(‘Administrator‘, ‘P@ssword‘) USER_ATTRS = [‘userAccountControl‘,‘displayName‘,‘description‘,‘homePhone‘,‘physicalDeliveryOfficeName‘,‘title‘,‘mail‘,‘telephoneNumber‘] filterstr = ‘(&(objectclass=user)‘ if len(usernames) > 0: filterstr = filterstr + ‘(|‘ for username in usernames: username = ‘%s@%s‘ % (username, domain) userPrincipalName = ‘(userPrincipalName=%s)‘ % username filterstr += userPrincipalName if len(usernames) > 0: filterstr += ‘))‘ else: filterstr += ‘)‘ if org_dn: ret = l.search_s(org_dn, ldap.SCOPE_SUBTREE, filterstr, attrlist=USER_ATTRS) else: ret = l.search_s(base_dn, ldap.SCOPE_SUBTREE, filterstr, attrlist=USER_ATTRS) print ret
- 查詢LDAP中的用戶
import ldap def describe_ldap_users(org_dn=‘‘, usernames = []): l = ldap.initialize(‘ldap://172.16.1.163:389‘) l.protocol_version = 3 l.set_option(ldap.OPT_REFERRALS, 0) l.simple_bind_s(‘Administrator‘, ‘P@ssword‘) USER_ATTRS = [‘userAccountControl‘,‘displayName‘,‘description‘,‘homePhone‘,‘physicalDeliveryOfficeName‘,‘title‘,‘mail‘,‘telephoneNumber‘] filterstr = ‘(&(objectclass=person)‘ if len(usernames) > 0: filterstr = filterstr + ‘(|‘ for cn in usernames: cn = ‘(cn=%s)‘ % cn filterstr += cn if len(usernames) > 0: filterstr += ‘))‘ else: filterstr += ‘)‘ if org_dn: ret = l.search_s(org_dn, ldap.SCOPE_SUBTREE, filterstr, attrlist=USER_ATTRS) else: ret = l.search_s(base_dn, ldap.SCOPE_SUBTREE, filterstr, attrlist=USER_ATTRS) print ret
- AD用戶認證
import ldap def login_ad(user_dn, password): l = ldap.initialize(‘ldap://172.16.1.163:389‘) l.protocol_version = 3 l.set_option(ldap.OPT_REFERRALS, 0) l.simple_bind_s(user_dn, password) cn = user_dn.split(‘,‘)[0].split(‘=‘) base_dn = ‘dc=testad,dc=com‘ domain = ‘testad.com‘ username = ‘%s@%s‘ % (cn[1], domain) ret = l.search_s(base_dn, ldap.SCOPE_SUBTREE,"(userPrincipalName=%s)" % username, ["userPrincipalName"]) if ret is None or len(ret) == 0: return False return True
- LDAP用戶認證
import ldap def login_ldap(user_dn, password): l = ldap.initialize(‘ldap://172.16.1.163:389‘) l.protocol_version = 3 l.set_option(ldap.OPT_REFERRALS, 0) l.simple_bind_s(user_dn, password) cn = user_dn.split(‘,‘)[0].split(‘=‘) base_dn = ‘dc=testad,dc=com‘ ret = l.search_s(base_dn, ldap.SCOPE_SUBTREE,"%s=%s" % (cn[0], cn[1])) if ret is None or len(ret) == 0: return False return True
- 設置AD用戶密碼,修改AD用戶密碼可以先認證再設置
import ldap def set_ad_password(user_dn, unicode_password): l = ldap.initialize(‘ldap://172.16.1.163:636‘) #use secure port l.simple_bind_s(‘Administrator‘, ‘P@ssword‘) param_pwd = [(ldap.MOD_REPLACE, ‘unicodePwd‘, [password_utf16]), (ldap.MOD_REPLACE, ‘unicodePwd‘, [password_utf16])] ret,_ = l.modify_s(user_dn, param_pwd) print ret
- 設置LDAP用戶密碼
import ldap def set_ldap_password(user_dn, password): l = ldap.initialize(‘ldap://172.16.1.163:389‘) l.protocol_version = 3 l.set_option(ldap.OPT_REFERRALS, 0) l.simple_bind_s(‘Administrator‘, ‘P@ssword‘) l.passwd_s(user_dn, None, password)
- 修改LDAP用戶密碼
import ldap def modify_ldap_password(user_dn, old_password, new_password): l = ldap.initialize(‘ldap://172.16.1.163:389‘) l.protocol_version = 3 l.set_option(ldap.OPT_REFERRALS, 0) l.simple_bind_s(‘Administrator‘, ‘P@ssword‘) l.passwd_s(user_dn, old_password, new_password)
- 創建AD/LDAP組織結構
import ldap def create_ou(parent_dn, ou): l = ldap.initialize(‘ldap://172.16.1.163:389‘) l.protocol_version = 3 l.set_option(ldap.OPT_REFERRALS, 0) l.simple_bind_s(‘Administrator‘, ‘P@ssword‘) attrs= {‘ou‘: ou} attrs[‘description‘] = ‘this is description‘ attrs[‘objectClass‘] = [‘organizationalUnit‘,‘top‘] dn = ‘ou=%s,%s‘ % (attrs[‘ou‘], parent_dn) ldif = modlist.addModlist(attrs) ret, _ = l.add_s(dn,ldif) print ret
- 修改AD/LDAP組織結構
import ldap def modify_ou(attrs={‘description‘: ‘new_description‘}): l = ldap.initialize(‘ldap://172.16.1.163:389‘) l.protocol_version = 3 l.set_option(ldap.OPT_REFERRALS, 0) l.simple_bind_s(‘Administrator‘, ‘P@ssword‘) old_attrs = {‘description‘: ‘old_description‘} ldif = modlist.modifyModlist(old_attrs, attrs) l.modify_s(dn,ldif)
- 刪除AD/LDAP組織結構
import ldap def delete_ou(dn): l = ldap.initialize(‘ldap://172.16.1.163:389‘) l.protocol_version = 3 l.set_option(ldap.OPT_REFERRALS, 0) l.simple_bind_s(‘Administrator‘, ‘P@ssword‘) l.delete_s(dn)
- 查詢AD/LDAP組織結構
import ldap def describe_ou(parent_dn=‘‘, org_dns=[]): ORGANIZATION_ATTRS = [‘ou‘, ‘description‘] l = ldap.initialize(‘ldap://172.16.1.163:389‘) l.protocol_version = 3 l.set_option(ldap.OPT_REFERRALS, 0) l.simple_bind_s(‘Administrator‘, ‘P@ssword‘) filterstr = ‘(&(objectclass=organizationalUnit)‘ for dn in org_dns: objectGUID = ‘(ou=%s)‘ % dn filterstr += objectGUID filterstr += ‘)‘ if parent_dn: ret = l.search_s(parent_dn, ldap.SCOPE_SUBTREE, filterstr, attrlist=ORGANIZATION_ATTRS) else: ret = l.search_s(base_dn, ldap.SCOPE_SUBTREE, filterstr, attrlist=ORGANIZATION_ATTRS) print ret
- 修改用戶所屬組織結構
import ldap def change_user_in_ou(user_dn, new_org_dn): l = ldap.initialize(‘ldap://172.16.1.163:389‘) l.protocol_version = 3 l.set_option(ldap.OPT_REFERRALS, 0) l.simple_bind_s(‘Administrator‘, ‘P@ssword‘) cn = user_dn.split(‘,‘)[0] ret = l.rename_s(user_dn, cn, new_org_dn) print ret
註意:AD和LDAP中如:創建用戶,查詢用戶等操作,其使用端口和查詢字段均有差異,還請格外註意,另外,代碼如有不明確指出,歡迎留言討論。
通過python-ldap操作管理AD/LDAP用戶及組織結構