如何基于primaryGroupId获取对应组并转换为DN?
解决通过PrimaryGroupId获取LDAP组DN的问题
为什么通配符查询无效?
objectSid是LDAP中的二进制属性,并非普通字符串类型,直接使用objectSid=*-550这类字符串通配符无法匹配二进制存储的SID值,因此返回null。
方法一:通过用户SID前缀拼接组SID查询
- 获取用户的
objectSid二进制值,解析出域的SID前缀(即去掉最后一段用户RID的部分) - 将用户的
primaryGroupId作为组RID,拼接到域SID前缀后,生成完整的组SID - 用完整组SID查询对应的组条目
Kotlin代码示例:
// 获取用户条目及objectSid二进制属性 val userEntry = ldapConnectionPool.getEntry(userDn) val userSidBytes = userEntry.getAttributeValue("objectSid") as ByteArray // 解析域SID前缀(去除最后一个用户RID段) val domainSidPrefix = parseDomainSidPrefix(userSidBytes) // 拼接组的完整SID字符串 val groupSid = "$domainSidPrefix-$primaryGroupID" // 查询目标组条目并获取DN val groupEntry = ldapConnectionPool.searchForEntry(baseDn, SearchScope.SUB, "objectSid=$groupSid") val groupDn = groupEntry.dn
SID解析工具方法(二进制转字符串并提取域前缀):
fun parseDomainSidPrefix(sidBytes: ByteArray): String { val sb = StringBuilder("S-") // 拼接SID版本号 sb.append(sidBytes[1].toInt()) // 拼接标识符权威值 val authorityBytes = byteArrayOf(sidBytes[2], sidBytes[3], sidBytes[4], sidBytes[5], sidBytes[6], sidBytes[7]) sb.append("-").append(java.math.BigInteger(1, authorityBytes)) // 子权威数量 val subAuthorityCount = sidBytes[8].toInt() // 拼接前subAuthorityCount-1个子权威(跳过最后一个用户RID) for (i in 0 until subAuthorityCount - 1) { val startIndex = 9 + i * 4 // 小端字节序转大端 val subAuthBytes = byteArrayOf(sidBytes[startIndex+3], sidBytes[startIndex+2], sidBytes[startIndex+1], sidBytes[startIndex]) sb.append("-").append(java.math.BigInteger(1, subAuthBytes)) } return sb.toString() }
方法二:使用LDAP扩展匹配规则直接匹配RID
Active Directory支持专属匹配规则1.2.840.113556.1.4.804(LDAP_MATCH_RID),可直接匹配SID的最后一段(RID),无需解析拼接完整SID。
Kotlin代码示例:
// 构造RID匹配过滤器:同时限定对象类型为组,匹配RID等于primaryGroupId val filter = "(& (objectCategory=group) (objectSid:1.2.840.113556.1.4.804:=$primaryGroupID))" val groupEntry = ldapConnectionPool.searchForEntry(baseDn, SearchScope.SUB, filter) val groupDn = groupEntry.dn
该方法更简洁,但仅适用于Active Directory环境,其他LDAP服务器可能不支持此匹配规则。
关于PrimaryGroupToken返回null的说明
你之前尝试读取PrimaryGroupToken返回null,是因为该属性并非所有LDAP服务器都会暴露。在Active Directory中,组的RID本质就是其PrimaryGroupToken,但通常需要通过SID的最后一段提取,而非直接读取该属性。
内容的提问来源于stack exchange,提问作者gstackoverflow
相关产品推荐
相关产品推荐

