@@ -22,6 +22,29 @@ import (
2222
2323type predicate func (entry Entry ) bool
2424
25+ func guidFromBytes (b []byte ) string {
26+ return fmt .Sprintf ("%08x-%04x-%04x-%02x%02x-%x" ,
27+ binary .LittleEndian .Uint32 (b [0 :4 ]),
28+ binary .LittleEndian .Uint16 (b [4 :6 ]),
29+ binary .LittleEndian .Uint16 (b [6 :8 ]),
30+ b [8 ], b [9 ],
31+ b [10 :16 ],
32+ )
33+ }
34+
35+ func updateBaseDnForGuidIfNeeded (msg * ldap.SearchRequest , e * Entry ) {
36+ binGuid , ok := e .Attributes ["objectGUID" ]
37+ if ! ok || len (binGuid ) == 0 {
38+ return
39+ }
40+ msgGuid := msg .BaseDN [6 : len (msg .BaseDN )- 1 ]
41+ if guidFromBytes ([]byte (binGuid [0 ])) != msgGuid {
42+ return
43+ }
44+ log .Infof ("Attributes: %+v" , guidFromBytes ([]byte (e .Attributes ["objectGUID" ][0 ])))
45+ msg .BaseDN = e .Dn
46+ }
47+
2548var matchingRules = map [string ]string {
2649 "1.3.6.1.4.1.1466.115.121.1.38" : "objectIdentifierMatch" ,
2750 "1.3.6.1.4.1.1466.115.121.1.15" : "caseIgnoreMatch" ,
@@ -40,6 +63,7 @@ func inferMatchingRule(syntaxOID string) string {
4063 return "caseExactMatch"
4164}
4265
66+
4367func (d * Directory ) serveSearch (rw ldap.ResponseWriter , r * ldap.Request ) {
4468 msg := r .Message .(* ldap.SearchRequest )
4569 m , doMonitor := monitor .LdapFromContext (r .Context )
@@ -87,6 +111,10 @@ func (d *Directory) serveSearch(rw ldap.ResponseWriter, r *ldap.Request) {
87111
88112 switch msg .Scope {
89113 case ldap .ScopeBaseObject :
114+ // handle Active Directory extended DN (see MS-ADTS for details)
115+ if strings .HasPrefix (msg .BaseDN , "<GUID=" ) {
116+ updateBaseDnForGuidIfNeeded (msg , & e )
117+ }
90118 if e .Dn != msg .BaseDN {
91119 continue
92120 }
0 commit comments