MS Active Directory中ldapsearch过滤器通配符失效问题排查求助
微软AD中memberUid属性通配符过滤失效问题排查与解决
问题描述
在微软Active Directory(MS AD)环境中使用ldapsearch查询时,遇到以下异常:
- 使用
memberUid完整属性值过滤能正常返回匹配结果 - 使用通配符
*对memberUid做前缀匹配时,返回空结果 - 该问题仅出现在MS AD中,OpenLDAP环境下两种查询均正常运行
正常工作的命令及结果
/usr/bin/ldapsearch -x -o ldif-wrap=no -D "cn=Manager,dc=learnitguide,dc=net" -b "dc=learnitguide,dc=net" -l 10 -w <Pass> -H ldap://<ip>:<port> "(memberUid=uid=ldap_test3,ou=People,dc=learnitguide,dc=net)"
返回结果:
# LDAPv3 # base <ou=People,dc=learnitguide,dc=net> with scope subtree # filter: (memberUid=uid=ldap_test3,ou=People,dc=learnitguide,dc=net) # requesting: ALL dn: cn=LDAP_GRP4,ou=People,dc=learnitguide,dc=net objectClass: posixGroup objectClass: top cn: LDAP_GRP4 gidNumber: 91878 memberUid: uid=ldap_test3,ou=People,dc=learnitguide,dc=net memberUid: uid=ldap_test11,ou=People,dc=learnitguide,dc=net memberUid: ldap_test12 # search result search: 2 result: 0 Success # numResponses: 2 # numEntries: 1
无法正常工作的命令及结果
/usr/bin/ldapsearch -x -o ldif-wrap=no -D "cn=Manager,dc=learnitguide,dc=net" -b "dc=learnitguide,dc=net" -l 10 -w <Pass> -H ldap://<ip>:<port> "(memberUid=uid=ldap_test3*)"
返回结果:
# LDAPv3 # base <ou=People,dc=learnitguide,dc=net> with scope subtree # filter: (memberUid=uid=ldap_test3*) # requesting: ALL # search result search: 2 result: 0 Success # numResponses: 1
原因分析
- 索引机制限制:MS AD中
memberUid是为兼容POSIX规范添加的属性,默认未启用子字符串索引。当使用通配符做前缀匹配时,AD无法通过索引快速定位结果,且默认不会对无索引属性执行全量扫描,因此返回空结果。 - 字符串匹配逻辑差异:OpenLDAP会自动解析DN格式的属性值进行匹配,但AD将
memberUid的完整DN值视为普通字符串,通配符匹配仅针对纯文本前缀,无索引支持时无法触发有效查询。
解决方案
方案1:改用AD原生member属性查询
AD原生使用member属性存储用户完整DN,该属性默认支持子字符串匹配且索引完善,修改查询命令如下:
/usr/bin/ldapsearch -x -o ldif-wrap=no -D "cn=Manager,dc=learnitguide,dc=net" -b "dc=learnitguide,dc=net" -l 10 -w <Pass> -H ldap://<ip>:<port> "(member=uid=ldap_test3*)"
方案2:为memberUid属性启用子字符串索引
需域管理员权限,操作步骤:
- 先注册架构编辑器组件:运行
regsvr32 schmmgmt.dll - 打开AD架构编辑器,找到
memberUid属性并右键打开属性窗口 - 在「索引」选项卡中勾选「子字符串」选项
- 保存设置,等待AD域架构复制完成(通常需数小时),之后即可正常使用
memberUid通配符查询
方案3:调整过滤规则匹配用户名而非完整DN
如果memberUid属性中同时存储了单纯用户名(如示例中的ldap_test12),可直接匹配用户名前缀:
/usr/bin/ldapsearch -x -o ldif-wrap=no -D "cn=Manager,dc=learnitguide,dc=net" -b "dc=learnitguide,dc=net" -l 10 -w <Pass> -H ldap://<ip>:<port> "(memberUid=ldap_test3*)"
内容的提问来源于stack exchange,提问作者Arm
相关产品推荐
相关产品推荐

