]> git.ipfire.org Git - thirdparty/shadow.git/log
thirdparty/shadow.git
3 hours agoTests: Add a new user with supplementary groups using default primary group master
aborah-sudo [Fri, 10 Apr 2026 07:46:07 +0000 (13:16 +0530)] 
Tests: Add a new user with supplementary groups using default primary group

This is the transformation to Python of the test located in
`tests/usertools/01/16_useradd_add_user_to_one_group.test` which checks that
`useradd` can add a new user with specific group

3 hours agoTests: Verify user creation fails when UID exceeds maximum allowed value (2^32 - 1)
aborah-sudo [Wed, 8 Apr 2026 11:37:22 +0000 (17:07 +0530)] 
Tests: Verify user creation fails when UID exceeds maximum allowed value (2^32 - 1)

This is the transformation to Python of the test located in
`tests/usertools/01/26_useradd_UID_-1.test`
which checks that `useradd` can not add a new user with specific uid

3 hours agoTests: Add a new user with custom primary group and supplementary groups
aborah-sudo [Wed, 8 Apr 2026 10:22:48 +0000 (15:52 +0530)] 
Tests: Add a new user with custom primary group and supplementary groups

This is the transformation to Python of the test located in
`tests/usertools/01/16_useradd_add_user_to_multiple_groups.test`
which checks that `useradd` can add a new user with specific group

3 hours agoTests: Verify user creation succeeds with large valid UIDs
aborah-sudo [Tue, 7 Apr 2026 10:20:51 +0000 (15:50 +0530)] 
Tests: Verify user creation succeeds with large valid UIDs

This is the transformation to Python of the test located in
`tests/usertools/01/25_useradd_specified_large_UID2.test`,
which checks that `useradd` can add a new user with large UID

9 hours agosubid: setup deterministic_wrap mode
Pat Riehecky [Fri, 13 Mar 2026 14:25:41 +0000 (09:25 -0500)] 
subid: setup deterministic_wrap mode

This adds two new options to /etc/login.defs:
* UNSAFE_SUB_UID_DETERMINISTIC_WRAP
* UNSAFE_SUB_GID_DETERMINISTIC_WRAP

Deterministic subordinate ID allocation ties each user's subid range
directly to their UID, giving consistent, reproducible ranges across all
hosts without a shared database.  This property breaks down when the
subordinate ID space is exhausted.

With a UID space that on Linux extends to 2^32-1 and the traditional
per-user subid allocation of 2^16 ranges, a site with a large UID
population could exhaust the subordinate ID space before all user UIDs
are allocated.

UNSAFE_SUB_UID_DETERMINISTIC_WRAP and UNSAFE_SUB_GID_DETERMINISTIC_WRAP
provide an explicit opt-in to modulo (ring-buffer) wrapping as a
predictable last resort.  This preserves the deterministic allocation
at the risk of subid overlap.

The UNSAFE_ prefix and the required explicit opt-in are intentional.

Overlapping ranges break namespace isolation and can allow container
escapes and privilege escalation between users whose ranges collide.

These options are appropriate only when all of the following hold:
  - Strict subid determinism is require
  - The active UID population on the host is small and well-known
  - The administrator regularly audits the UID distribution and confirms
    no two active users produce overlapping computed ranges

Do not enable these options on hosts with an uncontrolled user population.

Signed-off-by: Pat Riehecky <riehecky@fnal.gov>
9 hours agosubid: Define settings for deterministic wrap subid ranges
Pat Riehecky [Mon, 30 Mar 2026 18:27:45 +0000 (13:27 -0500)] 
subid: Define settings for deterministic wrap subid ranges

They are not active at this commit, but they are documented.

Signed-off-by: Pat Riehecky <riehecky@fnal.gov>
9 hours agosubid: Add deterministic subid ranges
Pat Riehecky [Mon, 16 Mar 2026 13:21:30 +0000 (08:21 -0500)] 
subid: Add deterministic subid ranges

This adds two new options to /etc/login.defs:
* SUB_UID_DETERMINISTIC
* SUB_GID_DETERMINISTIC

In a lab where users are created ad hoc subids might drift
from one host to the other. If there is a shared home area,
this drift can create some frustration.

Creating subids deterministically provides one type of solution
to this problem. Use of nonconsecutive UIDs will result in blocks
of unused subids.

The manpages provide documentation on how these can be used.

Signed-off-by: Pat Riehecky <riehecky@fnal.gov>
9 hours agosubid: Define settings for deterministic subid ranges
Pat Riehecky [Mon, 30 Mar 2026 18:24:37 +0000 (13:24 -0500)] 
subid: Define settings for deterministic subid ranges

They are not active at this commit, but they are documented.

Signed-off-by: Pat Riehecky <riehecky@fnal.gov>
9 hours agosubid: Move linear allocation into its own function
Pat Riehecky [Mon, 16 Mar 2026 13:18:36 +0000 (08:18 -0500)] 
subid: Move linear allocation into its own function

Signed-off-by: Pat Riehecky <riehecky@fnal.gov>
9 hours agolib/: find_new_sub_[ug]ids(): Remove redundant checks
Alejandro Colomar [Sun, 15 Mar 2026 14:57:43 +0000 (15:57 +0100)] 
lib/: find_new_sub_[ug]ids(): Remove redundant checks

find_free_range() already checks this, and does it better.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
9 hours agolib/subordinateio.c: find_free_range(): Validate input more carefully
Alejandro Colomar [Sun, 15 Mar 2026 14:55:30 +0000 (15:55 +0100)] 
lib/subordinateio.c: find_free_range(): Validate input more carefully

Cc: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
9 hours agolib/: find_free_range(): Set errno on error
Alejandro Colomar [Sun, 15 Mar 2026 14:34:09 +0000 (15:34 +0100)] 
lib/: find_free_range(): Set errno on error

Signed-off-by: Alejandro Colomar <alx@kernel.org>
9 hours agolib/subordinateio.c: find_free_range(): Use id_t instead of u_long
Alejandro Colomar [Sun, 15 Mar 2026 14:31:09 +0000 (15:31 +0100)] 
lib/subordinateio.c: find_free_range(): Use id_t instead of u_long

It's the natural type for this API, and it's also more
consistent with its wrappers.

Let's also use literal -1 for the error code, which is safer than
unsigned constants, as -1 is sign-extended to fit whatever unsigned type
we're using.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
9 hours agoautogen.sh: CFLAGS: Add -Werror=overflow
Alejandro Colomar [Sun, 15 Mar 2026 18:46:49 +0000 (19:46 +0100)] 
autogen.sh: CFLAGS: Add -Werror=overflow

This helped find a bug, and doesn't seem to have any false positives
here, so let's use it.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
9 hours agoautogen.sh: CFLAGS: Remove -Werror=sign-compare
Alejandro Colomar [Sun, 15 Mar 2026 15:19:31 +0000 (16:19 +0100)] 
autogen.sh: CFLAGS: Remove -Werror=sign-compare

GCC has issues with literal -1.

Link: <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119011>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
9 hours agolib/, src/: find_new_sub_[ug]ids(): Report errors through errno
Alejandro Colomar [Sun, 15 Mar 2026 14:09:18 +0000 (15:09 +0100)] 
lib/, src/: find_new_sub_[ug]ids(): Report errors through errno

Signed-off-by: Alejandro Colomar <alx@kernel.org>
9 hours agolib/: find_new_sub_*ids(): Remove dead assertions
Alejandro Colomar [Sun, 15 Mar 2026 13:05:21 +0000 (14:05 +0100)] 
lib/: find_new_sub_*ids(): Remove dead assertions

The input to these functions is always an address (&x); that's
guaranteed to be non-null.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 days agologin: Delete creds if pam_open_session fails
Tobias Stoeckmann [Tue, 24 Mar 2026 14:14:12 +0000 (15:14 +0100)] 
login: Delete creds if pam_open_session fails

Call pam_setcreds if pam_open_session fails. This deletes credentials
which are allocated with a previous pam_setcreds call.

Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2 days agologin: Call pam_close_session only with session
Tobias Stoeckmann [Tue, 24 Mar 2026 14:10:17 +0000 (15:10 +0100)] 
login: Call pam_close_session only with session

If authentication fails, call pam_end without pam_close_session, since
at this point, pam_open_session was never called.

Only two callers of PAM_END benefit from the macro, which is not worth
it. Inlined PAM_END instead.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2 days agologin: Call pam_open_session after pam_setcred
Tobias Stoeckmann [Tue, 24 Mar 2026 13:36:14 +0000 (14:36 +0100)] 
login: Call pam_open_session after pam_setcred

According to Linux-PAM's pam_setcred(3) and su implementation,
credentials shall be set before session is opened.

Adjust login to follow this rule, which is also applied by util-linux
login/su and at least gdm (didn't check more implementations).

The current style matches Appendix B of X/Open RFC 86.0 (from 1995).

Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
8 days agoman/passwd.5.xml: CAVEATS: Add section
Alejandro Colomar [Tue, 31 Mar 2026 12:50:00 +0000 (14:50 +0200)] 
man/passwd.5.xml: CAVEATS: Add section

Document that when reading passwd(5), the C locale should be used.

Cc: Iker Pedrosa <ipedrosa@redhat.com>
Cc: Mantas Mikulėnas <grawity@gmail.com>
Cc: KhaelK-Praetorian <khael.kugler@praetorian.com>
Cc: Tobias Stoeckmann <tobias@stoeckmann.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
8 days agoRevert "strchriscntrl: reject C1 control bytes (0x80-0x9F)"
Alejandro Colomar [Wed, 25 Mar 2026 21:00:40 +0000 (22:00 +0100)] 
Revert "strchriscntrl: reject C1 control bytes (0x80-0x9F)"

C1 control bytes are more complicated than that.  They're represented as
two bytes in UTF-8.

Commit 19d725da, has issues, rejecting otherwise valid UTF-8 multi-byte
characters.

We could in theory do correct parsing of UTF, possibly parsing the
multi-byte sequences, or translating to wchar_t.  However, that would
complicate the source code well beyond what I'd be comfortable with.

Instead, let's revert this, and claim no intention to support UTF-8.
If an admin uses a UTF-8 locale while reading /etc/passwd, that's their
own fault.

Reverts: 19d725da (2026-03-13; "strchriscntrl: reject C1 control bytes (0x80-0x9F)")
Fixes: 19d725da (2026-03-13; "strchriscntrl: reject C1 control bytes (0x80-0x9F)")
Closes: <https://github.com/shadow-maint/shadow/issues/1598>
Reported-by: Mantas Mikulėnas <grawity@gmail.com>
Cc: KhaelK-Praetorian <khael.kugler@praetorian.com>
Cc: Tobias Stoeckmann <tobias@stoeckmann.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
9 days agoTests: Add a new user with a specified large UID
aborah-sudo [Tue, 31 Mar 2026 04:23:42 +0000 (09:53 +0530)] 
Tests: Add a new user with a specified large UID

This is the transformation to Python of the test located in
`tests/usertools/01/15_useradd_specified_large_UID.test` which
checks that `useradd` can add a new user with large UID

9 days agoTests: Add a new user with an invalid UID
aborah-sudo [Tue, 31 Mar 2026 04:16:02 +0000 (09:46 +0530)] 
Tests: Add a new user with an invalid UID

This is the transformation to Python of the test located in
`tests/usertools/01/13_useradd_negative_UID.test`,
`tests/usertools/01/14_useradd_out_of_range_UID.test`
which checks that `useradd` can not add a new user with invalid UID

10 days agoman/po: fix pot file syntax errors after `groupmems` removal
Iker Pedrosa [Wed, 25 Mar 2026 14:04:35 +0000 (15:04 +0100)] 
man/po: fix pot file syntax errors after `groupmems` removal

Regenerate shadow-man-pages.pot to remove orphaned translation entries
and fix embedded temporary paths that were causing `msgmerge` failures
in CI.

Acked-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
10 days ago*/: groupmems(8): Remove program
Iker Pedrosa [Wed, 25 Mar 2026 13:37:01 +0000 (14:37 +0100)] 
*/: groupmems(8): Remove program

The utility is redundant for root and effectively broken for regular
users across major distributions, its continued maintenance adds
complexity for little to no benefit.

Closes: https://github.com/shadow-maint/shadow/issues/1343
Acked-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
11 days agotest/libsubid: update 01_list_ranges
Pat Riehecky [Fri, 13 Mar 2026 21:04:46 +0000 (16:04 -0500)] 
test/libsubid: update 01_list_ranges

Now that user resolution is required, ensure a resolvable user is used.

Signed-off-by: Pat Riehecky <riehecky@fnal.gov>
11 days agosubid: Remove get_owner_id
Pat Riehecky [Tue, 10 Mar 2026 23:58:33 +0000 (18:58 -0500)] 
subid: Remove get_owner_id

There are no longer any callers for get_owner_id so it can be removed.

Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Pat Riehecky <riehecky@fnal.gov>
11 days agosubid: start using SUB_UID_STORE_BY_UID/GID
Pat Riehecky [Wed, 11 Mar 2026 17:28:42 +0000 (12:28 -0500)] 
subid: start using SUB_UID_STORE_BY_UID/GID

This adds two new options to /etc/login.defs:
* SUB_UID_STORE_BY_UID
* SUB_GID_STORE_BY_UID

They default to 'no' but when set 'yes' the subuid/subgid
entries will be written by uid rather than username.

Closes: https://github.com/shadow-maint/shadow/issues/1554
Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Pat Riehecky <riehecky@fnal.gov>
11 days agosubid: Define SUB_UID_STORE_BY_UID and SUB_GID_STORE_BY_UID
Pat Riehecky [Tue, 10 Mar 2026 14:51:58 +0000 (09:51 -0500)] 
subid: Define SUB_UID_STORE_BY_UID and SUB_GID_STORE_BY_UID

They are not active within this commit, but they are fully documented

Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Pat Riehecky <riehecky@fnal.gov>
11 days agosubid: use is_same_user() for owner resolution in find_range
Pat Riehecky [Tue, 10 Mar 2026 14:47:26 +0000 (09:47 -0500)] 
subid: use is_same_user() for owner resolution in find_range

Replace the resolution in find_range with is_same_user(). The
actualy results should be the same.

Previously, find_range performed its own getpwnam() based UID lookup to
handle entries recorded by UID or by username. This duplicated logic
centralized in is_same_user().

is_same_user() resolves ownership by username, UID, and overlapping
entries, making find_range consistent with how ownership is determined
elsewhere.

Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Pat Riehecky <riehecky@fnal.gov>
11 days agosubid: use is_same_user() for owner resolution in range queries
Pat Riehecky [Tue, 10 Mar 2026 14:42:48 +0000 (09:42 -0500)] 
subid: use is_same_user() for owner resolution in range queries

Replace direct owner string comparison in range_exists, get_owner_id,
list_owner_ranges, and new_subid_range with is_same_user().

Previously, ownership checks required a literal match against the owner
field. This created a situation where if entries were recorded by UID and
by username not all would be identified.

is_same_user() resolves ownership by username, UID, and overlapping
entries, making range queries consistent with how ownership is determined
elsewhere.

Fixes: 0a7888b1 (2020-06-07; "Create a new libsubid")
CC: Serge Hallyn <serge@hallyn.com>
Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Pat Riehecky <riehecky@fnal.gov>
11 days agosubid: Add is_same_user for unified ID lookups
Pat Riehecky [Tue, 10 Mar 2026 14:39:57 +0000 (09:39 -0500)] 
subid: Add is_same_user for unified ID lookups

Each identifier is resolved via getpw_uid_or_nam and compared
numerically. Accepts usernames, numeric UIDs, or a mix of both.

Numeric resolution ensures stale entries for deleted users cannot
produce false matches, and handles systems with overlapping UIDs.

We do not perform a streq(3) on the passed strings themselves.
In this way we ensure the user is resolvable on the system
eliminating the ability to return results from deleted users
with stale entries.

Returns false if either identifier cannot be resolved, or if the
resolved UIDs do not match.

Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Pat Riehecky <riehecky@fnal.gov>
11 days agolib/shadow/passwd/: getpw_uid_or_nam(): Add function
Alejandro Colomar [Wed, 11 Mar 2026 19:29:22 +0000 (20:29 +0100)] 
lib/shadow/passwd/: getpw_uid_or_nam(): Add function

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 weeks agoTests: Add a new user with a specified existing numerical primary group
aborah-sudo [Wed, 25 Mar 2026 04:19:33 +0000 (09:49 +0530)] 
Tests: Add a new user with a specified existing numerical primary group

This is the transformation to Python of the test located in
`tests/usertools/01/07_useradd_numerical_primary_group.test`, which checks that `useradd` can add a new user with valid existing group as primary

2 weeks agotests/system/tests/test_vipw.py: implement basic tests
Iker Pedrosa [Fri, 12 Sep 2025 11:54:35 +0000 (13:54 +0200)] 
tests/system/tests/test_vipw.py: implement basic tests

* Run vipw on passwd file and add a user
* Run vipw on shadow file and add a user
* Run vipw on group file and add a group
* Run vipw on gshadow file and add a group

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2 weeks agoshare/ansible/: create the /etc/gshadow in OpenSUSE
Iker Pedrosa [Fri, 12 Sep 2025 12:58:57 +0000 (14:58 +0200)] 
share/ansible/: create the /etc/gshadow in OpenSUSE

Temporary workaround to create the /etc/gshadow in OpenSUSE.

Link: <https://forums.opensuse.org/t/no-etc-gshadow-gpasswd-puts-password-hash-into-world-readable-etc-group/179019>
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2 weeks agoshare/ansible/roles/ci_run/tasks/: add `vim` dependency
Iker Pedrosa [Thu, 11 Sep 2025 14:11:59 +0000 (16:11 +0200)] 
share/ansible/roles/ci_run/tasks/: add `vim` dependency

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2 weeks agotests/system/framework/roles/shadow.py: implement binding for `vipw`
Iker Pedrosa [Thu, 11 Sep 2025 09:38:59 +0000 (11:38 +0200)] 
tests/system/framework/roles/shadow.py: implement binding for `vipw`

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2 weeks agotests/system/tests/test_chgpasswd.py: change multiple group passwords from file
Iker Pedrosa [Thu, 11 Sep 2025 07:11:41 +0000 (09:11 +0200)] 
tests/system/tests/test_chgpasswd.py: change multiple group passwords from file

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2 weeks agotests/system/tests/test_chgpasswd.py: change multiple group passwords interactive
Iker Pedrosa [Wed, 10 Sep 2025 14:57:41 +0000 (16:57 +0200)] 
tests/system/tests/test_chgpasswd.py: change multiple group passwords interactive

This is the transformation to Python of the test located in
`tests/grouptools/chgpasswd/02_chgpasswd_multiple_groups/chgpasswd.test`,
which checks that `chgpasswd` is able to change the password of multiple
groups in batch.

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2 weeks agotests/system/framework/roles/shadow.py: implement binding for `chgpasswd`
Iker Pedrosa [Wed, 10 Sep 2025 14:53:02 +0000 (16:53 +0200)] 
tests/system/framework/roles/shadow.py: implement binding for `chgpasswd`

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2 weeks agotests/system/tests/test_gpasswd.py: add user to group membership as non-root user
Iker Pedrosa [Wed, 10 Sep 2025 10:58:24 +0000 (12:58 +0200)] 
tests/system/tests/test_gpasswd.py: add user to group membership as non-root user

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2 weeks agotests/system/tests/test_gpasswd.py: add user as group administrator
Iker Pedrosa [Wed, 10 Sep 2025 10:20:19 +0000 (12:20 +0200)] 
tests/system/tests/test_gpasswd.py: add user as group administrator

This is the transformation to Python of the test located in
`tests/grouptools/gpasswd/50_gpasswd_change_admin_list/gpasswd.test`,
which checks that `gpasswd` is able to add a user as a group
administrator.

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2 weeks agotests/system/conftest.py: import markers plugin
Iker Pedrosa [Wed, 10 Sep 2025 10:18:30 +0000 (12:18 +0200)] 
tests/system/conftest.py: import markers plugin

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2 weeks agotests/system/tests/test_gpasswd.py: add user to group membership as root user
Iker Pedrosa [Wed, 10 Sep 2025 09:26:56 +0000 (11:26 +0200)] 
tests/system/tests/test_gpasswd.py: add user to group membership as root user

This is the transformation to Python of the test located in
`tests/grouptools/gpasswd/31_gpasswd_add_user_to_group/gpasswd.test`,
which checks that `gpasswd` is able to add a user to a group membership
running as root.

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2 weeks agotests/system/framework/roles/shadow.py: implement binding for `gpasswd`
Iker Pedrosa [Wed, 10 Sep 2025 07:53:15 +0000 (09:53 +0200)] 
tests/system/framework/roles/shadow.py: implement binding for `gpasswd`

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2 weeks agotests/system/tests/test_chpasswd.py: change multiple user passwords from file
Iker Pedrosa [Tue, 9 Sep 2025 11:14:07 +0000 (13:14 +0200)] 
tests/system/tests/test_chpasswd.py: change multiple user passwords from file

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2 weeks agotests/system/tests/test_chpasswd.py: change multiple user passwords interactive
Iker Pedrosa [Tue, 9 Sep 2025 07:30:23 +0000 (09:30 +0200)] 
tests/system/tests/test_chpasswd.py: change multiple user passwords interactive

This is the transformation to Python of the test located in
`tests/usertools/chpasswd/02_chpasswd_multiple_users/chpasswd.test`,
which checks that `chpasswd` is able to change the password of multiple
users in batch.

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2 weeks agotests/system/framework/roles/shadow.py: implement binding for `chpasswd`
Iker Pedrosa [Mon, 8 Sep 2025 14:49:56 +0000 (16:49 +0200)] 
tests/system/framework/roles/shadow.py: implement binding for `chpasswd`

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2 weeks agoshare/ansible/: create the chpasswd PAM service file
Iker Pedrosa [Mon, 8 Sep 2025 14:50:35 +0000 (16:50 +0200)] 
share/ansible/: create the chpasswd PAM service file

Temporary workaround to create the chpasswd PAM service file. Fedora
will soon provide this service file and we'll be able to remove the
workaround.

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2 weeks agotests/system/tests/test_passwd.py: lock user password
Iker Pedrosa [Mon, 23 Feb 2026 13:35:28 +0000 (14:35 +0100)] 
tests/system/tests/test_passwd.py: lock user password

This is the transformation to Python of the test located in
`tests/passwd/06_passwd_-l_root_lock_account/passwd.test`,
which checks that `passwd` is able to lock a user's password.

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2 weeks agotests/system/tests/test_passwd.py: change user password as root in interactive mode
Iker Pedrosa [Tue, 9 Sep 2025 07:23:30 +0000 (09:23 +0200)] 
tests/system/tests/test_passwd.py: change user password as root in interactive mode

This is the transformation to Python of the test located in
`tests/passwd/18_passwd_root_change_password_user/passwd.test`,
which checks that `passwd` is able to change a user's password running
as root in interactive mode.

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2 weeks agotests/system/tests/test_passwd.py: change user password as root using stdin
Iker Pedrosa [Mon, 8 Sep 2025 09:10:05 +0000 (11:10 +0200)] 
tests/system/tests/test_passwd.py: change user password as root using stdin

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2 weeks agotests/system/framework/misc/__init__.py: password pattern
Iker Pedrosa [Tue, 9 Sep 2025 07:20:17 +0000 (09:20 +0200)] 
tests/system/framework/misc/__init__.py: password pattern

Expose shadow's password regex pattern in a function.

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2 weeks agotests/system/framework/roles/shadow.py: implement binding for `passwd`
Iker Pedrosa [Thu, 4 Sep 2025 14:13:50 +0000 (16:13 +0200)] 
tests/system/framework/roles/shadow.py: implement binding for `passwd`

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2 weeks agoshare/ansible/roles/ci_run/tasks/fedora.yml: add dependency
Iker Pedrosa [Mon, 8 Sep 2025 10:34:21 +0000 (12:34 +0200)] 
share/ansible/roles/ci_run/tasks/fedora.yml: add dependency

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2 weeks agotests/system/etc/login.defs: define ENCRYPT_METHOD
Iker Pedrosa [Mon, 8 Sep 2025 10:34:48 +0000 (12:34 +0200)] 
tests/system/etc/login.defs: define ENCRYPT_METHOD

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2 weeks agoTests: Add a new user with a specified non-existing primary group
aborah-sudo [Mon, 23 Mar 2026 05:12:09 +0000 (10:42 +0530)] 
Tests: Add a new user with a specified non-existing primary group

This is the transformation to Python of the test located in
`tests/usertools/01/06_useradd_invalid_named_primary_group.test`, which checks that `useradd` can not add a new user with invalid existing group as primary

2 weeks agolib/attr.h: exclude MCST LCC compiler from ATTR_MALLOC
a1batross [Sun, 22 Mar 2026 10:41:03 +0000 (15:41 +0500)] 
lib/attr.h: exclude MCST LCC compiler from ATTR_MALLOC

This particular compiler defines GCC compatibility like Clang but doesn't support this attribute.

Signed-off-by: Alibek Omarov <a1ba.omarov@gmail.com>
3 weeks agolib/string/README: [v]aprintf(3) are in libc
Alejandro Colomar [Thu, 19 Mar 2026 00:45:24 +0000 (01:45 +0100)] 
lib/string/README: [v]aprintf(3) are in libc

[v]aprintf(3) are now part of a libc implementation: gnulib.
They are also documented in a manual page.  Thus, refer to them as
[v]aprintf(3).

Signed-off-by: Alejandro Colomar <alx@kernel.org>
3 weeks agoTests: Add a new user with a valid existing group as primary
aborah-sudo [Tue, 17 Mar 2026 05:22:28 +0000 (10:52 +0530)] 
Tests: Add a new user with a valid existing group as primary

This is the transformation to Python of the test located in
`tests/usertools/01/08_useradd_named_primary_group.test`, which checks that `useradd` can add a new user with a valid existing group as primary

3 weeks agousermod: make fail_exit the reverse of the locking in open_files
Pat Riehecky [Tue, 10 Mar 2026 13:30:49 +0000 (08:30 -0500)] 
usermod: make fail_exit the reverse of the locking in open_files

Signed-off-by: Pat Riehecky <riehecky@fnal.gov>
3 weeks agousermod: close_files should unlock in reverse of open_files
Pat Riehecky [Tue, 10 Mar 2026 13:42:32 +0000 (08:42 -0500)] 
usermod: close_files should unlock in reverse of open_files

Signed-off-by: Pat Riehecky <riehecky@fnal.gov>
3 weeks agousermod: only unlock on close_files if we actually locked them
Pat Riehecky [Tue, 10 Mar 2026 13:37:29 +0000 (08:37 -0500)] 
usermod: only unlock on close_files if we actually locked them

Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Pat Riehecky <riehecky@fnal.gov>
3 weeks agousermod: only lock shadow file as needed
Pat Riehecky [Mon, 9 Mar 2026 16:43:12 +0000 (11:43 -0500)] 
usermod: only lock shadow file as needed

When setting user attributes that have nothing to do with shadow
we don't need to lock it.

Closes: https://github.com/shadow-maint/shadow/issues/1540
Signed-off-by: Pat Riehecky <riehecky@fnal.gov>
3 weeks agoTests: Add a new user with a specified non-existing gid
aborah-sudo [Fri, 13 Mar 2026 05:33:10 +0000 (11:03 +0530)] 
Tests: Add a new user with a specified non-existing gid

This is the transformation to Python of the test located in
`tests/usertools/01/05_useradd_invalid_numeric_primary_group.test`, which checks that `useradd` fails to create a new user with non-existing group

3 weeks agolib/io/README: Add file
Alejandro Colomar [Fri, 13 Mar 2026 00:53:38 +0000 (01:53 +0100)] 
lib/io/README: Add file

This documents the main APIs under 'lib/io/'.

Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
3 weeks agolib/, src/: Use fgets_a() instead of its pattern
Alejandro Colomar [Mon, 12 Aug 2024 01:24:48 +0000 (03:24 +0200)] 
lib/, src/: Use fgets_a() instead of its pattern

Except for the updated includes, this patch has been scripted with a
semantic patch:

$ cat ~/tmp/spatch/fgets_fgets_a.sp
@@
expression a, b;
@@

- fgets(a, countof(a), b)
+ fgets_a(a, b)

Applied as:

$ find lib* src -type f \
| xargs spatch --sp-file ~/tmp/spatch/fgets_fgets_a.sp --in-place;

Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
3 weeks agolib/io/: fgets_a(): Add macro
Alejandro Colomar [Mon, 12 Aug 2024 01:20:46 +0000 (03:20 +0200)] 
lib/io/: fgets_a(): Add macro

Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
3 weeks agolib/: Use countof() instead of hardcoded lengths
Alejandro Colomar [Mon, 12 Aug 2024 01:01:10 +0000 (03:01 +0200)] 
lib/: Use countof() instead of hardcoded lengths

Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
3 weeks agolib/fields.c: change_field(): Use a VLA
Alejandro Colomar [Mon, 12 Aug 2024 00:57:18 +0000 (02:57 +0200)] 
lib/fields.c: change_field(): Use a VLA

This allows using countof(), which is safer than a decoupled use of
the variable containing the length of the array.

Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
3 weeks agolib/, src/: Use countof() instead of sizeof() with fgets(3)
Alejandro Colomar [Mon, 12 Aug 2024 00:50:26 +0000 (02:50 +0200)] 
lib/, src/: Use countof() instead of sizeof() with fgets(3)

Except for the added includes, this patch has been scripted with a
semantic patch:

$ cat ~/tmp/spatch/fgets_nitems.sp
@@
expression a, b, c;
@@

- fgets(a, sizeof(b), c)
+ fgets(a, countof(b), c)

@@
expression a, b, c;
@@

- fgets(a, sizeof b, c)
+ fgets(a, countof(b), c)

Applied as:

$ find lib* src/ -type f \
| xargs spatch --sp-file ~/tmp/spatch/fgets_nitems.sp --in-place;

Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
3 weeks agousermod: Update passwd entry when shadowing entry
Tobias Stoeckmann [Sun, 15 Mar 2026 23:31:47 +0000 (00:31 +0100)] 
usermod: Update passwd entry when shadowing entry

If a new shadow entry is created, the passwd entry's password hash is
moved into shadow file and replaced with an "x". If this happens, update
the passwd file as well, otherwise the "x" is not written to disk.

Resolves: https://github.com/shadow-maint/shadow/issues/1580

Reproducer (as root):
```
BASE=$(mktemp -d)
mkdir -p $BASE/etc
useradd -P $BASE user
touch $BASE/etc/shadow
usermod -P $BASE -e 0 user
cat $BASE/etc/passwd
```

Incorrect output (before):
```
user:!:1000:1000::/home/user:/bin/bash
```

Correct output (after):
```
user:x:1000:1000::/home/user:/bin/bash
```

Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
3 weeks agolib/, src/: Remove superfluous #include <assert.h>
Alejandro Colomar [Fri, 13 Mar 2026 16:01:21 +0000 (17:01 +0100)] 
lib/, src/: Remove superfluous #include <assert.h>

Signed-off-by: Alejandro Colomar <alx@kernel.org>
3 weeks agolib/, src/, tests/: #undef NDEBUG before #include <assert.h>
Alejandro Colomar [Fri, 13 Mar 2026 15:57:52 +0000 (16:57 +0100)] 
lib/, src/, tests/: #undef NDEBUG before #include <assert.h>

Otherwise, assert(3) might do nothing, which would be unsafe.

The goal would be to not use assert(3) at all, actually, but as long as
we use it, we should make sure we do actually use it.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
3 weeks agolib/, src/, tests/: Move <assert.h> to be the last #include
Alejandro Colomar [Thu, 12 Mar 2026 12:39:33 +0000 (13:39 +0100)] 
lib/, src/, tests/: Move <assert.h> to be the last #include

<assert.h> should always be the last include.  Otherwise, you risk some
indirect inclusion might affect the behavior of assert(3).

Signed-off-by: Alejandro Colomar <alx@kernel.org>
3 weeks agolib/sysconf: Move sysconf handling into own file
Tobias Stoeckmann [Fri, 13 Mar 2026 16:23:45 +0000 (17:23 +0100)] 
lib/sysconf: Move sysconf handling into own file

Move sysconf() calls and error handling into its own file.

While at it, adjust the data type for ngroup max value.

Requested-by: Alejandro Colomar <alx@kernel.org>
Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
3 weeks agousermod: Check sysconf return value
Tobias Stoeckmann [Wed, 11 Mar 2026 21:35:22 +0000 (22:35 +0100)] 
usermod: Check sysconf return value

Verify that sysconf does not return -1. It is not important if it's due
to an error or due to a missing upper boundary. In both cases, fall back
to a constant value.

Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
3 weeks agouseradd: Check sysconf return value
Tobias Stoeckmann [Wed, 11 Mar 2026 21:34:05 +0000 (22:34 +0100)] 
useradd: Check sysconf return value

Verify that sysconf does not return -1. It is not important if it's due
to an error or due to a missing upper boundary. In both cases, fall back
to a constant value.

Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
4 weeks agostrchriscntrl: reject C1 control bytes (0x80-0x9F)
KhaelK-Praetorian [Wed, 11 Mar 2026 03:04:55 +0000 (22:04 -0500)] 
strchriscntrl: reject C1 control bytes (0x80-0x9F)

glibc's iscntrl() does not classify C1 control bytes as control
characters in any locale. The iscntrl() check was added as part of the
fix for CVE-2023-29383, which blocked C0 control characters, but C1
bytes were never considered.

The byte 0x9B is the C1 encoding of CSI (Control Sequence Introducer),
equivalent to ESC [. On terminals that interpret C1 codes (VTE-based
terminals such as GNOME Terminal, Tilix, Terminator, XFCE Terminal),
an attacker can inject terminal escape sequences into GECOS fields via
chfn. This allows visual spoofing of /etc/passwd output, for example
making a user's UID appear as 0 when viewed with cat.

Explicitly check for bytes in the 0x80-0x9F range in strchriscntrl()
so that valid_field() returns -1 (rejected) instead of 1 (non-ASCII
warning) for these bytes.

Before (unpatched chfn accepts C1 bytes and writes them to /etc/passwd):

  $ cat /etc/passwd | grep ubuntu
  ubuntu:x:1000:1000:ubuntu,,,:/home/ubuntu:/bin/bash
  $ chfn -r $'\xc2\x9b17D0\xc2\x9b3P\xc2\x9b1C0\xc2\x9b3P\xc2\x9b1Croot\xc2\x9b8m'
  Password:
  chfn: room number with non-ASCII characters: [...]
  $ cat /etc/passwd | grep ubuntu
  ubuntu:x:0:0:root,,:/home/ubuntu:/bin/bash

After (patched chfn rejects C1 bytes, /etc/passwd unchanged):

  $ chfn -r $'\xc2\x9b17D0\xc2\x9b3P\xc2\x9b1C0\xc2\x9b3P\xc2\x9b1Croot\xc2\x9b8m'
  Password:
  chfn: invalid room number: [...]
  $ cat /etc/passwd | grep ubuntu
  ubuntu:x:1000:1000:ubuntu,,,:/home/ubuntu:/bin/bash

Tested on Shadow 4.17.4-2ubuntu2 (Ubuntu 25.10, aarch64).

4 weeks agousermod: Create shadow entry with -e 0 or -f 0
Tobias Stoeckmann [Wed, 11 Mar 2026 20:15:10 +0000 (21:15 +0100)] 
usermod: Create shadow entry with -e 0 or -f 0

If -e 0 or -f 0 are supplied but no shadow entry exists, these flags are
silently ignored. Internally, the supplied values (0) are compared with
static long values which are initially 0 as well. If they are identical,
usermod drops the flags.

This does not match usermod's manual page, which states that a missing
shadow entry is created. This is also true for any other valid command
line values, e.g. -e 1 or -f 1.

Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
4 weeks agoTests: Add user with existing UID without -o flag
aborah-sudo [Wed, 11 Mar 2026 08:27:42 +0000 (13:57 +0530)] 
Tests: Add user with existing UID without -o flag

This is the transformation to Python of the test located in
`04_useradd_add_user_with_existing_UID_fail`, which checks that `useradd` fails to create a new user with existing UID without -o flag

4 weeks agolib/commonio.c: Diagnose non-text files
Alejandro Colomar [Wed, 11 Mar 2026 22:07:44 +0000 (23:07 +0100)] 
lib/commonio.c: Diagnose non-text files

Closes: <https://github.com/shadow-maint/shadow/issues/1581>
Reported-by: Tim Zhou <tizhou@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
4 weeks agoci: run unit-tests in Ubuntu build
Iker Pedrosa [Tue, 10 Mar 2026 09:32:47 +0000 (10:32 +0100)] 
ci: run unit-tests in Ubuntu build

Run unit-tests as part of the Ubuntu build

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
4 weeks agoci: add missing `cmocka` dependency for Ubuntu runners
Iker Pedrosa [Tue, 10 Mar 2026 09:48:16 +0000 (10:48 +0100)] 
ci: add missing `cmocka` dependency for Ubuntu runners

`cmocka` is required to run unit-tests

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
4 weeks agoTests: Add a new user with specified UID and GID
aborah-sudo [Mon, 9 Mar 2026 05:50:21 +0000 (11:20 +0530)] 
Tests: Add a new user with specified UID and GID

This is the transformation to Python of the test located in
`tests/usertools/01/04_useradd_specified_UID_and_GID.test`,
which checks that `useradd` is able to create a new user with specified uid and gid

4 weeks agoTests: Create user with custom uid options
aborah-sudo [Wed, 4 Mar 2026 06:59:16 +0000 (12:29 +0530)] 
Tests: Create user with custom uid options

This is the transformation to Python of the test located in
`tests/usertools/01/04_useradd_specified_UID.test`,

which checks that `useradd` is able to create a new user with specified uid

5 weeks agolib/io/syslog.h: SYSLOG_C(): Call setlocale(3) and free(3) unconditionally
Alejandro Colomar [Wed, 23 Jul 2025 00:23:57 +0000 (02:23 +0200)] 
lib/io/syslog.h: SYSLOG_C(): Call setlocale(3) and free(3) unconditionally

Both setlocale(3) and free(3) are okay to call with a null pointer.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
5 weeks agolib/io/syslog.h: SYSLOG_C(): Use a single local variable
Alejandro Colomar [Wed, 23 Jul 2025 17:59:02 +0000 (19:59 +0200)] 
lib/io/syslog.h: SYSLOG_C(): Use a single local variable

There's no need for two variables, and this avoids one assignment.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
5 weeks agolib/io/syslog.h: Rename local variable
Alejandro Colomar [Wed, 23 Jul 2025 17:58:07 +0000 (19:58 +0200)] 
lib/io/syslog.h: Rename local variable

Signed-off-by: Alejandro Colomar <alx@kernel.org>
5 weeks agolib/io/syslog.h: SYSLOG_C(): Split code to helper macro
Alejandro Colomar [Wed, 23 Jul 2025 17:50:04 +0000 (19:50 +0200)] 
lib/io/syslog.h: SYSLOG_C(): Split code to helper macro

The name of this macro makes it more evident what it does.  It's a
C-locale version of syslog(3).  We need to implement it as a macro
so that arguments such as strerror(3) are evaluated after setting
the C locale.  This would be impossible with a function.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
5 weeks agolib/: Move <syslog.h> wrappers to "io/syslog.h"
Alejandro Colomar [Tue, 22 Jul 2025 23:41:11 +0000 (01:41 +0200)] 
lib/: Move <syslog.h> wrappers to "io/syslog.h"

Signed-off-by: Alejandro Colomar <alx@kernel.org>
5 weeks agoTests: Create user with comment, expiredate, inactive, shell and custom home
aborah-sudo [Mon, 2 Mar 2026 07:04:18 +0000 (12:34 +0530)] 
Tests: Create user with comment, expiredate, inactive, shell and custom home

This is the transformation to Python of the test located in
`tests/usertools/01/03_useradd_additional_options.test`, which checks that
`useradd` is able to create a new user with comment, expiredate, inactive, shell and custom home

5 weeks agoFix build failure on hosts with gcc 10
Chen Qi [Wed, 11 Feb 2026 05:17:04 +0000 (05:17 +0000)] 
Fix build failure on hosts with gcc 10

We cannot just uname these unused parameters because gcc 10
need them. There will be error like below with gcc 10:

  lib/copydir.c:103:11: error: parameter name omitted

The Debian bullseye uses gcc 10 by default.

Most of the changes are done manually. Some changes in tests/unit
are done via the following shell command:
sed -i -e 's#void \*\*#MAYBE_UNUSED void \*\* _1#g'  tests/unit/test_*.c

Closes: <https://github.com/shadow-maint/shadow/issues/1530>
Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
5 weeks agoci: run privileged system tests in CI
Hadi Chokr [Thu, 12 Feb 2026 11:20:01 +0000 (12:20 +0100)] 
ci: run privileged system tests in CI

Signed-off-by: Hadi Chokr <hadichokr@icloud.com>
5 weeks agotests: add privileged useradd test for BTRFS subvolume homes
Hadi Chokr [Thu, 12 Feb 2026 11:17:52 +0000 (12:17 +0100)] 
tests: add privileged useradd test for BTRFS subvolume homes

Add a privileged system test that verifies useradd can create home
directories as BTRFS subvolumes.

This test requires elevated privileges to use:
The BTRFS filesystem Framework class to create a /home directory on
BTRFS and check if the Users Home directory is a BTRFS Subvolume.

The test is intentionally isolated and excluded from default test runs
to prevent accidental execution on host systems.

Signed-off-by: Hadi Chokr <hadichokr@icloud.com>
5 weeks agotests: add privileged topology and test configuration
Hadi Chokr [Thu, 12 Feb 2026 11:16:39 +0000 (12:16 +0100)] 
tests: add privileged topology and test configuration

Extend the Python system test framework with a dedicated privileged
topology and configuration, while keeping privileged tests excluded
by default. And include a BTRFS Framework class for BTRFS Operations.

This ensures:
- Clear separation between safe and destructive tests
- No accidental execution of privileged tests in normal CI or local runs
- Explicit opt-in for privileged environments

Signed-off-by: Hadi Chokr <hadichokr@icloud.com>
5 weeks agodoc: document privileged containers and privileged system tests
Hadi Chokr [Thu, 12 Feb 2026 11:14:54 +0000 (12:14 +0100)] 
doc: document privileged containers and privileged system tests

Document the distinction between unprivileged and privileged execution
modes for containers and system tests.

Add explicit warnings that privileged tests must never be run on the
host system, as they may mount filesystems, create loop devices, or
modify kernel-visible state.

Provide clear guidance on when privileged tests are acceptable and how
to execute them safely in disposable environments.

Signed-off-by: Hadi Chokr <hadichokr@icloud.com>
5 weeks agoshare: add privileged container support for CI and system tests
Hadi Chokr [Thu, 12 Feb 2026 11:13:46 +0000 (12:13 +0100)] 
share: add privileged container support for CI and system tests

Introduce opt-in privileged container execution for CI and local runs.
This enables filesystem-level tests (e.g. BTRFS, mounts) while keeping
unprivileged execution as the default and safe path.

Changes include:
- Separate privileged and unprivileged builders
- Conditional Ansible roles and inventories
- Privileged test execution wiring
- --privileged support in container-build.sh

Signed-off-by: Hadi Chokr <hadichokr@icloud.com>