我有一个程序,其系统调用getpwnam()
在运行时失败。为了调试此问题,我决定单独使用此代码运行getpwnam()
(它来自论坛):
#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);
}
奇怪的是,这似乎取决于
libnss_compat-2.3.5.so
的存在:与libnss_compat一起使用:
./pwnam roothome dir = /root
(无libnss_compat):
./pwnam rootgetpwnam failed
所以我的问题是;为什么
getpwnam()
取决于libnss_compat*.so
?我通过nm -D
命令发现libc-2.3.5.so
是提供getpwnam()
的库。readelf -d
向我显示libc
反过来仅取决于ld.so.1
。反过来,这无关紧要。那么,为什么libnss_compat
会产生影响呢?谢谢大家的帮助!!
最佳答案
NSS是名称服务交换机,它是一个可以在各种来源(传统密码文件,Network Information Service和LDAP)中查找用户信息的库。 getpwnam
可以在libc
中定义,但是它将在运行时加载实际的NSS库。在libc
里面,我发现
$ strings /lib/x86_64-linux-gnu/libc.so.6 | grep libnss
libnss_
libnss_
libnss_%s.so.%d.%d
最后一行显然是
snprintf
的格式字符串,用于构造要使用dlopen
加载的实际实现库的名称。使用/etc/nsswitch.conf
确定实现。编辑我在Glibc源代码中的the library is loaded中找到了这个地方。不再(不再使用)
snprintf
,但是原理仍然相同。