如何通过LDAP获取FreeIPA域用户的全部属性
如何获取FreeIPA域用户的所有LDAP属性(包括空属性)
我在通过LDAP获取FreeIPA域用户的全部属性时遇到问题:ldapsearch和ipa user-show仅返回非空属性,但我需要获取用户的所有属性。我正在使用Python的ldap3库编写脚本,以下是脚本示例:
from ldap3 import Server, Connection, ALL, SUBTREE, ALL_ATTRIBUTES ldap_server = 'ldap://$my_server$' ldap_user = 'uid=admin,cn=users,cn=accounts,dc=$my_dc$,dc=local' ldap_password = '$my_pass$' base_dn = 'cn=users,cn=accounts,dc=$my_dc$,dc=local' server = Server(ldap_server, get_info=ALL) conn = Connection(server, user=ldap_user, password=ldap_password, auto_bind=True) search_filter = '(uid=admin)' conn.search(search_base=base_dn, search_filter=search_filter, search_scope=SUBTREE, attributes=['*']) if conn.entries: user = conn.entries[0] print(f"User DN: {user.entry_dn}") for attribute in user.entry_attributes: print(f"{attribute}: {user[attribute]}") else: print("User not found") conn.unbind()
有意思的是,如果显式指定某个空属性(如attributes=['$my_attr$']),脚本会返回该属性的空值$my_attr$: [],但我不清楚LDAP浏览器是如何获取全部属性的,基础ldapsearch命令加参数也无法解决。
解决方法
方法1:通过LDAP Schema获取用户对象类的所有属性
FreeIPA用户属于特定LDAP对象类(如inetOrgPerson、posixAccount、ipaUser等),可以先查询用户的对象类,再从LDAP Schema中提取这些对象类的所有属性(含必选、可选),最后逐个查询这些属性:
from ldap3 import Server, Connection, ALL, SUBTREE ldap_server = 'ldap://$my_server$' ldap_user = 'uid=admin,cn=users,cn=accounts,dc=$my_dc$,dc=local' ldap_password = '$my_pass$' base_dn = 'cn=users,cn=accounts,dc=$my_dc$,dc=local' server = Server(ldap_server, get_info=ALL) conn = Connection(server, user=ldap_user, password=ldap_password, auto_bind=True) # 1. 查询目标用户的对象类 search_filter = '(uid=admin)' conn.search(search_base=base_dn, search_filter=search_filter, search_scope=SUBTREE, attributes=['objectClass']) if not conn.entries: print("User not found") conn.unbind() exit() user = conn.entries[0] object_classes = user['objectClass'] # 2. 从Schema中提取对象类的所有属性 all_attributes = set() for oc in object_classes: oc_schema = server.schema.object_classes[oc] all_attributes.update(oc_schema.must_contain) # 必选属性 all_attributes.update(oc_schema.may_contain) # 可选属性 # 3. 查询用户的所有属性(空属性会返回空列表) conn.search(search_base=base_dn, search_filter=search_filter, search_scope=SUBTREE, attributes=list(all_attributes)) user_full = conn.entries[0] print(f"User DN: {user_full.entry_dn}") for attr in sorted(all_attributes): print(f"{attr}: {user_full[attr]}") conn.unbind()
方法2:使用ldapsearch的特殊参数
默认ldapsearch不返回空属性,但可以通过*获取所有普通属性、+获取操作属性,再显式列出需要的空属性(因为LDAP服务器默认不会主动返回未赋值的属性):
ldapsearch -x -D "uid=admin,cn=users,cn=accounts,dc=$my_dc$,dc=local" -W -b "cn=users,cn=accounts,dc=$my_dc$,dc=local" "(uid=admin)" "*" "+" "attr1" "attr2"
注:attr1、attr2需替换为你需要的空属性名称,LDAP浏览器也是通过预先加载对象类的属性列表,再逐个对比展示空字段的。
核心原因
LDAP协议默认仅返回已赋值的属性,目的是减少数据传输量。要获取全部属性,必须先从Schema中拿到对象类的完整属性定义,再逐个查询这些属性。
内容的提问来源于stack exchange,提问作者Ylonya
相关产品推荐
相关产品推荐

