LDAP client deficiencies

I have been spending a bit of time lately configuring Solaris and Linux hosts to authenticate against LDAP. Authentication works well on the surface, but the actual client implementations are somewhat lacking. Let’s take the Linux pam_ldap module for instance. To authenticate a single session, the pam_ldap module performs thirty-three operations, which includes 7 TCP connections and a number of redundant searches. Here is what I see in my logfile for each login session that is authenticated through pam_ldap:

1. New connection
  conn=801 
  LDAP connection from 10.10.20.3 to 10.10.20.2

2. Anonymous BIND
  conn=801 
  BIND dn="" method=128 version=3

3. Search
   conn=801
   SRCH base="ou=people,dc=prefetch,dc=net" 
   FILTER="(&(objectClass=posixAccount)(uid=test))" 
   ATTRIBUTES="uid userPassword uidNumber gidNumber cn homeDirectory 
              loginShell gecos description objectClass"
   nentries => 1

4. New connection
   conn=802
    LDAP connection from 10.10.20.3 to 10.10.20.2

5. Anonymous BIND
   conn=802
   BIND dn="" method=128 version=3

6. Search
   conn=802
   SRCH base="ou=people,dc=prefetch,dc=net" 
   FILTER="(&(objectClass=posixAccount)(objectClass=posixAccount)(uid=test))"    
   ATTRIBUTES=ALL
   nentries => 1

7. BIND as user
   conn=802
   BIND dn="uid=test,ou=People,dc=prefetch,dc=net" method=128 version=3

8. Anonymous BIND
   conn=802
   BIND dn="" method=128 version=3

9. Close connection 801

10. New connection
    conn=803
    LDAP connection from 10.10.20.3 to 10.10.20.2

11. Anonymous BIND
    conn=803
    BIND dn="" method=128 version=3

12. Search
    conn=803
    SRCH base="ou=people,dc=prefetch,dc=net" 
    FILTER="(&(objectClass=posixAccount)(uid=test))" 
    ATTRIBUTES=ALL
    nentries => 1
    
13. Search
    conn=803
    SRCH base="ou=people,dc=prefetch,dc=net" 
    FILTER="(&(objectClass=posixGroup)(|(memberUid=test)
           (uniqueMember=uid=test,ou=People,dc=prefetch,dc=net)))" 
    attrs="gidNumber"
    nentries => 0

14. Close connection 802

15. New connection
    conn=804
    LDAP connection from 10.10.20.3 to 10.10.20.2

16. Anonymous BIND
    conn=804
    BIND dn="" method=128 version=3

17. Search
    conn=804
    SRCH base="ou=people,dc=prefetch,dc=net" 
    FILTER="(&(objectClass=posixAccount)(uidNumber=100))" 
    ATTRIBUTES="uid userPassword uidNumber gidNumber cn homeDirectory 
               loginShell gecos description objectClass"
    nentries => 1

18. Search
    conn=804
    SRCH base="ou=people,dc=prefetch,dc=net" 
    FILTER="(&(objectClass=posixAccount)(uid=test))" 
    ATTRIBUTES="uid userPassword uidNumber gidNumber cn homeDirectory 
               loginShell gecos description objectClass"
    nentries => 1

19. New connection
    conn=805
    LDAP connection from 10.10.20.3 to 10.10.20.2

20. Anonymous BIND
    conn=805
    BIND dn="" method=128 version=3

21. Search
    conn=805
    SRCH base="ou=people,dc=prefetch,dc=net" 
    FILTER="(&(objectClass=posixAccount)(uidNumber=100))" 
    ATTRIBUTES="uid userPassword uidNumber gidNumber cn homeDirectory 
               loginShell gecos description objectClass"
    nentries => 1

22. New connection
    conn=806
    LDAP connection from 10.10.20.3 to 10.10.20.2

23. Anonymous BIND
    conn=806
    BIND dn="" method=128 version=3

24. Search
    conn=806
    SRCH base="ou=people,dc=prefetch,dc=net" 
    FILTER="(&(objectClass=posixAccount)(uidNumber=100))" 
    ATTRIBUTES="uid userPassword uidNumber gidNumber cn homeDirectory 
               loginShell gecos description objectClass"
    nentries => 1


25. Close connection 806

26. New connection
    conn=807
    LDAP connection from 10.10.20.3 to 10.10.20.2

27. Anonymous BIND
    conn=807
    BIND dn="" method=128 version=3

28. Search
    conn=807
    SRCH base="ou=people,dc=prefetch,dc=net" 
    FILTER="(&(objectClass=posixAccount)(uidNumber=100))" 
    ATTRIBUTES="uid userPassword uidNumber gidNumber cn homeDirectory 
               loginShell gecos description objectClass"
    nentries => 1

29. Close connection 807

30. Close connection 805

31. Search
    conn=804
    SRCH base="ou=people,dc=prefetch,dc=net" 
    FILTER="(&(objectClass=posixAccount)(uid=test))" 
    ATTRIBUTES="uid userPassword uidNumber gidNumber cn homeDirectory 
               loginShell gecos description objectClass"
    nentries => 1

32. Close connection 803

33. Close connection 804

The Sun native LDAP client is not much better, and I am somewhat curious why the PAM modules couldn’t be written to use persistent connections, and to cache data between PAM phases. If you are using either of these implementations to authenticate users, I sure hope you’re using the name service caching daemon (nscd). :)

3 thoughts on “LDAP client deficiencies”

  1. That’s for sure! LDAP authentication on GNU/Linux without nscd is impracticable! I did saw some posts about problems with solaris/ssh and LDAP auth… do you got that problems? I see that is needed install openssh.

  2. The major reason is Solaris, AIX, and some others have a daemon that maintains a quasi persistant state. Linux and with the OpenLDAP client doesn’t, and it opens a new session each LDAP operation it needs. nscd is only somewhat useful.

    The upside is though that you don’t necessarily need a bind account with linux, where it’s mandatory, and sometimes bad practice with the others.

Leave a Reply

Your email address will not be published. Required fields are marked *