OpenLDAP中按目标对象的objectClass查询别名条目失败的服务器端解决方案咨询
嗨,我来帮你捋捋这个问题:
首先,你遇到的情况完全是符合LDAP规范和OpenLDAP预期的行为。LDAP的别名条目(alias类)本身就是独立的条目,它的核心作用就是做一个“指向”,本身并不会继承目标条目的任何属性(包括objectClass)。所以当应用用(&objectClass=person)(uid=alias)查询时,自然找不到这个别名条目——毕竟它的objectClass确实只有alias和extensibleObject。
接下来给你几个服务器端的可行 workaround,都是针对你用的slapd 2.4.57版本的:
方案1:用slapo-rwm叠加层重写查询
OpenLDAP的rwm(Rewrite/Remap)叠加层可以在服务器端修改传入的查询请求,完美适配你这种“应用不受控制、没法改查询逻辑”的场景。
你需要在数据库配置里(比如olcDatabase={1}mdb,cn=config这类条目下)添加这个叠加层,并配置查询重写规则,把针对objectClass=person的查询,自动扩展为同时匹配别名条目且目标是person类的情况:
- 先加载rwm模块:
dn: cn=module{0},cn=config add: olcModuleLoad olcModuleLoad: rwm.la
- 给你的数据库配置rwm叠加层的规则:
dn: olcOverlay=rwm,olcDatabase={1}mdb,cn=config objectClass: olcOverlayConfig objectClass: olcRwmConfig # 重写查询:把匹配person类+uid的请求,扩展为同时匹配别名条目(且目标是person类) olcRwmRewriteRule: filter "(&(objectClass=person)(uid=*))" "(|(&objectClass=person)(uid=$1)(&objectClass=alias)(uid=$1)(aliasedObjectName:dnSubtreeMatch:=objectClass=person))"
这个规则的意思是,把原本查询person类且带uid条件的请求,拆成三个条件的“或”逻辑:
- 本身是
person类且uid匹配的条目 - 是
alias类且uid匹配,同时目标条目属于person类
如果应用的查询里uid是固定值(不是通配符),你可以对应调整规则里的匹配模式。
方案2:用slapo-dynlist叠加层动态继承属性
如果觉得查询重写太绕,还可以用dynlist叠加层,让服务器在返回别名条目时,自动把目标条目的objectClass动态添加到别名条目中——这样应用查询objectClass=person时,就能匹配到这个别名条目了。
配置步骤大概是:
- 加载dynlist模块:
dn: cn=module{0},cn=config add: olcModuleLoad olcModuleLoad: dynlist.la
- 配置dynlist叠加层,让别名条目动态继承目标的
objectClass:
dn: olcOverlay=dynlist,olcDatabase={1}mdb,cn=config objectClass: olcOverlayConfig objectClass: olcDynListConfig olcDynListAttrSet: alias objectClass
这个配置会让所有alias类的条目,自动把目标条目的objectClass属性加到自身的返回结果里,而且查询时也会识别这个动态添加的属性。不过要注意,得确保slapd有权限读取目标条目的属性哦。
方案3:手动给别名条目加objectClass(应急用,不推荐)
如果上面的叠加层配置暂时搞不定,还有个临时应急的办法:给你的别名条目手动添加person这个objectClass,同时补上person类要求的必填属性(比如cn、sn)。不过这个办法有个大问题:你相当于给别名条目硬塞了不属于它的属性,虽然extensibleObject允许这么做,但不符合LDAP的设计规范,后续可能会引发其他问题(比如目标条目修改后,别名的person属性不会自动同步),所以只建议临时救急的时候用。
最后再确认下:你用的slapd 2.4.57完全支持上面这些叠加层,放心配置就行。
备注:内容来源于stack exchange,提问作者Joril

