如果用户是 LDAP 用户,我在检索 Red Hat Enterprise 6 的当前用户信息时遇到问题?
我有一些代码(实际上是安装工具的一部分)需要检索用户名、主目录和其他详细信息。它使用 getpwuid() 调用根据用户 ID 执行此操作。简化的分割:
uid_t uid = getuid();
printf("UID = %d\n", uid);
errno = 0;
struct passwd* udetails = getpwuid(uid);
if (udetails != NULL)
{
printf("User name = %s\n", udetails->pw_name);
}
else
{
printf("getpwuid returns NULL, errno=%d\n", errno);
}
如果用户是本地用户(在该系统的/etc/passwd 中),这可以毫无问题地工作。
当用户是LDAP认证用户时,调用getuid返回用户ID或当前用户,但调用getpwuid返回0,errno中没有设置错误码。根据文档,这意味着该用户不存在。
这应该有效吗?根据 getpwuid 联机帮助页:
getpwnam() 函数返回一个指向结构的指针,该结构包含密码数据库(例如,本地密码文件/etc/passwd、NIS 和 LDAP)中记录的断开字段用户名。
getpwuid() 函数返回一个指向结构的指针,该结构包含密码数据库中与用户 ID uid 匹配的记录的断开字段。
如果当前用户已通过 LDAP 身份验证,是否需要替代调用来获取详细信息?是否有必要在应用程序中打开 LDAP 数据库,或者应该由系统调用来处理?
附加:我现在也已经在 RHEL 5 机器上尝试过这个,针对同一个 LDAP 目录进行身份验证。这可能只是 RHEL 6 机器上的配置问题吗?还是更广泛的 RHEL 6 问题?
附加:/etc/nsswitch.conf 根据 Basile Starynkevitch 的要求(删除了注释行):
passwd: files sss
shadow: files sss
group: files sss
hosts: files dns
bootparams: nisplus [NOTFOUND=return] files
ethers: files
netmasks: files
networks: files
protocols: files
rpc: files
services: files sss
netgroup: files sss
publickey: nisplus
automount: files ldap
aliases: files nisplus
我猜其中一些应该在某个时候提到 ldap?事实上,这表明它根本没有使用 LDAP....
最佳答案
问题似乎是缺少 32 位的 nss_sss 库(在我的例子中)。我认为对于 redhat 它是 rpm 包:sssd-client.i686.rpm
我使用了以下生成文件:
all: getpwuid_bug-32bit getpwuid_bug-64bit
getpwuid_bug-32bit: getpwuid_bug.c makefile
$(CC) -Wall -m32 -o $@ $<
getpwuid_bug-64bit: getpwuid_bug.c makefile
$(CC) -Wall -m64 -o $@ $<
和下面的getpwuid_bug.c
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#include <pwd.h>
int main(argc, argv)
int argc; char **argv;
{
uid_t uid;
struct passwd *udetails;
uid = getuid();
printf("UID = %d\n", uid);
errno = 0;
udetails = getpwuid(uid);
if (udetails != NULL) {
printf("User name = %s\n", udetails->pw_name);
} else {
printf("getpwuid returns NULL, errno=%d\n", errno);
return 1;
}
return 0;
}
现在输入 make...
然后运行两个
$ ./getpwuid_bug-32bit
UID = 1234
getpwuid returns NULL, errno=0
$ ./getpwuid_bug-64bit
UID = 1234
User name = krico
$
然后如果你跟踪程序的两个版本,你会看到 64 位版本立即找到 nss_sss
open("/lib64/libnss_sss.so.2", O_RDONLY) = 3
其中 32 位的在经历了很多这些之后悲惨地失败了:
open("/lib/tls/i686/sse2/libnss_sss.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/tls/i686/sse2", 0xfffef338) = -1 ENOENT (No such file or directory)
open("/lib/tls/i686/libnss_sss.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
因此,我的结论是您需要使用 32 位版本的库安装一些 rpm(例如 sssd-client.i686.rpm)
关于linux - getpwuid() 为 LDAP 用户返回 NULL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18570177/