Linux getpwnam()库依赖项

时间:2014-10-31 10:45:10

标签: c linux

我有一个程序,其系统调用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 root home dir = /root

没有libnss_compat:

./pwnam root getpwnam failed

所以我的问题是;为什么getpwnam()依赖于libnss_compat*.so?我发现nm -D命令libc-2.3.5.so是提供getpwnam()的lib。

readelf -d告诉我,libc反过来只取决于ld.so.1。这反过来又取决于什么。那么为什么libnss_compat会产生影响?

感谢大家的帮助!!

1 个答案:

答案 0 :(得分:4)

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,但原则仍然相同。