You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用LDAP搜索过滤器查询Active Directory结果不全问题求助

LDAP搜索Active Directory用户结果不完整问题

环境与代码信息

依赖版本

  • ldap3: 2.9.1
  • Python: 3.9.16

连接配置

'ldap_server': 'ldap://IP:389',
'ldap_user': 'user',
'ldap_password': 'password',
'base_dn': 'DC=ORG,DC=COM'

连接代码

server = Server(config['ldap_server'], get_info=ALL)
conn = Connection(server, user=config['ldap_user'], password=config['ldap_password'], auto_bind=True)

用户查询函数

def get_domain_users(conn):
    search_filter = '(&(objectClass=user)(objectCategory=person)(!(sAMAccountName=*$))(!(userAccountControl:1.2.840.113556.1.4.803:=2)))'
    attributes = ['userAccountControl','displayName', 'sAMAccountName', 'mail', 'whenCreated', 'whenChanged', 'lastLogontimeStamp',
        'sAMAccountType', 'memberOf']

    conn.search(config['base_dn'], search_filter, SUBTREE, attributes=attributes)
    domain_users = []
    for entry in conn.entries:
        user_info = {
            'source.uac': get_account_type(entry['userAccountControl'].value)[1],
            'source.display_name': entry.displayName.value,
            'source.mail': entry.mail.value,
            'ad.memberOf': entry.memberOf.value,
            'ad.SamAccountName': entry.sAMAccountName.value,
            'ad.SamAccountType': get_sam_acc_type(entry.sAMAccountType.value)[1],
            'ad.whenCreated': str(entry.whenCreated.value),
            'ad.whenChanged': str(entry.whenChanged.value),
            'ad.lastLogonTime': str(entry.lastLogontimeStamp.value)
        }
        domain_users.append(user_info)
    return domain_users

问题描述

指定搜索范围内存在符合条件的用户,但当前搜索无法返回全部记录。过滤器已设置为筛选启用状态、sAMAccountName不以$结尾的用户,结果仍存在部分用户遗漏。


原因分析与修改建议

1. LDAP分页限制导致结果截断

Active Directory默认限制单页搜索结果数量(通常为1000条),ldap3默认未开启分页,当结果超过阈值时,仅返回第一页数据,后续用户会被遗漏。

修改建议:
在搜索时开启分页,可通过两种方式实现:

# 方式1:直接添加分页参数
conn.search(config['base_dn'], search_filter, SUBTREE, attributes=attributes, paged_size=1000)

# 方式2:使用PagedSearch类(更稳定)
from ldap3 import PagedSearch
domain_users = []
with PagedSearch(conn, config['base_dn'], search_filter, SUBTREE, attributes=attributes, paged_size=1000) as search:
    for entry in search:
        # 后续用户信息处理逻辑保持不变(需结合下文属性判断优化)
        user_info = {
            # ... 字段处理
        }
        domain_users.append(user_info)

2. 属性缺失引发循环中断

部分用户可能存在属性为空的情况(如mail、lastLogontimeStamp未配置),直接调用.value会抛出AttributeError,导致循环提前终止,后续用户无法被处理。

修改建议:
添加属性存在性判断,避免异常:

user_info = {
    'source.uac': get_account_type(entry['userAccountControl'].value)[1],
    'source.display_name': entry.displayName.value if 'displayName' in entry else None,
    'source.mail': entry.mail.value if 'mail' in entry else None,
    'ad.memberOf': entry.memberOf.value if 'memberOf' in entry else [],
    'ad.SamAccountName': entry.sAMAccountName.value,
    'ad.SamAccountType': get_sam_acc_type(entry.sAMAccountType.value)[1],
    'ad.whenCreated': str(entry.whenCreated.value) if 'whenCreated' in entry else None,
    'ad.whenChanged': str(entry.whenChanged.value) if 'whenChanged' in entry else None,
    'ad.lastLogonTime': str(entry.lastLogontimeStamp.value) if 'lastLogontimeStamp' in entry else None
}

注:memberOf为多值属性,空值时建议设为空列表,避免类型不一致问题。

3. 搜索过滤器存在转义错误

原过滤器中的&是HTML转义后的&,AD无法正确解析该字符,会导致过滤器逻辑失效,返回结果不符合预期。

修改建议:
修正过滤器的转义字符:

search_filter = '(&(objectClass=user)(objectCategory=person)(!(sAMAccountName=*$))(!(userAccountControl:1.2.840.113556.1.4.803:=2)))'

4. 绑定用户权限不足

如果绑定的LDAP用户没有读取AD中部分OU的权限,这些OU下的用户不会被返回。例如部分OU设置了独立权限,绑定用户无访问权限。

排查建议:

  • 通过AD用户和计算机工具,检查绑定用户对所有目标OU的读取权限。
  • 尝试使用域管理员账号测试,确认是否为权限问题。

内容的提问来源于stack exchange,提问作者Daniel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 04:33:15