getpwuid() возвращает NULL для пользователя LDAP
У меня проблемы с получением текущей информации о пользователе Red Hat Enterprise 6, где пользователь является пользователем LDAP?
У меня есть некоторый код (фактически часть инструмента установки), который должен получить имя пользователя, домашний каталог и другие детали. Для этого используется вызов getpwuid () на основе идентификатора пользователя. Упрощенная разбивка:
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 возвращает идентификатор пользователя или текущего пользователя, но вызов getpwuid возвращает 0 без кода ошибки, установленного в errno. Согласно документации это означает, что пользователь не существует.
Должно ли это работать? Согласно справочнику getpwuid:
Функция getpwnam () возвращает указатель на структуру, содержащую разбитые поля записи в базе данных паролей (например, локальный файл паролей / etc / passwd, NIS и LDAP), который соответствует имени пользователя.
Функция getpwuid () возвращает указатель на структуру, содержащую выделенные поля записи в базе данных паролей, которая соответствует идентификатору пользователя uid.
Требуется ли альтернативный вызов для получения подробной информации, если текущий пользователь был аутентифицирован LDAP? Нужно ли открывать базу данных LDAP в приложении или системный вызов должен это обрабатывать?
Дополнительно: я также попробовал это на коробке RHEL 5, проходящей аутентификацию в том же каталоге LDAP. Может ли это быть просто проблемой конфигурации на коробке RHEL 6? Или более широкий вопрос о RHEL 6?
Дополнительно: /etc/nsswitch.conf в соответствии с просьбой Василия Старынкевича (закомментированные строки удалены):
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....
3 ответа
У меня похожая проблема, я пытался запустить Teamviewer9 на Debian x64 (также пробовал Ubuntu). Это не работает для учетных записей в домене активного каталога, сбой Teamviewer, потому что getpwuid() возвращает ноль. Я решил установить nscd, как описано в этой ошибке в Ubuntu.
Мне потребовалось много времени, чтобы это исправить...
Кажется, проблема в том, что в 32-битных библиотеках nss_sss отсутствуют (в моем случае). Я думаю, для redhat это пакет rpm: sssd-client.i686.rpm
Я использовал следующий make-файл:
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)
Итак, мой вывод: вам нужно установить некоторые rpm с этой 32-битной версией библиотеки (как, например, sssd-client.i686.rpm)
У меня была точно такая же проблема на CentOS 8. Ответ @kriko помог мне решить ее, но мне пришлось
yum install nss_nis.i686
чтобы исправить это. Нет
sssd-client.i686