LDAP continued
Well, that’s another LDAP bug squashed. Well two in fact.
I was initially looking at and LDAP assertion failure which I saw whilst testing. I commented on Debian bug #399849 that I suspected it was due to the fairly rigid parsing of URI. Since I had altered the file since testing, I didn’t spend time looking further to verify or fix this.
However I then hit it again – and saw a better bug – Debian bug #375533. The strange thing was that “id” worked, but “id username” received the assertion failure and died. This broke between v238 and v251 – however there were some Debian build changes as well as upstream changes during this period – where did the problem lie?
The problem only struck if you had /etc/libnss-ldap.conf readable only by root – this is what I do since it means that only root has the password to the LDAP database – in this way we stop local users from being able to query the whole of the LDAP database. We could perhaps use LDAP permissions to lock certain attributes down, but this is easier and safer. However now normal users can’t lookup users/groups – so “ls -l” gets confused. The solution is to run NSCD (name service cache daemon) which runs as root. When asked about users/groups, the C library (libc6) asks NSCD instead.
After quite some time I found the bug and have submitted a patch to Debian and upstream under #375533. The libnss-ldap library was finding itself unconfigured, so it allocated some memory for the configuration, then found that it couldn’t read the file and return “NSS_UNAVAIL”. So far, so good. However on the next call, because the memory was allocated, it thought that it must be configured and hence died. The fix was just to move the file open before the memory allocation.
This fixed the assertion failure, however I then had the second problem to look at – why “id” worked and “id username” didn’t. I suspected that this was because of different calls – some of which libc6 asked NSCD (name service cache daemon) about, some of which it didn’t. A bit of source code hunting later and confirmation arrived – using “nscd -d” to double check, “id” uses getgroups() (queried via nscd) and “id username” uses getgwent() (not queried via nscd). Well that confirmed what the problem was, but not the solution. First of all, on a test machine I installed the latest libc6 and nscd to see if that adds support for getgwent() to nscd. Unfortunately not.
So then I found a helpful discussion on the excellent Debian Administration site. This suggested nss-updatedb which is what we might need to use (depending on how many important system calls are not passed to nscd).
Originally I had /etc/nsswitch.conf like this:
passwd: files ldap group: files ldap ...
To use nss-updatedb, install both nss-updatedb and libnss-db, then edit /etc/nsswitch.conf:
passwd: files db group: files db ...
Then, each hour or so, run (as root, so that it can read the libnss-ldap.conf file and also populate the database):
nss_updatedb ldap passwd nss_updatedb ldap group
Whilst this stuff is really interesting, I could do with these showing their heads a) during testing (I had tested with 238 but had to upgrade to 251), b) when I am not busy with other things.
Posted: January 17th, 2007 under Linux.
Comments: none
Write a comment