Bug 53858 - the "system-auth" pam substack still refers to uid 500
Summary: the "system-auth" pam substack still refers to uid 500
Status: CLOSED FIXED
Alias: None
Product: Sisyphus
Classification: Development
Component: pam-config (show other bugs)
Version: unstable
Hardware: x86_64 Linux
: P5 normal
Assignee: Dmitry V. Levin
QA Contact: qa-sisyphus
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2025-04-15 23:28 MSK by Arseny Maslennikov
Modified: 2026-01-23 17:53 MSK (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Arseny Maslennikov 2025-04-15 23:28:03 MSK
FWIW, ставлю control:

  # control system-auth
  ldap

В файле из сабжа написано:
  auth		[success=4 perm_denied=ignore default=die]	pam_localuser.so
  auth		[success=1 default=bad]	pam_succeed_if.so uid >= 500 quiet
  auth		[default=1]	pam_permit.so
  auth		substack	system-auth-ldap-only
  auth		[default=1]	pam_permit.so
  auth		substack	system-auth-local-only
  auth		substack	system-auth-common

Чуть более года назад в сизифе предикат "uid >= 500" потерял какой-либо смысл. Надо заменить условие во второй строке на более актуальное.
Comment 1 Arseny Maslennikov 2025-04-15 23:32:40 MSK
Условие "uid >= 1000" взамен — плохо, и не только по причинам совместимости.

Различие между UID пользователя и uid системной службы (aka "системный пользователь") по номеру, вообще говоря, не работает, и hasher — яркий тому пример.
Стоит вместо uid >= N использовать, например, предикат "годный логинный шелл или нет". При беглом взгляде кажется, будто модуль pam_shells ровно это и способен выразить — то есть, он вернёт значение, соответствующее этому предикату.
Comment 2 Evgeny Sinelnikov 2025-11-25 00:03:53 MSK
К сожалению, простого механизма узнать "годного" доменного пользователя пока не найдено.
Учитывая, что в systemd появились динамические пользователи, проблема ещё более усложнилась.

При этом модуль pam_shells пока не очень подходит - как следует из man'а: "The auth and account module types are provided", а нам требуется проверка для всех типов (и для passwd, и для session).

Учитывая новую схему распределения uid'ов и gid'ов в systemd, доменным пользователями не могут быть выделены uid/gid'ы из диапазона 0-65534 (https://systemd.io/UIDS-GIDS/). 

Дополнительно требуется решение проблемы "не позволяющей gdm создать временного пользователя через systemd-userdb после ввода устройства в домен" - проявляется только при доменной аутентификации в gdm, после обновления до gnome-49 и в текущем сизифе и выглядит вот так:

systemd[1]: Starting user@60578.service - User Manager for UID 60578...
(systemd)[7830]: user@60578.service: PAM failed: Authentication failure
(systemd)[7830]: user@60578.service: Failed to set up PAM session: Operation not permitted
(systemd)[7830]: user@60578.service: Failed at step PAM spawning /usr/lib/systemd/systemd: Operation not permitted
systemd[1]: user@60578.service: Main process exited, code=exited, status=224/PAM
systemd[1]: user@60578.service: Failed with result 'exit-code'.
systemd[1]: Failed to start user@60578.service - User Manager for UID 60578.
Comment 3 Arseny Maslennikov 2025-11-25 00:15:26 MSK
(In reply to Evgeny Sinelnikov from comment #2)
> Дополнительно требуется решение проблемы "не позволяющей gdm создать
> временного пользователя через systemd-userdb после ввода устройства в домен"
> - проявляется только при доменной аутентификации в gdm, после обновления до
> gnome-49 и в текущем сизифе и выглядит вот так:
> 
> systemd[1]: Starting user@60578.service - User Manager for UID 60578...
> (systemd)[7830]: user@60578.service: PAM failed: Authentication failure
> (systemd)[7830]: user@60578.service: Failed to set up PAM session: Operation
> not permitted
> (systemd)[7830]: user@60578.service: Failed at step PAM spawning
> /usr/lib/systemd/systemd: Operation not permitted
> systemd[1]: user@60578.service: Main process exited, code=exited,
> status=224/PAM
> systemd[1]: user@60578.service: Failed with result 'exit-code'.
> systemd[1]: Failed to start user@60578.service - User Manager for UID 60578.

Новые версии пакета systemd при установке патчат /etc/nsswitch.conf и добавляют модуль userdb; я бы предложил посмотреть в тот файл и в спек systemd. :)
Comment 4 Arseny Maslennikov 2025-11-25 00:18:12 MSK
(In reply to Evgeny Sinelnikov from comment #2)
> При этом модуль pam_shells пока не очень подходит - как следует из man'а:
> "The auth and account module types are provided", а нам требуется проверка
> для всех типов (и для passwd, и для session).
Что нужен session, я могу поверить. А для passwd это зачем?
Comment 5 Arseny Maslennikov 2025-11-25 00:21:10 MSK
(In reply to Evgeny Sinelnikov from comment #2)
> К сожалению, простого механизма узнать "годного" доменного пользователя пока
> не найдено.
Отличить доменного от локального?
или отличить пользователя от системного уида?
Это две разные задачи, текущая бага о второй из них.

> Учитывая, что в systemd появились динамические пользователи, проблема ещё
> более усложнилась.
Я б не сказал. Оно теперь "по-другому", да; многим из нас нужно повозиться и разобраться. Но бонусы далее очевидны. В частности, в доменном мире какая-нибудь программа зарегистрирует userdb-провайдера, получающего запросы на сокете "/run/userdb/$name" или как его там, и будет сообщать о своих пользователях через него, и снабжать записи таких пользователей свойством булевого типа, что он доменный.
Comment 6 Evgeny Sinelnikov 2025-11-25 00:21:29 MSK
Проблема разобрана.

Раньше мы фильтровали доменных пользователей по схеме:
- входит в /etc/passwd - локальный;
- не входит в /etc/passwd - доменный.

Дополнительно для доменных пользователей выполнялась проверка:
- если у доменного пользователя uid >= 500, то ему можно логиниться;
- если у доменного пользователя uid < 500, то ему можно логиниться нельзя - это "битый" доменный пользователь.

После анализа распределения uid'ов и gid'ов в systemd картина выглядит иначе - все пользователи, у которых uid < 65536, попадают в категорию локальных.

При этом могут быть такие локальные пользователи, которых невозможно вычислить просто по их отсутствию в /etc/passwd. Такие пользователи являются "динамическими".

Таким образом дополнительная проверка для доменных пользователей меняется:
- если пользователь не входит в /etc/passwd и у него uid < 65536, то это тоже локальный пользователь и его проверяет локальный pam_tcb;
- если пользователь не входит в /etc/passwd и у него uid >= 65536, то это доменный пользователь и его проверяет доменный pam-стек.

______________

При этом остаются два больших и один небольшой диапазоны:
- 524288…1879048191 (1878523904 штук) - Container UID ranges;
- 2147352576…2147418111 (65536 штук) - Foreign UID range;
- 2147483648…4294967294 (2147483647 штук) - HIC SVNT LEONES («здесь обитают драконы»).

Неиспользуемые диапазоны:
- 65536…524287 (458752 штук)
- 1879048192…2147352575 (268304384 штук)
- 2147418112…2147483647 (65536 штук)

Доменные пользователи попадают во все эти диапазоны, хотя ориентироваться стоит на HIC SVNT LEONES, но все текущие инсталляции на это пока никак не рассчитаны.
Comment 7 Evgeny Sinelnikov 2025-11-25 00:24:35 MSK
(Ответ для Arseny Maslennikov на комментарий #4)
> (In reply to Evgeny Sinelnikov from comment #2)
> > При этом модуль pam_shells пока не очень подходит - как следует из man'а:
> > "The auth and account module types are provided", а нам требуется проверка
> > для всех типов (и для passwd, и для session).
> Что нужен session, я могу поверить. А для passwd это зачем?

Проверялось - не работает.

Как зачем это нужен passwd? Вот зачем:
$ passwd 
Current Password: 
New Password:

Оно и так умеет:
$ passwd 
Current Password: 
Password change failed. Server message: Old password not accepted.
passwd: System error
Comment 8 Evgeny Sinelnikov 2025-11-25 00:34:33 MSK
(Ответ для Arseny Maslennikov на комментарий #5)
> (In reply to Evgeny Sinelnikov from comment #2)
> > К сожалению, простого механизма узнать "годного" доменного пользователя пока
> > не найдено.
> Отличить доменного от локального?
> или отличить пользователя от системного уида?
> Это две разные задачи, текущая бага о второй из них.

Да, это понятно. Но решение, которое связано с особенностями динамических пользователей приводит к тому, что мы перестаем проверять "доменность" uid'ов только для системных пользователей. Оно и раньше было по аналогии взято. Теперь локальность пользователя проверяется более ясным образом из спецификации распределения uid'ов в systemd.

Локальные пользователи, очевидно, включают в себя и системных.

> > Учитывая, что в systemd появились динамические пользователи, проблема ещё
> > более усложнилась.
> Я б не сказал. Оно теперь "по-другому", да; многим из нас нужно повозиться и
> разобраться. Но бонусы далее очевидны. В частности, в доменном мире
> какая-нибудь программа зарегистрирует userdb-провайдера, получающего запросы
> на сокете "/run/userdb/$name" или как его там, и будет сообщать о своих
> пользователях через него, и снабжать записи таких пользователей свойством
> булевого типа, что он доменный.

Это выглядит как заявка сильно на будущее, но интересно, да.
Comment 9 Evgeny Sinelnikov 2025-11-25 00:50:34 MSK
Отправил тестовую таску на сборку:
#400962 BUILDING #1 [locked] [test-only] sisyphus pam-config.git=1.9.2-alt1 sssd.git=2.9.7-alt5
Comment 10 Evgeny Sinelnikov 2025-11-29 02:09:51 MSK
Сделал новую версию с поддержкой разных вариантов вычисления "локальности" пользователя:

Перенес логику в отдельный модуль - system-check-localuser.

Добавил к нему control:

$ sudo control system-check-localuser help
legacy: legacy local user mode
systemd: systemd local user mode

$ cat /etc/pam.d/system-check-localuser-systemd
#%PAM-1.0

auth    [success=3 perm_denied=ignore default=die]  pam_localuser.so
auth    [success=2 auth_err=ignore default=bad]  pam_succeed_if.so uid < 65536 quiet

account    [success=3 perm_denied=ignore default=die]  pam_localuser.so
account    [success=2 auth_err=ignore default=bad]  pam_succeed_if.so uid < 65536 quiet

password  [success=3 perm_denied=ignore default=die]  pam_localuser.so
password  [success=2 auth_err=ignore default=bad]  pam_succeed_if.so uid < 65536 quiet

session    [success=3 perm_denied=ignore default=die]  pam_localuser.so
session    [success=2 auth_err=ignore default=bad]  pam_succeed_if.so uid < 65536 quiet

$ cat /etc/pam.d/system-check-localuser-legacy
#%PAM-1.0

auth    [success=3 perm_denied=ignore default=die]  pam_localuser.so
auth    [success=ignore auth_err=2 default=bad]  pam_succeed_if.so uid >= 1000 quiet

account    [success=3 perm_denied=ignore default=die]  pam_localuser.so
account    [success=ignore auth_err=2 default=bad]  pam_succeed_if.so uid >= 1000 quiet

password  [success=3 perm_denied=ignore default=die]  pam_localuser.so
password  [success=ignore auth_err=2 default=bad]  pam_succeed_if.so uid >= 1000 quiet

session    [success=3 perm_denied=ignore default=die]  pam_localuser.so
session    [success=ignore auth_err=2 default=bad]  pam_succeed_if.so uid >= 1000 quiet


____________

Получилось сократить объём дублирования проверок:

diff --git a/system-auth-sss.pam b/system-auth-sss.pam
index f91770e25..05714c591 100644
--- a/system-auth-sss.pam
+++ b/system-auth-sss.pam
@@ -1,32 +1,24 @@
 #%PAM-1.0
 
-auth           [success=4 perm_denied=ignore default=die]      pam_localuser.so
-auth           [success=3 auth_err=1 default=bad]      pam_succeed_if.so uid < 65536 quiet
-auth           [default=1]     pam_permit.so
+auth           include         system-check-localuser
 auth           substack        system-auth-sss-only
 auth           [default=1]     pam_permit.so
 auth           substack        system-auth-local-only
 auth           substack        system-auth-common


____________

Отправил на сборку:

#401311 BUILDING #2 [locked] [test-only] sisyphus pam-config.git=1.9.3-alt1 sssd.git=2.9.7-alt6

Суть:

    Move local user detection logic to system-check-localuser include file
    with two configuration variants: legacy mode ensures non-local users
    cannot have UID < 1000, while systemd mode ensures that dynamic users
    (not listed in /etc/passwd) cannot have UID >= 65536. Users present in
    /etc/passwd are always considered local. This provides flexibility in
    handling both traditional and systemd dynamic user schemes.
Comment 11 Arseny Maslennikov 2025-11-29 17:47:06 MSK
(In reply to Evgeny Sinelnikov from comment #7)
> (Ответ для Arseny Maslennikov на комментарий #4)
> > (In reply to Evgeny Sinelnikov from comment #2)
> > > При этом модуль pam_shells пока не очень подходит - как следует из man'а:
> > > "The auth and account module types are provided", а нам требуется проверка
> > > для всех типов (и для passwd, и для session).
> > Что нужен session, я могу поверить. А для passwd это зачем?
> 
> Проверялось - не работает.
> 
> Как зачем это нужен passwd? Вот зачем:
> $ passwd 
> Current Password: 
> New Password:
> 
> Оно и так умеет:
> $ passwd 
> Current Password: 
> Password change failed. Server message: Old password not accepted.
> passwd: System error
А! здесь, чтобы решить, какой компонент должен обновлять секретики, тоже нужно вычислять такое же условие, как и в других стеках. Понял, спасибо :)
Comment 12 Arseny Maslennikov 2025-11-29 18:17:16 MSK
(In reply to Evgeny Sinelnikov from comment #10)
> Сделал новую версию с поддержкой разных вариантов вычисления "локальности"
> пользователя:
> 
> Перенес логику в отдельный модуль - system-check-localuser.
> 
> Добавил к нему control:
> 
> $ sudo control system-check-localuser help
> legacy: legacy local user mode
> systemd: systemd local user mode
> ____________
> 
> Получилось сократить объём дублирования проверок:
> 
> diff --git a/system-auth-sss.pam b/system-auth-sss.pam
> index f91770e25..05714c591 100644
> --- a/system-auth-sss.pam
> +++ b/system-auth-sss.pam
> @@ -1,32 +1,24 @@
> ____________
> 
> Отправил на сборку:
> 
> #401311 BUILDING #2 [locked] [test-only] sisyphus pam-config.git=1.9.3-alt1
> sssd.git=2.9.7-alt6
> 
> Суть:
> 
>     Move local user detection logic to system-check-localuser include file
>     with two configuration variants: legacy mode ensures non-local users
>     cannot have UID < 1000, while systemd mode ensures that dynamic users
>     (not listed in /etc/passwd) cannot have UID >= 65536. Users present in
>     /etc/passwd are always considered local. This provides flexibility in
>     handling both traditional and systemd dynamic user schemes.
Круто, благодарю! Для моего кейса должно заработать.

Испытываю лёгкую горечь от того, что не-legacy вариант называется "systemd" и тем самым раздражает некоторых, но предложить вариант строго лучше не получается. Ну, может быть, "providers", но пока не очевидно, в чём связь.
Comment 13 Evgeny Sinelnikov 2025-12-02 22:42:07 MSK
Подготовил сборку:
#401311 EPERM #6 sisyphus pam-config.git=1.9.3-alt1 sssd.git=2.9.7-alt7

Ожидаю ревью и/или одобрения pam-config.
В целом, не живой системе всё проверено разных режимах.
Comment 14 Arseny Maslennikov 2025-12-09 20:53:34 MSK
(In reply to Evgeny Sinelnikov from comment #13)
> Подготовил сборку:
> #401311 EPERM #6 sisyphus pam-config.git=1.9.3-alt1 sssd.git=2.9.7-alt7
> 
> Ожидаю ревью и/или одобрения pam-config.
> В целом, не живой системе всё проверено разных режимах.

Добрался до наших систем. Там (в терминах этого задания) уместна настройка `system-check-localuser legacy`.

Ставлю два пакета из задания, переключаю контрольку. После этого логинюсь нелокальным пользователем; авторизует и обламывает сеанс.
Вывод `journalctl -f -u getty@tty3`:
  Dec 09 20:42:13 teacher.po.*.*.* systemd[1]: Started getty@tty3.service - Getty on tty3.
  Dec 09 20:42:44 teacher.po.*.*.* login[2610681]: pam_ldap(login:auth): nslcd authentication; user=s0xxxxxyz
  Dec 09 20:42:44 teacher.po.*.*.* login[2610681]: pam_ldap(login:auth): authentication succeeded
  Dec 09 20:42:45 teacher.po.*.*.* login[2610681]: unable to open session: Permission denied
  Dec 09 20:42:45 teacher.po.*.*.* login[2610681]: pam_open_session: unable to open session
  Dec 09 20:42:45 teacher.po.*.*.* systemd[1]: getty@tty3.service: Deactivated successfully.
  Dec 09 20:42:45 teacher.po.*.*.* systemd[1]: getty@tty3.service: Scheduled restart job, restart counter is at 6.
  Dec 09 20:42:45 teacher.po.*.*.* systemd[1]: Started getty@tty3.service - Getty on tty3.
При этом:
  # getent passwd s0xxxxxyz | cut -d: -f3
  11884
Comment 15 Arseny Maslennikov 2025-12-09 21:21:42 MSK
(In reply to Arseny Maslennikov from comment #14)
> (In reply to Evgeny Sinelnikov from comment #13)
> > Подготовил сборку:
> > #401311 EPERM #6 sisyphus pam-config.git=1.9.3-alt1 sssd.git=2.9.7-alt7
> > 
> > Ожидаю ревью и/или одобрения pam-config.
> > В целом, не живой системе всё проверено разных режимах.
> 
> Добрался до наших систем. Там (в терминах этого задания) уместна настройка
> `system-check-localuser legacy`.
> 
> Ставлю два пакета из задания, переключаю контрольку. После этого логинюсь
> нелокальным пользователем; авторизует и обламывает сеанс.
А на аналогичной стендовой машине, тем не менее, заработало; так что дело может быть и не в пакете pam-config. Буду ещё смотреть.
Comment 16 Evgeny Sinelnikov 2025-12-09 22:03:25 MSK
Да, поведение не должно измениться. Так что проблема в конфигурации.
Comment 17 Evgeny Sinelnikov 2025-12-09 22:05:00 MSK
Только один случай могу предположить, когда поведение будем иным - если uid'ы нелокальных пользователей окажутся в диапазоне от 500 до 999.
Comment 18 Evgeny Sinelnikov 2025-12-15 21:46:57 MSK
Если нет возражений, прошу одобрить pam-config в задании:
$ ssh girar task show 401311 | grep pam-config
 140:dir=/people/sin/packages/pam-config.git
 140:pkgname=pam-config
Comment 19 Evgeny Sinelnikov 2026-01-19 04:42:02 MSK
Внёс ряд правок.

1. Упростил схему проверки с трёх до двух правил.
2. Добавил подробные комментарии в модули pam-стека для нелокальных пользователей.
3. Зафиксировал логику принятия решений о "нелокальности".
4. Вернул поведение в legacy режиме к более соответствующему исходному.

Подготовил и предварительно потестировал новую сборку:
#401311 EPERM #8 [locked] sisyphus pam-config.git=1.9.3-alt1 sssd.git=2.9.7-alt7

___

Пример с сокращениями:

# cat /etc/pam.d/system-auth-sss
#%PAM-1.0
#
# Hybrid authentication with conditional branching.
# The 'system-check-localuser' module determines the authentication path:
# - Local users (in /etc/passwd) are processed by the 'local-only' substack.
# - Non-local users with UID meeting a specific threshold are processed by the
#   'sss-only' substack.
# - Other cases are handled according to the router's mode (legacy or systemd).
#
# Post-condition stack summary:
#
# Condition                        | Action                    | Rule
# ----------------------------------------------------------------------------
# Local user (or treated as local) | Proceeds to the next line | 'local-only'
# Specific non-local user          | Jumps over two lines      | 'method-only'
# Critical failure (default=bad)   | Marks the stack as failed | 'local-only'
# Termination (default=die)        | Entire authentication stack terminates.

auth		include		system-check-localuser
auth		substack	system-auth-local-only
auth		[default=1]	pam_permit.so
auth		substack	system-auth-sss-only
auth		substack	system-auth-common

[...]


$ cat /etc/pam.d/system-check-localuser-systemd 
#%PAM-1.0
#
# Authentication router (Systemd dynamic mode).
# Directs authentication flow, accounting for systemd dynamic users (not in
# /etc/passwd). UID < 65536 is the threshold for systemd dynamic users.
#
# Process:
# 1. Check if user exists locally (pam_localuser.so).
#    - Exists: Proceed to the next line in parent stack -> 'local-only' substack.
#    - Does not exist: Continue to step 2.
#
# 2. Check UID >= 65536 (pam_succeed_if.so).
#    - UID >= 65536: Skip two lines in parent -> 'method-only' substack.
#    - UID < 65536: Proceed to next line in parent -> 'local-only' substack.
#
# Summary for parent stack:
#
# Condition                                      | Path in Parent Stack
# ---------------------------------------------------------------------
# User exists in /etc/passwd                     | -> 'local-only'
# User not in /etc/passwd, UID >= 65536          | -> 'method-only'
# User not in /etc/passwd, UID < 65536 (dynamic) | -> 'local-only'

auth		[success=1 perm_denied=ignore default=die]	pam_localuser.so
auth		[success=2 auth_err=ignore default=bad]	pam_succeed_if.so uid >= 65536 quiet

[...]


$ cat /etc/pam.d/system-check-localuser-legacy 
#%PAM-1.0
#
# Authentication router (Legacy mode).
# Directs authentication flow based on user existence in /etc/passwd and UID.
# UID >= 1000 is the threshold for "regular" non-local users.
#
# Process:
# 1. Check if user exists locally (pam_localuser.so).
#    - Exists: Proceed to the next line in parent stack -> 'local-only' substack.
#    - Does not exist: Continue to step 2.
#
# 2. Check UID >= 1000 (pam_succeed_if.so).
#    - UID >= 1000: Skip two lines in parent -> 'method-only' substack.
#    - UID < 1000: Return 'bad' -> Authentication fails.
#
# Summary for parent stack:
#
# Condition                            | Path in Parent Stack
# -----------------------------------------------------------
# User exists in /etc/passwd           | -> 'local-only'
# User not in /etc/passwd, UID >= 1000 | -> 'method-only'
# User not in /etc/passwd, UID < 1000  | -> FAIL (bad)

auth		[success=1 perm_denied=ignore default=die]	pam_localuser.so
auth		[success=2 default=bad]	pam_succeed_if.so uid >= 1000 quiet

[...]
Comment 20 Repository Robot 2026-01-23 17:53:54 MSK
pam-config-1.10.0-alt1 -> sisyphus:

Thu Jan 22 2026 Evgeny Sinelnikov <sin@altlinux> 1.10.0-alt1
- system-check-localuser.control: local user detection method.
- system-auth-chooser (closes: #53858):
  + update system UID validation range (from UID < 500 to UID < 1000)
  + extract local user check into separate module system-check-localuser
  + add systemd dynamic user support
  + add detailed in-file documentation