使用LDAP_MATCHING_RULE_IN_CHAIN查询返回空结果的技术求助
解决Python中LDAP子组递归查询的问题
首先咱们先排查你用LDAP_MATCHING_RULE_IN_CHAIN返回空结果的原因,这个匹配规则对查询语法和base路径有严格要求,我帮你修正一下用法,再给你兜底的手动递归方案。
一、修正LDAP_MATCHING_RULE_IN_CHAIN的用法
你之前的写法有两个关键问题:
- Base路径不能限定在组OU:这个匹配规则是遍历整个域的组嵌套关系,如果你把base设为
OU=Security Groups,OU=Groups,DC=myserver,DC=com,会导致无法跨OU查找嵌套组,甚至可能截断链的遍历。 - 查询条件需要完整DN:只写
CN=MatchedRuleChainExample不足以让LDAP准确定位目标对象,必须传入目标的完整区分名(DN)。
修正后的代码示例
import ldap # 假设你已经通过connection = ldap.initialize(...)等步骤建立了有效连接 domain_base = 'DC=myserver,DC=com' # 改为域根路径 # 目标对象的完整DN,比如用户或组的完整路径 target_full_dn = 'CN=MatchedRuleChainExample,OU=Security Groups,OU=Groups,DC=myserver,DC=com' # 正确的匹配规则查询语法 search_criteria = f'(member:1.2.840.113556.1.4.1941:={target_full_dn})' attributes = ['member', 'groupType', 'description', 'memberOf'] # 执行查询 result = connection.search_ext_s( domain_base, ldap.SCOPE_SUBTREE, search_criteria, attributes, sizelimit=0 ) # 打印结果 for dn, attrs in result: print(f"找到组: {dn}") print(f"描述: {attrs.get('description', ['无描述'])[0]}")
二、如果匹配规则不可用,手动实现递归查询
有些LDAP服务器可能不支持这个匹配规则,或者你的账号没有足够权限,这时候可以手动递归遍历memberOf属性来实现嵌套查询:
递归查询函数示例
def get_all_nested_groups(connection, target_dn, visited_groups=None): # 用visited集合避免循环引用(比如组A包含组B,组B又包含组A) if visited_groups is None: visited_groups = set() # 查询直接包含目标的组 search_base = 'OU=Security Groups,OU=Groups,DC=myserver,DC=com' search_filter = f'(member={target_dn})' result = connection.search_ext_s( search_base, ldap.SCOPE_SUBTREE, search_filter, ['cn', 'description', 'memberOf'], sizelimit=0 ) nested_groups = [] for group_dn, group_attrs in result: if group_dn in visited_groups: continue visited_groups.add(group_dn) nested_groups.append((group_dn, group_attrs)) # 递归查询当前组所属的父组 nested_groups.extend(get_all_nested_groups(connection, group_dn, visited_groups)) return nested_groups # 使用示例 target_full_dn = 'CN=MatchedRuleChainExample,OU=Security Groups,OU=Groups,DC=myserver,DC=com' all_groups = get_all_nested_groups(connection, target_full_dn) # 输出所有嵌套组信息 for group_dn, attrs in all_groups: print(f"组DN: {group_dn}") print(f"组描述: {attrs.get('description', ['无'])[0]}") print("---")
注意事项
- 确保你的LDAP账号有权限读取
member和memberOf属性,否则会返回空结果或权限错误。 - 如果是查询用户所属的所有嵌套组,只需要把
target_full_dn换成用户的完整DN即可。 - 手动递归时一定要处理循环引用,避免无限递归。
内容的提问来源于stack exchange,提问作者ToastGhost
相关产品推荐
相关产品推荐

