我有一个程序,其系统调用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,但是原理仍然相同.

标签: linux

相关文章推荐

添加新评论,含*的栏目为必填