Bug 54283

Summary: mkhomedir_helper ошибка при выставлении прав на каталог.
Product: Sisyphus Reporter: nik
Component: pamAssignee: Michael Shigorin <mike>
Status: ASSIGNED --- QA Contact: qa-sisyphus
Severity: normal    
Priority: P5 CC: glebfm, ilyakurdyukov, ldv, mike, placeholder
Version: unstable   
Hardware: e2k   
OS: Linux   
Attachments:
Description Flags
тестовый пример none

Description nik 2025-05-15 12:12:19 MSK
Обнаружилась проблема в ALT Server 10.2.
При попытке зайти под LDAP-учетной записью в первый раз, вылетает ошибка:
Could not chdir to home directory: Permission Denied
Попытка решить проблему привела к утилите mkhomedir_helper. 
Именно данная утилита отвечает за создание домашних директорий в модуле pam_mkhomedir. 
Данная утилита не хочет менять владельца у директории /home/$USER, и у всех директорий, которые расположены в /etc/skel. При этом обычные файлы из /etc/skel в домашнюю дир-ю переносятся корректно, со сменой владельца.
В логах systemd следующая картина:
PAM unable to changes perms on directory /home/$USER/.ssh: Operation not supported
PAM unable to changes perms on directory /home/$USER: Operation not supported
PAM failed: Permission denied

Для локального пользователя попытка создать дом-юю дир-ю утилитой mkhomedir_helper заканчивается тем же результатом: Дир-я создана, но владельцем остается root.
Файл /sbin/mkhomedir_helper принадлежит пакету pam-1.6.1-alt1.E2K.1.e2kv5
Файл бинарный, поэтому детали посмотреть проблематично.

Для теста:  создаем локального пользователя test 
 useadd test

Проверяем, и если есть, удаляем его домашний каталог. (rm -rf /home/test)
Запускаем:
  mkhomedir_helper test ; echo $?

Смотрим  содержимое:  ls -la /home/test

Если в /etc/skel есть каталоги,   то будут файлы до первого каталога.
Файлы будут иметь правильного владельца, каталог будет иметь владельца root.

Если из /etc/skel убрать все каталоги, то  все файлы будут скопированы нормально, но владелец домашнего каталога останется root.

В journalctl фиксируется событие: 
May 14 21:00:47 alt-16c mkhomedir_helper[84656]: PAM unable to change perms on directory /home/test: Operation not supported

Но по strace я не увидел что бы на каком-то системном вызове возникала ошибка.

То ли в самом бинарнике ошибка, то ли  что-то с настройками не доделали. Но без исходника – только гадать.
Comment 1 Michael Shigorin 2025-05-15 12:26:32 MSK
(Ответ для nik на комментарий #0)
> Файл /sbin/mkhomedir_helper принадлежит пакету pam-1.6.1-alt1.E2K.1.e2kv5
Посмотрел -- сборка отличается от pam-1.6.1-alt1 патчем МЦСТ, поскольку на эльбрусе несколько стеков; возможно, надо патчить и mkhomedir.

Илья, гляньте, вдруг получится нашими силами что-то тут понять.
Comment 2 Dmitry V. Levin 2025-05-15 13:41:32 MSK
(In reply to nik from comment #0)
> В journalctl фиксируется событие: 
> May 14 21:00:47 alt-16c mkhomedir_helper[84656]: PAM unable to change perms
> on directory /home/test: Operation not supported
> 
> Но по strace я не увидел что бы на каком-то системном вызове возникала
> ошибка.
> 
> То ли в самом бинарнике ошибка, то ли  что-то с настройками не доделали. Но
> без исходника – только гадать.

В апстримном PAM этот код выглядит следующим образом:

   if (fchmodat(parent->fd, dest, dir_mode, AT_SYMLINK_NOFOLLOW) != 0 ||
       fchownat(parent->fd, dest, pwd->pw_uid, pwd->pw_gid,
                AT_SYMLINK_NOFOLLOW) != 0)
   {
      pam_syslog(NULL, LOG_DEBUG,
                 "unable to change perms on directory %s/%s: %m",
                 parent->path, dest);
      retval = PAM_PERM_DENIED;
   }

Если у вас работает этот код, то я бы предположил, что проблема либо в ядре, либо в libc.
Comment 3 nik 2025-05-15 21:00:46 MSK
В переданных исходниках работает такой код:

    if (fchmodat(parent->fd, dest, dir_mode, AT_SYMLINK_NOFOLLOW) != 0 ||
        fchownat(parent->fd, dest, pwd->pw_uid, pwd->pw_gid,
                 AT_SYMLINK_NOFOLLOW) != 0)


Был написан небольшой тест, который вызывает данный вызов и проверен на 
alt 10.2 SP (8СВ) - glibc 2.29  ( Эльбрус)

redhat 9.5 - glibc 2.34  (x86)

На x86 тестовый код отрабатывает без ошибок, на эльбрусах вызов fchmodat вызыват ошибку  : Operation not supported


Обнаружено, что  в redhat в файле mkhomedir_helper.c не используются вызовы функций fchownat и fchmodat. вместо них используются chown и chmod

    if (chmod(dest, 0777 & (~u_mask)) != 0 ||
        chown(dest, pwd->pw_uid, pwd->pw_gid) != 0)


Ошибку можно исправить, используя вместо fchownat и fchmodat - chown и chmod соответственно.

Тестовый файл в attach.
Comment 4 nik 2025-05-15 21:01:48 MSK
Created attachment 18474 [details]
тестовый пример
Comment 5 Dmitry V. Levin 2025-05-16 04:33:13 MSK
(In reply to nik from comment #3)
> В переданных исходниках работает такой код:
> 
>     if (fchmodat(parent->fd, dest, dir_mode, AT_SYMLINK_NOFOLLOW) != 0 ||
>         fchownat(parent->fd, dest, pwd->pw_uid, pwd->pw_gid,
>                  AT_SYMLINK_NOFOLLOW) != 0)
> 
> 
> Был написан небольшой тест, который вызывает данный вызов и проверен на 
> alt 10.2 SP (8СВ) - glibc 2.29  ( Эльбрус)
> 
> redhat 9.5 - glibc 2.34  (x86)
> 
> На x86 тестовый код отрабатывает без ошибок, на эльбрусах вызов fchmodat
> вызыват ошибку  : Operation not supported

Очевидно, ошибка специфична для эльбруса, точнее говоря, для связки тамошних kernel+glibc, поскольку в тестовом примере ничего, кроме них и компилятора, не используется.

Для справки, вот апстримный коммит из PAM v1.6.0, от которого на эльбрусе такие сложности: https://github.com/linux-pam/linux-pam/pull/638/commits/12e829094b0ee4f16b716285684e1a0df4541910

Полагаю, что багрепорт можно смело перевешивать с пакета pam на эльбрус.
Comment 6 Michael Shigorin 2025-05-16 10:50:43 MSK
Благодарю за разбор; упомянутый коммит откатывать даже под %ifarch %e2k неохота в силу полезности изменения, повесил mcst#9485 с выдержкой и примером отсюда.

Воспроизводится на текущих ядре 5.10-1.40 и glibc 2.29-26.020 из p10_e2k;
не воспроизводится на 6.1-1.2 и 2.35-2.29.006 из нынешнего sisyphus_e2k.