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

Другие вопросы по тегам