[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
equation:x:50000:
[root@server9 root]# service nscd stop
Arrêt de nscd : [ OK ]
[root@server9 root]# getent group equation
equation:x:50000:aalgoud,acourrat,administrateur,arichard,asohier,cfarget,
efaye,jgalletti,jpsaby,lbonneville,llaunier,lmagaud,mabrunet,nkrupa,ovigne,
pfaure,psaby,sguillot,svalla,tjamen,xmartin
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.