I had a program whose system call getpwnam() was failing at runtime. To debug this, I decided to run getpwnam() in isolation with this code (it came from a forum):
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
struct passwd *pw;
if (argc != 2) {
printf("usage: %s username\n", argv[0]);
exit(0);
}
pw = getpwnam(argv[1]);
if (pw == NULL)
printf("getpwnam failed\n");
else
printf("home dir = %s\n", pw->pw_dir);
exit(0);
}
Oddly it seems to depend on libnss_compat-2.3.5.so being present:
With libnss_compat:
./pwnam root
home dir = /root
Without libnss_compat:
./pwnam root
getpwnam failed
So my question is; why is getpwnam() dependent on libnss_compat*.so? I found out with the nm -D command that libc-2.3.5.so is the lib which provides getpwnam().
readelf -d shows me that libc in turn only depends on ld.so.1. That in turn depends on nothing. So why on earth is libnss_compat having an impact?
Thanks for your help everyone!!
NSS is the Name Service Switch, a library that can look up user information in various sources (traditional password files, Network Information Service, LDAP). getpwnam may be defined in libc, but that will load the actual NSS library at runtime. Looking inside libc, I find
$ strings /lib/x86_64-linux-gnu/libc.so.6 | grep libnss
libnss_
libnss_
libnss_%s.so.%d.%d
The last line is clearly a format string for snprintf that is used to construct the name of the actual implementation library to load using dlopen. The implementation is determined using /etc/nsswitch.conf.
EDIT I found the place in the Glibc sources where the library is loaded. It's not (no longer?) using snprintf, but the principle is still the same.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With