Linux getpwnam()库依赖项教程
我有一个程序,其系统调用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
如果没有libnss\_compat:
./pwnam根
getpwnam失败
所以我的问题是;为什么getpwnam()依赖libnss\_compat * .so?我用nm -D命令发现libc-2.3.5.so是提供getpwnam()的lib.
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,但是原理仍然相同.