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. Согласно документации, это означает, что пользователя не существует.

Должно ли это сработать? Согласно man-странице 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 ....


person dtopham75    schedule 02.09.2013    source источник
comment
Покажи свой /etc/nsswitch.conf файл.   -  person Basile Starynkevitch    schedule 02.09.2013
comment
Я добавил это к вопросу.   -  person dtopham75    schedule 02.09.2013
comment
У меня такая же проблема. В моем случае двоичный файл был скомпилирован 32-битным и работает на 64-битной машине. Если я попробую использовать perl, все заработает: perl -e 'my $ uid = $ ‹; распечатать UID:. $ uid. \ n; мой @all = getpwuid ($ uid); распечатать ВСЕ:. присоединиться (,, @all). \ n, если скаляр (@all); '   -  person krico    schedule 18.11.2013
comment
Привет, если вы скомпилируете свой код exapmle в 64-битной cc -m64 и тот же код в 32-битной cc -m32, проблема возникает только в 32-битной версии.   -  person krico    schedule 19.11.2013


Ответы (3)


Проблема заключается в отсутствии библиотеки nss_sss для 32-битной версии (в моем случае). Я думаю, что для 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)

person krico    schedule 19.11.2013

У меня похожая проблема, я пытался запустить Teamviewer9 на x64 debian (также пробовал Ubuntu). Это не работало для учетных записей в домене активного каталога, Teamviewer вылетал из строя, потому что getpwuid () возвращал null. Я решил установить nscd, как описано в этой ошибке ubuntu .

Мне потребовалось много времени, чтобы это исправить ...

person Tommaso    schedule 02.05.2014
comment
Это похоже на общее решение, когда вы не можете самостоятельно скомпилировать проблемное приложение. - person goe; 31.01.2018

У меня была точно такая же проблема на CentOS 8. Ответ @kriko помог мне решить ее, но мне пришлось yum install nss_nis.i686, чтобы исправить это. Не sssd-client.i686

person BunbySoft    schedule 08.12.2020