[Date Prev][Date Next] [Chronological] [Thread] [Top]

Bug in nss_ldap group handling

I have discovered a very bad bug in nss_ldap when dealing with groups that have several members.

The bug is triggered when using nscd, but may also be triggered without it.

Example :

[root@server9 root]# service nscd start
Démarrage de nscd:                                          [  OK  ]
[root@server9 root]# getent group equation
[root@server9 root]# service nscd stop
Arrêt de nscd :                                             [  OK  ]
[root@server9 root]# getent group equation

The group (here equation) contains 21 users and if I remove 3 users, the problem is not triggered.

After searching in the various codes (nscd and nss_ldap), I have found the bug :

when a client program asks for the group description, it passes to nss a buffer to store the informations. The nss subsystem then asks each modules in the order defined by /etc/nsswitch.conf passing the buffer and buffer length. The module (in the case of ldap, /lib/libnss_ldap.so.2) then must fill the buffer with information or return NSS_TRYAGIN if the buffer is too small.

The problem is that the nss_ldap module has a bug in that case because it returns a result of NSS_SUCCESS with an empty group (no members).

Here is a very simple fix for that applied to the current nss_ldap-183 version :

[root@server9 nss_ldap-183]# diff -u ldap-grp.c.orig ldap-grp.c
--- ldap-grp.c.orig Wed Feb 6 16:39:37 2002
+++ ldap-grp.c Wed Feb 6 16:40:27 2002
@@ -154,6 +154,10 @@
stat =
_nss_ldap_assign_attrvals (ld, e, AT (memberUid), NULL, &uid_mems,
&buffer, &buflen, &uid_mems_c);
+ if (stat == NSS_TRYAGAIN)
+ return NSS_TRYAGAIN; // buffer too small, caller must try again with a larger buffer
if (stat != NSS_SUCCESS)
uid_mems = NULL;

[root@server9 nss_ldap-183]#

With that fix, the problem is solved.

Please note that nscd triggers the bug because it calls the nss subsystem with an initial buffer of 256 bytes. It is probable that the code calling the nss subsystem when nscd is not running uses a bigger buffer.

When nscd receive the status that its buffer is too small, it adds 256 bytes to the buffer and retries. This is probably a big performance penality if you have got very big groups, because each time the nss_ldap module redo the ldap search and retries to fill the buffer. I think using a bigger buffer (4k) and increment (4k) may be a good idea for nscd.