mmitton/ldap

Search returns each result twice?

Closed this issue · 8 comments

I seem to be getting each search result twice when querying Active Directory. Haven't dug into debugging yet. Any ideas?

I have some code like this:

  fmt.Printf("TestSearch: %s -> num of entries = %d\n", search_request.Filter, len(sr.Entries))
  for idx, entry := range sr.Entries {
    fmt.Printf("    %4d - entry: %+v\n", idx, entry)
  }

The output looks like this:

TestSearch: (objectClass=user) -> num of entries = 579
       0 - entry: &{DN:CN=Kanye West Attributes:[0xc2081b2420 0xc2081b2450]}
       1 - entry: &{DN:CN=Kanye West Attributes:[0xc2081b24b0 0xc2081b24e0]}
       2 - entry: &{DN:CN=Alicia Keys Attributes:[0xc2081b3140 0xc2081b3170]}
       3 - entry: &{DN:CN=Alicia Keys Attributes:[0xc2081b31d0 0xc2081b3200]}
...

I don't see duplicate entries being returned when I use the ldapsearch command, but I do notice this at the bottom of the output:

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

Could the numResponses: 2 be relevant? Perhaps multiple servers are responding and the client is supposed to know how to uniquify or merge? I don't know much about LDAP.

I think above theory about numResponses: 2 is wrong because I did a search that returned a lot more results and got:

# search result
search: 2
result: 0 Success

# numResponses: 661
# numEntries: 660

So it's not getting twice as many responses as entries. There's just one extra response, which I am guessing is for a header or something.

This is still true even after changing the code to use NeverDerefAliases:

  search_request := ldap.NewSearchRequest(
    base_dn,
    ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
    filter[0],
    attributes,
    nil)

Also and I don't know if this is a related issue or completely separate, it is not finding records that I definitely know to be there.

TestSearch: (&(objectClass=user)(cn=Marc*)) -> num of entries = 2
       0 - entry: &{DN:CN=Marcus H.,OU=Portland,... Attributes:[0xc208191110 0xc208191140]}
       1 - entry: &{DN:CN=Marcus H.,OU=Portland,... Attributes:[0xc2081911a0 0xc2081911d0]}
2015-01-12T09:01:19.503034381-08:00 POST /users/marca/tokens 500 in 13.973487ms

My own name starts with "Marc" and it doesn't show up here, but it shows up with the ldapsearch command:

$ ldapsearch -H ldap://ldapserver.corp.mycompany.com -x -b "OU=MyCompany,DC=corp,DC=mycompany,DC=com" -D "me" -W '(&(objectClass=user)(cn=Marc*))' name
...
# Marc A. ...
dn: CN=Marc A., ...
name: Marc A.

# Marcus H. ...
dn: CN=Marcus H., ...
name: Marcus H.

# search result
search: 2
result: 0 Success

# numResponses: 3
# numEntries: 2

I turned on the Debug flag for the connection and it looks like at a fairly low level it is processing the same data twice.

Receiving message 2
Receiving message 2
2: got response 0xc2082bb400
LDAP Response: (Universal, Constructed, Sequence and Sequence of) Len=186 "<nil>"
 Message ID: (Universal, Primative, Integer) Len=1 "2"
 Search Result Entry: (Application, Constructed, 0x04) Len=180 "<nil>"
  Object Name: (Universal, Primative, Octet String) Len=61 "CN=Marcus H...."
  Attributes: (Universal, Constructed, Sequence and Sequence of) Len=115 "<nil>"
   Attribute: (Universal, Constructed, Sequence and Sequence of) Len=84 "<nil>"
    Attribute Name: (Universal, Primative, Octet String) Len=17 "distinguishedName"
    Attribute Values: (Universal, Constructed, Set and Set OF) Len=63 "<nil>"
     Attribute Value: (Universal, Primative, Octet String) Len=61 "CN=Marcus H...
   Attribute: (Universal, Constructed, Sequence and Sequence of) Len=27 "<nil>"
    Attribute Name: (Universal, Primative, Octet String) Len=14 "sAMAccountName"
    Attribute Values: (Universal, Constructed, Set and Set OF) Len=9 "<nil>"
     Attribute Value: (Universal, Primative, Octet String) Len=7 "marcush"
2: waiting for response
2: got response 0xc2082bb400
LDAP Response: (Universal, Constructed, Sequence and Sequence of) Len=186 "<nil>"
 Message ID: (Universal, Primative, Integer) Len=1 "2"
 Search Result Entry: (Application, Constructed, 0x04) Len=180 "<nil>"
  Object Name: (Universal, Primative, Octet String) Len=61 "CN=Marcus H...."
  Attributes: (Universal, Constructed, Sequence and Sequence of) Len=115 "<nil>"
   Attribute: (Universal, Constructed, Sequence and Sequence of) Len=84 "<nil>"
    Attribute Name: (Universal, Primative, Octet String) Len=17 "distinguishedName"
    Attribute Values: (Universal, Constructed, Set and Set OF) Len=63 "<nil>"
     Attribute Value: (Universal, Primative, Octet String) Len=61 "CN=Marcus H...."
   Attribute: (Universal, Constructed, Sequence and Sequence of) Len=27 "<nil>"
    Attribute Name: (Universal, Primative, Octet String) Len=14 "sAMAccountName"
    Attribute Values: (Universal, Constructed, Set and Set OF) Len=9 "<nil>"
     Attribute Value: (Universal, Primative, Octet String) Len=7 "marcush"

FWIW, https://github.com/mavricknz/ldap doesn't seem to have this problem.

I encountered the same issue. I tracked it down to a bug in conn.go. Mutations to message_packet are seen by the goroutine, so the two goroutines race and messages are dropped or duplicated.

Not using the goroutine (and using the commented out line) worked for me, or to continue using the goroutine you just need to make another variable or pass it as a parameter:

go func(message_packet *messagePacket) {
    chanResult <- message_packet.Packet
}(message_packet)

@ejona86 same thing here. With the goroutine, nothing. Using the commented out line instead, I get results.