From 875723a30b2d8c026c43a0a13d8eaadcd99f7e76 Mon Sep 17 00:00:00 2001 From: Tim Landscheidt Date: Thu, 7 Mar 2019 03:45:18 +0000 Subject: [PATCH 001/134] Remove obsolete requirements for post/pre scriptlets --- shadow-utils.spec | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index 750a26c..ed97a4d 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.6 -Release: 8%{?dist} +Release: 9%{?dist} Epoch: 2 URL: http://pkg-shadow.alioth.debian.org/ Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -48,8 +48,6 @@ BuildRequires: /usr/bin/xsltproc, /usr/bin/itstool Requires: libselinux >= 1.25.2-1 Requires: audit-libs >= 1.6.5 Requires: setup -Requires(pre): coreutils -Requires(post): coreutils %description The shadow-utils package includes the necessary programs for @@ -241,6 +239,9 @@ done %{_mandir}/man8/vigr.8* %changelog +* Thu Mar 7 2019 Tim Landscheidt - 2:4.6-9 +- Remove obsolete requirements for post/pre scriptlets + * Sat Feb 02 2019 Fedora Release Engineering - 2:4.6-8 - Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild From 75c680d3182b8de12f2d68468203d46d92cb6b0e Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Thu, 21 Mar 2019 15:09:54 +0100 Subject: [PATCH 002/134] Ignore LOGIN_PLAIN_PROMPT variable in login.defs --- shadow-4.6-ignore-login-prompt.patch | 11 +++++++++++ shadow-utils.spec | 7 ++++++- 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 shadow-4.6-ignore-login-prompt.patch diff --git a/shadow-4.6-ignore-login-prompt.patch b/shadow-4.6-ignore-login-prompt.patch new file mode 100644 index 0000000..faf50f7 --- /dev/null +++ b/shadow-4.6-ignore-login-prompt.patch @@ -0,0 +1,11 @@ +diff -up shadow-4.6/lib/getdef.c.login-prompt shadow-4.6/lib/getdef.c +--- shadow-4.6/lib/getdef.c.login-prompt 2018-04-29 18:42:37.000000000 +0200 ++++ shadow-4.6/lib/getdef.c 2019-03-21 15:06:58.009280504 +0100 +@@ -94,6 +94,7 @@ static struct itemdef def_table[] = { + {"KILLCHAR", NULL}, + {"LOGIN_RETRIES", NULL}, + {"LOGIN_TIMEOUT", NULL}, ++ {"LOGIN_PLAIN_PROMPT", NULL}, + {"LOG_OK_LOGINS", NULL}, + {"LOG_UNKFAIL_ENAB", NULL}, + {"MAIL_DIR", NULL}, diff --git a/shadow-utils.spec b/shadow-utils.spec index ed97a4d..9d81c19 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.6 -Release: 9%{?dist} +Release: 10%{?dist} Epoch: 2 URL: http://pkg-shadow.alioth.debian.org/ Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -35,6 +35,7 @@ Patch36: shadow-4.6-use-itstool.patch Patch37: shadow-4.6-sssd-flush.patch Patch38: shadow-4.6-sysugid-min-limit.patch Patch39: shadow-4.6-chgrp-guard.patch +Patch40: shadow-4.6-ignore-login-prompt.patch License: BSD and GPLv2+ BuildRequires: gcc @@ -88,6 +89,7 @@ are used for managing group accounts. %patch37 -p1 -b .sssd-flush %patch38 -p1 -b .sysugid-min-limit %patch39 -p1 -b .chgrp-guard +%patch40 -p1 -b .login-prompt iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -239,6 +241,9 @@ done %{_mandir}/man8/vigr.8* %changelog +* Thu Mar 21 2019 Tomáš Mráz - 2:4.6-10 +- Ignore LOGIN_PLAIN_PROMPT variable in login.defs + * Thu Mar 7 2019 Tim Landscheidt - 2:4.6-9 - Remove obsolete requirements for post/pre scriptlets From 713a388dfc57d74ebab532b53cfa171d845fb0c9 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Fri, 22 Mar 2019 13:24:42 +0100 Subject: [PATCH 003/134] clarify chage manual page in regards to shadow and passwd inconsistency (#1686440) --- shadow-4.3.1-manfix.patch | 19 +++++++++++++++++++ shadow-utils.spec | 6 +++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/shadow-4.3.1-manfix.patch b/shadow-4.3.1-manfix.patch index 3782e55..43d5e9a 100644 --- a/shadow-4.3.1-manfix.patch +++ b/shadow-4.3.1-manfix.patch @@ -54,6 +54,25 @@ Index: shadow-4.5/man/chage.1.xml Passing the number -1 as the EXPIRE_DATE will remove an account expiration date. +@@ -233,6 +243,18 @@ + The chage program requires a shadow password file to + be available. + ++ ++ The chage program will report only the information from the shadow ++ password file. This implies that configuration from other sources ++ (e.g. LDAP or empty password hash field from the passwd file) that ++ affect the user's login will not be shown in the chage output. ++ ++ ++ The chage program will also not report any ++ inconsistency between the shadow and passwd files (e.g. missing x in ++ the passwd file). The pwck can be used to check ++ for this kind of inconsistencies. ++ + The chage command is restricted to the root + user, except for the option, which may be used by + an unprivileged user to determine when their password or account is due Index: shadow-4.5/man/ja/man5/login.defs.5 =================================================================== --- shadow-4.5.orig/man/ja/man5/login.defs.5 diff --git a/shadow-utils.spec b/shadow-utils.spec index 9d81c19..86e216f 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.6 -Release: 10%{?dist} +Release: 11%{?dist} Epoch: 2 URL: http://pkg-shadow.alioth.debian.org/ Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -241,6 +241,10 @@ done %{_mandir}/man8/vigr.8* %changelog +* Fri Mar 22 2019 Tomáš Mráz - 2:4.6-11 +- clarify chage manual page in regards to shadow and passwd + inconsistency (#1686440) + * Thu Mar 21 2019 Tomáš Mráz - 2:4.6-10 - Ignore LOGIN_PLAIN_PROMPT variable in login.defs From c5ff8b2cd3fdb3e6762ffc6de3d71c99396c71de Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Tue, 2 Apr 2019 16:53:44 +0200 Subject: [PATCH 004/134] force regeneration of getdate.c otherwise the date parsing fix is not applied --- shadow-utils.spec | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index 86e216f..bcdcd94 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.6 -Release: 11%{?dist} +Release: 12%{?dist} Epoch: 2 URL: http://pkg-shadow.alioth.debian.org/ Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -96,6 +96,9 @@ cp -f doc/HOWTO.utf8 doc/HOWTO cp -a %{SOURCE4} %{SOURCE5} . +# Force regeneration of getdate.c +rm libmisc/getdate.c + %build %ifarch sparc64 #sparc64 need big PIE @@ -241,6 +244,10 @@ done %{_mandir}/man8/vigr.8* %changelog +* Tue Apr 2 2019 Tomáš Mráz - 2:4.6-12 +- force regeneration of getdate.c otherwise the date parsing fix + is not applied + * Fri Mar 22 2019 Tomáš Mráz - 2:4.6-11 - clarify chage manual page in regards to shadow and passwd inconsistency (#1686440) From c2e806d82cc13ad12130da83db2e36a1977eff14 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Fri, 3 May 2019 11:22:39 +0200 Subject: [PATCH 005/134] use lckpwdf() again to disable concurrent edits of databases by other applications --- shadow-4.6-use-lckpwdf.patch | 190 +++++++++++++++++++++++++++++++++++ shadow-utils.spec | 8 +- 2 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 shadow-4.6-use-lckpwdf.patch diff --git a/shadow-4.6-use-lckpwdf.patch b/shadow-4.6-use-lckpwdf.patch new file mode 100644 index 0000000..363579a --- /dev/null +++ b/shadow-4.6-use-lckpwdf.patch @@ -0,0 +1,190 @@ +commit 408b8a548243aebaa6d773beeae8ddf4bb6100f0 +Author: Tomas Mraz +Date: Thu May 2 14:33:06 2019 +0200 + + Use the lckpwdf() again if prefix is not set + + The implementation of prefix option dropped the use of lckpwdf(). + However that is incorrect as other tools manipulating the shadow passwords + such as PAM use lckpwdf() and do not know anything about the + shadow's own locking mechanism. + + This reverts the implementation to use lckpwdf() if prefix option + is not used. + +diff --git a/lib/commonio.c b/lib/commonio.c +index 26e518f2..94dda779 100644 +--- a/lib/commonio.c ++++ b/lib/commonio.c +@@ -364,6 +364,7 @@ static void free_linked_list (struct commonio_db *db) + int commonio_setname (struct commonio_db *db, const char *name) + { + snprintf (db->filename, sizeof (db->filename), "%s", name); ++ db->setname = true; + return 1; + } + +@@ -414,37 +415,39 @@ cleanup_ENOMEM: + + int commonio_lock (struct commonio_db *db) + { +-/*#ifdef HAVE_LCKPWDF*/ /* not compatible with prefix option*/ +-#if 0 +- /* +- * only if the system libc has a real lckpwdf() - the one from +- * lockpw.c calls us and would cause infinite recursion! +- */ ++ int i; + ++#ifdef HAVE_LCKPWDF + /* +- * Call lckpwdf() on the first lock. +- * If it succeeds, call *_lock() only once +- * (no retries, it should always succeed). ++ * Only if the system libc has a real lckpwdf() - the one from ++ * lockpw.c calls us and would cause infinite recursion! ++ * It is also not used with the prefix option. + */ +- if (0 == lock_count) { +- if (lckpwdf () == -1) { +- if (geteuid () != 0) { +- (void) fprintf (stderr, +- "%s: Permission denied.\n", +- Prog); ++ if (!db->setname) { ++ /* ++ * Call lckpwdf() on the first lock. ++ * If it succeeds, call *_lock() only once ++ * (no retries, it should always succeed). ++ */ ++ if (0 == lock_count) { ++ if (lckpwdf () == -1) { ++ if (geteuid () != 0) { ++ (void) fprintf (stderr, ++ "%s: Permission denied.\n", ++ Prog); ++ } ++ return 0; /* failure */ + } +- return 0; /* failure */ + } +- } + +- if (commonio_lock_nowait (db, true) != 0) { +- return 1; /* success */ +- } ++ if (commonio_lock_nowait (db, true) != 0) { ++ return 1; /* success */ ++ } + +- ulckpwdf (); +- return 0; /* failure */ +-#else /* !HAVE_LCKPWDF */ +- int i; ++ ulckpwdf (); ++ return 0; /* failure */ ++ } ++#endif /* !HAVE_LCKPWDF */ + + /* + * lckpwdf() not used - do it the old way. +@@ -471,7 +474,6 @@ int commonio_lock (struct commonio_db *db) + } + } + return 0; /* failure */ +-#endif /* !HAVE_LCKPWDF */ + } + + static void dec_lock_count (void) +diff --git a/lib/commonio.h b/lib/commonio.h +index 40e5708f..64e83073 100644 +--- a/lib/commonio.h ++++ b/lib/commonio.h +@@ -143,6 +143,7 @@ struct commonio_db { + bool isopen:1; + bool locked:1; + bool readonly:1; ++ bool setname:1; + }; + + extern int commonio_setname (struct commonio_db *, const char *); +diff --git a/lib/groupio.c b/lib/groupio.c +index ae2302b5..bffb06e0 100644 +--- a/lib/groupio.c ++++ b/lib/groupio.c +@@ -139,7 +139,8 @@ static /*@owned@*/struct commonio_db group_db = { + false, /* changed */ + false, /* isopen */ + false, /* locked */ +- false /* readonly */ ++ false, /* readonly */ ++ false /* setname */ + }; + + int gr_setdbname (const char *filename) +diff --git a/lib/pwio.c b/lib/pwio.c +index 7ee85377..127719cb 100644 +--- a/lib/pwio.c ++++ b/lib/pwio.c +@@ -114,7 +114,8 @@ static struct commonio_db passwd_db = { + false, /* changed */ + false, /* isopen */ + false, /* locked */ +- false /* readonly */ ++ false, /* readonly */ ++ false /* setname */ + }; + + int pw_setdbname (const char *filename) +diff --git a/lib/sgroupio.c b/lib/sgroupio.c +index 5423626a..ffbdb263 100644 +--- a/lib/sgroupio.c ++++ b/lib/sgroupio.c +@@ -238,7 +238,8 @@ static struct commonio_db gshadow_db = { + false, /* changed */ + false, /* isopen */ + false, /* locked */ +- false /* readonly */ ++ false, /* readonly */ ++ false /* setname */ + }; + + int sgr_setdbname (const char *filename) +diff --git a/lib/shadowio.c b/lib/shadowio.c +index 5fa3d312..676b1f1a 100644 +--- a/lib/shadowio.c ++++ b/lib/shadowio.c +@@ -114,7 +114,8 @@ static struct commonio_db shadow_db = { + false, /* changed */ + false, /* isopen */ + false, /* locked */ +- false /* readonly */ ++ false, /* readonly */ ++ false /* setname */ + }; + + int spw_setdbname (const char *filename) +diff --git a/lib/subordinateio.c b/lib/subordinateio.c +index a662e67e..dd779c59 100644 +--- a/lib/subordinateio.c ++++ b/lib/subordinateio.c +@@ -550,7 +550,8 @@ static struct commonio_db subordinate_uid_db = { + false, /* changed */ + false, /* isopen */ + false, /* locked */ +- false /* readonly */ ++ false, /* readonly */ ++ false /* setname */ + }; + + int sub_uid_setdbname (const char *filename) +@@ -631,7 +632,8 @@ static struct commonio_db subordinate_gid_db = { + false, /* changed */ + false, /* isopen */ + false, /* locked */ +- false /* readonly */ ++ false, /* readonly */ ++ false /* setname */ + }; + + int sub_gid_setdbname (const char *filename) diff --git a/shadow-utils.spec b/shadow-utils.spec index bcdcd94..a032118 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.6 -Release: 12%{?dist} +Release: 13%{?dist} Epoch: 2 URL: http://pkg-shadow.alioth.debian.org/ Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -36,6 +36,7 @@ Patch37: shadow-4.6-sssd-flush.patch Patch38: shadow-4.6-sysugid-min-limit.patch Patch39: shadow-4.6-chgrp-guard.patch Patch40: shadow-4.6-ignore-login-prompt.patch +Patch41: shadow-4.6-use-lckpwdf.patch License: BSD and GPLv2+ BuildRequires: gcc @@ -90,6 +91,7 @@ are used for managing group accounts. %patch38 -p1 -b .sysugid-min-limit %patch39 -p1 -b .chgrp-guard %patch40 -p1 -b .login-prompt +%patch41 -p1 -b .use-lckpwdf iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -244,6 +246,10 @@ done %{_mandir}/man8/vigr.8* %changelog +* Fri May 3 2019 Tomáš Mráz - 2:4.6-13 +- use lckpwdf() again to disable concurrent edits of databases by + other applications + * Tue Apr 2 2019 Tomáš Mráz - 2:4.6-12 - force regeneration of getdate.c otherwise the date parsing fix is not applied From e17e2fa767aec510adca1ed3af0c8f6554d624ae Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Fri, 7 Jun 2019 14:40:46 +0200 Subject: [PATCH 006/134] minor auditing fixes --- shadow-4.3.1-manfix.patch | 20 +++++++++++++++ shadow-4.6-audit-update.patch | 46 ++++++++++++++++++++++++----------- shadow-utils.spec | 5 +++- 3 files changed, 56 insertions(+), 15 deletions(-) diff --git a/shadow-4.3.1-manfix.patch b/shadow-4.3.1-manfix.patch index 43d5e9a..bd1577e 100644 --- a/shadow-4.3.1-manfix.patch +++ b/shadow-4.3.1-manfix.patch @@ -327,3 +327,23 @@ index 5ad812f7..516417b7 100644 +diff -up shadow-4.6/man/groupadd.8.xml.manfix shadow-4.6/man/groupadd.8.xml +--- shadow-4.6/man/groupadd.8.xml.manfix 2019-04-02 16:35:52.096637444 +0200 ++++ shadow-4.6/man/groupadd.8.xml 2019-06-07 14:23:57.477602106 +0200 +@@ -320,13 +320,13 @@ + + 4 + +- GID not unique (when not used) ++ GID is already used (when called without ) + + + + 9 + +- group name not unique ++ group name is already used + + + + diff --git a/shadow-4.6-audit-update.patch b/shadow-4.6-audit-update.patch index b9d0a67..4237739 100644 --- a/shadow-4.6-audit-update.patch +++ b/shadow-4.6-audit-update.patch @@ -834,16 +834,23 @@ diff -up shadow-4.6/src/groupmod.c.audit-update shadow-4.6/src/groupmod.c info_group.audit_msg, group_name, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); -@@ -472,7 +472,7 @@ static void close_files (void) +@@ -472,7 +472,14 @@ static void close_files (void) exit (E_GRP_UPDATE); } #ifdef WITH_AUDIT - audit_logger (AUDIT_USER_ACCT, Prog, -+ audit_logger (AUDIT_GRP_MGMT, Prog, ++ /* If both happened, log password change as its more important */ ++ if (pflg) ++ audit_logger (AUDIT_GRP_CHAUTHTOK, Prog, ++ info_gshadow.audit_msg, ++ group_name, AUDIT_NO_ID, ++ SHADOW_AUDIT_SUCCESS); ++ else ++ audit_logger (AUDIT_GRP_MGMT, Prog, info_gshadow.audit_msg, group_name, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); -@@ -495,7 +495,7 @@ static void close_files (void) +@@ -495,7 +502,7 @@ static void close_files (void) exit (E_GRP_UPDATE); } #ifdef WITH_AUDIT @@ -852,7 +859,7 @@ diff -up shadow-4.6/src/groupmod.c.audit-update shadow-4.6/src/groupmod.c info_passwd.audit_msg, group_name, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); -@@ -510,8 +510,8 @@ static void close_files (void) +@@ -510,8 +517,8 @@ static void close_files (void) } #ifdef WITH_AUDIT @@ -863,7 +870,7 @@ diff -up shadow-4.6/src/groupmod.c.audit-update shadow-4.6/src/groupmod.c group_name, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); #endif -@@ -523,6 +523,8 @@ static void close_files (void) +@@ -523,6 +530,8 @@ static void close_files (void) */ static void prepare_failure_reports (void) { @@ -872,7 +879,7 @@ diff -up shadow-4.6/src/groupmod.c.audit-update shadow-4.6/src/groupmod.c info_group.name = group_name; #ifdef SHADOWGRP info_gshadow.name = group_name; -@@ -535,76 +537,106 @@ static void prepare_failure_reports (voi +@@ -535,76 +544,109 @@ static void prepare_failure_reports (voi #endif info_passwd.audit_msg = xmalloc (512); @@ -971,6 +978,9 @@ diff -up shadow-4.6/src/groupmod.c.audit-update shadow-4.6/src/groupmod.c + free(nv_pair); } if (pflg) { ++ strncat(info_passwd.audit_msg, "op=change-password", ++ 511 - strlen (info_passwd.action)); ++ + /* Note: audit doesn't want this value recorded */ strncat (info_group.action, ", new password", - 511 - strlen (info_group.audit_msg)); @@ -1006,7 +1016,7 @@ diff -up shadow-4.6/src/groupmod.c.audit-update shadow-4.6/src/groupmod.c "%lu", (unsigned long int) group_newid); } info_group.audit_msg[511] = '\0'; -@@ -612,6 +644,11 @@ static void prepare_failure_reports (voi +@@ -612,6 +654,11 @@ static void prepare_failure_reports (voi info_gshadow.audit_msg[511] = '\0'; #endif info_passwd.audit_msg[511] = '\0'; @@ -1603,16 +1613,24 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c fail_exit (E_PW_UPDATE); } #ifdef ENABLE_SUBIDS -@@ -1997,7 +1939,7 @@ static void usr_update (void) +@@ -1996,9 +1938,14 @@ static void usr_update (void) + #endif /* ENABLE_SUBIDS */ #ifdef WITH_AUDIT ++ /* ++ * Even though we have the ID of the user, we won't send it now ++ * because its not written to disk yet. After close_files it is ++ * and we can use the real ID thereafter. ++ */ audit_logger (AUDIT_ADD_USER, Prog, - "adding user", +- user_name, (unsigned int) user_id, + "add-user", - user_name, (unsigned int) user_id, ++ user_name, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); #endif -@@ -2032,12 +1974,6 @@ static void create_home (void) + /* +@@ -2032,12 +1979,6 @@ static void create_home (void) fprintf (stderr, _("%s: cannot create directory %s\n"), Prog, prefix_user_home); @@ -1625,7 +1643,7 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c fail_exit (E_HOMEDIR); } (void) chown (prefix_user_home, user_id, user_gid); -@@ -2045,8 +1981,8 @@ static void create_home (void) +@@ -2045,8 +1986,8 @@ static void create_home (void) 0777 & ~getdef_num ("UMASK", GETDEF_DEFAULT_UMASK)); home_added = true; #ifdef WITH_AUDIT @@ -1636,7 +1654,7 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c user_name, (unsigned int) user_id, SHADOW_AUDIT_SUCCESS); #endif -@@ -2231,12 +2167,6 @@ int main (int argc, char **argv) +@@ -2231,12 +2172,6 @@ int main (int argc, char **argv) */ if (prefix_getpwnam (user_name) != NULL) { /* local, no need for xgetpwnam */ fprintf (stderr, _("%s: user '%s' already exists\n"), Prog, user_name); @@ -1649,7 +1667,7 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c fail_exit (E_NAME_IN_USE); } -@@ -2252,12 +2182,6 @@ int main (int argc, char **argv) +@@ -2252,12 +2187,6 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: group %s exists - if you want to add this user to that group, use -g.\n"), Prog, user_name); @@ -1662,7 +1680,7 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c fail_exit (E_NAME_IN_USE); } } -@@ -2287,12 +2211,6 @@ int main (int argc, char **argv) +@@ -2287,12 +2216,6 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: UID %lu is not unique\n"), Prog, (unsigned long) user_id); diff --git a/shadow-utils.spec b/shadow-utils.spec index a032118..5fcc027 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.6 -Release: 13%{?dist} +Release: 14%{?dist} Epoch: 2 URL: http://pkg-shadow.alioth.debian.org/ Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -246,6 +246,9 @@ done %{_mandir}/man8/vigr.8* %changelog +* Fri Jun 7 2019 Tomáš Mráz - 2:4.6-14 +- minor auditing fixes + * Fri May 3 2019 Tomáš Mráz - 2:4.6-13 - use lckpwdf() again to disable concurrent edits of databases by other applications From 6065752fdce81cfde0a9b4cc509e282f086f87e0 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 26 Jul 2019 23:10:38 +0000 Subject: [PATCH 007/134] - Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- shadow-utils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index 5fcc027..9a85fd6 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.6 -Release: 14%{?dist} +Release: 15%{?dist} Epoch: 2 URL: http://pkg-shadow.alioth.debian.org/ Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -246,6 +246,9 @@ done %{_mandir}/man8/vigr.8* %changelog +* Fri Jul 26 2019 Fedora Release Engineering - 2:4.6-15 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + * Fri Jun 7 2019 Tomáš Mráz - 2:4.6-14 - minor auditing fixes From 3e9ca2fc3346ff6b5cbdf4a3a2c21828dfafc8bd Mon Sep 17 00:00:00 2001 From: Petr Lautrbach Date: Mon, 2 Sep 2019 14:37:23 +0200 Subject: [PATCH 008/134] chpasswd, chgpasswd: Run SELinux checks before chroot() libselinux checks the state of SELinux only in the library constructor and then uses a cached value. It can be a problem for processes which do chroot() as there's usually no SELinux interface (/sys/fs/selinux) in the chroot. For chpasswd/chgpasswd is enough to do SELinux checks before processes are chroot()ed. Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1747215 --- shadow-4.3.1-selinux-perms.patch | 33 ++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/shadow-4.3.1-selinux-perms.patch b/shadow-4.3.1-selinux-perms.patch index 8550150..a08660f 100644 --- a/shadow-4.3.1-selinux-perms.patch +++ b/shadow-4.3.1-selinux-perms.patch @@ -98,7 +98,17 @@ Index: shadow-4.5/src/chgpasswd.c int errors = 0; int line = 0; -@@ -408,8 +476,33 @@ int main (int argc, char **argv) +@@ -402,12 +470,37 @@ int main (int argc, char **argv) + (void) bindtextdomain (PACKAGE, LOCALEDIR); + (void) textdomain (PACKAGE); + ++#ifdef WITH_SELINUX ++ selinux_check_root (); ++#endif ++ + process_root_flag ("-R", argc, argv); + + process_flags (argc, argv); OPENLOG ("chgpasswd"); @@ -125,10 +135,6 @@ Index: shadow-4.5/src/chgpasswd.c + check_perms (); -+#ifdef WITH_SELINUX -+ selinux_check_root (); -+#endif -+ #ifdef SHADOWGRP is_shadow_grp = sgr_file_present (); #endif @@ -230,7 +236,18 @@ Index: shadow-4.5/src/chpasswd.c /* * open_files - lock and open the password databases */ -@@ -405,8 +469,16 @@ int main (int argc, char **argv) +@@ -393,6 +457,10 @@ int main (int argc, char **argv) + (void) bindtextdomain (PACKAGE, LOCALEDIR); + (void) textdomain (PACKAGE); + ++#ifdef WITH_SELINUX ++ selinux_check_root (); ++#endif ++ + process_root_flag ("-R", argc, argv); + + process_flags (argc, argv); +@@ -405,6 +473,10 @@ int main (int argc, char **argv) OPENLOG ("chpasswd"); @@ -240,10 +257,6 @@ Index: shadow-4.5/src/chpasswd.c + check_perms (); -+#ifdef WITH_SELINUX -+ selinux_check_root (); -+#endif -+ #ifdef USE_PAM if (!use_pam) #endif /* USE_PAM */ From 36709cd2d7efbd1eb5969c4b09bd53ffb8ad3574 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Mon, 2 Sep 2019 15:48:01 +0200 Subject: [PATCH 009/134] fix SELinux related problem in chpasswd/chgpasswd when run with -R (patch by Petr Lautrbach) (#1747215) --- shadow-utils.spec | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index 9a85fd6..37dc958 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.6 -Release: 15%{?dist} +Release: 16%{?dist} Epoch: 2 URL: http://pkg-shadow.alioth.debian.org/ Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -246,6 +246,10 @@ done %{_mandir}/man8/vigr.8* %changelog +* Mon Sep 2 2019 Tomáš Mráz - 2:4.6-16 +- fix SELinux related problem in chpasswd/chgpasswd when run with -R + (patch by Petr Lautrbach) (#1747215) + * Fri Jul 26 2019 Fedora Release Engineering - 2:4.6-15 - Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild From b76250c68afcfb22146f4f0053d82a0975e85252 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Mon, 13 Jan 2020 11:46:38 +0100 Subject: [PATCH 010/134] update to current upstream release 4.8 --- .gitignore | 2 + shadow-4.2.1-no-lock-dos.patch | 16 - shadow-4.5-crypt_h.patch | 41 -- shadow-4.6-chgrp-guard.patch | 44 -- shadow-4.6-coverity.patch | 223 ------ shadow-4.6-ignore-login-prompt.patch | 11 - shadow-4.6-orig-context.patch | 128 ---- shadow-4.6-selinux.patch | 115 ---- shadow-4.6-sssd-flush.patch | 641 ------------------ shadow-4.6-use-itstool.patch | 31 - shadow-4.6-use-lckpwdf.patch | 190 ------ shadow-4.6-usermod-crash.patch | 42 -- ...ate.patch => shadow-4.8-audit-update.patch | 538 +++++++-------- shadow-4.8-crypt_h.patch | 35 + ...oodname.patch => shadow-4.8-goodname.patch | 38 +- shadow-4.8-ignore-login-prompt.patch | 11 + ...entry.patch => shadow-4.8-long-entry.patch | 36 +- ....1-manfix.patch => shadow-4.8-manfix.patch | 216 +++--- ...ms.patch => shadow-4.8-selinux-perms.patch | 76 +-- shadow-4.8-selinux.patch | 241 +++++++ shadow-utils.spec | 58 +- sources | 4 +- 22 files changed, 744 insertions(+), 1993 deletions(-) delete mode 100644 shadow-4.2.1-no-lock-dos.patch delete mode 100644 shadow-4.5-crypt_h.patch delete mode 100644 shadow-4.6-chgrp-guard.patch delete mode 100644 shadow-4.6-coverity.patch delete mode 100644 shadow-4.6-ignore-login-prompt.patch delete mode 100644 shadow-4.6-orig-context.patch delete mode 100644 shadow-4.6-selinux.patch delete mode 100644 shadow-4.6-sssd-flush.patch delete mode 100644 shadow-4.6-use-itstool.patch delete mode 100644 shadow-4.6-use-lckpwdf.patch delete mode 100644 shadow-4.6-usermod-crash.patch rename shadow-4.6-audit-update.patch => shadow-4.8-audit-update.patch (87%) create mode 100644 shadow-4.8-crypt_h.patch rename shadow-4.5-goodname.patch => shadow-4.8-goodname.patch (79%) create mode 100644 shadow-4.8-ignore-login-prompt.patch rename shadow-4.5-long-entry.patch => shadow-4.8-long-entry.patch (64%) rename shadow-4.3.1-manfix.patch => shadow-4.8-manfix.patch (74%) rename shadow-4.3.1-selinux-perms.patch => shadow-4.8-selinux-perms.patch (65%) create mode 100644 shadow-4.8-selinux.patch diff --git a/.gitignore b/.gitignore index 3b04b1e..9e9905a 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ shadow-4.1.4.2.tar.bz2 /shadow-4.5.tar.xz.asc /shadow-4.6.tar.xz /shadow-4.6.tar.xz.asc +/shadow-4.8.tar.xz +/shadow-4.8.tar.xz.asc diff --git a/shadow-4.2.1-no-lock-dos.patch b/shadow-4.2.1-no-lock-dos.patch deleted file mode 100644 index c6873e9..0000000 --- a/shadow-4.2.1-no-lock-dos.patch +++ /dev/null @@ -1,16 +0,0 @@ -Index: shadow-4.5/lib/commonio.c -=================================================================== ---- shadow-4.5.orig/lib/commonio.c -+++ shadow-4.5/lib/commonio.c -@@ -140,7 +140,10 @@ static int do_lock_file (const char *fil - int retval; - char buf[32]; - -- fd = open (file, O_CREAT | O_EXCL | O_WRONLY, 0600); -+ /* We depend here on the fact, that the file name is pid-specific. -+ * So no O_EXCL here and no DoS. -+ */ -+ fd = open (file, O_CREAT | O_TRUNC | O_WRONLY, 0600); - if (-1 == fd) { - if (log) { - (void) fprintf (stderr, diff --git a/shadow-4.5-crypt_h.patch b/shadow-4.5-crypt_h.patch deleted file mode 100644 index c8d19e4..0000000 --- a/shadow-4.5-crypt_h.patch +++ /dev/null @@ -1,41 +0,0 @@ -Index: shadow-4.5/configure.ac -=================================================================== ---- shadow-4.5.orig/configure.ac -+++ shadow-4.5/configure.ac -@@ -32,9 +32,9 @@ AC_HEADER_STDC - AC_HEADER_SYS_WAIT - AC_HEADER_STDBOOL - --AC_CHECK_HEADERS(errno.h fcntl.h limits.h unistd.h sys/time.h utmp.h \ -- utmpx.h termios.h termio.h sgtty.h sys/ioctl.h syslog.h paths.h \ -- utime.h ulimit.h sys/resource.h gshadow.h lastlog.h \ -+AC_CHECK_HEADERS(crypt.h errno.h fcntl.h limits.h unistd.h sys/time.h \ -+ utmp.h utmpx.h termios.h termio.h sgtty.h sys/ioctl.h syslog.h \ -+ paths.h utime.h ulimit.h sys/resource.h gshadow.h lastlog.h \ - locale.h rpc/key_prot.h netdb.h acl/libacl.h attr/libattr.h \ - attr/error_context.h) - -Index: shadow-4.5/lib/defines.h -=================================================================== ---- shadow-4.5.orig/lib/defines.h -+++ shadow-4.5/lib/defines.h -@@ -4,6 +4,8 @@ - #ifndef _DEFINES_H_ - #define _DEFINES_H_ - -+#include "config.h" -+ - #if HAVE_STDBOOL_H - # include - #else -@@ -94,6 +96,10 @@ char *strchr (), *strrchr (), *strtok () - # include - #endif - -+#if HAVE_CRYPT_H -+# include /* crypt(3) may be defined in here */ -+#endif -+ - #if TIME_WITH_SYS_TIME - # include - # include diff --git a/shadow-4.6-chgrp-guard.patch b/shadow-4.6-chgrp-guard.patch deleted file mode 100644 index 2918684..0000000 --- a/shadow-4.6-chgrp-guard.patch +++ /dev/null @@ -1,44 +0,0 @@ -diff -up shadow-4.6/man/usermod.8.xml.chgrp-guard shadow-4.6/man/usermod.8.xml ---- shadow-4.6/man/usermod.8.xml.chgrp-guard 2018-11-06 09:08:54.170095358 +0100 -+++ shadow-4.6/man/usermod.8.xml 2018-12-18 15:24:12.283181180 +0100 -@@ -195,6 +195,12 @@ - The group ownership of files outside of the user's home directory - must be fixed manually. - -+ -+ The change of the group ownership of files inside of the user's -+ home directory is also not done if the home dir owner uid is -+ different from the current or new user id. This is safety measure -+ for special home directories such as /. -+ - - - -@@ -372,6 +378,12 @@ - must be fixed manually. - - -+ The change of the user ownership of files inside of the user's -+ home directory is also not done if the home dir owner uid is -+ different from the current or new user id. This is safety measure -+ for special home directories such as /. -+ -+ - No checks will be performed with regard to the - , , - , or -diff -up shadow-4.6/src/usermod.c.chgrp-guard shadow-4.6/src/usermod.c ---- shadow-4.6/src/usermod.c.chgrp-guard 2018-12-18 15:24:12.286181249 +0100 -+++ shadow-4.6/src/usermod.c 2018-12-18 15:26:51.227841435 +0100 -@@ -2336,7 +2336,10 @@ int main (int argc, char **argv) - } - - if (!mflg && (uflg || gflg)) { -- if (access (dflg ? prefix_user_newhome : prefix_user_home, F_OK) == 0) { -+ struct stat sb; -+ -+ if (stat (dflg ? prefix_user_newhome : prefix_user_home, &sb) == 0 && -+ ((uflg && sb.st_uid == user_newid) || sb.st_uid == user_id)) { - /* - * Change the UID on all of the files owned by - * `user_id' to `user_newid' in the user's home diff --git a/shadow-4.6-coverity.patch b/shadow-4.6-coverity.patch deleted file mode 100644 index 44533e2..0000000 --- a/shadow-4.6-coverity.patch +++ /dev/null @@ -1,223 +0,0 @@ -diff -up shadow-4.6/lib/commonio.c.coverity shadow-4.6/lib/commonio.c ---- shadow-4.6/lib/commonio.c.coverity 2018-10-10 09:50:59.307738194 +0200 -+++ shadow-4.6/lib/commonio.c 2018-10-10 09:55:32.919319048 +0200 -@@ -382,7 +382,7 @@ int commonio_lock_nowait (struct commoni - char* lock = NULL; - size_t lock_file_len; - size_t file_len; -- int err; -+ int err = 0; - - if (db->locked) { - return 1; -@@ -391,12 +391,10 @@ int commonio_lock_nowait (struct commoni - lock_file_len = strlen(db->filename) + 6; /* sizeof ".lock" */ - file = (char*)malloc(file_len); - if(file == NULL) { -- err = ENOMEM; - goto cleanup_ENOMEM; - } - lock = (char*)malloc(lock_file_len); - if(lock == NULL) { -- err = ENOMEM; - goto cleanup_ENOMEM; - } - snprintf (file, file_len, "%s.%lu", -diff -up shadow-4.6/libmisc/console.c.coverity shadow-4.6/libmisc/console.c ---- shadow-4.6/libmisc/console.c.coverity 2018-04-29 18:42:37.000000000 +0200 -+++ shadow-4.6/libmisc/console.c 2018-10-10 11:56:51.368837533 +0200 -@@ -50,7 +50,7 @@ static bool is_listed (const char *cfgin - static bool is_listed (const char *cfgin, const char *tty, bool def) - { - FILE *fp; -- char buf[200], *s; -+ char buf[1024], *s; - const char *cons; - - /* -@@ -70,7 +70,8 @@ static bool is_listed (const char *cfgin - - if (*cons != '/') { - char *pbuf; -- strcpy (buf, cons); -+ strncpy (buf, cons, sizeof (buf)); -+ buf[sizeof (buf) - 1] = '\0'; - pbuf = &buf[0]; - while ((s = strtok (pbuf, ":")) != NULL) { - if (strcmp (s, tty) == 0) { -diff -up shadow-4.6/lib/spawn.c.coverity shadow-4.6/lib/spawn.c ---- shadow-4.6/lib/spawn.c.coverity 2018-04-29 18:42:37.000000001 +0200 -+++ shadow-4.6/lib/spawn.c 2018-10-10 11:36:49.035784609 +0200 -@@ -69,7 +69,7 @@ int run_command (const char *cmd, const - do { - wpid = waitpid (pid, status, 0); - } while ( ((pid_t)-1 == wpid && errno == EINTR) -- || (wpid != pid)); -+ || ((pid_t)-1 != wpid && wpid != pid)); - - if ((pid_t)-1 == wpid) { - fprintf (stderr, "%s: waitpid (status: %d): %s\n", -diff -up shadow-4.6/src/useradd.c.coverity shadow-4.6/src/useradd.c ---- shadow-4.6/src/useradd.c.coverity 2018-10-10 09:50:59.303738098 +0200 -+++ shadow-4.6/src/useradd.c 2018-10-12 13:51:54.480490257 +0200 -@@ -314,7 +314,7 @@ static void fail_exit (int code) - static void get_defaults (void) - { - FILE *fp; -- char* default_file = USER_DEFAULTS_FILE; -+ char *default_file = USER_DEFAULTS_FILE; - char buf[1024]; - char *cp; - -@@ -324,6 +324,8 @@ static void get_defaults (void) - - len = strlen(prefix) + strlen(USER_DEFAULTS_FILE) + 2; - default_file = malloc(len); -+ if (default_file == NULL) -+ return; - wlen = snprintf(default_file, len, "%s/%s", prefix, USER_DEFAULTS_FILE); - assert (wlen == (int) len -1); - } -@@ -334,7 +336,7 @@ static void get_defaults (void) - - fp = fopen (default_file, "r"); - if (NULL == fp) { -- return; -+ goto getdef_err; - } - - /* -@@ -445,7 +447,7 @@ static void get_defaults (void) - } - } - (void) fclose (fp); -- -+ getdef_err: - if(prefix[0]) { - free(default_file); - } -@@ -480,8 +482,8 @@ static int set_defaults (void) - FILE *ifp; - FILE *ofp; - char buf[1024]; -- char* new_file = NEW_USER_FILE; -- char* default_file = USER_DEFAULTS_FILE; -+ char *new_file = NULL; -+ char *default_file = USER_DEFAULTS_FILE; - char *cp; - int ofd; - int wlen; -@@ -492,17 +494,30 @@ static int set_defaults (void) - bool out_shell = false; - bool out_skel = false; - bool out_create_mail_spool = false; -+ size_t len; -+ int ret = -1; - -- if(prefix[0]) { -- size_t len; - -- len = strlen(prefix) + strlen(NEW_USER_FILE) + 2; -- new_file = malloc(len); -- wlen = snprintf(new_file, len, "%s/%s", prefix, NEW_USER_FILE); -- assert (wlen == (int) len -1); -+ len = strlen(prefix) + strlen(NEW_USER_FILE) + 2; -+ new_file = malloc(len); -+ if (new_file == NULL) { -+ fprintf (stderr, -+ _("%s: cannot create new defaults file: %s\n"), -+ Prog, strerror(errno)); -+ return -1; -+ } -+ wlen = snprintf(new_file, len, "%s%s%s", prefix, prefix[0]?"/":"", NEW_USER_FILE); -+ assert (wlen <= (int) len -1); - -+ if(prefix[0]) { - len = strlen(prefix) + strlen(USER_DEFAULTS_FILE) + 2; - default_file = malloc(len); -+ if (default_file == NULL) { -+ fprintf (stderr, -+ _("%s: cannot create new defaults file: %s\n"), -+ Prog, strerror(errno)); -+ goto setdef_err; -+ } - wlen = snprintf(default_file, len, "%s/%s", prefix, USER_DEFAULTS_FILE); - assert (wlen == (int) len -1); - } -@@ -515,7 +530,7 @@ static int set_defaults (void) - fprintf (stderr, - _("%s: cannot create new defaults file\n"), - Prog); -- return -1; -+ goto setdef_err; - } - - ofp = fdopen (ofd, "w"); -@@ -523,7 +538,7 @@ static int set_defaults (void) - fprintf (stderr, - _("%s: cannot open new defaults file\n"), - Prog); -- return -1; -+ goto setdef_err; - } - - /* -@@ -550,7 +565,7 @@ static int set_defaults (void) - _("%s: line too long in %s: %s..."), - Prog, default_file, buf); - (void) fclose (ifp); -- return -1; -+ goto setdef_err; - } - } - -@@ -614,7 +629,7 @@ static int set_defaults (void) - || (fsync (fileno (ofp)) != 0) - || (fclose (ofp) != 0)) { - unlink (new_file); -- return -1; -+ goto setdef_err; - } - - /* -@@ -629,7 +644,7 @@ static int set_defaults (void) - _("%s: Cannot create backup file (%s): %s\n"), - Prog, buf, strerror (err)); - unlink (new_file); -- return -1; -+ goto setdef_err; - } - - /* -@@ -640,11 +655,11 @@ static int set_defaults (void) - fprintf (stderr, - _("%s: rename: %s: %s\n"), - Prog, new_file, strerror (err)); -- return -1; -+ goto setdef_err; - } - #ifdef WITH_AUDIT - audit_logger (AUDIT_USYS_CONFIG, Prog, -- "changing-useradd-defaults", -+ "changing useradd defaults", - NULL, AUDIT_NO_ID, - SHADOW_AUDIT_SUCCESS); - #endif -@@ -654,13 +669,14 @@ static int set_defaults (void) - (unsigned int) def_group, def_home, def_shell, - def_inactive, def_expire, def_template, - def_create_mail_spool)); -- -+ ret = 0; -+ setdef_err: -+ free(new_file); - if(prefix[0]) { -- free(new_file); - free(default_file); - } - -- return 0; -+ return ret; - } - - /* diff --git a/shadow-4.6-ignore-login-prompt.patch b/shadow-4.6-ignore-login-prompt.patch deleted file mode 100644 index faf50f7..0000000 --- a/shadow-4.6-ignore-login-prompt.patch +++ /dev/null @@ -1,11 +0,0 @@ -diff -up shadow-4.6/lib/getdef.c.login-prompt shadow-4.6/lib/getdef.c ---- shadow-4.6/lib/getdef.c.login-prompt 2018-04-29 18:42:37.000000000 +0200 -+++ shadow-4.6/lib/getdef.c 2019-03-21 15:06:58.009280504 +0100 -@@ -94,6 +94,7 @@ static struct itemdef def_table[] = { - {"KILLCHAR", NULL}, - {"LOGIN_RETRIES", NULL}, - {"LOGIN_TIMEOUT", NULL}, -+ {"LOGIN_PLAIN_PROMPT", NULL}, - {"LOG_OK_LOGINS", NULL}, - {"LOG_UNKFAIL_ENAB", NULL}, - {"MAIL_DIR", NULL}, diff --git a/shadow-4.6-orig-context.patch b/shadow-4.6-orig-context.patch deleted file mode 100644 index ea522e7..0000000 --- a/shadow-4.6-orig-context.patch +++ /dev/null @@ -1,128 +0,0 @@ -diff -up shadow-4.6/lib/commonio.c.orig-context shadow-4.6/lib/commonio.c ---- shadow-4.6/lib/commonio.c.orig-context 2018-04-29 18:42:37.000000000 +0200 -+++ shadow-4.6/lib/commonio.c 2018-05-28 14:56:37.287929667 +0200 -@@ -961,7 +961,7 @@ int commonio_close (struct commonio_db * - snprintf (buf, sizeof buf, "%s-", db->filename); - - #ifdef WITH_SELINUX -- if (set_selinux_file_context (buf) != 0) { -+ if (set_selinux_file_context (buf, db->filename) != 0) { - errors++; - } - #endif -@@ -994,7 +994,7 @@ int commonio_close (struct commonio_db * - snprintf (buf, sizeof buf, "%s+", db->filename); - - #ifdef WITH_SELINUX -- if (set_selinux_file_context (buf) != 0) { -+ if (set_selinux_file_context (buf, db->filename) != 0) { - errors++; - } - #endif -diff -up shadow-4.6/libmisc/copydir.c.orig-context shadow-4.6/libmisc/copydir.c ---- shadow-4.6/libmisc/copydir.c.orig-context 2018-04-29 18:42:37.000000000 +0200 -+++ shadow-4.6/libmisc/copydir.c 2018-05-28 14:56:37.287929667 +0200 -@@ -484,7 +484,7 @@ static int copy_dir (const char *src, co - */ - - #ifdef WITH_SELINUX -- if (set_selinux_file_context (dst) != 0) { -+ if (set_selinux_file_context (dst, NULL) != 0) { - return -1; - } - #endif /* WITH_SELINUX */ -@@ -605,7 +605,7 @@ static int copy_symlink (const char *src - } - - #ifdef WITH_SELINUX -- if (set_selinux_file_context (dst) != 0) { -+ if (set_selinux_file_context (dst, NULL) != 0) { - free (oldlink); - return -1; - } -@@ -684,7 +684,7 @@ static int copy_special (const char *src - int err = 0; - - #ifdef WITH_SELINUX -- if (set_selinux_file_context (dst) != 0) { -+ if (set_selinux_file_context (dst, NULL) != 0) { - return -1; - } - #endif /* WITH_SELINUX */ -@@ -744,7 +744,7 @@ static int copy_file (const char *src, c - return -1; - } - #ifdef WITH_SELINUX -- if (set_selinux_file_context (dst) != 0) { -+ if (set_selinux_file_context (dst, NULL) != 0) { - return -1; - } - #endif /* WITH_SELINUX */ -diff -up shadow-4.6/lib/prototypes.h.orig-context shadow-4.6/lib/prototypes.h ---- shadow-4.6/lib/prototypes.h.orig-context 2018-04-29 18:42:37.000000000 +0200 -+++ shadow-4.6/lib/prototypes.h 2018-05-28 14:56:37.287929667 +0200 -@@ -326,7 +326,7 @@ extern /*@observer@*/const char *crypt_m - - /* selinux.c */ - #ifdef WITH_SELINUX --extern int set_selinux_file_context (const char *dst_name); -+extern int set_selinux_file_context (const char *dst_name, const char *orig_name); - extern int reset_selinux_file_context (void); - #endif - -diff -up shadow-4.6/lib/selinux.c.orig-context shadow-4.6/lib/selinux.c ---- shadow-4.6/lib/selinux.c.orig-context 2018-04-29 18:42:37.000000000 +0200 -+++ shadow-4.6/lib/selinux.c 2018-05-28 14:56:37.287929667 +0200 -@@ -50,7 +50,7 @@ static bool selinux_enabled; - * Callers may have to Reset SELinux to create files with default - * contexts with reset_selinux_file_context - */ --int set_selinux_file_context (const char *dst_name) -+int set_selinux_file_context (const char *dst_name, const char *orig_name) - { - /*@null@*/security_context_t scontext = NULL; - -@@ -62,19 +62,23 @@ int set_selinux_file_context (const char - if (selinux_enabled) { - /* Get the default security context for this file */ - if (matchpathcon (dst_name, 0, &scontext) < 0) { -- if (security_getenforce () != 0) { -- return 1; -- } -+ /* We could not get the default, copy the original */ -+ if (orig_name == NULL) -+ goto error; -+ if (getfilecon (orig_name, &scontext) < 0) -+ goto error; - } - /* Set the security context for the next created file */ -- if (setfscreatecon (scontext) < 0) { -- if (security_getenforce () != 0) { -- return 1; -- } -- } -+ if (setfscreatecon (scontext) < 0) -+ goto error; - freecon (scontext); - } - return 0; -+ error: -+ if (security_getenforce () != 0) { -+ return 1; -+ } -+ return 0; - } - - /* -diff -up shadow-4.6/src/useradd.c.orig-context shadow-4.6/src/useradd.c ---- shadow-4.6/src/useradd.c.orig-context 2018-05-28 14:56:37.288929688 +0200 -+++ shadow-4.6/src/useradd.c 2018-05-28 14:58:02.242730903 +0200 -@@ -2020,7 +2020,7 @@ static void create_home (void) - { - if (access (prefix_user_home, F_OK) != 0) { - #ifdef WITH_SELINUX -- if (set_selinux_file_context (prefix_user_home) != 0) { -+ if (set_selinux_file_context (prefix_user_home, NULL) != 0) { - fprintf (stderr, - _("%s: cannot set SELinux context for home directory %s\n"), - Prog, user_home); diff --git a/shadow-4.6-selinux.patch b/shadow-4.6-selinux.patch deleted file mode 100644 index dfd5140..0000000 --- a/shadow-4.6-selinux.patch +++ /dev/null @@ -1,115 +0,0 @@ -diff -up shadow-4.6/lib/semanage.c.selinux shadow-4.6/lib/semanage.c ---- shadow-4.6/lib/semanage.c.selinux 2018-04-29 18:42:37.000000000 +0200 -+++ shadow-4.6/lib/semanage.c 2018-05-28 13:38:20.551008911 +0200 -@@ -294,6 +294,9 @@ int set_seuser (const char *login_name, - - ret = 0; - -+ /* drop obsolete matchpathcon cache */ -+ matchpathcon_fini(); -+ - done: - semanage_seuser_key_free (key); - semanage_handle_destroy (handle); -@@ -369,6 +372,10 @@ int del_seuser (const char *login_name) - } - - ret = 0; -+ -+ /* drop obsolete matchpathcon cache */ -+ matchpathcon_fini(); -+ - done: - semanage_handle_destroy (handle); - return ret; -diff -up shadow-4.6/src/useradd.c.selinux shadow-4.6/src/useradd.c ---- shadow-4.6/src/useradd.c.selinux 2018-05-28 13:43:30.996748997 +0200 -+++ shadow-4.6/src/useradd.c 2018-05-28 13:44:04.645486199 +0200 -@@ -2120,6 +2120,7 @@ static void create_mail (void) - */ - int main (int argc, char **argv) - { -+ int rv = E_SUCCESS; - #ifdef ACCT_TOOLS_SETUID - #ifdef USE_PAM - pam_handle_t *pamh = NULL; -@@ -2342,27 +2343,11 @@ int main (int argc, char **argv) - - usr_update (); - -- if (mflg) { -- create_home (); -- if (home_added) { -- copy_tree (def_template, prefix_user_home, false, false, -- (uid_t)-1, user_id, (gid_t)-1, user_gid); -- } else { -- fprintf (stderr, -- _("%s: warning: the home directory already exists.\n" -- "Not copying any file from skel directory into it.\n"), -- Prog); -- } -- -- } -- -- /* Do not create mail directory for system accounts */ -- if (!rflg) { -- create_mail (); -- } -- - close_files (); - -+ nscd_flush_cache ("passwd"); -+ nscd_flush_cache ("group"); -+ - /* - * tallylog_reset needs to be able to lookup - * a valid existing user name, -@@ -2373,8 +2358,9 @@ int main (int argc, char **argv) - } - - #ifdef WITH_SELINUX -- if (Zflg) { -- if (set_seuser (user_name, user_selinux) != 0) { -+ if (Zflg && *user_selinux) { -+ if (is_selinux_enabled () > 0) { -+ if (set_seuser (user_name, user_selinux) != 0) { - fprintf (stderr, - _("%s: warning: the user name %s to %s SELinux user mapping failed.\n"), - Prog, user_name, user_selinux); -@@ -2383,14 +2369,31 @@ int main (int argc, char **argv) - "adding SELinux user mapping", - user_name, (unsigned int) user_id, 0); - #endif /* WITH_AUDIT */ -- fail_exit (E_SE_UPDATE); -+ rv = E_SE_UPDATE; -+ } - } - } --#endif /* WITH_SELINUX */ -+#endif - -- nscd_flush_cache ("passwd"); -- nscd_flush_cache ("group"); -+ if (mflg) { -+ create_home (); -+ if (home_added) { -+ copy_tree (def_template, prefix_user_home, false, true, -+ (uid_t)-1, user_id, (gid_t)-1, user_gid); -+ } else { -+ fprintf (stderr, -+ _("%s: warning: the home directory already exists.\n" -+ "Not copying any file from skel directory into it.\n"), -+ Prog); -+ } -+ -+ } -+ -+ /* Do not create mail directory for system accounts */ -+ if (!rflg) { -+ create_mail (); -+ } - -- return E_SUCCESS; -+ return rv; - } - diff --git a/shadow-4.6-sssd-flush.patch b/shadow-4.6-sssd-flush.patch deleted file mode 100644 index 025c1d3..0000000 --- a/shadow-4.6-sssd-flush.patch +++ /dev/null @@ -1,641 +0,0 @@ -From 4aaf05d72e9d6daf348cefb8a6ad35d2966cbe9b Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Wed, 12 Sep 2018 14:22:11 +0200 -Subject: [PATCH] Flush sssd caches in addition to nscd caches - -Some distributions, notably Fedora, have the following order of nsswitch -modules by default: - passwd: sss files - group: sss files - -The advantage of serving local users through SSSD is that the nss_sss -module has a fast mmapped-cache that speeds up NSS lookups compared to -accessing the disk an opening the files on each NSS request. - -Traditionally, this has been done with the help of nscd, but using nscd -in parallel with sssd is cumbersome, as both SSSD and nscd use their own -independent caching, so using nscd in setups where sssd is also serving -users from some remote domain (LDAP, AD, ...) can result in a bit of -unpredictability. - -More details about why Fedora chose to use sss before files can be found -on e.g.: - https://fedoraproject.org//wiki/Changes/SSSDCacheForLocalUsers -or: - https://docs.pagure.org/SSSD.sssd/design_pages/files_provider.html - -Now, even though sssd watches the passwd and group files with the help -of inotify, there can still be a small window where someone requests a -user or a group, finds that it doesn't exist, adds the entry and checks -again. Without some support in shadow-utils that would explicitly drop -the sssd caches, the inotify watch can fire a little late, so a -combination of commands like this: - getent passwd user || useradd user; getent passwd user -can result in the second getent passwd not finding the newly added user -as the racy behaviour might still return the cached negative hit from -the first getent passwd. - -This patch more or less copies the already existing support that -shadow-utils had for dropping nscd caches, except using the "sss_cache" -tool that sssd ships. ---- - configure.ac | 10 +++++++ - lib/Makefile.am | 2 ++ - lib/commonio.c | 2 ++ - lib/sssd.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++ - lib/sssd.h | 17 +++++++++++ - src/chfn.c | 2 ++ - src/chgpasswd.c | 2 ++ - src/chpasswd.c | 2 ++ - src/chsh.c | 2 ++ - src/gpasswd.c | 2 ++ - src/groupadd.c | 2 ++ - src/groupdel.c | 2 ++ - src/groupmod.c | 2 ++ - src/grpck.c | 2 ++ - src/grpconv.c | 2 ++ - src/grpunconv.c | 2 ++ - src/newusers.c | 2 ++ - src/passwd.c | 2 ++ - src/pwck.c | 2 ++ - src/pwconv.c | 2 ++ - src/pwunconv.c | 2 ++ - src/useradd.c | 2 ++ - src/userdel.c | 2 ++ - src/usermod.c | 2 ++ - src/vipw.c | 2 ++ - 25 files changed, 146 insertions(+) - create mode 100644 lib/sssd.c - create mode 100644 lib/sssd.h - -diff --git a/configure.ac b/configure.ac -index 41068a5d..10ad70cf 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -280,6 +280,9 @@ AC_ARG_WITH(sha-crypt, - AC_ARG_WITH(nscd, - [AC_HELP_STRING([--with-nscd], [enable support for nscd @<:@default=yes@:>@])], - [with_nscd=$withval], [with_nscd=yes]) -+AC_ARG_WITH(sssd, -+ [AC_HELP_STRING([--with-sssd], [enable support for flushing sssd caches @<:@default=yes@:>@])], -+ [with_sssd=$withval], [with_sssd=yes]) - AC_ARG_WITH(group-name-max-length, - [AC_HELP_STRING([--with-group-name-max-length], [set max group name length @<:@default=16@:>@])], - [with_group_name_max_length=$withval], [with_group_name_max_length=yes]) -@@ -304,6 +307,12 @@ if test "$with_nscd" = "yes"; then - [AC_MSG_ERROR([posix_spawn is needed for nscd support])]) - fi - -+if test "$with_sssd" = "yes"; then -+ AC_CHECK_FUNC(posix_spawn, -+ [AC_DEFINE(USE_SSSD, 1, [Define to support flushing of sssd caches])], -+ [AC_MSG_ERROR([posix_spawn is needed for sssd support])]) -+fi -+ - dnl Check for some functions in libc first, only if not found check for - dnl other libraries. This should prevent linking libnsl if not really - dnl needed (Linux glibc, Irix), but still link it if needed (Solaris). -@@ -679,5 +688,6 @@ echo " shadow group support: $enable_shadowgrp" - echo " S/Key support: $with_skey" - echo " SHA passwords encryption: $with_sha_crypt" - echo " nscd support: $with_nscd" -+echo " sssd support: $with_sssd" - echo " subordinate IDs support: $enable_subids" - echo -diff --git a/lib/Makefile.am b/lib/Makefile.am -index 6db86cd6..fd634542 100644 ---- a/lib/Makefile.am -+++ b/lib/Makefile.am -@@ -30,6 +30,8 @@ libshadow_la_SOURCES = \ - lockpw.c \ - nscd.c \ - nscd.h \ -+ sssd.c \ -+ sssd.h \ - pam_defs.h \ - port.c \ - port.h \ -diff --git a/lib/commonio.c b/lib/commonio.c -index d06b8e7d..96f2d5f7 100644 ---- a/lib/commonio.c -+++ b/lib/commonio.c -@@ -45,6 +45,7 @@ - #include - #include - #include "nscd.h" -+#include "sssd.h" - #ifdef WITH_TCB - #include - #endif /* WITH_TCB */ -@@ -485,6 +486,7 @@ static void dec_lock_count (void) - if (nscd_need_reload) { - nscd_flush_cache ("passwd"); - nscd_flush_cache ("group"); -+ sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP); - nscd_need_reload = false; - } - #ifdef HAVE_LCKPWDF -diff --git a/lib/sssd.c b/lib/sssd.c -new file mode 100644 -index 00000000..80e49e55 ---- /dev/null -+++ b/lib/sssd.c -@@ -0,0 +1,75 @@ -+/* Author: Peter Vrabec */ -+ -+#include -+#ifdef USE_SSSD -+ -+#include -+#include -+#include -+#include "exitcodes.h" -+#include "defines.h" -+#include "prototypes.h" -+#include "sssd.h" -+ -+#define MSG_SSSD_FLUSH_CACHE_FAILED "%s: Failed to flush the sssd cache.\n" -+ -+int sssd_flush_cache (int dbflags) -+{ -+ int status, code, rv; -+ const char *cmd = "/usr/sbin/sss_cache"; -+ char *sss_cache_args = NULL; -+ const char *spawnedArgs[] = {"sss_cache", NULL, NULL}; -+ const char *spawnedEnv[] = {NULL}; -+ int i = 0; -+ -+ sss_cache_args = malloc(4); -+ if (sss_cache_args == NULL) { -+ return -1; -+ } -+ -+ sss_cache_args[i++] = '-'; -+ if (dbflags & SSSD_DB_PASSWD) { -+ sss_cache_args[i++] = 'U'; -+ } -+ if (dbflags & SSSD_DB_GROUP) { -+ sss_cache_args[i++] = 'G'; -+ } -+ sss_cache_args[i++] = '\0'; -+ if (i == 2) { -+ /* Neither passwd nor group, nothing to do */ -+ free(sss_cache_args); -+ return 0; -+ } -+ spawnedArgs[1] = sss_cache_args; -+ -+ rv = run_command (cmd, spawnedArgs, spawnedEnv, &status); -+ free(sss_cache_args); -+ if (rv != 0) { -+ /* run_command writes its own more detailed message. */ -+ (void) fprintf (stderr, _(MSG_SSSD_FLUSH_CACHE_FAILED), Prog); -+ return -1; -+ } -+ -+ code = WEXITSTATUS (status); -+ if (!WIFEXITED (status)) { -+ (void) fprintf (stderr, -+ _("%s: sss_cache did not terminate normally (signal %d)\n"), -+ Prog, WTERMSIG (status)); -+ return -1; -+ } else if (code == E_CMD_NOTFOUND) { -+ /* sss_cache is not installed, or it is installed but uses an -+ interpreter that is missing. Probably the former. */ -+ return 0; -+ } else if (code != 0) { -+ (void) fprintf (stderr, _("%s: sss_cache exited with status %d\n"), -+ Prog, code); -+ (void) fprintf (stderr, _(MSG_SSSD_FLUSH_CACHE_FAILED), Prog); -+ return -1; -+ } -+ -+ return 0; -+} -+#else /* USE_SSSD */ -+extern int errno; /* warning: ANSI C forbids an empty source file */ -+#endif /* USE_SSSD */ -+ -diff --git a/lib/sssd.h b/lib/sssd.h -new file mode 100644 -index 00000000..00ff2a8a ---- /dev/null -+++ b/lib/sssd.h -@@ -0,0 +1,17 @@ -+#ifndef _SSSD_H_ -+#define _SSSD_H_ -+ -+#define SSSD_DB_PASSWD 0x001 -+#define SSSD_DB_GROUP 0x002 -+ -+/* -+ * sssd_flush_cache - flush specified service buffer in sssd cache -+ */ -+#ifdef USE_SSSD -+extern int sssd_flush_cache (int dbflags); -+#else -+#define sssd_flush_cache(service) (0) -+#endif -+ -+#endif -+ -diff --git a/src/chfn.c b/src/chfn.c -index 18aa3de7..0725e1c7 100644 ---- a/src/chfn.c -+++ b/src/chfn.c -@@ -47,6 +47,7 @@ - #include "defines.h" - #include "getdef.h" - #include "nscd.h" -+#include "sssd.h" - #ifdef USE_PAM - #include "pam_defs.h" - #endif -@@ -746,6 +747,7 @@ int main (int argc, char **argv) - SYSLOG ((LOG_INFO, "changed user '%s' information", user)); - - nscd_flush_cache ("passwd"); -+ sssd_flush_cache (SSSD_DB_PASSWD); - - closelog (); - exit (E_SUCCESS); -diff --git a/src/chgpasswd.c b/src/chgpasswd.c -index 13203a46..e5f2eb7e 100644 ---- a/src/chgpasswd.c -+++ b/src/chgpasswd.c -@@ -46,6 +46,7 @@ - #endif /* ACCT_TOOLS_SETUID */ - #include "defines.h" - #include "nscd.h" -+#include "sssd.h" - #include "prototypes.h" - #include "groupio.h" - #ifdef SHADOWGRP -@@ -581,6 +582,7 @@ int main (int argc, char **argv) - close_files (); - - nscd_flush_cache ("group"); -+ sssd_flush_cache (SSSD_DB_GROUP); - - return (0); - } -diff --git a/src/chpasswd.c b/src/chpasswd.c -index 918b27ee..49e79cdb 100644 ---- a/src/chpasswd.c -+++ b/src/chpasswd.c -@@ -44,6 +44,7 @@ - #endif /* USE_PAM */ - #include "defines.h" - #include "nscd.h" -+#include "sssd.h" - #include "getdef.h" - #include "prototypes.h" - #include "pwio.h" -@@ -624,6 +625,7 @@ int main (int argc, char **argv) - } - - nscd_flush_cache ("passwd"); -+ sssd_flush_cache (SSSD_DB_PASSWD); - - return (0); - } -diff --git a/src/chsh.c b/src/chsh.c -index c89708b9..910e3dd4 100644 ---- a/src/chsh.c -+++ b/src/chsh.c -@@ -46,6 +46,7 @@ - #include "defines.h" - #include "getdef.h" - #include "nscd.h" -+#include "sssd.h" - #include "prototypes.h" - #include "pwauth.h" - #include "pwio.h" -@@ -557,6 +558,7 @@ int main (int argc, char **argv) - SYSLOG ((LOG_INFO, "changed user '%s' shell to '%s'", user, loginsh)); - - nscd_flush_cache ("passwd"); -+ sssd_flush_cache (SSSD_DB_PASSWD); - - closelog (); - exit (E_SUCCESS); -diff --git a/src/gpasswd.c b/src/gpasswd.c -index c4a492b1..4d75af96 100644 ---- a/src/gpasswd.c -+++ b/src/gpasswd.c -@@ -45,6 +45,7 @@ - #include "defines.h" - #include "groupio.h" - #include "nscd.h" -+#include "sssd.h" - #include "prototypes.h" - #ifdef SHADOWGRP - #include "sgroupio.h" -@@ -1201,6 +1202,7 @@ int main (int argc, char **argv) - close_files (); - - nscd_flush_cache ("group"); -+ sssd_flush_cache (SSSD_DB_GROUP); - - exit (E_SUCCESS); - } -diff --git a/src/groupadd.c b/src/groupadd.c -index b57006c5..2dd8eec9 100644 ---- a/src/groupadd.c -+++ b/src/groupadd.c -@@ -51,6 +51,7 @@ - #include "getdef.h" - #include "groupio.h" - #include "nscd.h" -+#include "sssd.h" - #include "prototypes.h" - #ifdef SHADOWGRP - #include "sgroupio.h" -@@ -625,6 +626,7 @@ int main (int argc, char **argv) - close_files (); - - nscd_flush_cache ("group"); -+ sssd_flush_cache (SSSD_DB_GROUP); - - return E_SUCCESS; - } -diff --git a/src/groupdel.c b/src/groupdel.c -index 70bed010..f941a84a 100644 ---- a/src/groupdel.c -+++ b/src/groupdel.c -@@ -49,6 +49,7 @@ - #include "defines.h" - #include "groupio.h" - #include "nscd.h" -+#include "sssd.h" - #include "prototypes.h" - #ifdef SHADOWGRP - #include "sgroupio.h" -@@ -492,6 +493,7 @@ int main (int argc, char **argv) - close_files (); - - nscd_flush_cache ("group"); -+ sssd_flush_cache (SSSD_DB_GROUP); - - return E_SUCCESS; - } -diff --git a/src/groupmod.c b/src/groupmod.c -index b293b98f..1dca5fc9 100644 ---- a/src/groupmod.c -+++ b/src/groupmod.c -@@ -51,6 +51,7 @@ - #include "groupio.h" - #include "pwio.h" - #include "nscd.h" -+#include "sssd.h" - #include "prototypes.h" - #ifdef SHADOWGRP - #include "sgroupio.h" -@@ -877,6 +878,7 @@ int main (int argc, char **argv) - close_files (); - - nscd_flush_cache ("group"); -+ sssd_flush_cache (SSSD_DB_GROUP); - - return E_SUCCESS; - } -diff --git a/src/grpck.c b/src/grpck.c -index ea5d3b39..6140b10d 100644 ---- a/src/grpck.c -+++ b/src/grpck.c -@@ -45,6 +45,7 @@ - #include "defines.h" - #include "groupio.h" - #include "nscd.h" -+#include "sssd.h" - #include "prototypes.h" - - #ifdef SHADOWGRP -@@ -870,6 +871,7 @@ int main (int argc, char **argv) - close_files (changed); - - nscd_flush_cache ("group"); -+ sssd_flush_cache (SSSD_DB_GROUP); - - /* - * Tell the user what we did and exit. -diff --git a/src/grpconv.c b/src/grpconv.c -index f95f4960..5e5eaaca 100644 ---- a/src/grpconv.c -+++ b/src/grpconv.c -@@ -48,6 +48,7 @@ - #include - #include - #include "nscd.h" -+#include "sssd.h" - #include "prototypes.h" - /*@-exitarg@*/ - #include "exitcodes.h" -@@ -273,6 +274,7 @@ int main (int argc, char **argv) - } - - nscd_flush_cache ("group"); -+ sssd_flush_cache (SSSD_DB_GROUP); - - return 0; - } -diff --git a/src/grpunconv.c b/src/grpunconv.c -index 253f06f5..e4105c26 100644 ---- a/src/grpunconv.c -+++ b/src/grpunconv.c -@@ -48,6 +48,7 @@ - #include - #include - #include "nscd.h" -+#include "sssd.h" - #include "prototypes.h" - /*@-exitarg@*/ - #include "exitcodes.h" -@@ -236,6 +237,7 @@ int main (int argc, char **argv) - } - - nscd_flush_cache ("group"); -+ sssd_flush_cache (SSSD_DB_GROUP); - - return 0; - } -diff --git a/src/newusers.c b/src/newusers.c -index 8e4bef97..7c3bb1c2 100644 ---- a/src/newusers.c -+++ b/src/newusers.c -@@ -62,6 +62,7 @@ - #include "getdef.h" - #include "groupio.h" - #include "nscd.h" -+#include "sssd.h" - #include "pwio.h" - #include "sgroupio.h" - #include "shadowio.h" -@@ -1233,6 +1234,7 @@ int main (int argc, char **argv) - - nscd_flush_cache ("passwd"); - nscd_flush_cache ("group"); -+ sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP); - - #ifdef USE_PAM - unsigned int i; -diff --git a/src/passwd.c b/src/passwd.c -index 3af3e651..5bea2765 100644 ---- a/src/passwd.c -+++ b/src/passwd.c -@@ -51,6 +51,7 @@ - #include "defines.h" - #include "getdef.h" - #include "nscd.h" -+#include "sssd.h" - #include "prototypes.h" - #include "pwauth.h" - #include "pwio.h" -@@ -1150,6 +1151,7 @@ int main (int argc, char **argv) - - nscd_flush_cache ("passwd"); - nscd_flush_cache ("group"); -+ sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP); - - SYSLOG ((LOG_INFO, "password for '%s' changed by '%s'", name, myname)); - closelog (); -diff --git a/src/pwck.c b/src/pwck.c -index 05df68ec..0ffb711e 100644 ---- a/src/pwck.c -+++ b/src/pwck.c -@@ -48,6 +48,7 @@ - #include "shadowio.h" - #include "getdef.h" - #include "nscd.h" -+#include "sssd.h" - #ifdef WITH_TCB - #include "tcbfuncs.h" - #endif /* WITH_TCB */ -@@ -877,6 +878,7 @@ int main (int argc, char **argv) - close_files (changed); - - nscd_flush_cache ("passwd"); -+ sssd_flush_cache (SSSD_DB_PASSWD); - - /* - * Tell the user what we did and exit. -diff --git a/src/pwconv.c b/src/pwconv.c -index d6ee31a8..9c69fa13 100644 ---- a/src/pwconv.c -+++ b/src/pwconv.c -@@ -72,6 +72,7 @@ - #include "pwio.h" - #include "shadowio.h" - #include "nscd.h" -+#include "sssd.h" - - /* - * exit status values -@@ -328,6 +329,7 @@ int main (int argc, char **argv) - } - - nscd_flush_cache ("passwd"); -+ sssd_flush_cache (SSSD_DB_PASSWD); - - return E_SUCCESS; - } -diff --git a/src/pwunconv.c b/src/pwunconv.c -index fabf0237..e11ea494 100644 ---- a/src/pwunconv.c -+++ b/src/pwunconv.c -@@ -42,6 +42,7 @@ - #include - #include "defines.h" - #include "nscd.h" -+#include "sssd.h" - #include "prototypes.h" - #include "pwio.h" - #include "shadowio.h" -@@ -250,6 +251,7 @@ int main (int argc, char **argv) - } - - nscd_flush_cache ("passwd"); -+ sssd_flush_cache (SSSD_DB_PASSWD); - - return 0; - } -diff --git a/src/useradd.c b/src/useradd.c -index ca90f076..b0c2224d 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -60,6 +60,7 @@ - #include "getdef.h" - #include "groupio.h" - #include "nscd.h" -+#include "sssd.h" - #include "prototypes.h" - #include "pwauth.h" - #include "pwio.h" -@@ -2425,6 +2426,7 @@ int main (int argc, char **argv) - - nscd_flush_cache ("passwd"); - nscd_flush_cache ("group"); -+ sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP); - - /* - * tallylog_reset needs to be able to lookup -diff --git a/src/userdel.c b/src/userdel.c -index c8de1d31..0715e4fe 100644 ---- a/src/userdel.c -+++ b/src/userdel.c -@@ -53,6 +53,7 @@ - #include "getdef.h" - #include "groupio.h" - #include "nscd.h" -+#include "sssd.h" - #include "prototypes.h" - #include "pwauth.h" - #include "pwio.h" -@@ -1328,6 +1329,7 @@ int main (int argc, char **argv) - - nscd_flush_cache ("passwd"); - nscd_flush_cache ("group"); -+ sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP); - - return ((0 != errors) ? E_HOMEDIR : E_SUCCESS); - } -diff --git a/src/usermod.c b/src/usermod.c -index 7355ad31..fd9a98a6 100644 ---- a/src/usermod.c -+++ b/src/usermod.c -@@ -57,6 +57,7 @@ - #include "getdef.h" - #include "groupio.h" - #include "nscd.h" -+#include "sssd.h" - #include "prototypes.h" - #include "pwauth.h" - #include "pwio.h" -@@ -2255,6 +2256,7 @@ int main (int argc, char **argv) - - nscd_flush_cache ("passwd"); - nscd_flush_cache ("group"); -+ sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP); - - #ifdef WITH_SELINUX - if (Zflg) { -diff --git a/src/vipw.c b/src/vipw.c -index 6d730f65..2cfac6b4 100644 ---- a/src/vipw.c -+++ b/src/vipw.c -@@ -42,6 +42,7 @@ - #include "defines.h" - #include "groupio.h" - #include "nscd.h" -+#include "sssd.h" - #include "prototypes.h" - #include "pwio.h" - #include "sgroupio.h" -@@ -556,6 +557,7 @@ int main (int argc, char **argv) - - nscd_flush_cache ("passwd"); - nscd_flush_cache ("group"); -+ sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP); - - return E_SUCCESS; - } diff --git a/shadow-4.6-use-itstool.patch b/shadow-4.6-use-itstool.patch deleted file mode 100644 index 760b5b3..0000000 --- a/shadow-4.6-use-itstool.patch +++ /dev/null @@ -1,31 +0,0 @@ -diff -up shadow-4.6/man/generate_translations.mak.use-itstool shadow-4.6/man/generate_translations.mak ---- shadow-4.6/man/generate_translations.mak.use-itstool 2018-04-29 18:42:37.000000000 +0200 -+++ shadow-4.6/man/generate_translations.mak 2018-07-31 16:42:21.623990969 +0200 -@@ -5,8 +5,19 @@ config.xml: ../config.xml.in - $(MAKE) -C .. config.xml - cp ../config.xml $@ - --%.xml: ../%.xml ../po/$(LANG).po -- xml2po --expand-all-entities -l $(LANG) -p ../po/$(LANG).po -o $@ ../$@ -+messages.mo: ../po/$(LANG).po -+ msgfmt ../po/$(LANG).po -o messages.mo -+ -+login.defs.d: -+ ln -sf ../login.defs.d login.defs.d -+ -+%.xml: ../%.xml messages.mo login.defs.d -+ if grep -q SHADOW-CONFIG-HERE $< ; then \ -+ sed -e 's/^/%config;/' $< > $@; \ -+ else \ -+ sed -e 's/^\(/\1 [%config;]>/' $< > $@; \ -+ fi -+ itstool -d -l $(LANG) -m messages.mo -o . $@ - sed -i 's:\(^:\1 lang="$(LANG)">:' $@ - - include ../generate_mans.mak -@@ -16,4 +27,4 @@ $(man_MANS): - @echo you need to run configure with --enable-man to generate man pages - endif - --CLEANFILES = .xml2po.mo $(EXTRA_DIST) $(addsuffix .xml,$(EXTRA_DIST)) config.xml -+CLEANFILES = messages.mo login.defs.d $(EXTRA_DIST) $(addsuffix .xml,$(EXTRA_DIST)) config.xml diff --git a/shadow-4.6-use-lckpwdf.patch b/shadow-4.6-use-lckpwdf.patch deleted file mode 100644 index 363579a..0000000 --- a/shadow-4.6-use-lckpwdf.patch +++ /dev/null @@ -1,190 +0,0 @@ -commit 408b8a548243aebaa6d773beeae8ddf4bb6100f0 -Author: Tomas Mraz -Date: Thu May 2 14:33:06 2019 +0200 - - Use the lckpwdf() again if prefix is not set - - The implementation of prefix option dropped the use of lckpwdf(). - However that is incorrect as other tools manipulating the shadow passwords - such as PAM use lckpwdf() and do not know anything about the - shadow's own locking mechanism. - - This reverts the implementation to use lckpwdf() if prefix option - is not used. - -diff --git a/lib/commonio.c b/lib/commonio.c -index 26e518f2..94dda779 100644 ---- a/lib/commonio.c -+++ b/lib/commonio.c -@@ -364,6 +364,7 @@ static void free_linked_list (struct commonio_db *db) - int commonio_setname (struct commonio_db *db, const char *name) - { - snprintf (db->filename, sizeof (db->filename), "%s", name); -+ db->setname = true; - return 1; - } - -@@ -414,37 +415,39 @@ cleanup_ENOMEM: - - int commonio_lock (struct commonio_db *db) - { --/*#ifdef HAVE_LCKPWDF*/ /* not compatible with prefix option*/ --#if 0 -- /* -- * only if the system libc has a real lckpwdf() - the one from -- * lockpw.c calls us and would cause infinite recursion! -- */ -+ int i; - -+#ifdef HAVE_LCKPWDF - /* -- * Call lckpwdf() on the first lock. -- * If it succeeds, call *_lock() only once -- * (no retries, it should always succeed). -+ * Only if the system libc has a real lckpwdf() - the one from -+ * lockpw.c calls us and would cause infinite recursion! -+ * It is also not used with the prefix option. - */ -- if (0 == lock_count) { -- if (lckpwdf () == -1) { -- if (geteuid () != 0) { -- (void) fprintf (stderr, -- "%s: Permission denied.\n", -- Prog); -+ if (!db->setname) { -+ /* -+ * Call lckpwdf() on the first lock. -+ * If it succeeds, call *_lock() only once -+ * (no retries, it should always succeed). -+ */ -+ if (0 == lock_count) { -+ if (lckpwdf () == -1) { -+ if (geteuid () != 0) { -+ (void) fprintf (stderr, -+ "%s: Permission denied.\n", -+ Prog); -+ } -+ return 0; /* failure */ - } -- return 0; /* failure */ - } -- } - -- if (commonio_lock_nowait (db, true) != 0) { -- return 1; /* success */ -- } -+ if (commonio_lock_nowait (db, true) != 0) { -+ return 1; /* success */ -+ } - -- ulckpwdf (); -- return 0; /* failure */ --#else /* !HAVE_LCKPWDF */ -- int i; -+ ulckpwdf (); -+ return 0; /* failure */ -+ } -+#endif /* !HAVE_LCKPWDF */ - - /* - * lckpwdf() not used - do it the old way. -@@ -471,7 +474,6 @@ int commonio_lock (struct commonio_db *db) - } - } - return 0; /* failure */ --#endif /* !HAVE_LCKPWDF */ - } - - static void dec_lock_count (void) -diff --git a/lib/commonio.h b/lib/commonio.h -index 40e5708f..64e83073 100644 ---- a/lib/commonio.h -+++ b/lib/commonio.h -@@ -143,6 +143,7 @@ struct commonio_db { - bool isopen:1; - bool locked:1; - bool readonly:1; -+ bool setname:1; - }; - - extern int commonio_setname (struct commonio_db *, const char *); -diff --git a/lib/groupio.c b/lib/groupio.c -index ae2302b5..bffb06e0 100644 ---- a/lib/groupio.c -+++ b/lib/groupio.c -@@ -139,7 +139,8 @@ static /*@owned@*/struct commonio_db group_db = { - false, /* changed */ - false, /* isopen */ - false, /* locked */ -- false /* readonly */ -+ false, /* readonly */ -+ false /* setname */ - }; - - int gr_setdbname (const char *filename) -diff --git a/lib/pwio.c b/lib/pwio.c -index 7ee85377..127719cb 100644 ---- a/lib/pwio.c -+++ b/lib/pwio.c -@@ -114,7 +114,8 @@ static struct commonio_db passwd_db = { - false, /* changed */ - false, /* isopen */ - false, /* locked */ -- false /* readonly */ -+ false, /* readonly */ -+ false /* setname */ - }; - - int pw_setdbname (const char *filename) -diff --git a/lib/sgroupio.c b/lib/sgroupio.c -index 5423626a..ffbdb263 100644 ---- a/lib/sgroupio.c -+++ b/lib/sgroupio.c -@@ -238,7 +238,8 @@ static struct commonio_db gshadow_db = { - false, /* changed */ - false, /* isopen */ - false, /* locked */ -- false /* readonly */ -+ false, /* readonly */ -+ false /* setname */ - }; - - int sgr_setdbname (const char *filename) -diff --git a/lib/shadowio.c b/lib/shadowio.c -index 5fa3d312..676b1f1a 100644 ---- a/lib/shadowio.c -+++ b/lib/shadowio.c -@@ -114,7 +114,8 @@ static struct commonio_db shadow_db = { - false, /* changed */ - false, /* isopen */ - false, /* locked */ -- false /* readonly */ -+ false, /* readonly */ -+ false /* setname */ - }; - - int spw_setdbname (const char *filename) -diff --git a/lib/subordinateio.c b/lib/subordinateio.c -index a662e67e..dd779c59 100644 ---- a/lib/subordinateio.c -+++ b/lib/subordinateio.c -@@ -550,7 +550,8 @@ static struct commonio_db subordinate_uid_db = { - false, /* changed */ - false, /* isopen */ - false, /* locked */ -- false /* readonly */ -+ false, /* readonly */ -+ false /* setname */ - }; - - int sub_uid_setdbname (const char *filename) -@@ -631,7 +632,8 @@ static struct commonio_db subordinate_gid_db = { - false, /* changed */ - false, /* isopen */ - false, /* locked */ -- false /* readonly */ -+ false, /* readonly */ -+ false /* setname */ - }; - - int sub_gid_setdbname (const char *filename) diff --git a/shadow-4.6-usermod-crash.patch b/shadow-4.6-usermod-crash.patch deleted file mode 100644 index d2861b3..0000000 --- a/shadow-4.6-usermod-crash.patch +++ /dev/null @@ -1,42 +0,0 @@ -diff -up shadow-4.6/libmisc/prefix_flag.c.usermod-crash shadow-4.6/libmisc/prefix_flag.c ---- shadow-4.6/libmisc/prefix_flag.c.usermod-crash 2018-04-29 18:42:37.000000000 +0200 -+++ shadow-4.6/libmisc/prefix_flag.c 2018-05-28 15:14:10.642302440 +0200 -@@ -319,6 +319,7 @@ extern struct group *prefix_getgr_nam_gi - { - long long int gid; - char *endptr; -+ struct group *g; - - if (NULL == grname) { - return NULL; -@@ -333,7 +334,8 @@ extern struct group *prefix_getgr_nam_gi - && (gid == (gid_t)gid)) { - return prefix_getgrgid ((gid_t) gid); - } -- return prefix_getgrnam (grname); -+ g = prefix_getgrnam (grname); -+ return g ? __gr_dup(g) : NULL; - } - else - return getgr_nam_gid(grname); -diff -up shadow-4.6/src/usermod.c.usermod-crash shadow-4.6/src/usermod.c ---- shadow-4.6/src/usermod.c.usermod-crash 2018-05-28 15:12:37.920332763 +0200 -+++ shadow-4.6/src/usermod.c 2018-05-28 15:15:50.337422470 +0200 -@@ -1276,11 +1276,13 @@ static void process_flags (int argc, cha - prefix_user_home = xmalloc(len); - wlen = snprintf(prefix_user_home, len, "%s/%s", prefix, user_home); - assert (wlen == (int) len -1); -+ if (user_newhome) { -+ len = strlen(prefix) + strlen(user_newhome) + 2; -+ prefix_user_newhome = xmalloc(len); -+ wlen = snprintf(prefix_user_newhome, len, "%s/%s", prefix, user_newhome); -+ assert (wlen == (int) len -1); -+ } - -- len = strlen(prefix) + strlen(user_newhome) + 2; -- prefix_user_newhome = xmalloc(len); -- wlen = snprintf(prefix_user_newhome, len, "%s/%s", prefix, user_newhome); -- assert (wlen == (int) len -1); - } - else { - prefix_user_home = user_home; diff --git a/shadow-4.6-audit-update.patch b/shadow-4.8-audit-update.patch similarity index 87% rename from shadow-4.6-audit-update.patch rename to shadow-4.8-audit-update.patch index 4237739..153adfe 100644 --- a/shadow-4.6-audit-update.patch +++ b/shadow-4.8-audit-update.patch @@ -1,6 +1,6 @@ -diff -up shadow-4.6/libmisc/audit_help.c.audit-update shadow-4.6/libmisc/audit_help.c ---- shadow-4.6/libmisc/audit_help.c.audit-update 2018-04-29 18:42:37.000000000 +0200 -+++ shadow-4.6/libmisc/audit_help.c 2018-05-28 15:01:09.913717564 +0200 +diff -up shadow-4.8/libmisc/audit_help.c.audit-update shadow-4.8/libmisc/audit_help.c +--- shadow-4.8/libmisc/audit_help.c.audit-update 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8/libmisc/audit_help.c 2020-01-13 10:15:51.802073378 +0100 @@ -68,7 +68,7 @@ void audit_help_open (void) * This function will log a message to the audit system using a predefined * message format. Parameter usage is as follows: @@ -50,9 +50,9 @@ diff -up shadow-4.6/libmisc/audit_help.c.audit-update shadow-4.6/libmisc/audit_h void audit_logger_message (const char *message, shadow_audit_result result) { if (audit_fd < 0) { -diff -up shadow-4.6/libmisc/cleanup_group.c.audit-update shadow-4.6/libmisc/cleanup_group.c ---- shadow-4.6/libmisc/cleanup_group.c.audit-update 2018-04-29 18:42:37.000000000 +0200 -+++ shadow-4.6/libmisc/cleanup_group.c 2018-05-28 15:01:09.913717564 +0200 +diff -up shadow-4.8/libmisc/cleanup_group.c.audit-update shadow-4.8/libmisc/cleanup_group.c +--- shadow-4.8/libmisc/cleanup_group.c.audit-update 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8/libmisc/cleanup_group.c 2020-01-13 10:15:51.802073378 +0100 @@ -83,7 +83,7 @@ void cleanup_report_mod_group (void *cle gr_dbname (), info->action)); @@ -131,9 +131,9 @@ diff -up shadow-4.6/libmisc/cleanup_group.c.audit-update shadow-4.6/libmisc/clea SHADOW_AUDIT_FAILURE); #endif } -diff -up shadow-4.6/libmisc/cleanup_user.c.audit-update shadow-4.6/libmisc/cleanup_user.c ---- shadow-4.6/libmisc/cleanup_user.c.audit-update 2018-04-29 18:42:37.000000000 +0200 -+++ shadow-4.6/libmisc/cleanup_user.c 2018-05-28 15:01:09.913717564 +0200 +diff -up shadow-4.8/libmisc/cleanup_user.c.audit-update shadow-4.8/libmisc/cleanup_user.c +--- shadow-4.8/libmisc/cleanup_user.c.audit-update 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8/libmisc/cleanup_user.c 2020-01-13 10:15:51.802073378 +0100 @@ -65,7 +65,7 @@ void cleanup_report_mod_passwd (void *cl pw_dbname (), info->action)); @@ -181,10 +181,10 @@ diff -up shadow-4.6/libmisc/cleanup_user.c.audit-update shadow-4.6/libmisc/clean SHADOW_AUDIT_FAILURE); #endif } -diff -up shadow-4.6/lib/prototypes.h.audit-update shadow-4.6/lib/prototypes.h ---- shadow-4.6/lib/prototypes.h.audit-update 2018-05-28 15:01:09.901717309 +0200 -+++ shadow-4.6/lib/prototypes.h 2018-05-28 15:01:09.913717564 +0200 -@@ -211,12 +211,21 @@ extern int audit_fd; +diff -up shadow-4.8/lib/prototypes.h.audit-update shadow-4.8/lib/prototypes.h +--- shadow-4.8/lib/prototypes.h.audit-update 2020-01-13 10:15:51.785073664 +0100 ++++ shadow-4.8/lib/prototypes.h 2020-01-13 10:15:51.803073362 +0100 +@@ -219,12 +219,21 @@ extern int audit_fd; extern void audit_help_open (void); /* Use AUDIT_NO_ID when a name is provided to audit_logger instead of an ID */ #define AUDIT_NO_ID ((unsigned int) -1) @@ -206,10 +206,100 @@ diff -up shadow-4.6/lib/prototypes.h.audit-update shadow-4.6/lib/prototypes.h void audit_logger_message (const char *message, shadow_audit_result result); #endif -diff -up shadow-4.6/src/gpasswd.c.audit-update shadow-4.6/src/gpasswd.c ---- shadow-4.6/src/gpasswd.c.audit-update 2018-04-29 18:42:37.000000000 +0200 -+++ shadow-4.6/src/gpasswd.c 2018-05-28 15:01:09.914717585 +0200 -@@ -137,7 +137,7 @@ static void usage (int status) +diff -up shadow-4.8/src/chage.c.audit-update shadow-4.8/src/chage.c +--- shadow-4.8/src/chage.c.audit-update 2019-11-12 01:18:25.000000000 +0100 ++++ shadow-4.8/src/chage.c 2020-01-13 10:15:51.806073311 +0100 +@@ -123,9 +123,10 @@ static /*@noreturn@*/void fail_exit (int + + #ifdef WITH_AUDIT + if (E_SUCCESS != code) { +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "change age", +- user_name, (unsigned int) user_uid, 0); ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "change-age", ++ user_name, (unsigned int) user_uid, ++ SHADOW_AUDIT_FAILURE); + } + #endif + +@@ -883,11 +884,7 @@ int main (int argc, char **argv) + fprintf (stderr, _("%s: Permission denied.\n"), Prog); + fail_exit (E_NOPERM); + } +-#ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "display aging info", +- user_name, (unsigned int) user_uid, 1); +-#endif ++ /* Displaying fields is not of interest to audit */ + list_fields (); + fail_exit (E_SUCCESS); + } +@@ -906,41 +903,43 @@ int main (int argc, char **argv) + } + #ifdef WITH_AUDIT + else { +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "change all aging information", +- user_name, (unsigned int) user_uid, 1); ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "change-all-aging-information", ++ user_name, (unsigned int) user_uid, ++ SHADOW_AUDIT_SUCCESS); + } + #endif + } else { + #ifdef WITH_AUDIT + if (Mflg) { +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "change max age", +- user_name, (unsigned int) user_uid, 1); ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "change-max-age", ++ user_name, (unsigned int) user_uid, ++ SHADOW_AUDIT_SUCCESS); + } + if (mflg) { +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "change min age", ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "change-min-age", + user_name, (unsigned int) user_uid, 1); + } + if (dflg) { +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "change last change date", ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "change-last-change-date", + user_name, (unsigned int) user_uid, 1); + } + if (Wflg) { +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "change passwd warning", ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "change-passwd-warning", + user_name, (unsigned int) user_uid, 1); + } + if (Iflg) { +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "change inactive days", ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "change-inactive-days", + user_name, (unsigned int) user_uid, 1); + } + if (Eflg) { +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "change passwd expiration", ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "change-passwd-expiration", + user_name, (unsigned int) user_uid, 1); + } + #endif +diff -up shadow-4.8/src/gpasswd.c.audit-update shadow-4.8/src/gpasswd.c +--- shadow-4.8/src/gpasswd.c.audit-update 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8/src/gpasswd.c 2020-01-13 10:15:51.803073362 +0100 +@@ -138,7 +138,7 @@ static void usage (int status) (void) fputs (_(" -d, --delete USER remove USER from GROUP\n"), usageout); (void) fputs (_(" -h, --help display this help message and exit\n"), usageout); (void) fputs (_(" -Q, --root CHROOT_DIR directory to chroot into\n"), usageout); @@ -218,7 +308,7 @@ diff -up shadow-4.6/src/gpasswd.c.audit-update shadow-4.6/src/gpasswd.c (void) fputs (_(" -R, --restrict restrict access to GROUP to its members\n"), usageout); (void) fputs (_(" -M, --members USER,... set the list of members of GROUP\n"), usageout); #ifdef SHADOWGRP -@@ -396,21 +396,14 @@ static void open_files (void) +@@ -397,21 +397,14 @@ static void open_files (void) static void log_gpasswd_failure (const char *suffix) { @@ -243,7 +333,7 @@ diff -up shadow-4.6/src/gpasswd.c.audit-update shadow-4.6/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } else if (dflg) { -@@ -418,13 +411,9 @@ static void log_gpasswd_failure (const c +@@ -419,13 +412,9 @@ static void log_gpasswd_failure (const c "%s failed to remove user %s from group %s%s", myname, user, group, suffix)); #ifdef WITH_AUDIT @@ -260,7 +350,7 @@ diff -up shadow-4.6/src/gpasswd.c.audit-update shadow-4.6/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } else if (rflg) { -@@ -432,13 +421,9 @@ static void log_gpasswd_failure (const c +@@ -433,13 +422,9 @@ static void log_gpasswd_failure (const c "%s failed to remove password of group %s%s", myname, group, suffix)); #ifdef WITH_AUDIT @@ -277,7 +367,7 @@ diff -up shadow-4.6/src/gpasswd.c.audit-update shadow-4.6/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } else if (Rflg) { -@@ -446,13 +431,9 @@ static void log_gpasswd_failure (const c +@@ -447,13 +432,9 @@ static void log_gpasswd_failure (const c "%s failed to restrict access to group %s%s", myname, group, suffix)); #ifdef WITH_AUDIT @@ -294,7 +384,7 @@ diff -up shadow-4.6/src/gpasswd.c.audit-update shadow-4.6/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } else if (Aflg || Mflg) { -@@ -462,13 +443,9 @@ static void log_gpasswd_failure (const c +@@ -463,13 +444,9 @@ static void log_gpasswd_failure (const c "%s failed to set the administrators of group %s to %s%s", myname, group, admins, suffix)); #ifdef WITH_AUDIT @@ -311,7 +401,7 @@ diff -up shadow-4.6/src/gpasswd.c.audit-update shadow-4.6/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } -@@ -478,13 +455,9 @@ static void log_gpasswd_failure (const c +@@ -479,13 +456,9 @@ static void log_gpasswd_failure (const c "%s failed to set the members of group %s to %s%s", myname, group, members, suffix)); #ifdef WITH_AUDIT @@ -328,7 +418,7 @@ diff -up shadow-4.6/src/gpasswd.c.audit-update shadow-4.6/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } -@@ -493,13 +466,9 @@ static void log_gpasswd_failure (const c +@@ -494,13 +467,9 @@ static void log_gpasswd_failure (const c "%s failed to change password of group %s%s", myname, group, suffix)); #ifdef WITH_AUDIT @@ -345,7 +435,7 @@ diff -up shadow-4.6/src/gpasswd.c.audit-update shadow-4.6/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } -@@ -530,21 +499,14 @@ static void log_gpasswd_failure_gshadow +@@ -531,21 +500,14 @@ static void log_gpasswd_failure_gshadow static void log_gpasswd_success (const char *suffix) { @@ -370,7 +460,7 @@ diff -up shadow-4.6/src/gpasswd.c.audit-update shadow-4.6/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } else if (dflg) { -@@ -552,13 +514,9 @@ static void log_gpasswd_success (const c +@@ -553,13 +515,9 @@ static void log_gpasswd_success (const c "user %s removed by %s from group %s%s", user, myname, group, suffix)); #ifdef WITH_AUDIT @@ -387,7 +477,7 @@ diff -up shadow-4.6/src/gpasswd.c.audit-update shadow-4.6/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } else if (rflg) { -@@ -566,13 +524,9 @@ static void log_gpasswd_success (const c +@@ -567,13 +525,9 @@ static void log_gpasswd_success (const c "password of group %s removed by %s%s", group, myname, suffix)); #ifdef WITH_AUDIT @@ -404,7 +494,7 @@ diff -up shadow-4.6/src/gpasswd.c.audit-update shadow-4.6/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } else if (Rflg) { -@@ -580,13 +534,9 @@ static void log_gpasswd_success (const c +@@ -581,13 +535,9 @@ static void log_gpasswd_success (const c "access to group %s restricted by %s%s", group, myname, suffix)); #ifdef WITH_AUDIT @@ -421,7 +511,7 @@ diff -up shadow-4.6/src/gpasswd.c.audit-update shadow-4.6/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } else if (Aflg || Mflg) { -@@ -596,13 +546,9 @@ static void log_gpasswd_success (const c +@@ -597,13 +547,9 @@ static void log_gpasswd_success (const c "administrators of group %s set by %s to %s%s", group, myname, admins, suffix)); #ifdef WITH_AUDIT @@ -438,7 +528,7 @@ diff -up shadow-4.6/src/gpasswd.c.audit-update shadow-4.6/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } -@@ -612,13 +558,9 @@ static void log_gpasswd_success (const c +@@ -613,13 +559,9 @@ static void log_gpasswd_success (const c "members of group %s set by %s to %s%s", group, myname, members, suffix)); #ifdef WITH_AUDIT @@ -455,7 +545,7 @@ diff -up shadow-4.6/src/gpasswd.c.audit-update shadow-4.6/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } -@@ -627,13 +569,9 @@ static void log_gpasswd_success (const c +@@ -628,13 +570,9 @@ static void log_gpasswd_success (const c "password of group %s changed by %s%s", group, myname, suffix)); #ifdef WITH_AUDIT @@ -472,10 +562,10 @@ diff -up shadow-4.6/src/gpasswd.c.audit-update shadow-4.6/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } -diff -up shadow-4.6/src/groupadd.c.audit-update shadow-4.6/src/groupadd.c ---- shadow-4.6/src/groupadd.c.audit-update 2018-04-29 18:42:37.000000000 +0200 -+++ shadow-4.6/src/groupadd.c 2018-05-28 15:02:53.137910337 +0200 -@@ -130,6 +130,15 @@ static /*@noreturn@*/void usage (int sta +diff -up shadow-4.8/src/groupadd.c.audit-update shadow-4.8/src/groupadd.c +--- shadow-4.8/src/groupadd.c.audit-update 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8/src/groupadd.c 2020-01-13 10:15:51.804073345 +0100 +@@ -131,6 +131,15 @@ static /*@noreturn@*/void usage (int sta exit (status); } @@ -491,7 +581,7 @@ diff -up shadow-4.6/src/groupadd.c.audit-update shadow-4.6/src/groupadd.c /* * new_grent - initialize the values in a group file entry * -@@ -213,7 +222,7 @@ static void grp_update (void) +@@ -214,7 +223,7 @@ static void grp_update (void) fprintf (stderr, _("%s: failed to prepare the new %s entry '%s'\n"), Prog, gr_dbname (), grp.gr_name); @@ -500,7 +590,7 @@ diff -up shadow-4.6/src/groupadd.c.audit-update shadow-4.6/src/groupadd.c } #ifdef SHADOWGRP /* -@@ -223,7 +232,7 @@ static void grp_update (void) +@@ -224,7 +233,7 @@ static void grp_update (void) fprintf (stderr, _("%s: failed to prepare the new %s entry '%s'\n"), Prog, sgr_dbname (), sgrp.sg_name); @@ -509,7 +599,7 @@ diff -up shadow-4.6/src/groupadd.c.audit-update shadow-4.6/src/groupadd.c } #endif /* SHADOWGRP */ } -@@ -247,7 +256,7 @@ static void check_new_name (void) +@@ -248,7 +257,7 @@ static void check_new_name (void) fprintf (stderr, _("%s: '%s' is not a valid group name\n"), Prog, group_name); @@ -518,7 +608,7 @@ diff -up shadow-4.6/src/groupadd.c.audit-update shadow-4.6/src/groupadd.c } /* -@@ -263,11 +272,11 @@ static void close_files (void) +@@ -264,11 +273,11 @@ static void close_files (void) fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, gr_dbname ()); @@ -532,7 +622,7 @@ diff -up shadow-4.6/src/groupadd.c.audit-update shadow-4.6/src/groupadd.c group_name, (unsigned int) group_id, SHADOW_AUDIT_SUCCESS); #endif -@@ -285,11 +294,11 @@ static void close_files (void) +@@ -286,11 +295,11 @@ static void close_files (void) fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sgr_dbname ()); @@ -547,7 +637,7 @@ diff -up shadow-4.6/src/groupadd.c.audit-update shadow-4.6/src/groupadd.c group_name, (unsigned int) group_id, SHADOW_AUDIT_SUCCESS); #endif -@@ -303,12 +312,6 @@ static void close_files (void) +@@ -304,12 +313,6 @@ static void close_files (void) #endif /* SHADOWGRP */ /* Report success at the system level */ @@ -560,7 +650,7 @@ diff -up shadow-4.6/src/groupadd.c.audit-update shadow-4.6/src/groupadd.c SYSLOG ((LOG_INFO, "new group: name=%s, GID=%u", group_name, (unsigned int) group_id)); del_cleanup (cleanup_report_add_group); -@@ -326,7 +329,7 @@ static void open_files (void) +@@ -327,7 +330,7 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, gr_dbname ()); @@ -569,7 +659,7 @@ diff -up shadow-4.6/src/groupadd.c.audit-update shadow-4.6/src/groupadd.c } add_cleanup (cleanup_unlock_group, NULL); -@@ -336,7 +339,7 @@ static void open_files (void) +@@ -337,7 +340,7 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, sgr_dbname ()); @@ -578,7 +668,7 @@ diff -up shadow-4.6/src/groupadd.c.audit-update shadow-4.6/src/groupadd.c } add_cleanup (cleanup_unlock_gshadow, NULL); } -@@ -352,7 +355,7 @@ static void open_files (void) +@@ -353,7 +356,7 @@ static void open_files (void) if (gr_open (O_CREAT | O_RDWR) == 0) { fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ()); SYSLOG ((LOG_WARN, "cannot open %s", gr_dbname ())); @@ -587,7 +677,7 @@ diff -up shadow-4.6/src/groupadd.c.audit-update shadow-4.6/src/groupadd.c } #ifdef SHADOWGRP -@@ -362,7 +365,7 @@ static void open_files (void) +@@ -363,7 +366,7 @@ static void open_files (void) _("%s: cannot open %s\n"), Prog, sgr_dbname ()); SYSLOG ((LOG_WARN, "cannot open %s", sgr_dbname ())); @@ -596,7 +686,7 @@ diff -up shadow-4.6/src/groupadd.c.audit-update shadow-4.6/src/groupadd.c } } #endif /* SHADOWGRP */ -@@ -495,7 +498,7 @@ static void check_flags (void) +@@ -496,7 +499,7 @@ static void check_flags (void) fprintf (stderr, _("%s: group '%s' already exists\n"), Prog, group_name); @@ -605,7 +695,7 @@ diff -up shadow-4.6/src/groupadd.c.audit-update shadow-4.6/src/groupadd.c } if (gflg && (prefix_getgrgid (group_id) != NULL)) { -@@ -514,7 +517,7 @@ static void check_flags (void) +@@ -515,7 +518,7 @@ static void check_flags (void) fprintf (stderr, _("%s: GID '%lu' already exists\n"), Prog, (unsigned long int) group_id); @@ -614,7 +704,7 @@ diff -up shadow-4.6/src/groupadd.c.audit-update shadow-4.6/src/groupadd.c } } } -@@ -542,7 +545,7 @@ static void check_perms (void) +@@ -543,7 +546,7 @@ static void check_perms (void) fprintf (stderr, _("%s: Cannot determine your user name.\n"), Prog); @@ -623,7 +713,7 @@ diff -up shadow-4.6/src/groupadd.c.audit-update shadow-4.6/src/groupadd.c } retval = pam_start ("groupadd", pampw->pw_name, &conv, &pamh); -@@ -562,7 +565,7 @@ static void check_perms (void) +@@ -563,7 +566,7 @@ static void check_perms (void) if (NULL != pamh) { (void) pam_end (pamh, retval); } @@ -632,7 +722,7 @@ diff -up shadow-4.6/src/groupadd.c.audit-update shadow-4.6/src/groupadd.c } (void) pam_end (pamh, retval); #endif /* USE_PAM */ -@@ -595,7 +598,7 @@ int main (int argc, char **argv) +@@ -596,7 +599,7 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: Cannot setup cleanup service.\n"), Prog); @@ -641,7 +731,7 @@ diff -up shadow-4.6/src/groupadd.c.audit-update shadow-4.6/src/groupadd.c } /* -@@ -617,7 +620,7 @@ int main (int argc, char **argv) +@@ -618,7 +621,7 @@ int main (int argc, char **argv) if (!gflg) { if (find_new_gid (rflg, &group_id, NULL) < 0) { @@ -650,10 +740,10 @@ diff -up shadow-4.6/src/groupadd.c.audit-update shadow-4.6/src/groupadd.c } } -diff -up shadow-4.6/src/groupdel.c.audit-update shadow-4.6/src/groupdel.c ---- shadow-4.6/src/groupdel.c.audit-update 2018-04-29 18:42:37.000000000 +0200 -+++ shadow-4.6/src/groupdel.c 2018-05-28 15:01:09.914717585 +0200 -@@ -105,6 +105,15 @@ static /*@noreturn@*/void usage (int sta +diff -up shadow-4.8/src/groupdel.c.audit-update shadow-4.8/src/groupdel.c +--- shadow-4.8/src/groupdel.c.audit-update 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8/src/groupdel.c 2020-01-13 10:15:51.804073345 +0100 +@@ -106,6 +106,15 @@ static /*@noreturn@*/void usage (int sta exit (status); } @@ -669,7 +759,7 @@ diff -up shadow-4.6/src/groupdel.c.audit-update shadow-4.6/src/groupdel.c /* * grp_update - update group file entries * -@@ -131,7 +140,7 @@ static void grp_update (void) +@@ -132,7 +141,7 @@ static void grp_update (void) fprintf (stderr, _("%s: cannot remove entry '%s' from %s\n"), Prog, group_name, gr_dbname ()); @@ -678,7 +768,7 @@ diff -up shadow-4.6/src/groupdel.c.audit-update shadow-4.6/src/groupdel.c } #ifdef SHADOWGRP -@@ -143,7 +152,7 @@ static void grp_update (void) +@@ -144,7 +153,7 @@ static void grp_update (void) fprintf (stderr, _("%s: cannot remove entry '%s' from %s\n"), Prog, group_name, sgr_dbname ()); @@ -687,7 +777,7 @@ diff -up shadow-4.6/src/groupdel.c.audit-update shadow-4.6/src/groupdel.c } } #endif /* SHADOWGRP */ -@@ -162,12 +171,12 @@ static void close_files (void) +@@ -163,12 +172,12 @@ static void close_files (void) fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, gr_dbname ()); @@ -702,7 +792,7 @@ diff -up shadow-4.6/src/groupdel.c.audit-update shadow-4.6/src/groupdel.c group_name, (unsigned int) group_id, SHADOW_AUDIT_SUCCESS); #endif -@@ -187,12 +196,12 @@ static void close_files (void) +@@ -188,12 +197,12 @@ static void close_files (void) fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sgr_dbname ()); @@ -718,7 +808,7 @@ diff -up shadow-4.6/src/groupdel.c.audit-update shadow-4.6/src/groupdel.c group_name, (unsigned int) group_id, SHADOW_AUDIT_SUCCESS); #endif -@@ -206,13 +215,6 @@ static void close_files (void) +@@ -207,13 +216,6 @@ static void close_files (void) } #endif /* SHADOWGRP */ @@ -732,7 +822,7 @@ diff -up shadow-4.6/src/groupdel.c.audit-update shadow-4.6/src/groupdel.c SYSLOG ((LOG_INFO, "group '%s' removed\n", group_name)); del_cleanup (cleanup_report_del_group); } -@@ -229,7 +231,7 @@ static void open_files (void) +@@ -230,7 +232,7 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, gr_dbname ()); @@ -741,7 +831,7 @@ diff -up shadow-4.6/src/groupdel.c.audit-update shadow-4.6/src/groupdel.c } add_cleanup (cleanup_unlock_group, NULL); #ifdef SHADOWGRP -@@ -238,7 +240,7 @@ static void open_files (void) +@@ -239,7 +241,7 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, sgr_dbname ()); @@ -750,7 +840,7 @@ diff -up shadow-4.6/src/groupdel.c.audit-update shadow-4.6/src/groupdel.c } add_cleanup (cleanup_unlock_gshadow, NULL); } -@@ -256,7 +258,7 @@ static void open_files (void) +@@ -257,7 +259,7 @@ static void open_files (void) _("%s: cannot open %s\n"), Prog, gr_dbname ()); SYSLOG ((LOG_WARN, "cannot open %s", gr_dbname ())); @@ -759,7 +849,7 @@ diff -up shadow-4.6/src/groupdel.c.audit-update shadow-4.6/src/groupdel.c } #ifdef SHADOWGRP if (is_shadow_grp) { -@@ -265,7 +267,7 @@ static void open_files (void) +@@ -266,7 +268,7 @@ static void open_files (void) _("%s: cannot open %s\n"), Prog, sgr_dbname ()); SYSLOG ((LOG_WARN, "cannot open %s", sgr_dbname ())); @@ -768,7 +858,7 @@ diff -up shadow-4.6/src/groupdel.c.audit-update shadow-4.6/src/groupdel.c } } #endif /* SHADOWGRP */ -@@ -306,7 +308,7 @@ static void group_busy (gid_t gid) +@@ -307,7 +309,7 @@ static void group_busy (gid_t gid) fprintf (stderr, _("%s: cannot remove the primary group of user '%s'\n"), Prog, pwd->pw_name); @@ -777,7 +867,7 @@ diff -up shadow-4.6/src/groupdel.c.audit-update shadow-4.6/src/groupdel.c } /* -@@ -391,7 +393,7 @@ int main (int argc, char **argv) +@@ -392,7 +394,7 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: Cannot setup cleanup service.\n"), Prog); @@ -786,7 +876,7 @@ diff -up shadow-4.6/src/groupdel.c.audit-update shadow-4.6/src/groupdel.c } process_flags (argc, argv); -@@ -405,7 +407,7 @@ int main (int argc, char **argv) +@@ -406,7 +408,7 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: Cannot determine your user name.\n"), Prog); @@ -795,7 +885,7 @@ diff -up shadow-4.6/src/groupdel.c.audit-update shadow-4.6/src/groupdel.c } retval = pam_start ("groupdel", pampw->pw_name, &conv, &pamh); -@@ -426,7 +428,7 @@ int main (int argc, char **argv) +@@ -427,7 +429,7 @@ int main (int argc, char **argv) if (NULL != pamh) { (void) pam_end (pamh, retval); } @@ -804,7 +894,7 @@ diff -up shadow-4.6/src/groupdel.c.audit-update shadow-4.6/src/groupdel.c } (void) pam_end (pamh, retval); #endif /* USE_PAM */ -@@ -446,7 +448,7 @@ int main (int argc, char **argv) +@@ -447,7 +449,7 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: group '%s' does not exist\n"), Prog, group_name); @@ -813,7 +903,7 @@ diff -up shadow-4.6/src/groupdel.c.audit-update shadow-4.6/src/groupdel.c } group_id = grp->gr_gid; -@@ -470,7 +472,7 @@ int main (int argc, char **argv) +@@ -471,7 +473,7 @@ int main (int argc, char **argv) _("%s: %s is the NIS master\n"), Prog, nis_master); } @@ -822,10 +912,10 @@ diff -up shadow-4.6/src/groupdel.c.audit-update shadow-4.6/src/groupdel.c } #endif -diff -up shadow-4.6/src/groupmod.c.audit-update shadow-4.6/src/groupmod.c ---- shadow-4.6/src/groupmod.c.audit-update 2018-04-29 18:42:37.000000000 +0200 -+++ shadow-4.6/src/groupmod.c 2018-05-28 15:01:09.915717607 +0200 -@@ -449,7 +449,7 @@ static void close_files (void) +diff -up shadow-4.8/src/groupmod.c.audit-update shadow-4.8/src/groupmod.c +--- shadow-4.8/src/groupmod.c.audit-update 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8/src/groupmod.c 2020-01-13 10:15:51.805073328 +0100 +@@ -450,7 +450,7 @@ static void close_files (void) exit (E_GRP_UPDATE); } #ifdef WITH_AUDIT @@ -834,7 +924,7 @@ diff -up shadow-4.6/src/groupmod.c.audit-update shadow-4.6/src/groupmod.c info_group.audit_msg, group_name, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); -@@ -472,7 +472,14 @@ static void close_files (void) +@@ -473,7 +473,14 @@ static void close_files (void) exit (E_GRP_UPDATE); } #ifdef WITH_AUDIT @@ -850,7 +940,7 @@ diff -up shadow-4.6/src/groupmod.c.audit-update shadow-4.6/src/groupmod.c info_gshadow.audit_msg, group_name, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); -@@ -495,7 +502,7 @@ static void close_files (void) +@@ -496,7 +503,7 @@ static void close_files (void) exit (E_GRP_UPDATE); } #ifdef WITH_AUDIT @@ -859,7 +949,7 @@ diff -up shadow-4.6/src/groupmod.c.audit-update shadow-4.6/src/groupmod.c info_passwd.audit_msg, group_name, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); -@@ -510,8 +517,8 @@ static void close_files (void) +@@ -511,8 +518,8 @@ static void close_files (void) } #ifdef WITH_AUDIT @@ -870,7 +960,7 @@ diff -up shadow-4.6/src/groupmod.c.audit-update shadow-4.6/src/groupmod.c group_name, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); #endif -@@ -523,6 +530,8 @@ static void close_files (void) +@@ -524,6 +531,8 @@ static void close_files (void) */ static void prepare_failure_reports (void) { @@ -879,7 +969,7 @@ diff -up shadow-4.6/src/groupmod.c.audit-update shadow-4.6/src/groupmod.c info_group.name = group_name; #ifdef SHADOWGRP info_gshadow.name = group_name; -@@ -535,76 +544,109 @@ static void prepare_failure_reports (voi +@@ -536,76 +545,109 @@ static void prepare_failure_reports (voi #endif info_passwd.audit_msg = xmalloc (512); @@ -1016,7 +1106,7 @@ diff -up shadow-4.6/src/groupmod.c.audit-update shadow-4.6/src/groupmod.c "%lu", (unsigned long int) group_newid); } info_group.audit_msg[511] = '\0'; -@@ -612,6 +654,11 @@ static void prepare_failure_reports (voi +@@ -613,6 +655,11 @@ static void prepare_failure_reports (voi info_gshadow.audit_msg[511] = '\0'; #endif info_passwd.audit_msg[511] = '\0'; @@ -1028,99 +1118,9 @@ diff -up shadow-4.6/src/groupmod.c.audit-update shadow-4.6/src/groupmod.c // FIXME: add a system cleanup add_cleanup (cleanup_report_mod_group, &info_group); -diff -up shadow-4.6/src/chage.c.audit-update shadow-4.6/src/chage.c ---- shadow-4.6/src/chage.c.audit-update 2018-04-29 18:42:37.000000000 +0200 -+++ shadow-4.6/src/chage.c 2018-05-28 15:01:09.915717607 +0200 -@@ -126,9 +126,10 @@ static /*@noreturn@*/void fail_exit (int - - #ifdef WITH_AUDIT - if (E_SUCCESS != code) { -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "change age", -- user_name, (unsigned int) user_uid, 0); -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "change-age", -+ user_name, (unsigned int) user_uid, -+ SHADOW_AUDIT_FAILURE); - } - #endif - -@@ -873,11 +874,7 @@ int main (int argc, char **argv) - fprintf (stderr, _("%s: Permission denied.\n"), Prog); - fail_exit (E_NOPERM); - } --#ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "display aging info", -- user_name, (unsigned int) user_uid, 1); --#endif -+ /* Displaying fields is not of interest to audit */ - list_fields (); - fail_exit (E_SUCCESS); - } -@@ -896,41 +893,43 @@ int main (int argc, char **argv) - } - #ifdef WITH_AUDIT - else { -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "change all aging information", -- user_name, (unsigned int) user_uid, 1); -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "change-all-aging-information", -+ user_name, (unsigned int) user_uid, -+ SHADOW_AUDIT_SUCCESS); - } - #endif - } else { - #ifdef WITH_AUDIT - if (Mflg) { -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "change max age", -- user_name, (unsigned int) user_uid, 1); -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "change-max-age", -+ user_name, (unsigned int) user_uid, -+ SHADOW_AUDIT_SUCCESS); - } - if (mflg) { -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "change min age", -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "change-min-age", - user_name, (unsigned int) user_uid, 1); - } - if (dflg) { -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "change last change date", -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "change-last-change-date", - user_name, (unsigned int) user_uid, 1); - } - if (Wflg) { -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "change passwd warning", -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "change-passwd-warning", - user_name, (unsigned int) user_uid, 1); - } - if (Iflg) { -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "change inactive days", -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "change-inactive-days", - user_name, (unsigned int) user_uid, 1); - } - if (Eflg) { -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "change passwd expiration", -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "change-passwd-expiration", - user_name, (unsigned int) user_uid, 1); - } - #endif -diff -up shadow-4.6/src/newgrp.c.audit-update shadow-4.6/src/newgrp.c ---- shadow-4.6/src/newgrp.c.audit-update 2018-04-29 18:42:37.000000000 +0200 -+++ shadow-4.6/src/newgrp.c 2018-05-28 15:01:09.915717607 +0200 +diff -up shadow-4.8/src/newgrp.c.audit-update shadow-4.8/src/newgrp.c +--- shadow-4.8/src/newgrp.c.audit-update 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8/src/newgrp.c 2020-01-13 10:15:51.806073311 +0100 @@ -206,11 +206,12 @@ static void check_perms (const struct gr strcmp (cpasswd, grp->gr_passwd) != 0) { #ifdef WITH_AUDIT @@ -1325,10 +1325,10 @@ diff -up shadow-4.6/src/newgrp.c.audit-update shadow-4.6/src/newgrp.c } #endif exit (EXIT_FAILURE); -diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c ---- shadow-4.6/src/useradd.c.audit-update 2018-05-28 15:01:09.903717352 +0200 -+++ shadow-4.6/src/useradd.c 2018-05-28 15:06:36.824662074 +0200 -@@ -229,6 +229,8 @@ static void create_mail (void); +diff -up shadow-4.8/src/useradd.c.audit-update shadow-4.8/src/useradd.c +--- shadow-4.8/src/useradd.c.audit-update 2020-01-13 10:15:51.789073597 +0100 ++++ shadow-4.8/src/useradd.c 2020-01-13 10:17:30.929406913 +0100 +@@ -233,6 +233,8 @@ static void create_mail (void); */ static void fail_exit (int code) { @@ -1337,7 +1337,7 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c if (home_added) { if (rmdir (prefix_user_home) != 0) { fprintf (stderr, -@@ -242,12 +244,6 @@ static void fail_exit (int code) +@@ -246,12 +248,6 @@ static void fail_exit (int code) if (spw_unlock () == 0) { fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); @@ -1350,7 +1350,7 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c /* continue */ } } -@@ -255,12 +251,6 @@ static void fail_exit (int code) +@@ -259,12 +255,6 @@ static void fail_exit (int code) if (pw_unlock () == 0) { fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); @@ -1363,7 +1363,7 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c /* continue */ } } -@@ -268,12 +258,6 @@ static void fail_exit (int code) +@@ -272,12 +262,6 @@ static void fail_exit (int code) if (gr_unlock () == 0) { fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); @@ -1376,7 +1376,7 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c /* continue */ } } -@@ -282,12 +266,6 @@ static void fail_exit (int code) +@@ -286,12 +270,6 @@ static void fail_exit (int code) if (sgr_unlock () == 0) { fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); @@ -1389,7 +1389,7 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c /* continue */ } } -@@ -297,12 +275,6 @@ static void fail_exit (int code) +@@ -301,12 +279,6 @@ static void fail_exit (int code) if (sub_uid_unlock () == 0) { fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); @@ -1402,7 +1402,7 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c /* continue */ } } -@@ -310,20 +282,19 @@ static void fail_exit (int code) +@@ -314,20 +286,19 @@ static void fail_exit (int code) if (sub_gid_unlock () == 0) { fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); @@ -1430,7 +1430,7 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -673,7 +644,7 @@ static int set_defaults (void) +@@ -692,7 +663,7 @@ static int set_defaults (void) } #ifdef WITH_AUDIT audit_logger (AUDIT_USYS_CONFIG, Prog, @@ -1439,7 +1439,7 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c NULL, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); #endif -@@ -950,12 +921,6 @@ static void grp_update (void) +@@ -974,12 +945,6 @@ static void grp_update (void) _("%s: Out of memory. Cannot update %s.\n"), Prog, gr_dbname ()); SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", gr_dbname (), user_name)); @@ -1452,7 +1452,7 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c fail_exit (E_GRP_UPDATE); /* XXX */ } -@@ -969,18 +934,12 @@ static void grp_update (void) +@@ -993,18 +958,12 @@ static void grp_update (void) _("%s: failed to prepare the new %s entry '%s'\n"), Prog, gr_dbname (), ngrp->gr_name); SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", gr_dbname (), user_name)); @@ -1474,7 +1474,7 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c SHADOW_AUDIT_SUCCESS); #endif SYSLOG ((LOG_INFO, -@@ -1025,12 +984,6 @@ static void grp_update (void) +@@ -1049,12 +1008,6 @@ static void grp_update (void) _("%s: Out of memory. Cannot update %s.\n"), Prog, sgr_dbname ()); SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", sgr_dbname (), user_name)); @@ -1487,7 +1487,7 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c fail_exit (E_GRP_UPDATE); /* XXX */ } -@@ -1044,18 +997,13 @@ static void grp_update (void) +@@ -1068,18 +1021,13 @@ static void grp_update (void) _("%s: failed to prepare the new %s entry '%s'\n"), Prog, sgr_dbname (), nsgrp->sg_name); SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", sgr_dbname (), user_name)); @@ -1510,7 +1510,7 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c SHADOW_AUDIT_SUCCESS); #endif SYSLOG ((LOG_INFO, -@@ -1407,7 +1355,7 @@ static void process_flags (int argc, cha +@@ -1445,7 +1393,7 @@ static void process_flags (int argc, cha Prog, user_name); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1519,7 +1519,7 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1522,7 +1470,7 @@ static void close_files (void) +@@ -1560,7 +1508,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1528,7 +1528,7 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1535,7 +1483,7 @@ static void close_files (void) +@@ -1573,7 +1521,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1537,7 +1537,7 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1547,7 +1495,7 @@ static void close_files (void) +@@ -1585,7 +1533,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1546,7 +1546,7 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1561,7 +1509,7 @@ static void close_files (void) +@@ -1599,7 +1547,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1555,7 +1555,7 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1577,7 +1525,7 @@ static void close_files (void) +@@ -1615,7 +1563,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1564,7 +1564,7 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1591,7 +1539,7 @@ static void close_files (void) +@@ -1629,7 +1577,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1573,7 +1573,7 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1783,7 +1731,7 @@ static void grp_add (void) +@@ -1821,7 +1769,7 @@ static void grp_add (void) Prog, gr_dbname (), grp.gr_name); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_GROUP, Prog, @@ -1582,7 +1582,7 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c grp.gr_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1799,7 +1747,7 @@ static void grp_add (void) +@@ -1837,7 +1785,7 @@ static void grp_add (void) Prog, sgr_dbname (), sgrp.sg_name); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_GROUP, Prog, @@ -1591,7 +1591,7 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c grp.gr_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1809,7 +1757,7 @@ static void grp_add (void) +@@ -1847,7 +1795,7 @@ static void grp_add (void) SYSLOG ((LOG_INFO, "new group: name=%s, GID=%u", user_name, user_gid)); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_GROUP, Prog, @@ -1600,7 +1600,7 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c grp.gr_name, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); #endif -@@ -1970,12 +1918,6 @@ static void usr_update (void) +@@ -2015,12 +1963,6 @@ static void usr_update (void) fprintf (stderr, _("%s: failed to prepare the new %s entry '%s'\n"), Prog, spw_dbname (), spent.sp_namp); @@ -1613,7 +1613,7 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c fail_exit (E_PW_UPDATE); } #ifdef ENABLE_SUBIDS -@@ -1996,9 +1938,14 @@ static void usr_update (void) +@@ -2041,9 +1983,14 @@ static void usr_update (void) #endif /* ENABLE_SUBIDS */ #ifdef WITH_AUDIT @@ -1630,20 +1630,20 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c SHADOW_AUDIT_SUCCESS); #endif /* -@@ -2032,12 +1979,6 @@ static void create_home (void) +@@ -2130,12 +2077,6 @@ static void create_home (void) fprintf (stderr, - _("%s: cannot create directory %s\n"), - Prog, prefix_user_home); + _("%s: cannot create directory %s\n"), + Prog, path); -#ifdef WITH_AUDIT - audit_logger (AUDIT_ADD_USER, Prog, -- "adding home directory", -- user_name, (unsigned int) user_id, -- SHADOW_AUDIT_FAILURE); +- "adding home directory", +- user_name, (unsigned int) user_id, +- SHADOW_AUDIT_FAILURE); -#endif fail_exit (E_HOMEDIR); } - (void) chown (prefix_user_home, user_id, user_gid); -@@ -2045,8 +1986,8 @@ static void create_home (void) + if (chown (path, 0, 0) < 0) { +@@ -2157,8 +2098,8 @@ static void create_home (void) 0777 & ~getdef_num ("UMASK", GETDEF_DEFAULT_UMASK)); home_added = true; #ifdef WITH_AUDIT @@ -1654,7 +1654,7 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c user_name, (unsigned int) user_id, SHADOW_AUDIT_SUCCESS); #endif -@@ -2231,12 +2172,6 @@ int main (int argc, char **argv) +@@ -2343,12 +2284,6 @@ int main (int argc, char **argv) */ if (prefix_getpwnam (user_name) != NULL) { /* local, no need for xgetpwnam */ fprintf (stderr, _("%s: user '%s' already exists\n"), Prog, user_name); @@ -1667,7 +1667,7 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c fail_exit (E_NAME_IN_USE); } -@@ -2252,12 +2187,6 @@ int main (int argc, char **argv) +@@ -2364,12 +2299,6 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: group %s exists - if you want to add this user to that group, use -g.\n"), Prog, user_name); @@ -1680,7 +1680,7 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c fail_exit (E_NAME_IN_USE); } } -@@ -2287,12 +2216,6 @@ int main (int argc, char **argv) +@@ -2399,12 +2328,6 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: UID %lu is not unique\n"), Prog, (unsigned long) user_id); @@ -1693,7 +1693,7 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c fail_exit (E_UID_IN_USE); } } -@@ -2365,9 +2283,10 @@ int main (int argc, char **argv) +@@ -2478,9 +2401,10 @@ int main (int argc, char **argv) _("%s: warning: the user name %s to %s SELinux user mapping failed.\n"), Prog, user_name, user_selinux); #ifdef WITH_AUDIT @@ -1707,10 +1707,10 @@ diff -up shadow-4.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c #endif /* WITH_AUDIT */ rv = E_SE_UPDATE; } -diff -up shadow-4.6/src/userdel.c.audit-update shadow-4.6/src/userdel.c ---- shadow-4.6/src/userdel.c.audit-update 2018-05-28 15:01:09.909717479 +0200 -+++ shadow-4.6/src/userdel.c 2018-05-28 15:01:09.916717628 +0200 -@@ -219,9 +219,9 @@ static void update_groups (void) +diff -up shadow-4.8/src/userdel.c.audit-update shadow-4.8/src/userdel.c +--- shadow-4.8/src/userdel.c.audit-update 2020-01-13 10:15:51.797073462 +0100 ++++ shadow-4.8/src/userdel.c 2020-01-13 10:15:51.809073261 +0100 +@@ -222,9 +222,9 @@ static void update_groups (void) * Update the DBM group file with the new entry as well. */ #ifdef WITH_AUDIT @@ -1723,7 +1723,7 @@ diff -up shadow-4.6/src/userdel.c.audit-update shadow-4.6/src/userdel.c SHADOW_AUDIT_SUCCESS); #endif /* WITH_AUDIT */ SYSLOG ((LOG_INFO, "delete '%s' from group '%s'\n", -@@ -281,9 +281,9 @@ static void update_groups (void) +@@ -284,9 +284,9 @@ static void update_groups (void) exit (E_GRP_UPDATE); } #ifdef WITH_AUDIT @@ -1736,7 +1736,7 @@ diff -up shadow-4.6/src/userdel.c.audit-update shadow-4.6/src/userdel.c SHADOW_AUDIT_SUCCESS); #endif /* WITH_AUDIT */ SYSLOG ((LOG_INFO, "delete '%s' from shadow group '%s'\n", -@@ -360,9 +360,9 @@ static void remove_usergroup (void) +@@ -363,9 +363,9 @@ static void remove_usergroup (void) } #ifdef WITH_AUDIT @@ -1749,7 +1749,7 @@ diff -up shadow-4.6/src/userdel.c.audit-update shadow-4.6/src/userdel.c SHADOW_AUDIT_SUCCESS); #endif /* WITH_AUDIT */ SYSLOG ((LOG_INFO, -@@ -378,9 +378,9 @@ static void remove_usergroup (void) +@@ -381,9 +381,9 @@ static void remove_usergroup (void) fail_exit (E_GRP_UPDATE); } #ifdef WITH_AUDIT @@ -1762,7 +1762,7 @@ diff -up shadow-4.6/src/userdel.c.audit-update shadow-4.6/src/userdel.c SHADOW_AUDIT_SUCCESS); #endif /* WITH_AUDIT */ SYSLOG ((LOG_INFO, -@@ -542,7 +542,7 @@ static void fail_exit (int code) +@@ -545,7 +545,7 @@ static void fail_exit (int code) #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, @@ -1771,7 +1771,7 @@ diff -up shadow-4.6/src/userdel.c.audit-update shadow-4.6/src/userdel.c user_name, (unsigned int) user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -562,24 +562,12 @@ static void open_files (void) +@@ -565,24 +565,12 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, pw_dbname ()); @@ -1796,7 +1796,7 @@ diff -up shadow-4.6/src/userdel.c.audit-update shadow-4.6/src/userdel.c fail_exit (E_PW_UPDATE); } if (is_shadow_pwd) { -@@ -587,12 +575,6 @@ static void open_files (void) +@@ -590,12 +578,6 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, spw_dbname ()); @@ -1809,7 +1809,7 @@ diff -up shadow-4.6/src/userdel.c.audit-update shadow-4.6/src/userdel.c fail_exit (E_PW_UPDATE); } spw_locked = true; -@@ -600,12 +582,6 @@ static void open_files (void) +@@ -603,12 +585,6 @@ static void open_files (void) fprintf (stderr, _("%s: cannot open %s\n"), Prog, spw_dbname ()); @@ -1822,7 +1822,7 @@ diff -up shadow-4.6/src/userdel.c.audit-update shadow-4.6/src/userdel.c fail_exit (E_PW_UPDATE); } } -@@ -613,23 +589,11 @@ static void open_files (void) +@@ -616,23 +592,11 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, gr_dbname ()); @@ -1846,7 +1846,7 @@ diff -up shadow-4.6/src/userdel.c.audit-update shadow-4.6/src/userdel.c fail_exit (E_GRP_UPDATE); } #ifdef SHADOWGRP -@@ -638,24 +602,12 @@ static void open_files (void) +@@ -641,24 +605,12 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, sgr_dbname ()); @@ -1871,7 +1871,7 @@ diff -up shadow-4.6/src/userdel.c.audit-update shadow-4.6/src/userdel.c fail_exit (E_GRP_UPDATE); } } -@@ -666,24 +618,12 @@ static void open_files (void) +@@ -669,24 +621,12 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, sub_uid_dbname ()); @@ -1896,7 +1896,7 @@ diff -up shadow-4.6/src/userdel.c.audit-update shadow-4.6/src/userdel.c fail_exit (E_SUB_UID_UPDATE); } } -@@ -692,24 +632,12 @@ static void open_files (void) +@@ -695,24 +635,12 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, sub_gid_dbname ()); @@ -1921,7 +1921,7 @@ diff -up shadow-4.6/src/userdel.c.audit-update shadow-4.6/src/userdel.c fail_exit (E_SUB_GID_UPDATE); } } -@@ -754,7 +682,7 @@ static void update_user (void) +@@ -757,7 +685,7 @@ static void update_user (void) #endif /* ENABLE_SUBIDS */ #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, @@ -1930,7 +1930,7 @@ diff -up shadow-4.6/src/userdel.c.audit-update shadow-4.6/src/userdel.c user_name, (unsigned int) user_id, SHADOW_AUDIT_SUCCESS); #endif /* WITH_AUDIT */ -@@ -862,7 +790,7 @@ static int remove_mailbox (void) +@@ -865,7 +793,7 @@ static int remove_mailbox (void) SYSLOG ((LOG_ERR, "Cannot remove %s: %s", mailfile, strerror (errno))); #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, @@ -1939,7 +1939,7 @@ diff -up shadow-4.6/src/userdel.c.audit-update shadow-4.6/src/userdel.c user_name, (unsigned int) user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -879,7 +807,7 @@ static int remove_mailbox (void) +@@ -882,7 +810,7 @@ static int remove_mailbox (void) SYSLOG ((LOG_ERR, "Cannot remove %s: %s", mailfile, strerror (errno))); #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, @@ -1948,7 +1948,7 @@ diff -up shadow-4.6/src/userdel.c.audit-update shadow-4.6/src/userdel.c user_name, (unsigned int) user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -889,8 +817,8 @@ static int remove_mailbox (void) +@@ -892,8 +820,8 @@ static int remove_mailbox (void) #ifdef WITH_AUDIT else { @@ -1959,7 +1959,7 @@ diff -up shadow-4.6/src/userdel.c.audit-update shadow-4.6/src/userdel.c user_name, (unsigned int) user_id, SHADOW_AUDIT_SUCCESS); } -@@ -908,7 +836,7 @@ static int remove_mailbox (void) +@@ -911,7 +839,7 @@ static int remove_mailbox (void) mailfile, strerror (errno))); #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, @@ -1968,7 +1968,7 @@ diff -up shadow-4.6/src/userdel.c.audit-update shadow-4.6/src/userdel.c user_name, (unsigned int) user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -925,7 +853,7 @@ static int remove_mailbox (void) +@@ -928,7 +856,7 @@ static int remove_mailbox (void) SYSLOG ((LOG_ERR, "Cannot remove %s: %s", mailfile, strerror (errno))); #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, @@ -1977,7 +1977,7 @@ diff -up shadow-4.6/src/userdel.c.audit-update shadow-4.6/src/userdel.c user_name, (unsigned int) user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -935,8 +863,8 @@ static int remove_mailbox (void) +@@ -938,8 +866,8 @@ static int remove_mailbox (void) #ifdef WITH_AUDIT else { @@ -1988,7 +1988,7 @@ diff -up shadow-4.6/src/userdel.c.audit-update shadow-4.6/src/userdel.c user_name, (unsigned int) user_id, SHADOW_AUDIT_SUCCESS); } -@@ -1149,7 +1077,7 @@ int main (int argc, char **argv) +@@ -1152,7 +1080,7 @@ int main (int argc, char **argv) Prog, user_name); #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, @@ -1997,7 +1997,7 @@ diff -up shadow-4.6/src/userdel.c.audit-update shadow-4.6/src/userdel.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -1205,7 +1133,7 @@ int main (int argc, char **argv) +@@ -1208,7 +1136,7 @@ int main (int argc, char **argv) if (!fflg) { #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, @@ -2006,7 +2006,7 @@ diff -up shadow-4.6/src/userdel.c.audit-update shadow-4.6/src/userdel.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -1282,8 +1210,8 @@ int main (int argc, char **argv) +@@ -1302,8 +1230,8 @@ int main (int argc, char **argv) #ifdef WITH_AUDIT else { @@ -2017,7 +2017,7 @@ diff -up shadow-4.6/src/userdel.c.audit-update shadow-4.6/src/userdel.c user_name, (unsigned int) user_id, SHADOW_AUDIT_SUCCESS); } -@@ -1292,7 +1220,7 @@ int main (int argc, char **argv) +@@ -1312,7 +1240,7 @@ int main (int argc, char **argv) #ifdef WITH_AUDIT if (0 != errors) { audit_logger (AUDIT_DEL_USER, Prog, @@ -2026,7 +2026,7 @@ diff -up shadow-4.6/src/userdel.c.audit-update shadow-4.6/src/userdel.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); } -@@ -1305,8 +1233,8 @@ int main (int argc, char **argv) +@@ -1325,8 +1253,8 @@ int main (int argc, char **argv) _("%s: warning: the user name %s to SELinux user mapping removal failed.\n"), Prog, user_name); #ifdef WITH_AUDIT @@ -2037,10 +2037,10 @@ diff -up shadow-4.6/src/userdel.c.audit-update shadow-4.6/src/userdel.c user_name, (unsigned int) user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -diff -up shadow-4.6/src/usermod.c.audit-update shadow-4.6/src/usermod.c ---- shadow-4.6/src/usermod.c.audit-update 2018-05-28 15:01:09.912717543 +0200 -+++ shadow-4.6/src/usermod.c 2018-05-28 15:08:25.424969050 +0200 -@@ -453,8 +453,8 @@ static char *new_pw_passwd (char *pw_pas +diff -up shadow-4.8/src/usermod.c.audit-update shadow-4.8/src/usermod.c +--- shadow-4.8/src/usermod.c.audit-update 2020-01-13 10:15:51.800073412 +0100 ++++ shadow-4.8/src/usermod.c 2020-01-13 10:15:51.812073210 +0100 +@@ -457,8 +457,8 @@ static char *new_pw_passwd (char *pw_pas #ifdef WITH_AUDIT audit_logger (AUDIT_USER_CHAUTHTOK, Prog, @@ -2051,7 +2051,7 @@ diff -up shadow-4.6/src/usermod.c.audit-update shadow-4.6/src/usermod.c #endif SYSLOG ((LOG_INFO, "lock user '%s' password", user_newname)); strcpy (buf, "!"); -@@ -473,8 +473,8 @@ static char *new_pw_passwd (char *pw_pas +@@ -477,8 +477,8 @@ static char *new_pw_passwd (char *pw_pas #ifdef WITH_AUDIT audit_logger (AUDIT_USER_CHAUTHTOK, Prog, @@ -2062,7 +2062,7 @@ diff -up shadow-4.6/src/usermod.c.audit-update shadow-4.6/src/usermod.c #endif SYSLOG ((LOG_INFO, "unlock user '%s' password", user_newname)); s = pw_pass; -@@ -485,7 +485,7 @@ static char *new_pw_passwd (char *pw_pas +@@ -489,7 +489,7 @@ static char *new_pw_passwd (char *pw_pas } else if (pflg) { #ifdef WITH_AUDIT audit_logger (AUDIT_USER_CHAUTHTOK, Prog, @@ -2071,7 +2071,7 @@ diff -up shadow-4.6/src/usermod.c.audit-update shadow-4.6/src/usermod.c user_newname, (unsigned int) user_newid, 1); #endif SYSLOG ((LOG_INFO, "change user '%s' password", user_newname)); -@@ -514,8 +514,8 @@ static void new_pwent (struct passwd *pw +@@ -518,8 +518,8 @@ static void new_pwent (struct passwd *pw fail_exit (E_NAME_IN_USE); } #ifdef WITH_AUDIT @@ -2082,7 +2082,7 @@ diff -up shadow-4.6/src/usermod.c.audit-update shadow-4.6/src/usermod.c user_newname, (unsigned int) user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -535,8 +535,8 @@ static void new_pwent (struct passwd *pw +@@ -539,8 +539,8 @@ static void new_pwent (struct passwd *pw if (uflg) { #ifdef WITH_AUDIT @@ -2093,7 +2093,7 @@ diff -up shadow-4.6/src/usermod.c.audit-update shadow-4.6/src/usermod.c user_newname, (unsigned int) user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -546,8 +546,8 @@ static void new_pwent (struct passwd *pw +@@ -550,8 +550,8 @@ static void new_pwent (struct passwd *pw } if (gflg) { #ifdef WITH_AUDIT @@ -2104,7 +2104,7 @@ diff -up shadow-4.6/src/usermod.c.audit-update shadow-4.6/src/usermod.c user_newname, (unsigned int) user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -557,8 +557,8 @@ static void new_pwent (struct passwd *pw +@@ -561,8 +561,8 @@ static void new_pwent (struct passwd *pw } if (cflg) { #ifdef WITH_AUDIT @@ -2115,7 +2115,7 @@ diff -up shadow-4.6/src/usermod.c.audit-update shadow-4.6/src/usermod.c user_newname, (unsigned int) user_newid, 1); #endif pwent->pw_gecos = user_newcomment; -@@ -566,8 +566,8 @@ static void new_pwent (struct passwd *pw +@@ -570,8 +570,8 @@ static void new_pwent (struct passwd *pw if (dflg) { #ifdef WITH_AUDIT @@ -2126,7 +2126,7 @@ diff -up shadow-4.6/src/usermod.c.audit-update shadow-4.6/src/usermod.c user_newname, (unsigned int) user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -577,8 +577,8 @@ static void new_pwent (struct passwd *pw +@@ -581,8 +581,8 @@ static void new_pwent (struct passwd *pw } if (sflg) { #ifdef WITH_AUDIT @@ -2137,7 +2137,7 @@ diff -up shadow-4.6/src/usermod.c.audit-update shadow-4.6/src/usermod.c user_newname, (unsigned int) user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -608,8 +608,8 @@ static void new_spent (struct spwd *spen +@@ -612,8 +612,8 @@ static void new_spent (struct spwd *spen if (fflg) { #ifdef WITH_AUDIT @@ -2148,7 +2148,7 @@ diff -up shadow-4.6/src/usermod.c.audit-update shadow-4.6/src/usermod.c user_newname, (unsigned int) user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -625,8 +625,8 @@ static void new_spent (struct spwd *spen +@@ -629,8 +629,8 @@ static void new_spent (struct spwd *spen date_to_str (old_exp, sizeof(old_exp), user_expire * DAY); #ifdef WITH_AUDIT @@ -2159,7 +2159,7 @@ diff -up shadow-4.6/src/usermod.c.audit-update shadow-4.6/src/usermod.c user_newname, (unsigned int) user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -709,9 +709,9 @@ static /*@noreturn@*/void fail_exit (int +@@ -713,9 +713,9 @@ static /*@noreturn@*/void fail_exit (int #endif /* ENABLE_SUBIDS */ #ifdef WITH_AUDIT @@ -2172,7 +2172,7 @@ diff -up shadow-4.6/src/usermod.c.audit-update shadow-4.6/src/usermod.c #endif exit (code); } -@@ -765,9 +765,12 @@ static void update_group (void) +@@ -769,9 +769,12 @@ static void update_group (void) user_newname); changed = true; #ifdef WITH_AUDIT @@ -2188,7 +2188,7 @@ diff -up shadow-4.6/src/usermod.c.audit-update shadow-4.6/src/usermod.c #endif SYSLOG ((LOG_INFO, "change '%s' to '%s' in group '%s'", -@@ -781,9 +784,11 @@ static void update_group (void) +@@ -785,9 +788,11 @@ static void update_group (void) ngrp->gr_mem = del_list (ngrp->gr_mem, user_name); changed = true; #ifdef WITH_AUDIT @@ -2203,7 +2203,7 @@ diff -up shadow-4.6/src/usermod.c.audit-update shadow-4.6/src/usermod.c #endif SYSLOG ((LOG_INFO, "delete '%s' from group '%s'", -@@ -796,9 +801,11 @@ static void update_group (void) +@@ -800,9 +805,11 @@ static void update_group (void) ngrp->gr_mem = add_list (ngrp->gr_mem, user_newname); changed = true; #ifdef WITH_AUDIT @@ -2218,7 +2218,7 @@ diff -up shadow-4.6/src/usermod.c.audit-update shadow-4.6/src/usermod.c #endif SYSLOG ((LOG_INFO, "add '%s' to group '%s'", user_newname, ngrp->gr_name)); -@@ -873,9 +880,10 @@ static void update_gshadow (void) +@@ -877,9 +884,10 @@ static void update_gshadow (void) nsgrp->sg_adm = add_list (nsgrp->sg_adm, user_newname); changed = true; #ifdef WITH_AUDIT @@ -2232,7 +2232,7 @@ diff -up shadow-4.6/src/usermod.c.audit-update shadow-4.6/src/usermod.c #endif SYSLOG ((LOG_INFO, "change admin '%s' to '%s' in shadow group '%s'", -@@ -895,9 +903,10 @@ static void update_gshadow (void) +@@ -899,9 +907,10 @@ static void update_gshadow (void) user_newname); changed = true; #ifdef WITH_AUDIT @@ -2246,7 +2246,7 @@ diff -up shadow-4.6/src/usermod.c.audit-update shadow-4.6/src/usermod.c #endif SYSLOG ((LOG_INFO, "change '%s' to '%s' in shadow group '%s'", -@@ -911,9 +920,10 @@ static void update_gshadow (void) +@@ -915,9 +924,10 @@ static void update_gshadow (void) nsgrp->sg_mem = del_list (nsgrp->sg_mem, user_name); changed = true; #ifdef WITH_AUDIT @@ -2260,7 +2260,7 @@ diff -up shadow-4.6/src/usermod.c.audit-update shadow-4.6/src/usermod.c #endif SYSLOG ((LOG_INFO, "delete '%s' from shadow group '%s'", -@@ -926,9 +936,10 @@ static void update_gshadow (void) +@@ -930,9 +940,10 @@ static void update_gshadow (void) nsgrp->sg_mem = add_list (nsgrp->sg_mem, user_newname); changed = true; #ifdef WITH_AUDIT @@ -2274,7 +2274,7 @@ diff -up shadow-4.6/src/usermod.c.audit-update shadow-4.6/src/usermod.c #endif SYSLOG ((LOG_INFO, "add '%s' to shadow group '%s'", user_newname, nsgrp->sg_name)); -@@ -1789,8 +1800,8 @@ static void move_home (void) +@@ -1799,8 +1810,8 @@ static void move_home (void) #ifdef WITH_AUDIT if (uflg || gflg) { @@ -2285,7 +2285,7 @@ diff -up shadow-4.6/src/usermod.c.audit-update shadow-4.6/src/usermod.c user_newname, (unsigned int) user_newid, 1); } #endif -@@ -1808,8 +1819,8 @@ static void move_home (void) +@@ -1818,8 +1829,8 @@ static void move_home (void) fail_exit (E_HOMEDIR); } #ifdef WITH_AUDIT @@ -2296,7 +2296,7 @@ diff -up shadow-4.6/src/usermod.c.audit-update shadow-4.6/src/usermod.c user_newname, (unsigned int) user_newid, 1); #endif -@@ -1828,9 +1839,9 @@ static void move_home (void) +@@ -1847,9 +1858,9 @@ static void move_home (void) Prog, prefix_user_home); } #ifdef WITH_AUDIT @@ -2308,7 +2308,7 @@ diff -up shadow-4.6/src/usermod.c.audit-update shadow-4.6/src/usermod.c user_newname, (unsigned int) user_newid, 1); -@@ -2045,8 +2056,8 @@ static void move_mailbox (void) +@@ -2071,8 +2082,8 @@ static void move_mailbox (void) } #ifdef WITH_AUDIT else { @@ -2319,7 +2319,7 @@ diff -up shadow-4.6/src/usermod.c.audit-update shadow-4.6/src/usermod.c user_newname, (unsigned int) user_newid, 1); } #endif -@@ -2072,8 +2083,8 @@ static void move_mailbox (void) +@@ -2098,8 +2109,8 @@ static void move_mailbox (void) } #ifdef WITH_AUDIT else { @@ -2330,7 +2330,7 @@ diff -up shadow-4.6/src/usermod.c.audit-update shadow-4.6/src/usermod.c user_newname, (unsigned int) user_newid, 1); } #endif -@@ -2267,8 +2278,8 @@ int main (int argc, char **argv) +@@ -2294,8 +2305,8 @@ int main (int argc, char **argv) _("%s: warning: the user name %s to %s SELinux user mapping failed.\n"), Prog, user_name, user_selinux); #ifdef WITH_AUDIT @@ -2341,7 +2341,7 @@ diff -up shadow-4.6/src/usermod.c.audit-update shadow-4.6/src/usermod.c user_name, (unsigned int) user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -2280,8 +2291,8 @@ int main (int argc, char **argv) +@@ -2307,8 +2318,8 @@ int main (int argc, char **argv) _("%s: warning: the user name %s to SELinux user mapping removal failed.\n"), Prog, user_name); #ifdef WITH_AUDIT @@ -2352,7 +2352,7 @@ diff -up shadow-4.6/src/usermod.c.audit-update shadow-4.6/src/usermod.c user_name, (unsigned int) user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -2319,8 +2330,8 @@ int main (int argc, char **argv) +@@ -2349,8 +2360,8 @@ int main (int argc, char **argv) */ #ifdef WITH_AUDIT if (uflg || gflg) { diff --git a/shadow-4.8-crypt_h.patch b/shadow-4.8-crypt_h.patch new file mode 100644 index 0000000..e2704e8 --- /dev/null +++ b/shadow-4.8-crypt_h.patch @@ -0,0 +1,35 @@ +diff -up shadow-4.8/configure.ac.crypt_h shadow-4.8/configure.ac +--- shadow-4.8/configure.ac.crypt_h 2020-01-13 10:26:17.400481712 +0100 ++++ shadow-4.8/configure.ac 2020-01-13 10:29:11.563529093 +0100 +@@ -32,7 +32,7 @@ AC_HEADER_STDC + AC_HEADER_SYS_WAIT + AC_HEADER_STDBOOL + +-AC_CHECK_HEADERS(errno.h fcntl.h limits.h unistd.h sys/time.h utmp.h \ ++AC_CHECK_HEADERS(crypt.h errno.h fcntl.h limits.h unistd.h sys/time.h utmp.h \ + utmpx.h termios.h termio.h sgtty.h sys/ioctl.h syslog.h paths.h \ + utime.h ulimit.h sys/capability.h sys/resource.h gshadow.h lastlog.h \ + locale.h rpc/key_prot.h netdb.h acl/libacl.h attr/libattr.h \ +diff -up shadow-4.8/lib/defines.h.crypt_h shadow-4.8/lib/defines.h +--- shadow-4.8/lib/defines.h.crypt_h 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8/lib/defines.h 2020-01-13 10:26:17.400481712 +0100 +@@ -4,6 +4,8 @@ + #ifndef _DEFINES_H_ + #define _DEFINES_H_ + ++#include "config.h" ++ + #if HAVE_STDBOOL_H + # include + #else +@@ -94,6 +96,10 @@ char *strchr (), *strrchr (), *strtok () + # include + #endif + ++#if HAVE_CRYPT_H ++# include /* crypt(3) may be defined in here */ ++#endif ++ + #if TIME_WITH_SYS_TIME + # include + # include diff --git a/shadow-4.5-goodname.patch b/shadow-4.8-goodname.patch similarity index 79% rename from shadow-4.5-goodname.patch rename to shadow-4.8-goodname.patch index b107e3f..f3c18d5 100644 --- a/shadow-4.5-goodname.patch +++ b/shadow-4.8-goodname.patch @@ -1,18 +1,12 @@ -Index: shadow-4.5/libmisc/chkname.c -=================================================================== ---- shadow-4.5.orig/libmisc/chkname.c -+++ shadow-4.5/libmisc/chkname.c -@@ -47,27 +47,46 @@ - #include "chkname.h" +diff -up shadow-4.8/libmisc/chkname.c.goodname shadow-4.8/libmisc/chkname.c +--- shadow-4.8/libmisc/chkname.c.goodname 2020-01-13 09:44:41.968507996 +0100 ++++ shadow-4.8/libmisc/chkname.c 2020-01-13 09:46:27.863727732 +0100 +@@ -55,26 +55,44 @@ static bool is_valid_name (const char *n + } - static bool is_valid_name (const char *name) --{ -+{ /* - * User/group names must match [a-z_][a-z0-9_-]*[$] - */ -- if (('\0' == *name) || -- !((('a' <= *name) && ('z' >= *name)) || ('_' == *name))) { + * User/group names must match gnu e-regex: + * [a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,30}[a-zA-Z0-9_.$-]? + * @@ -22,7 +16,9 @@ Index: shadow-4.5/libmisc/chkname.c + * Also do not allow fully numeric names or just "." or "..". + */ + int numeric; -+ + +- if (('\0' == *name) || +- !((('a' <= *name) && ('z' >= *name)) || ('_' == *name))) { + if ('\0' == *name || + ('.' == *name && (('.' == name[1] && '\0' == name[2]) || + '\0' == name[1])) || @@ -60,11 +56,10 @@ Index: shadow-4.5/libmisc/chkname.c } bool is_valid_user_name (const char *name) -Index: shadow-4.5/man/groupadd.8.xml -=================================================================== ---- shadow-4.5.orig/man/groupadd.8.xml -+++ shadow-4.5/man/groupadd.8.xml -@@ -256,10 +256,12 @@ +diff -up shadow-4.8/man/groupadd.8.xml.goodname shadow-4.8/man/groupadd.8.xml +--- shadow-4.8/man/groupadd.8.xml.goodname 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8/man/groupadd.8.xml 2020-01-13 09:44:41.968507996 +0100 +@@ -273,10 +273,12 @@ CAVEATS @@ -81,11 +76,10 @@ Index: shadow-4.5/man/groupadd.8.xml Groupnames may only be up to &GROUP_NAME_MAX_LENGTH; characters long. -Index: shadow-4.5/man/useradd.8.xml -=================================================================== ---- shadow-4.5.orig/man/useradd.8.xml -+++ shadow-4.5/man/useradd.8.xml -@@ -633,10 +633,14 @@ +diff -up shadow-4.8/man/useradd.8.xml.goodname shadow-4.8/man/useradd.8.xml +--- shadow-4.8/man/useradd.8.xml.goodname 2019-10-05 03:23:58.000000000 +0200 ++++ shadow-4.8/man/useradd.8.xml 2020-01-13 09:44:41.968507996 +0100 +@@ -661,10 +661,14 @@ diff --git a/shadow-4.8-ignore-login-prompt.patch b/shadow-4.8-ignore-login-prompt.patch new file mode 100644 index 0000000..c93aae7 --- /dev/null +++ b/shadow-4.8-ignore-login-prompt.patch @@ -0,0 +1,11 @@ +diff -up shadow-4.8/lib/getdef.c.login-prompt shadow-4.8/lib/getdef.c +--- shadow-4.8/lib/getdef.c.login-prompt 2020-01-13 10:38:44.852796681 +0100 ++++ shadow-4.8/lib/getdef.c 2020-01-13 10:39:54.472612511 +0100 +@@ -98,6 +98,7 @@ static struct itemdef def_table[] = { + {"LASTLOG_UID_MAX", NULL}, + {"LOGIN_RETRIES", NULL}, + {"LOGIN_TIMEOUT", NULL}, ++ {"LOGIN_PLAIN_PROMPT", NULL}, + {"LOG_OK_LOGINS", NULL}, + {"LOG_UNKFAIL_ENAB", NULL}, + {"MAIL_DIR", NULL}, diff --git a/shadow-4.5-long-entry.patch b/shadow-4.8-long-entry.patch similarity index 64% rename from shadow-4.5-long-entry.patch rename to shadow-4.8-long-entry.patch index 8670e75..64d9636 100644 --- a/shadow-4.5-long-entry.patch +++ b/shadow-4.8-long-entry.patch @@ -1,17 +1,19 @@ -diff -up shadow-4.5/lib/defines.h.long-entry shadow-4.5/lib/defines.h ---- shadow-4.5/lib/defines.h.long-entry 2014-09-01 16:36:40.000000000 +0200 -+++ shadow-4.5/lib/defines.h 2018-04-20 11:53:07.419308212 +0200 -@@ -382,4 +382,7 @@ extern char *strerror (); +diff -up shadow-4.8/lib/defines.h.long-entry shadow-4.8/lib/defines.h +--- shadow-4.8/lib/defines.h.long-entry 2020-01-13 10:29:45.288957339 +0100 ++++ shadow-4.8/lib/defines.h 2020-01-13 10:30:47.482902954 +0100 +@@ -388,6 +388,9 @@ extern char *strerror (); # endif #endif +/* Maximum length of passwd entry */ +#define PASSWD_ENTRY_MAX_LENGTH 32768 + - #endif /* _DEFINES_H_ */ -diff -up shadow-4.5/lib/pwio.c.long-entry shadow-4.5/lib/pwio.c ---- shadow-4.5/lib/pwio.c.long-entry 2015-11-17 17:45:15.000000000 +0100 -+++ shadow-4.5/lib/pwio.c 2018-04-20 12:10:24.400837235 +0200 + #ifdef HAVE_SECURE_GETENV + # define shadow_getenv(name) secure_getenv(name) + # else +diff -up shadow-4.8/lib/pwio.c.long-entry shadow-4.8/lib/pwio.c +--- shadow-4.8/lib/pwio.c.long-entry 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8/lib/pwio.c 2020-01-13 10:29:45.288957339 +0100 @@ -79,7 +79,10 @@ static int passwd_put (const void *ent, || (pw->pw_gid == (gid_t)-1) || (valid_field (pw->pw_gecos, ":\n") == -1) @@ -24,9 +26,9 @@ diff -up shadow-4.5/lib/pwio.c.long-entry shadow-4.5/lib/pwio.c return -1; } -diff -up shadow-4.5/lib/sgetpwent.c.long-entry shadow-4.5/lib/sgetpwent.c ---- shadow-4.5/lib/sgetpwent.c.long-entry 2014-09-01 16:36:40.000000000 +0200 -+++ shadow-4.5/lib/sgetpwent.c 2018-04-20 12:16:31.911513808 +0200 +diff -up shadow-4.8/lib/sgetpwent.c.long-entry shadow-4.8/lib/sgetpwent.c +--- shadow-4.8/lib/sgetpwent.c.long-entry 2019-10-05 03:23:58.000000000 +0200 ++++ shadow-4.8/lib/sgetpwent.c 2020-01-13 10:29:45.288957339 +0100 @@ -57,7 +57,7 @@ struct passwd *sgetpwent (const char *buf) { @@ -48,9 +50,9 @@ diff -up shadow-4.5/lib/sgetpwent.c.long-entry shadow-4.5/lib/sgetpwent.c strcpy (pwdbuf, buf); /* -diff -up shadow-4.5/lib/sgetspent.c.long-entry shadow-4.5/lib/sgetspent.c ---- shadow-4.5/lib/sgetspent.c.long-entry 2014-09-01 16:36:40.000000000 +0200 -+++ shadow-4.5/lib/sgetspent.c 2018-04-20 12:16:54.505056257 +0200 +diff -up shadow-4.8/lib/sgetspent.c.long-entry shadow-4.8/lib/sgetspent.c +--- shadow-4.8/lib/sgetspent.c.long-entry 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8/lib/sgetspent.c 2020-01-13 10:29:45.289957322 +0100 @@ -48,7 +48,7 @@ */ struct spwd *sgetspent (const char *string) @@ -68,9 +70,9 @@ diff -up shadow-4.5/lib/sgetspent.c.long-entry shadow-4.5/lib/sgetspent.c return 0; /* fail if too long */ } strcpy (spwbuf, string); -diff -up shadow-4.5/lib/shadowio.c.long-entry shadow-4.5/lib/shadowio.c ---- shadow-4.5/lib/shadowio.c.long-entry 2016-12-07 06:30:41.000000001 +0100 -+++ shadow-4.5/lib/shadowio.c 2018-04-20 12:12:03.292171667 +0200 +diff -up shadow-4.8/lib/shadowio.c.long-entry shadow-4.8/lib/shadowio.c +--- shadow-4.8/lib/shadowio.c.long-entry 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8/lib/shadowio.c 2020-01-13 10:29:45.289957322 +0100 @@ -79,7 +79,9 @@ static int shadow_put (const void *ent, if ( (NULL == sp) diff --git a/shadow-4.3.1-manfix.patch b/shadow-4.8-manfix.patch similarity index 74% rename from shadow-4.3.1-manfix.patch rename to shadow-4.8-manfix.patch index bd1577e..ecb99a4 100644 --- a/shadow-4.3.1-manfix.patch +++ b/shadow-4.8-manfix.patch @@ -1,35 +1,6 @@ -Index: shadow-4.5/man/groupmems.8.xml -=================================================================== ---- shadow-4.5.orig/man/groupmems.8.xml -+++ shadow-4.5/man/groupmems.8.xml -@@ -179,20 +179,10 @@ - - SETUP - -- The groupmems executable should be in mode -- 2770 as user root and in group -- groups. The system administrator can add users to -- group groups to allow or disallow them using the -- groupmems utility to manage their own group -- membership list. -+ In this operating system the groupmems executable -+ is not setuid and regular users cannot use it to manipulate -+ the membership of their own group. - -- -- -- $ groupadd -r groups -- $ chmod 2770 groupmems -- $ chown root.groups groupmems -- $ groupmems -g groups -a gk4 -- - - - -Index: shadow-4.5/man/chage.1.xml -=================================================================== ---- shadow-4.5.orig/man/chage.1.xml -+++ shadow-4.5/man/chage.1.xml +diff -up shadow-4.8/man/chage.1.xml.manfix shadow-4.8/man/chage.1.xml +--- shadow-4.8/man/chage.1.xml.manfix 2019-10-05 01:28:34.000000000 +0200 ++++ shadow-4.8/man/chage.1.xml 2020-01-13 10:12:48.445155882 +0100 @@ -102,6 +102,9 @@ Set the number of days since January 1st, 1970 when the password was last changed. The date may also be expressed in the format @@ -54,7 +25,7 @@ Index: shadow-4.5/man/chage.1.xml Passing the number -1 as the EXPIRE_DATE will remove an account expiration date. -@@ -233,6 +243,18 @@ +@@ -239,6 +249,18 @@ The chage program requires a shadow password file to be available. @@ -73,11 +44,56 @@ Index: shadow-4.5/man/chage.1.xml The chage command is restricted to the root user, except for the option, which may be used by an unprivileged user to determine when their password or account is due -Index: shadow-4.5/man/ja/man5/login.defs.5 -=================================================================== ---- shadow-4.5.orig/man/ja/man5/login.defs.5 -+++ shadow-4.5/man/ja/man5/login.defs.5 -@@ -147,10 +147,6 @@ PASS_MAX_DAYS, PASS_MIN_DAYS, PASS_WARN_ +diff -up shadow-4.8/man/groupadd.8.xml.manfix shadow-4.8/man/groupadd.8.xml +--- shadow-4.8/man/groupadd.8.xml.manfix 2020-01-13 10:12:48.432156100 +0100 ++++ shadow-4.8/man/groupadd.8.xml 2020-01-13 10:13:06.096859122 +0100 +@@ -320,13 +320,13 @@ + + 4 + +- GID not unique (when not used) ++ GID is already used (when called without ) + + + + 9 + +- group name not unique ++ group name is already used + + + +diff -up shadow-4.8/man/groupmems.8.xml.manfix shadow-4.8/man/groupmems.8.xml +--- shadow-4.8/man/groupmems.8.xml.manfix 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8/man/groupmems.8.xml 2020-01-13 10:12:48.445155882 +0100 +@@ -179,20 +179,10 @@ + + SETUP + +- The groupmems executable should be in mode +- 2770 as user root and in group +- groups. The system administrator can add users to +- group groups to allow or disallow them using the +- groupmems utility to manage their own group +- membership list. ++ In this operating system the groupmems executable ++ is not setuid and regular users cannot use it to manipulate ++ the membership of their own group. + +- +- +- $ groupadd -r groups +- $ chmod 2770 groupmems +- $ chown root.groups groupmems +- $ groupmems -g groups -a gk4 +- + + + +diff -up shadow-4.8/man/ja/man5/login.defs.5.manfix shadow-4.8/man/ja/man5/login.defs.5 +--- shadow-4.8/man/ja/man5/login.defs.5.manfix 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8/man/ja/man5/login.defs.5 2020-01-13 10:12:48.445155882 +0100 +@@ -147,10 +147,6 @@ 以下の参照表は、 shadow パスワード機能のどのプログラムが どのパラメータを使用するかを示したものである。 .na @@ -88,11 +104,10 @@ Index: shadow-4.5/man/ja/man5/login.defs.5 .IP groupadd 12 GID_MAX GID_MIN .IP newusers 12 -Index: shadow-4.5/man/login.defs.5.xml -=================================================================== ---- shadow-4.5.orig/man/login.defs.5.xml -+++ shadow-4.5/man/login.defs.5.xml -@@ -162,6 +162,17 @@ +diff -up shadow-4.8/man/login.defs.5.xml.manfix shadow-4.8/man/login.defs.5.xml +--- shadow-4.8/man/login.defs.5.xml.manfix 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8/man/login.defs.5.xml 2020-01-13 10:14:10.491776547 +0100 +@@ -163,6 +163,17 @@ long numeric parameters is machine-dependent. @@ -110,7 +125,7 @@ Index: shadow-4.5/man/login.defs.5.xml The following configuration items are provided: -@@ -252,16 +263,6 @@ +@@ -254,16 +265,6 @@ @@ -127,7 +142,7 @@ Index: shadow-4.5/man/login.defs.5.xml chgpasswd -@@ -282,14 +283,6 @@ +@@ -284,14 +285,6 @@ @@ -142,10 +157,10 @@ Index: shadow-4.5/man/login.defs.5.xml -@@ -350,34 +343,6 @@ +@@ -357,34 +350,6 @@ + LASTLOG_UID_MAX + - - - - login - @@ -161,7 +176,7 @@ Index: shadow-4.5/man/login.defs.5.xml - HUSHLOGIN_FILE - ISSUE_FILE - KILLCHAR -- LASTLOG_ENAB +- LASTLOG_ENAB LASTLOG_UID_MAX - LOGIN_RETRIES - LOGIN_STRING - LOGIN_TIMEOUT LOG_OK_LOGINS LOG_UNKFAIL_ENAB @@ -177,7 +192,7 @@ Index: shadow-4.5/man/login.defs.5.xml newgrp / sg -@@ -405,17 +370,6 @@ +@@ -412,17 +377,6 @@ @@ -195,7 +210,7 @@ Index: shadow-4.5/man/login.defs.5.xml pwck -@@ -442,32 +396,6 @@ +@@ -449,32 +403,6 @@ @@ -228,10 +243,9 @@ Index: shadow-4.5/man/login.defs.5.xml useradd -Index: shadow-4.5/man/shadow.5.xml -=================================================================== ---- shadow-4.5.orig/man/shadow.5.xml -+++ shadow-4.5/man/shadow.5.xml +diff -up shadow-4.8/man/shadow.5.xml.manfix shadow-4.8/man/shadow.5.xml +--- shadow-4.8/man/shadow.5.xml.manfix 2019-12-01 17:52:32.000000000 +0100 ++++ shadow-4.8/man/shadow.5.xml 2020-01-13 10:12:48.446155865 +0100 @@ -129,7 +129,7 @@ @@ -261,11 +275,10 @@ Index: shadow-4.5/man/shadow.5.xml Note that an account expiration differs from a password -Index: shadow-4.5/man/useradd.8.xml -=================================================================== ---- shadow-4.5.orig/man/useradd.8.xml -+++ shadow-4.5/man/useradd.8.xml -@@ -347,6 +347,11 @@ +diff -up shadow-4.8/man/useradd.8.xml.manfix shadow-4.8/man/useradd.8.xml +--- shadow-4.8/man/useradd.8.xml.manfix 2020-01-13 10:12:48.432156100 +0100 ++++ shadow-4.8/man/useradd.8.xml 2020-01-13 10:12:48.446155865 +0100 +@@ -358,6 +358,11 @@ is not enabled, no home directories are created. @@ -277,11 +290,10 @@ Index: shadow-4.5/man/useradd.8.xml -Index: shadow-4.5/man/usermod.8.xml -=================================================================== ---- shadow-4.5.orig/man/usermod.8.xml -+++ shadow-4.5/man/usermod.8.xml -@@ -132,7 +132,8 @@ +diff -up shadow-4.8/man/usermod.8.xml.manfix shadow-4.8/man/usermod.8.xml +--- shadow-4.8/man/usermod.8.xml.manfix 2019-10-05 03:23:58.000000000 +0200 ++++ shadow-4.8/man/usermod.8.xml 2020-01-13 10:12:48.446155865 +0100 +@@ -153,7 +153,8 @@ If the option is given, the contents of the current home directory will be moved to the new home directory, which is created if it does @@ -291,7 +303,20 @@ Index: shadow-4.5/man/usermod.8.xml -@@ -256,7 +257,8 @@ +@@ -215,6 +216,12 @@ + The group ownership of files outside of the user's home directory + must be fixed manually. + ++ ++ The change of the group ownership of files inside of the user's ++ home directory is also not done if the home dir owner uid is ++ different from the current or new user id. This is safety measure ++ for special home directories such as /. ++ + + + +@@ -277,7 +284,8 @@ Move the content of the user's home directory to the new @@ -301,49 +326,16 @@ Index: shadow-4.5/man/usermod.8.xml This option is only valid in combination with the -diff --git a/man/login.defs.d/SUB_GID_COUNT.xml b/man/login.defs.d/SUB_GID_COUNT.xml -index 01ace007..93fe7421 100644 ---- a/man/login.defs.d/SUB_GID_COUNT.xml -+++ b/man/login.defs.d/SUB_GID_COUNT.xml -@@ -42,7 +42,7 @@ - - The default values for , - , -- are respectively 100000, 600100000 and 10000. -+ are respectively 100000, 600100000 and 65536. - - - -diff --git a/man/login.defs.d/SUB_UID_COUNT.xml b/man/login.defs.d/SUB_UID_COUNT.xml -index 5ad812f7..516417b7 100644 ---- a/man/login.defs.d/SUB_UID_COUNT.xml -+++ b/man/login.defs.d/SUB_UID_COUNT.xml -@@ -42,7 +42,7 @@ - - The default values for , - , -- are respectively 100000, 600100000 and 10000. -+ are respectively 100000, 600100000 and 65536. - - - -diff -up shadow-4.6/man/groupadd.8.xml.manfix shadow-4.6/man/groupadd.8.xml ---- shadow-4.6/man/groupadd.8.xml.manfix 2019-04-02 16:35:52.096637444 +0200 -+++ shadow-4.6/man/groupadd.8.xml 2019-06-07 14:23:57.477602106 +0200 -@@ -320,13 +320,13 @@ - - 4 - -- GID not unique (when not used) -+ GID is already used (when called without ) - - - - 9 - -- group name not unique -+ group name is already used - - - - +@@ -391,6 +399,12 @@ + must be fixed manually. + + ++ The change of the user ownership of files inside of the user's ++ home directory is also not done if the home dir owner uid is ++ different from the current or new user id. This is safety measure ++ for special home directories such as /. ++ ++ + No checks will be performed with regard to the + , , + , or diff --git a/shadow-4.3.1-selinux-perms.patch b/shadow-4.8-selinux-perms.patch similarity index 65% rename from shadow-4.3.1-selinux-perms.patch rename to shadow-4.8-selinux-perms.patch index a08660f..dfb32ec 100644 --- a/shadow-4.3.1-selinux-perms.patch +++ b/shadow-4.8-selinux-perms.patch @@ -1,7 +1,6 @@ -Index: shadow-4.5/src/chgpasswd.c -=================================================================== ---- shadow-4.5.orig/src/chgpasswd.c -+++ shadow-4.5/src/chgpasswd.c +diff -up shadow-4.8/src/chgpasswd.c.selinux-perms shadow-4.8/src/chgpasswd.c +--- shadow-4.8/src/chgpasswd.c.selinux-perms 2019-12-01 18:02:43.000000000 +0100 ++++ shadow-4.8/src/chgpasswd.c 2020-01-13 10:21:44.558107260 +0100 @@ -39,6 +39,13 @@ #include #include @@ -16,7 +15,7 @@ Index: shadow-4.5/src/chgpasswd.c #ifdef ACCT_TOOLS_SETUID #ifdef USE_PAM #include "pam_defs.h" -@@ -76,6 +83,9 @@ static bool sgr_locked = false; +@@ -80,6 +87,9 @@ static bool sgr_locked = false; #endif static bool gr_locked = false; @@ -26,7 +25,7 @@ Index: shadow-4.5/src/chgpasswd.c /* local function prototypes */ static void fail_exit (int code); static /*@noreturn@*/void usage (int status); -@@ -300,6 +310,63 @@ static void check_perms (void) +@@ -334,6 +344,63 @@ static void check_perms (void) #endif /* ACCT_TOOLS_SETUID */ } @@ -90,7 +89,7 @@ Index: shadow-4.5/src/chgpasswd.c /* * open_files - lock and open the group databases */ -@@ -393,6 +460,7 @@ int main (int argc, char **argv) +@@ -427,6 +494,7 @@ int main (int argc, char **argv) const struct group *gr; struct group newgr; @@ -98,7 +97,7 @@ Index: shadow-4.5/src/chgpasswd.c int errors = 0; int line = 0; -@@ -402,12 +470,37 @@ int main (int argc, char **argv) +@@ -436,12 +504,37 @@ int main (int argc, char **argv) (void) bindtextdomain (PACKAGE, LOCALEDIR); (void) textdomain (PACKAGE); @@ -136,28 +135,9 @@ Index: shadow-4.5/src/chgpasswd.c check_perms (); #ifdef SHADOWGRP - is_shadow_grp = sgr_file_present (); - #endif -@@ -536,6 +629,15 @@ int main (int argc, char **argv) - newgr.gr_passwd = cp; - } - -+#ifdef WITH_AUDIT -+ { -+ -+ audit_logger_with_group (AUDIT_GRP_CHAUTHTOK, Prog, -+ "change-password", -+ myname, AUDIT_NO_ID, gr->gr_name, -+ SHADOW_AUDIT_SUCCESS); -+ } -+#endif - /* - * The updated group file entry is then put back and will - * be written to the group file later, after all the -Index: shadow-4.5/src/chpasswd.c -=================================================================== ---- shadow-4.5.orig/src/chpasswd.c -+++ shadow-4.5/src/chpasswd.c +diff -up shadow-4.8/src/chpasswd.c.selinux-perms shadow-4.8/src/chpasswd.c +--- shadow-4.8/src/chpasswd.c.selinux-perms 2019-12-01 18:02:43.000000000 +0100 ++++ shadow-4.8/src/chpasswd.c 2020-01-13 10:21:44.558107260 +0100 @@ -39,6 +39,13 @@ #include #include @@ -172,7 +152,7 @@ Index: shadow-4.5/src/chpasswd.c #ifdef USE_PAM #include "pam_defs.h" #endif /* USE_PAM */ -@@ -297,6 +304,63 @@ static void check_perms (void) +@@ -332,6 +339,63 @@ static void check_perms (void) #endif /* USE_PAM */ } @@ -236,7 +216,7 @@ Index: shadow-4.5/src/chpasswd.c /* * open_files - lock and open the password databases */ -@@ -393,6 +457,10 @@ int main (int argc, char **argv) +@@ -428,6 +492,10 @@ int main (int argc, char **argv) (void) bindtextdomain (PACKAGE, LOCALEDIR); (void) textdomain (PACKAGE); @@ -247,7 +227,7 @@ Index: shadow-4.5/src/chpasswd.c process_root_flag ("-R", argc, argv); process_flags (argc, argv); -@@ -405,6 +473,10 @@ int main (int argc, char **argv) +@@ -440,6 +508,10 @@ int main (int argc, char **argv) OPENLOG ("chpasswd"); @@ -258,33 +238,3 @@ Index: shadow-4.5/src/chpasswd.c check_perms (); #ifdef USE_PAM - if (!use_pam) - #endif /* USE_PAM */ -@@ -566,6 +638,11 @@ int main (int argc, char **argv) - newpw.pw_passwd = cp; - } - -+#ifdef WITH_AUDIT -+ audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -+ "updating-password", -+ pw->pw_name, (unsigned int) pw->pw_uid, 1); -+#endif - /* - * The updated password file entry is then put back and will - * be written to the password file later, after all the -Index: shadow-4.5/src/Makefile.am -=================================================================== ---- shadow-4.5.orig/src/Makefile.am -+++ shadow-4.5/src/Makefile.am -@@ -87,9 +87,9 @@ chage_LDADD = $(LDADD) $(LIBPAM_SUID) - newuidmap_LDADD = $(LDADD) $(LIBSELINUX) - newgidmap_LDADD = $(LDADD) $(LIBSELINUX) - chfn_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) --chgpasswd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBSELINUX) $(LIBCRYPT) -+chgpasswd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBSELINUX) $(LIBAUDIT) $(LIBCRYPT) - chsh_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) --chpasswd_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBCRYPT) -+chpasswd_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBAUDIT) $(LIBCRYPT) - gpasswd_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) - groupadd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) - groupdel_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) diff --git a/shadow-4.8-selinux.patch b/shadow-4.8-selinux.patch new file mode 100644 index 0000000..7b2177b --- /dev/null +++ b/shadow-4.8-selinux.patch @@ -0,0 +1,241 @@ +diff -up shadow-4.8/lib/commonio.c.selinux shadow-4.8/lib/commonio.c +--- shadow-4.8/lib/commonio.c.selinux 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8/lib/commonio.c 2020-01-13 10:08:53.769101131 +0100 +@@ -964,7 +964,7 @@ int commonio_close (struct commonio_db * + snprintf (buf, sizeof buf, "%s-", db->filename); + + #ifdef WITH_SELINUX +- if (set_selinux_file_context (buf) != 0) { ++ if (set_selinux_file_context (buf, db->filename) != 0) { + errors++; + } + #endif +@@ -997,7 +997,7 @@ int commonio_close (struct commonio_db * + snprintf (buf, sizeof buf, "%s+", db->filename); + + #ifdef WITH_SELINUX +- if (set_selinux_file_context (buf) != 0) { ++ if (set_selinux_file_context (buf, db->filename) != 0) { + errors++; + } + #endif +diff -up shadow-4.8/libmisc/copydir.c.selinux shadow-4.8/libmisc/copydir.c +--- shadow-4.8/libmisc/copydir.c.selinux 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8/libmisc/copydir.c 2020-01-13 10:08:53.769101131 +0100 +@@ -484,7 +484,7 @@ static int copy_dir (const char *src, co + */ + + #ifdef WITH_SELINUX +- if (set_selinux_file_context (dst) != 0) { ++ if (set_selinux_file_context (dst, NULL) != 0) { + return -1; + } + #endif /* WITH_SELINUX */ +@@ -605,7 +605,7 @@ static int copy_symlink (const char *src + } + + #ifdef WITH_SELINUX +- if (set_selinux_file_context (dst) != 0) { ++ if (set_selinux_file_context (dst, NULL) != 0) { + free (oldlink); + return -1; + } +@@ -684,7 +684,7 @@ static int copy_special (const char *src + int err = 0; + + #ifdef WITH_SELINUX +- if (set_selinux_file_context (dst) != 0) { ++ if (set_selinux_file_context (dst, NULL) != 0) { + return -1; + } + #endif /* WITH_SELINUX */ +@@ -744,7 +744,7 @@ static int copy_file (const char *src, c + return -1; + } + #ifdef WITH_SELINUX +- if (set_selinux_file_context (dst) != 0) { ++ if (set_selinux_file_context (dst, NULL) != 0) { + return -1; + } + #endif /* WITH_SELINUX */ +diff -up shadow-4.8/lib/prototypes.h.selinux shadow-4.8/lib/prototypes.h +--- shadow-4.8/lib/prototypes.h.selinux 2020-01-13 10:08:53.769101131 +0100 ++++ shadow-4.8/lib/prototypes.h 2020-01-13 10:11:20.914627399 +0100 +@@ -334,7 +334,7 @@ extern /*@observer@*/const char *crypt_m + + /* selinux.c */ + #ifdef WITH_SELINUX +-extern int set_selinux_file_context (const char *dst_name); ++extern int set_selinux_file_context (const char *dst_name, const char *orig_name); + extern int reset_selinux_file_context (void); + extern int check_selinux_permit (const char *perm_name); + #endif +diff -up shadow-4.8/lib/selinux.c.selinux shadow-4.8/lib/selinux.c +--- shadow-4.8/lib/selinux.c.selinux 2019-11-12 01:18:25.000000000 +0100 ++++ shadow-4.8/lib/selinux.c 2020-01-13 10:08:53.769101131 +0100 +@@ -51,7 +51,7 @@ static bool selinux_enabled; + * Callers may have to Reset SELinux to create files with default + * contexts with reset_selinux_file_context + */ +-int set_selinux_file_context (const char *dst_name) ++int set_selinux_file_context (const char *dst_name, const char *orig_name) + { + /*@null@*/security_context_t scontext = NULL; + +@@ -63,19 +63,23 @@ int set_selinux_file_context (const char + if (selinux_enabled) { + /* Get the default security context for this file */ + if (matchpathcon (dst_name, 0, &scontext) < 0) { +- if (security_getenforce () != 0) { +- return 1; +- } ++ /* We could not get the default, copy the original */ ++ if (orig_name == NULL) ++ goto error; ++ if (getfilecon (orig_name, &scontext) < 0) ++ goto error; + } + /* Set the security context for the next created file */ +- if (setfscreatecon (scontext) < 0) { +- if (security_getenforce () != 0) { +- return 1; +- } +- } ++ if (setfscreatecon (scontext) < 0) ++ goto error; + freecon (scontext); + } + return 0; ++ error: ++ if (security_getenforce () != 0) { ++ return 1; ++ } ++ return 0; + } + + /* +diff -up shadow-4.8/lib/semanage.c.selinux shadow-4.8/lib/semanage.c +--- shadow-4.8/lib/semanage.c.selinux 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8/lib/semanage.c 2020-01-13 10:08:53.766101181 +0100 +@@ -294,6 +294,9 @@ int set_seuser (const char *login_name, + + ret = 0; + ++ /* drop obsolete matchpathcon cache */ ++ matchpathcon_fini(); ++ + done: + semanage_seuser_key_free (key); + semanage_handle_destroy (handle); +@@ -369,6 +372,10 @@ int del_seuser (const char *login_name) + } + + ret = 0; ++ ++ /* drop obsolete matchpathcon cache */ ++ matchpathcon_fini(); ++ + done: + semanage_handle_destroy (handle); + return ret; +diff -up shadow-4.8/src/useradd.c.selinux shadow-4.8/src/useradd.c +--- shadow-4.8/src/useradd.c.selinux 2020-01-13 10:08:53.762101248 +0100 ++++ shadow-4.8/src/useradd.c 2020-01-13 10:08:53.767101164 +0100 +@@ -2078,7 +2078,7 @@ static void create_home (void) + ++bhome; + + #ifdef WITH_SELINUX +- if (set_selinux_file_context (prefix_user_home) != 0) { ++ if (set_selinux_file_context (prefix_user_home, NULL) != 0) { + fprintf (stderr, + _("%s: cannot set SELinux context for home directory %s\n"), + Prog, user_home); +@@ -2232,6 +2232,7 @@ static void create_mail (void) + */ + int main (int argc, char **argv) + { ++ int rv = E_SUCCESS; + #ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + pam_handle_t *pamh = NULL; +@@ -2454,27 +2455,12 @@ int main (int argc, char **argv) + + usr_update (); + +- if (mflg) { +- create_home (); +- if (home_added) { +- copy_tree (def_template, prefix_user_home, false, false, +- (uid_t)-1, user_id, (gid_t)-1, user_gid); +- } else { +- fprintf (stderr, +- _("%s: warning: the home directory %s already exists.\n" +- "%s: Not copying any file from skel directory into it.\n"), +- Prog, user_home, Prog); +- } +- +- } +- +- /* Do not create mail directory for system accounts */ +- if (!rflg) { +- create_mail (); +- } +- + close_files (); + ++ nscd_flush_cache ("passwd"); ++ nscd_flush_cache ("group"); ++ sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP); ++ + /* + * tallylog_reset needs to be able to lookup + * a valid existing user name, +@@ -2485,8 +2471,9 @@ int main (int argc, char **argv) + } + + #ifdef WITH_SELINUX +- if (Zflg) { +- if (set_seuser (user_name, user_selinux) != 0) { ++ if (Zflg && *user_selinux) { ++ if (is_selinux_enabled () > 0) { ++ if (set_seuser (user_name, user_selinux) != 0) { + fprintf (stderr, + _("%s: warning: the user name %s to %s SELinux user mapping failed.\n"), + Prog, user_name, user_selinux); +@@ -2495,15 +2482,31 @@ int main (int argc, char **argv) + "adding SELinux user mapping", + user_name, (unsigned int) user_id, 0); + #endif /* WITH_AUDIT */ +- fail_exit (E_SE_UPDATE); ++ rv = E_SE_UPDATE; ++ } + } + } + #endif /* WITH_SELINUX */ + +- nscd_flush_cache ("passwd"); +- nscd_flush_cache ("group"); +- sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP); ++ if (mflg) { ++ create_home (); ++ if (home_added) { ++ copy_tree (def_template, prefix_user_home, false, true, ++ (uid_t)-1, user_id, (gid_t)-1, user_gid); ++ } else { ++ fprintf (stderr, ++ _("%s: warning: the home directory %s already exists.\n" ++ "%s: Not copying any file from skel directory into it.\n"), ++ Prog, user_home, Prog); ++ } ++ ++ } ++ ++ /* Do not create mail directory for system accounts */ ++ if (!rflg) { ++ create_mail (); ++ } + +- return E_SUCCESS; ++ return rv; + } + diff --git a/shadow-utils.spec b/shadow-utils.spec index 37dc958..0b0c13e 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils -Version: 4.6 -Release: 16%{?dist} +Version: 4.8 +Release: 1%{?dist} Epoch: 2 URL: http://pkg-shadow.alioth.debian.org/ Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -10,33 +10,44 @@ Source2: shadow-utils.useradd Source3: shadow-utils.login.defs Source4: shadow-bsd.txt Source5: https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +# Misc small changes - most probably non-upstreamable Patch0: shadow-4.6-redhat.patch -Patch1: shadow-4.5-goodname.patch +# Be more lenient with acceptable user/group names - non upstreamable +Patch1: shadow-4.8-goodname.patch +# Docfix for newusers - could be upstreamed Patch2: shadow-4.1.5.1-info-parent-dir.patch -Patch6: shadow-4.6-selinux.patch -Patch10: shadow-4.6-orig-context.patch +# Misc SElinux related changes - upstreamability unknown +Patch6: shadow-4.8-selinux.patch +# Syslog message change - could be upstreamed Patch11: shadow-4.1.5.1-logmsg.patch +# SElinux related - upstreamability unknown Patch14: shadow-4.1.5.1-default-range.patch -Patch15: shadow-4.3.1-manfix.patch +# Misc manual page changes - only some of them could be upstreamed +Patch15: shadow-4.8-manfix.patch +# Userdel usage message change - could be upstreamed Patch17: shadow-4.1.5.1-userdel-helpfix.patch +# Date parsing improvement - could be upstreamed Patch19: shadow-4.2.1-date-parsing.patch +# Additional error message - could be upstreamed Patch21: shadow-4.6-move-home.patch -Patch22: shadow-4.6-audit-update.patch +# Audit message changes - upstreamability unknown +Patch22: shadow-4.8-audit-update.patch +# Changes related to password unlocking - could be upstreamed Patch23: shadow-4.5-usermod-unlock.patch -Patch24: shadow-4.2.1-no-lock-dos.patch -Patch28: shadow-4.3.1-selinux-perms.patch +# Additional SElinux related changes - upstreamability unknown +Patch28: shadow-4.8-selinux-perms.patch +# Handle NULL return from *time funcs - could be upstreamed Patch29: shadow-4.2.1-null-tm.patch +# SElinux related - upstreamability unknown Patch31: shadow-4.6-getenforce.patch -Patch32: shadow-4.5-crypt_h.patch -Patch33: shadow-4.5-long-entry.patch -Patch34: shadow-4.6-usermod-crash.patch -Patch35: shadow-4.6-coverity.patch -Patch36: shadow-4.6-use-itstool.patch -Patch37: shadow-4.6-sssd-flush.patch +# Handle include of crypt.h - could be upstreamed +Patch32: shadow-4.8-crypt_h.patch +# Handle /etc/passwd corruption - could be upstreamed +Patch33: shadow-4.8-long-entry.patch +# Limit uid/gid allocation to non-zero - could be upstreamed Patch38: shadow-4.6-sysugid-min-limit.patch -Patch39: shadow-4.6-chgrp-guard.patch -Patch40: shadow-4.6-ignore-login-prompt.patch -Patch41: shadow-4.6-use-lckpwdf.patch +# Ignore LOGIN_PLAIN_PROMPT in login.defs - upstreamability unknown +Patch40: shadow-4.8-ignore-login-prompt.patch License: BSD and GPLv2+ BuildRequires: gcc @@ -69,7 +80,6 @@ are used for managing group accounts. %patch1 -p1 -b .goodname %patch2 -p1 -b .info-parent-dir %patch6 -p1 -b .selinux -%patch10 -p1 -b .orig-context %patch11 -p1 -b .logmsg %patch14 -p1 -b .default-range %patch15 -p1 -b .manfix @@ -78,20 +88,13 @@ are used for managing group accounts. %patch21 -p1 -b .move-home %patch22 -p1 -b .audit-update %patch23 -p1 -b .unlock -%patch24 -p1 -b .no-lock-dos %patch28 -p1 -b .selinux-perms %patch29 -p1 -b .null-tm %patch31 -p1 -b .getenforce %patch32 -p1 -b .crypt_h %patch33 -p1 -b .long-entry -%patch34 -p1 -b .usermod-crash -%patch35 -p1 -b .coverity -%patch36 -p1 -b .use-itstool -%patch37 -p1 -b .sssd-flush %patch38 -p1 -b .sysugid-min-limit -%patch39 -p1 -b .chgrp-guard %patch40 -p1 -b .login-prompt -%patch41 -p1 -b .use-lckpwdf iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -246,6 +249,9 @@ done %{_mandir}/man8/vigr.8* %changelog +* Mon Jan 13 2020 Tomáš Mráz - 2:4.8-1 +- update to current upstream release 4.8 + * Mon Sep 2 2019 Tomáš Mráz - 2:4.6-16 - fix SELinux related problem in chpasswd/chgpasswd when run with -R (patch by Petr Lautrbach) (#1747215) diff --git a/sources b/sources index 2093465..c9450ff 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (shadow-4.6.tar.xz) = e8eee52c649d9973f724bc2d5aeee71fa2e6a2e41ec3487cd6cf6d47af70c32e0cdf304df29b32eae2b6eb6f9066866b5f2c891add0ec87ba583bea3207b3631 -SHA512 (shadow-4.6.tar.xz.asc) = 8728bff5544db6ea123f758cce5bd5c2d346489570c33092e4e97db35c274d7aba01580018f120e4ad80b8f79cfe296a33bccbe9bf68df51bf9b2004c6bfffed +SHA512 (shadow-4.8.tar.xz) = 1c607aec541400fc179d6cbbac7511289c618ab2ce6ee9d7c18a8bfda00421c62d4b9e58aff52b5f82d485468e7db955c186ea0faad9a08003ffc01bdf2ccece +SHA512 (shadow-4.8.tar.xz.asc) = 200f7793e55447cc5c0d11988ee26511167c5fe23e1f6622b6b0c8cb74498052f2df855f02e351fee0da16562f6a6510ad3954b4c5e13dd9a8da0d998f8dc5e6 From 88156a40674d363cb81430e39e8302500f112fe5 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Thu, 16 Jan 2020 09:04:04 +0100 Subject: [PATCH 011/134] make the invalid shell check into warning --- shadow-utils.spec | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index 0b0c13e..d1a3753 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.8 -Release: 1%{?dist} +Release: 2%{?dist} Epoch: 2 URL: http://pkg-shadow.alioth.debian.org/ Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -48,6 +48,8 @@ Patch33: shadow-4.8-long-entry.patch Patch38: shadow-4.6-sysugid-min-limit.patch # Ignore LOGIN_PLAIN_PROMPT in login.defs - upstreamability unknown Patch40: shadow-4.8-ignore-login-prompt.patch +# Make the missing shell check into warning - could be upstreamed +Patch41: shadow-4.8-invalid-shell-check.patch License: BSD and GPLv2+ BuildRequires: gcc @@ -95,6 +97,7 @@ are used for managing group accounts. %patch33 -p1 -b .long-entry %patch38 -p1 -b .sysugid-min-limit %patch40 -p1 -b .login-prompt +%patch41 -p1 -b .invalid-shell iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -249,6 +252,9 @@ done %{_mandir}/man8/vigr.8* %changelog +* Thu Jan 16 2020 Tomáš Mráz - 2:4.8-2 +- make the invalid shell check into warning + * Mon Jan 13 2020 Tomáš Mráz - 2:4.8-1 - update to current upstream release 4.8 From fd2aa2917b7a9fa587bb56a58d32b9f22af6fce3 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Thu, 16 Jan 2020 09:04:30 +0100 Subject: [PATCH 012/134] make the invalid shell check into warning --- shadow-4.8-invalid-shell-check.patch | 30 ++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 shadow-4.8-invalid-shell-check.patch diff --git a/shadow-4.8-invalid-shell-check.patch b/shadow-4.8-invalid-shell-check.patch new file mode 100644 index 0000000..2c525c0 --- /dev/null +++ b/shadow-4.8-invalid-shell-check.patch @@ -0,0 +1,30 @@ +diff -up shadow-4.8/src/useradd.c.invalid-shell shadow-4.8/src/useradd.c +--- shadow-4.8/src/useradd.c.invalid-shell 2020-01-16 08:47:13.841921106 +0100 ++++ shadow-4.8/src/useradd.c 2020-01-16 08:57:26.338421901 +0100 +@@ -1277,15 +1277,22 @@ static void process_flags (int argc, cha + if ( ( !VALID (optarg) ) + || ( ('\0' != optarg[0]) + && ('/' != optarg[0]) +- && ('*' != optarg[0]) ) +- || (stat(optarg, &st) != 0) +- || (S_ISDIR(st.st_mode)) +- || (access(optarg, X_OK) != 0)) { ++ && ('*' != optarg[0]) )) { + fprintf (stderr, + _("%s: invalid shell '%s'\n"), + Prog, optarg); + exit (E_BAD_ARG); + } ++ if ( '\0' != optarg[0] ++ && '*' != optarg[0] ++ && strcmp(optarg, "/sbin/nologin") != 0 ++ && ( stat(optarg, &st) != 0 ++ || S_ISDIR(st.st_mode) ++ || access(optarg, X_OK) != 0)) { ++ fprintf (stderr, ++ _("%s: Warning: missing or not executable shell '%s'\n"), ++ Prog, optarg); ++ } + user_shell = optarg; + def_shell = optarg; + sflg = true; From a1cd6a4b05214b350df0cab19284cdc59b6cde43 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Thu, 16 Jan 2020 13:00:26 +0100 Subject: [PATCH 013/134] Fix grammar mistake in invalid shell check patch --- shadow-4.8-invalid-shell-check.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shadow-4.8-invalid-shell-check.patch b/shadow-4.8-invalid-shell-check.patch index 2c525c0..fb586e0 100644 --- a/shadow-4.8-invalid-shell-check.patch +++ b/shadow-4.8-invalid-shell-check.patch @@ -22,7 +22,7 @@ diff -up shadow-4.8/src/useradd.c.invalid-shell shadow-4.8/src/useradd.c + || S_ISDIR(st.st_mode) + || access(optarg, X_OK) != 0)) { + fprintf (stderr, -+ _("%s: Warning: missing or not executable shell '%s'\n"), ++ _("%s: Warning: missing or non-executable shell '%s'\n"), + Prog, optarg); + } user_shell = optarg; From c44360b6f95c54240d6d8d3adedf87a1470d7ea3 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 30 Jan 2020 23:20:27 +0000 Subject: [PATCH 014/134] - Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- shadow-utils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index d1a3753..485ef25 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.8 -Release: 2%{?dist} +Release: 3%{?dist} Epoch: 2 URL: http://pkg-shadow.alioth.debian.org/ Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -252,6 +252,9 @@ done %{_mandir}/man8/vigr.8* %changelog +* Thu Jan 30 2020 Fedora Release Engineering - 2:4.8-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + * Thu Jan 16 2020 Tomáš Mráz - 2:4.8-2 - make the invalid shell check into warning From f5a51331feea44ad95392e4672f2e4671ff531ab Mon Sep 17 00:00:00 2001 From: ikerexxe Date: Mon, 24 Feb 2020 16:36:57 +0100 Subject: [PATCH 015/134] useradd: generate /var/spool/mail/$USER with the proper SELinux user identity Explanation: use set_selinux_file_context() and reset_selinux_file_context() for create_mail() just as is done for create_home() Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1690527 --- shadow-4.8-useradd-selinux-mail.patch | 61 +++++++++++++++++++++++++++ shadow-utils.spec | 9 +++- 2 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 shadow-4.8-useradd-selinux-mail.patch diff --git a/shadow-4.8-useradd-selinux-mail.patch b/shadow-4.8-useradd-selinux-mail.patch new file mode 100644 index 0000000..1777f2d --- /dev/null +++ b/shadow-4.8-useradd-selinux-mail.patch @@ -0,0 +1,61 @@ +From 4dc62ebcf37d7568be1d4ca54367215eba8b8a28 Mon Sep 17 00:00:00 2001 +From: ikerexxe +Date: Wed, 5 Feb 2020 15:04:39 +0100 +Subject: [PATCH] useradd: doesn't generate /var/spool/mail/$USER with the + proper SELinux user identity + +Explanation: use set_selinux_file_context() and reset_selinux_file_context() for create_mail() just as is done for create_home() + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1690527 +--- + src/useradd.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/src/useradd.c b/src/useradd.c +index a679392d..645d4a40 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -190,6 +190,7 @@ static bool home_added = false; + #define E_NAME_IN_USE 9 /* username already in use */ + #define E_GRP_UPDATE 10 /* can't update group file */ + #define E_HOMEDIR 12 /* can't create home directory */ ++#define E_MAILBOXFILE 13 /* can't create mailbox file */ + #define E_SE_UPDATE 14 /* can't update SELinux user mapping */ + #ifdef ENABLE_SUBIDS + #define E_SUB_UID_UPDATE 16 /* can't update the subordinate uid file */ +@@ -2210,6 +2211,16 @@ static void create_mail (void) + sprintf (file, "%s/%s/%s", prefix, spool, user_name); + else + sprintf (file, "%s/%s", spool, user_name); ++ ++#ifdef WITH_SELINUX ++ if (set_selinux_file_context (file, NULL) != 0) { ++ fprintf (stderr, ++ _("%s: cannot set SELinux context for mailbox file %s\n"), ++ Prog, file); ++ fail_exit (E_MAILBOXFILE); ++ } ++#endif ++ + fd = open (file, O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, 0); + if (fd < 0) { + perror (_("Creating mailbox file")); +@@ -2234,6 +2245,15 @@ static void create_mail (void) + + fsync (fd); + close (fd); ++#ifdef WITH_SELINUX ++ /* Reset SELinux to create files with default contexts */ ++ if (reset_selinux_file_context () != 0) { ++ fprintf (stderr, ++ _("%s: cannot reset SELinux file creation context\n"), ++ Prog); ++ fail_exit (E_MAILBOXFILE); ++ } ++#endif + } + } + +-- +2.24.1 + diff --git a/shadow-utils.spec b/shadow-utils.spec index 485ef25..dd1b37b 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.8 -Release: 3%{?dist} +Release: 4%{?dist} Epoch: 2 URL: http://pkg-shadow.alioth.debian.org/ Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -50,6 +50,8 @@ Patch38: shadow-4.6-sysugid-min-limit.patch Patch40: shadow-4.8-ignore-login-prompt.patch # Make the missing shell check into warning - could be upstreamed Patch41: shadow-4.8-invalid-shell-check.patch +# Generate /var/spool/mail/$USER with the proper SELinux user identity - already upstreamed +Patch42: shadow-4.8-useradd-selinux-mail.patch License: BSD and GPLv2+ BuildRequires: gcc @@ -98,6 +100,7 @@ are used for managing group accounts. %patch38 -p1 -b .sysugid-min-limit %patch40 -p1 -b .login-prompt %patch41 -p1 -b .invalid-shell +%patch42 -p1 -b .useradd-selinux-mail iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -252,6 +255,10 @@ done %{_mandir}/man8/vigr.8* %changelog +* Mon Feb 24 2020 Iker Pedrosa - 2:4.8-4 +- fix useradd: doesn't generate spool mail with the proper SELinux user identity + (#1690527) + * Thu Jan 30 2020 Fedora Release Engineering - 2:4.8-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild From 7309a53c2af98c76e438e050f9dafa0d49175b46 Mon Sep 17 00:00:00 2001 From: ikerexxe Date: Tue, 17 Mar 2020 12:17:29 +0100 Subject: [PATCH 016/134] Synchronized login.defs with upstream file (#1261099 and #1807957) --- shadow-utils.login.defs | 232 ++++++++++++++++++++++++++++++++++++---- shadow-utils.spec | 5 +- 2 files changed, 218 insertions(+), 19 deletions(-) diff --git a/shadow-utils.login.defs b/shadow-utils.login.defs index 0adfb66..7f1c0e4 100644 --- a/shadow-utils.login.defs +++ b/shadow-utils.login.defs @@ -6,15 +6,121 @@ # /etc/pam.d/system-auth for more information. # +# +# Delay in seconds before being allowed another attempt after a login failure +# Note: When PAM is used, some modules may enforce a minimum delay (e.g. +# pam_unix(8) enforces a 2s delay) +# +#FAIL_DELAY 3 + +# Currently FAILLOG_ENAB is not supported + +# +# Enable display of unknown usernames when login(1) failures are recorded. +# +#LOG_UNKFAIL_ENAB no + +# Currently LOG_OK_LOGINS is not supported + +# Currently LASTLOG_ENAB is not supported + +# +# Limit the highest user ID number for which the lastlog entries should +# be updated. +# +# No LASTLOG_UID_MAX means that there is no user ID limit for writing +# lastlog entries. +# +#LASTLOG_UID_MAX + +# Currently MAIL_CHECK_ENAB is not supported + +# Currently OBSCURE_CHECKS_ENAB is not supported + +# Currently PORTTIME_CHECKS_ENAB is not supported + +# Currently QUOTAS_ENAB is not supported + +# Currently SYSLOG_SU_ENAB is not supported + +# +# Enable "syslog" logging of newgrp(1) and sg(1) activity. +# +#SYSLOG_SG_ENAB yes + +# Currently CONSOLE is not supported + +# Currently SULOG_FILE is not supported + +# Currently MOTD_FILE is not supported + +# Currently ISSUE_FILE is not supported + +# Currently TTYTYPE_FILE is not supported + +# Currently FTMP_FILE is not supported + +# Currently NOLOGINS_FILE is not supported + +# Currently SU_NAME is not supported + # *REQUIRED* # Directory where mailboxes reside, _or_ name of file, relative to the # home directory. If you _do_ define both, MAIL_DIR takes precedence. -# QMAIL_DIR is for Qmail # -#QMAIL_DIR Maildir MAIL_DIR /var/spool/mail #MAIL_FILE .mail +# +# If defined, file which inhibits all the usual chatter during the login +# sequence. If a full pathname, then hushed mode will be enabled if the +# user's name or shell are found in the file. If not a full pathname, then +# hushed mode will be enabled if the file exists in the user's home directory. +# +#HUSHLOGIN_FILE .hushlogin +#HUSHLOGIN_FILE /etc/hushlogins + +# Currently ENV_TZ is not supported + +# Currently ENV_HZ is not supported + +# +# The default PATH settings, for superuser and normal users. +# +# (they are minimal, add the rest in the shell startup files) +#ENV_SUPATH PATH=/sbin:/bin:/usr/sbin:/usr/bin +#ENV_PATH PATH=/bin:/usr/bin + +# +# Terminal permissions +# +# TTYGROUP Login tty will be assigned this group ownership. +# TTYPERM Login tty will be set to this permission. +# +# If you have a write(1) program which is "setgid" to a special group +# which owns the terminals, define TTYGROUP as the number of such group +# and TTYPERM as 0620. Otherwise leave TTYGROUP commented out and +# set TTYPERM to either 622 or 600. +# +#TTYGROUP tty +#TTYPERM 0600 + +# Currently ERASECHAR, KILLCHAR and ULIMIT are not supported + +# Default initial "umask" value used by login(1) on non-PAM enabled systems. +# Default "umask" value for pam_umask(8) on PAM enabled systems. +# UMASK is also used by useradd(8) and newusers(8) to set the mode for new +# home directories if HOME_MODE is not set. +# 022 is the default value, but 027, or even 077, could be considered +# for increased privacy. There is no One True Answer here: each sysadmin +# must make up their mind. +UMASK 022 + +# HOME_MODE is used by useradd(8) and newusers(8) to set the mode for new +# home directories. +# If HOME_MODE is not set, the value of UMASK is used to create the mode. +HOME_MODE 0700 + # Password aging controls: # # PASS_MAX_DAYS Maximum number of days a password may be used. @@ -24,26 +130,105 @@ MAIL_DIR /var/spool/mail # PASS_MAX_DAYS 99999 PASS_MIN_DAYS 0 -PASS_MIN_LEN 5 PASS_WARN_AGE 7 +# Currently PASS_MIN_LEN is not supported + +# Currently SU_WHEEL_ONLY is not supported + +# Currently CRACKLIB_DICTPATH is not supported + # -# Min/max values for automatic uid selection in useradd +# Min/max values for automatic uid selection in useradd(8) # UID_MIN 1000 UID_MAX 60000 # System accounts SYS_UID_MIN 201 SYS_UID_MAX 999 +# Extra per user uids +SUB_UID_MIN 100000 +SUB_UID_MAX 600100000 +SUB_UID_COUNT 65536 # -# Min/max values for automatic gid selection in groupadd +# Min/max values for automatic gid selection in groupadd(8) # GID_MIN 1000 GID_MAX 60000 # System accounts SYS_GID_MIN 201 SYS_GID_MAX 999 +# Extra per user group ids +SUB_GID_MIN 100000 +SUB_GID_MAX 600100000 +SUB_GID_COUNT 65536 + +# +# Max number of login(1) retries if password is bad +# +#LOGIN_RETRIES 3 + +# +# Max time in seconds for login(1) +# +#LOGIN_TIMEOUT 60 + +# Currently PASS_CHANGE_TRIES is not supported + +# Currently PASS_ALWAYS_WARN is not supported + +# Currently PASS_MAX_LEN is not supported + +# Currently CHFN_AUTH is not supported + +# +# Which fields may be changed by regular users using chfn(1) - use +# any combination of letters "frwh" (full name, room number, work +# phone, home phone). If not defined, no changes are allowed. +# For backward compatibility, "yes" = "rwh" and "no" = "frwh". +# +#CHFN_RESTRICT rwh + +# Currently LOGIN_STRING is not supported + +# Currently MD5_CRYPT_ENAB is not supported + +# +# If set to MD5, MD5-based algorithm will be used for encrypting password +# If set to SHA256, SHA256-based algorithm will be used for encrypting password +# If set to SHA512, SHA512-based algorithm will be used for encrypting password +# If set to BLOWFISH, BLOWFISH-based algorithm will be used for encrypting password +# If set to DES, DES-based algorithm will be used for encrypting password (default) +# +ENCRYPT_METHOD SHA512 + +# +# Only works if ENCRYPT_METHOD is set to SHA256 or SHA512. +# +# Define the number of SHA rounds. +# With a lot of rounds, it is more difficult to brute-force the password. +# However, more CPU resources will be needed to authenticate users if +# this value is increased. +# +# If not specified, the libc will choose the default number of rounds (5000). +# The values must be within the 1000-999999999 range. +# +#SHA_CRYPT_MAX_ROUNDS 5000 + +# Currently SHA_CRYPT_MIN_ROUNDS is not supported + +# Currently BCRYPT_MIN_ROUNDS and BCRYPT_MAX_ROUNDS are not supported + +# Currently CONSOLE_GROUPS is not supported + +# +# Should login be allowed if we can't cd to the home directory? +# Default is yes. +# +#DEFAULT_HOME yes + +# Currently ENVIRON_FILE is not supported # # If defined, this command is run when removing a user. @@ -53,20 +238,31 @@ SYS_GID_MAX 999 #USERDEL_CMD /usr/sbin/userdel_local # -# If useradd should create home directories for users by default -# On RH systems, we do. This option is overridden with the -m flag on -# useradd command line. -# -CREATE_HOME yes - -# The permission mask is initialized to this value. If not specified, -# the permission mask will be initialized to 022. -UMASK 077 - -# This enables userdel to remove user groups if no members exist. +# Enables userdel(8) to remove user groups if no members exist. # USERGROUPS_ENAB yes -# Use SHA512 to encrypt password. -ENCRYPT_METHOD SHA512 +# +# If set to a non-zero number, the shadow utilities will make sure that +# groups never have more than this number of users on one line. +# This permits to support split groups (groups split into multiple lines, +# with the same group ID, to avoid limitation of the line length in the +# group file). +# +# 0 is the default value and disables this feature. +# +#MAX_MEMBERS_PER_GROUP 0 +# +# If useradd(8) should create home directories for users by default (non +# system users only). +# This option is overridden with the -M or -m flags on the useradd(8) +# command-line. +# +CREATE_HOME yes + +# +# Force use shadow, even if shadow passwd & shadow group files are +# missing. +# +#FORCE_SHADOW yes diff --git a/shadow-utils.spec b/shadow-utils.spec index dd1b37b..481a534 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.8 -Release: 4%{?dist} +Release: 5%{?dist} Epoch: 2 URL: http://pkg-shadow.alioth.debian.org/ Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -255,6 +255,9 @@ done %{_mandir}/man8/vigr.8* %changelog +* Mon Mar 17 2020 Iker Pedrosa - 2:4.8-5 +- synchronized login.defs with upstream file (#1261099 and #1807957) + * Mon Feb 24 2020 Iker Pedrosa - 2:4.8-4 - fix useradd: doesn't generate spool mail with the proper SELinux user identity (#1690527) From b926b118d9c888e4f6b9de16dd607992201cb1e8 Mon Sep 17 00:00:00 2001 From: ikerexxe Date: Tue, 17 Mar 2020 18:18:50 +0100 Subject: [PATCH 017/134] Rebased to 4.8.1 --- .gitignore | 2 + shadow-4.8-invalid-shell-check.patch | 30 ---- ...e.patch => shadow-4.8.1-audit-update.patch | 130 +++++++++--------- ...-manfix.patch => shadow-4.8.1-manfix.patch | 74 +++++----- shadow-utils.HOME_MODE.xml | 43 ++++++ shadow-utils.spec | 18 +-- sources | 4 +- 7 files changed, 159 insertions(+), 142 deletions(-) delete mode 100644 shadow-4.8-invalid-shell-check.patch rename shadow-4.8-audit-update.patch => shadow-4.8.1-audit-update.patch (94%) rename shadow-4.8-manfix.patch => shadow-4.8.1-manfix.patch (82%) create mode 100644 shadow-utils.HOME_MODE.xml diff --git a/.gitignore b/.gitignore index 9e9905a..de3b420 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,5 @@ shadow-4.1.4.2.tar.bz2 /shadow-4.6.tar.xz.asc /shadow-4.8.tar.xz /shadow-4.8.tar.xz.asc +/shadow-4.8.1.tar.xz +/shadow-4.8.1.tar.xz.asc diff --git a/shadow-4.8-invalid-shell-check.patch b/shadow-4.8-invalid-shell-check.patch deleted file mode 100644 index fb586e0..0000000 --- a/shadow-4.8-invalid-shell-check.patch +++ /dev/null @@ -1,30 +0,0 @@ -diff -up shadow-4.8/src/useradd.c.invalid-shell shadow-4.8/src/useradd.c ---- shadow-4.8/src/useradd.c.invalid-shell 2020-01-16 08:47:13.841921106 +0100 -+++ shadow-4.8/src/useradd.c 2020-01-16 08:57:26.338421901 +0100 -@@ -1277,15 +1277,22 @@ static void process_flags (int argc, cha - if ( ( !VALID (optarg) ) - || ( ('\0' != optarg[0]) - && ('/' != optarg[0]) -- && ('*' != optarg[0]) ) -- || (stat(optarg, &st) != 0) -- || (S_ISDIR(st.st_mode)) -- || (access(optarg, X_OK) != 0)) { -+ && ('*' != optarg[0]) )) { - fprintf (stderr, - _("%s: invalid shell '%s'\n"), - Prog, optarg); - exit (E_BAD_ARG); - } -+ if ( '\0' != optarg[0] -+ && '*' != optarg[0] -+ && strcmp(optarg, "/sbin/nologin") != 0 -+ && ( stat(optarg, &st) != 0 -+ || S_ISDIR(st.st_mode) -+ || access(optarg, X_OK) != 0)) { -+ fprintf (stderr, -+ _("%s: Warning: missing or non-executable shell '%s'\n"), -+ Prog, optarg); -+ } - user_shell = optarg; - def_shell = optarg; - sflg = true; diff --git a/shadow-4.8-audit-update.patch b/shadow-4.8.1-audit-update.patch similarity index 94% rename from shadow-4.8-audit-update.patch rename to shadow-4.8.1-audit-update.patch index 153adfe..1b9586a 100644 --- a/shadow-4.8-audit-update.patch +++ b/shadow-4.8.1-audit-update.patch @@ -1,6 +1,6 @@ -diff -up shadow-4.8/libmisc/audit_help.c.audit-update shadow-4.8/libmisc/audit_help.c ---- shadow-4.8/libmisc/audit_help.c.audit-update 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8/libmisc/audit_help.c 2020-01-13 10:15:51.802073378 +0100 +diff -up shadow-4.8.1/libmisc/audit_help.c.audit-update shadow-4.8.1/libmisc/audit_help.c +--- shadow-4.8.1/libmisc/audit_help.c.audit-update 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/libmisc/audit_help.c 2020-03-17 16:53:44.371943299 +0100 @@ -68,7 +68,7 @@ void audit_help_open (void) * This function will log a message to the audit system using a predefined * message format. Parameter usage is as follows: @@ -50,9 +50,9 @@ diff -up shadow-4.8/libmisc/audit_help.c.audit-update shadow-4.8/libmisc/audit_h void audit_logger_message (const char *message, shadow_audit_result result) { if (audit_fd < 0) { -diff -up shadow-4.8/libmisc/cleanup_group.c.audit-update shadow-4.8/libmisc/cleanup_group.c ---- shadow-4.8/libmisc/cleanup_group.c.audit-update 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8/libmisc/cleanup_group.c 2020-01-13 10:15:51.802073378 +0100 +diff -up shadow-4.8.1/libmisc/cleanup_group.c.audit-update shadow-4.8.1/libmisc/cleanup_group.c +--- shadow-4.8.1/libmisc/cleanup_group.c.audit-update 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/libmisc/cleanup_group.c 2020-03-17 16:53:44.371943299 +0100 @@ -83,7 +83,7 @@ void cleanup_report_mod_group (void *cle gr_dbname (), info->action)); @@ -131,9 +131,9 @@ diff -up shadow-4.8/libmisc/cleanup_group.c.audit-update shadow-4.8/libmisc/clea SHADOW_AUDIT_FAILURE); #endif } -diff -up shadow-4.8/libmisc/cleanup_user.c.audit-update shadow-4.8/libmisc/cleanup_user.c ---- shadow-4.8/libmisc/cleanup_user.c.audit-update 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8/libmisc/cleanup_user.c 2020-01-13 10:15:51.802073378 +0100 +diff -up shadow-4.8.1/libmisc/cleanup_user.c.audit-update shadow-4.8.1/libmisc/cleanup_user.c +--- shadow-4.8.1/libmisc/cleanup_user.c.audit-update 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/libmisc/cleanup_user.c 2020-03-17 16:53:44.371943299 +0100 @@ -65,7 +65,7 @@ void cleanup_report_mod_passwd (void *cl pw_dbname (), info->action)); @@ -181,9 +181,9 @@ diff -up shadow-4.8/libmisc/cleanup_user.c.audit-update shadow-4.8/libmisc/clean SHADOW_AUDIT_FAILURE); #endif } -diff -up shadow-4.8/lib/prototypes.h.audit-update shadow-4.8/lib/prototypes.h ---- shadow-4.8/lib/prototypes.h.audit-update 2020-01-13 10:15:51.785073664 +0100 -+++ shadow-4.8/lib/prototypes.h 2020-01-13 10:15:51.803073362 +0100 +diff -up shadow-4.8.1/lib/prototypes.h.audit-update shadow-4.8.1/lib/prototypes.h +--- shadow-4.8.1/lib/prototypes.h.audit-update 2020-03-17 16:53:44.364943206 +0100 ++++ shadow-4.8.1/lib/prototypes.h 2020-03-17 16:53:44.371943299 +0100 @@ -219,12 +219,21 @@ extern int audit_fd; extern void audit_help_open (void); /* Use AUDIT_NO_ID when a name is provided to audit_logger instead of an ID */ @@ -206,9 +206,9 @@ diff -up shadow-4.8/lib/prototypes.h.audit-update shadow-4.8/lib/prototypes.h void audit_logger_message (const char *message, shadow_audit_result result); #endif -diff -up shadow-4.8/src/chage.c.audit-update shadow-4.8/src/chage.c ---- shadow-4.8/src/chage.c.audit-update 2019-11-12 01:18:25.000000000 +0100 -+++ shadow-4.8/src/chage.c 2020-01-13 10:15:51.806073311 +0100 +diff -up shadow-4.8.1/src/chage.c.audit-update shadow-4.8.1/src/chage.c +--- shadow-4.8.1/src/chage.c.audit-update 2019-11-12 01:18:25.000000000 +0100 ++++ shadow-4.8.1/src/chage.c 2020-03-17 16:53:44.371943299 +0100 @@ -123,9 +123,10 @@ static /*@noreturn@*/void fail_exit (int #ifdef WITH_AUDIT @@ -296,9 +296,9 @@ diff -up shadow-4.8/src/chage.c.audit-update shadow-4.8/src/chage.c user_name, (unsigned int) user_uid, 1); } #endif -diff -up shadow-4.8/src/gpasswd.c.audit-update shadow-4.8/src/gpasswd.c ---- shadow-4.8/src/gpasswd.c.audit-update 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8/src/gpasswd.c 2020-01-13 10:15:51.803073362 +0100 +diff -up shadow-4.8.1/src/gpasswd.c.audit-update shadow-4.8.1/src/gpasswd.c +--- shadow-4.8.1/src/gpasswd.c.audit-update 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/src/gpasswd.c 2020-03-17 16:53:44.371943299 +0100 @@ -138,7 +138,7 @@ static void usage (int status) (void) fputs (_(" -d, --delete USER remove USER from GROUP\n"), usageout); (void) fputs (_(" -h, --help display this help message and exit\n"), usageout); @@ -562,9 +562,9 @@ diff -up shadow-4.8/src/gpasswd.c.audit-update shadow-4.8/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } -diff -up shadow-4.8/src/groupadd.c.audit-update shadow-4.8/src/groupadd.c ---- shadow-4.8/src/groupadd.c.audit-update 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8/src/groupadd.c 2020-01-13 10:15:51.804073345 +0100 +diff -up shadow-4.8.1/src/groupadd.c.audit-update shadow-4.8.1/src/groupadd.c +--- shadow-4.8.1/src/groupadd.c.audit-update 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/src/groupadd.c 2020-03-17 16:53:44.372943312 +0100 @@ -131,6 +131,15 @@ static /*@noreturn@*/void usage (int sta exit (status); } @@ -740,9 +740,9 @@ diff -up shadow-4.8/src/groupadd.c.audit-update shadow-4.8/src/groupadd.c } } -diff -up shadow-4.8/src/groupdel.c.audit-update shadow-4.8/src/groupdel.c ---- shadow-4.8/src/groupdel.c.audit-update 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8/src/groupdel.c 2020-01-13 10:15:51.804073345 +0100 +diff -up shadow-4.8.1/src/groupdel.c.audit-update shadow-4.8.1/src/groupdel.c +--- shadow-4.8.1/src/groupdel.c.audit-update 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/src/groupdel.c 2020-03-17 16:53:44.372943312 +0100 @@ -106,6 +106,15 @@ static /*@noreturn@*/void usage (int sta exit (status); } @@ -912,9 +912,9 @@ diff -up shadow-4.8/src/groupdel.c.audit-update shadow-4.8/src/groupdel.c } #endif -diff -up shadow-4.8/src/groupmod.c.audit-update shadow-4.8/src/groupmod.c ---- shadow-4.8/src/groupmod.c.audit-update 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8/src/groupmod.c 2020-01-13 10:15:51.805073328 +0100 +diff -up shadow-4.8.1/src/groupmod.c.audit-update shadow-4.8.1/src/groupmod.c +--- shadow-4.8.1/src/groupmod.c.audit-update 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/src/groupmod.c 2020-03-17 16:53:44.372943312 +0100 @@ -450,7 +450,7 @@ static void close_files (void) exit (E_GRP_UPDATE); } @@ -1118,9 +1118,9 @@ diff -up shadow-4.8/src/groupmod.c.audit-update shadow-4.8/src/groupmod.c // FIXME: add a system cleanup add_cleanup (cleanup_report_mod_group, &info_group); -diff -up shadow-4.8/src/newgrp.c.audit-update shadow-4.8/src/newgrp.c ---- shadow-4.8/src/newgrp.c.audit-update 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8/src/newgrp.c 2020-01-13 10:15:51.806073311 +0100 +diff -up shadow-4.8.1/src/newgrp.c.audit-update shadow-4.8.1/src/newgrp.c +--- shadow-4.8.1/src/newgrp.c.audit-update 2020-01-12 15:19:28.000000000 +0100 ++++ shadow-4.8.1/src/newgrp.c 2020-03-17 16:53:44.372943312 +0100 @@ -206,11 +206,12 @@ static void check_perms (const struct gr strcmp (cpasswd, grp->gr_passwd) != 0) { #ifdef WITH_AUDIT @@ -1203,7 +1203,7 @@ diff -up shadow-4.8/src/newgrp.c.audit-update shadow-4.8/src/newgrp.c } #endif exit (EXIT_FAILURE); -@@ -457,7 +458,7 @@ int main (int argc, char **argv) +@@ -458,7 +459,7 @@ int main (int argc, char **argv) #ifdef WITH_AUDIT audit_logger (AUDIT_CHGRP_ID, Prog, "changing", NULL, @@ -1212,7 +1212,7 @@ diff -up shadow-4.8/src/newgrp.c.audit-update shadow-4.8/src/newgrp.c #endif SYSLOG ((LOG_WARN, "Cannot determine the user name of the caller (UID %lu)", (unsigned long) getuid ())); -@@ -573,15 +574,26 @@ int main (int argc, char **argv) +@@ -574,15 +575,26 @@ int main (int argc, char **argv) perror ("getgroups"); #ifdef WITH_AUDIT if (group) { @@ -1243,7 +1243,7 @@ diff -up shadow-4.8/src/newgrp.c.audit-update shadow-4.8/src/newgrp.c } #endif exit (EXIT_FAILURE); -@@ -738,10 +750,10 @@ int main (int argc, char **argv) +@@ -739,10 +751,10 @@ int main (int argc, char **argv) perror ("setgid"); #ifdef WITH_AUDIT snprintf (audit_buf, sizeof(audit_buf), @@ -1256,7 +1256,7 @@ diff -up shadow-4.8/src/newgrp.c.audit-update shadow-4.8/src/newgrp.c #endif exit (EXIT_FAILURE); } -@@ -750,10 +762,10 @@ int main (int argc, char **argv) +@@ -751,10 +763,10 @@ int main (int argc, char **argv) perror ("setuid"); #ifdef WITH_AUDIT snprintf (audit_buf, sizeof(audit_buf), @@ -1269,7 +1269,7 @@ diff -up shadow-4.8/src/newgrp.c.audit-update shadow-4.8/src/newgrp.c #endif exit (EXIT_FAILURE); } -@@ -767,10 +779,10 @@ int main (int argc, char **argv) +@@ -768,10 +780,10 @@ int main (int argc, char **argv) execl (SHELL, "sh", "-c", command, (char *) 0); #ifdef WITH_AUDIT snprintf (audit_buf, sizeof(audit_buf), @@ -1282,7 +1282,7 @@ diff -up shadow-4.8/src/newgrp.c.audit-update shadow-4.8/src/newgrp.c #endif perror (SHELL); exit ((errno == ENOENT) ? E_CMD_NOTFOUND : E_CMD_NOEXEC); -@@ -834,11 +846,11 @@ int main (int argc, char **argv) +@@ -835,11 +847,11 @@ int main (int argc, char **argv) } #ifdef WITH_AUDIT @@ -1296,7 +1296,7 @@ diff -up shadow-4.8/src/newgrp.c.audit-update shadow-4.8/src/newgrp.c #endif /* * Exec the login shell and go away. We are trying to get back to -@@ -862,15 +874,24 @@ int main (int argc, char **argv) +@@ -863,15 +875,24 @@ int main (int argc, char **argv) closelog (); #ifdef WITH_AUDIT if (NULL != group) { @@ -1325,9 +1325,9 @@ diff -up shadow-4.8/src/newgrp.c.audit-update shadow-4.8/src/newgrp.c } #endif exit (EXIT_FAILURE); -diff -up shadow-4.8/src/useradd.c.audit-update shadow-4.8/src/useradd.c ---- shadow-4.8/src/useradd.c.audit-update 2020-01-13 10:15:51.789073597 +0100 -+++ shadow-4.8/src/useradd.c 2020-01-13 10:17:30.929406913 +0100 +diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c +--- shadow-4.8.1/src/useradd.c.audit-update 2020-03-17 16:53:44.365943219 +0100 ++++ shadow-4.8.1/src/useradd.c 2020-03-17 17:03:11.614503929 +0100 @@ -233,6 +233,8 @@ static void create_mail (void); */ static void fail_exit (int code) @@ -1510,7 +1510,7 @@ diff -up shadow-4.8/src/useradd.c.audit-update shadow-4.8/src/useradd.c SHADOW_AUDIT_SUCCESS); #endif SYSLOG ((LOG_INFO, -@@ -1445,7 +1393,7 @@ static void process_flags (int argc, cha +@@ -1452,7 +1400,7 @@ static void process_flags (int argc, cha Prog, user_name); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1519,7 +1519,7 @@ diff -up shadow-4.8/src/useradd.c.audit-update shadow-4.8/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1560,7 +1508,7 @@ static void close_files (void) +@@ -1567,7 +1515,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1528,7 +1528,7 @@ diff -up shadow-4.8/src/useradd.c.audit-update shadow-4.8/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1573,7 +1521,7 @@ static void close_files (void) +@@ -1580,7 +1528,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1537,7 +1537,7 @@ diff -up shadow-4.8/src/useradd.c.audit-update shadow-4.8/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1585,7 +1533,7 @@ static void close_files (void) +@@ -1592,7 +1540,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1546,7 +1546,7 @@ diff -up shadow-4.8/src/useradd.c.audit-update shadow-4.8/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1599,7 +1547,7 @@ static void close_files (void) +@@ -1606,7 +1554,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1555,7 +1555,7 @@ diff -up shadow-4.8/src/useradd.c.audit-update shadow-4.8/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1615,7 +1563,7 @@ static void close_files (void) +@@ -1622,7 +1570,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1564,7 +1564,7 @@ diff -up shadow-4.8/src/useradd.c.audit-update shadow-4.8/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1629,7 +1577,7 @@ static void close_files (void) +@@ -1636,7 +1584,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1573,7 +1573,7 @@ diff -up shadow-4.8/src/useradd.c.audit-update shadow-4.8/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1821,7 +1769,7 @@ static void grp_add (void) +@@ -1828,7 +1776,7 @@ static void grp_add (void) Prog, gr_dbname (), grp.gr_name); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_GROUP, Prog, @@ -1582,7 +1582,7 @@ diff -up shadow-4.8/src/useradd.c.audit-update shadow-4.8/src/useradd.c grp.gr_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1837,7 +1785,7 @@ static void grp_add (void) +@@ -1844,7 +1792,7 @@ static void grp_add (void) Prog, sgr_dbname (), sgrp.sg_name); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_GROUP, Prog, @@ -1591,7 +1591,7 @@ diff -up shadow-4.8/src/useradd.c.audit-update shadow-4.8/src/useradd.c grp.gr_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1847,7 +1795,7 @@ static void grp_add (void) +@@ -1854,7 +1802,7 @@ static void grp_add (void) SYSLOG ((LOG_INFO, "new group: name=%s, GID=%u", user_name, user_gid)); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_GROUP, Prog, @@ -1600,7 +1600,7 @@ diff -up shadow-4.8/src/useradd.c.audit-update shadow-4.8/src/useradd.c grp.gr_name, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); #endif -@@ -2015,12 +1963,6 @@ static void usr_update (void) +@@ -2025,12 +1973,6 @@ static void usr_update (void) fprintf (stderr, _("%s: failed to prepare the new %s entry '%s'\n"), Prog, spw_dbname (), spent.sp_namp); @@ -1613,7 +1613,7 @@ diff -up shadow-4.8/src/useradd.c.audit-update shadow-4.8/src/useradd.c fail_exit (E_PW_UPDATE); } #ifdef ENABLE_SUBIDS -@@ -2041,9 +1983,14 @@ static void usr_update (void) +@@ -2051,9 +1993,14 @@ static void usr_update (void) #endif /* ENABLE_SUBIDS */ #ifdef WITH_AUDIT @@ -1630,7 +1630,7 @@ diff -up shadow-4.8/src/useradd.c.audit-update shadow-4.8/src/useradd.c SHADOW_AUDIT_SUCCESS); #endif /* -@@ -2130,12 +2077,6 @@ static void create_home (void) +@@ -2140,12 +2087,6 @@ static void create_home (void) fprintf (stderr, _("%s: cannot create directory %s\n"), Prog, path); @@ -1643,8 +1643,8 @@ diff -up shadow-4.8/src/useradd.c.audit-update shadow-4.8/src/useradd.c fail_exit (E_HOMEDIR); } if (chown (path, 0, 0) < 0) { -@@ -2157,8 +2098,8 @@ static void create_home (void) - 0777 & ~getdef_num ("UMASK", GETDEF_DEFAULT_UMASK)); +@@ -2168,8 +2109,8 @@ static void create_home (void) + chmod (prefix_user_home, mode); home_added = true; #ifdef WITH_AUDIT - audit_logger (AUDIT_ADD_USER, Prog, @@ -1654,7 +1654,7 @@ diff -up shadow-4.8/src/useradd.c.audit-update shadow-4.8/src/useradd.c user_name, (unsigned int) user_id, SHADOW_AUDIT_SUCCESS); #endif -@@ -2343,12 +2284,6 @@ int main (int argc, char **argv) +@@ -2354,12 +2295,6 @@ int main (int argc, char **argv) */ if (prefix_getpwnam (user_name) != NULL) { /* local, no need for xgetpwnam */ fprintf (stderr, _("%s: user '%s' already exists\n"), Prog, user_name); @@ -1667,7 +1667,7 @@ diff -up shadow-4.8/src/useradd.c.audit-update shadow-4.8/src/useradd.c fail_exit (E_NAME_IN_USE); } -@@ -2364,12 +2299,6 @@ int main (int argc, char **argv) +@@ -2375,12 +2310,6 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: group %s exists - if you want to add this user to that group, use -g.\n"), Prog, user_name); @@ -1680,7 +1680,7 @@ diff -up shadow-4.8/src/useradd.c.audit-update shadow-4.8/src/useradd.c fail_exit (E_NAME_IN_USE); } } -@@ -2399,12 +2328,6 @@ int main (int argc, char **argv) +@@ -2410,12 +2339,6 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: UID %lu is not unique\n"), Prog, (unsigned long) user_id); @@ -1693,7 +1693,7 @@ diff -up shadow-4.8/src/useradd.c.audit-update shadow-4.8/src/useradd.c fail_exit (E_UID_IN_USE); } } -@@ -2478,9 +2401,10 @@ int main (int argc, char **argv) +@@ -2489,9 +2412,10 @@ int main (int argc, char **argv) _("%s: warning: the user name %s to %s SELinux user mapping failed.\n"), Prog, user_name, user_selinux); #ifdef WITH_AUDIT @@ -1707,9 +1707,9 @@ diff -up shadow-4.8/src/useradd.c.audit-update shadow-4.8/src/useradd.c #endif /* WITH_AUDIT */ rv = E_SE_UPDATE; } -diff -up shadow-4.8/src/userdel.c.audit-update shadow-4.8/src/userdel.c ---- shadow-4.8/src/userdel.c.audit-update 2020-01-13 10:15:51.797073462 +0100 -+++ shadow-4.8/src/userdel.c 2020-01-13 10:15:51.809073261 +0100 +diff -up shadow-4.8.1/src/userdel.c.audit-update shadow-4.8.1/src/userdel.c +--- shadow-4.8.1/src/userdel.c.audit-update 2020-03-17 16:53:44.368943259 +0100 ++++ shadow-4.8.1/src/userdel.c 2020-03-17 16:53:44.373943325 +0100 @@ -222,9 +222,9 @@ static void update_groups (void) * Update the DBM group file with the new entry as well. */ @@ -2037,9 +2037,9 @@ diff -up shadow-4.8/src/userdel.c.audit-update shadow-4.8/src/userdel.c user_name, (unsigned int) user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -diff -up shadow-4.8/src/usermod.c.audit-update shadow-4.8/src/usermod.c ---- shadow-4.8/src/usermod.c.audit-update 2020-01-13 10:15:51.800073412 +0100 -+++ shadow-4.8/src/usermod.c 2020-01-13 10:15:51.812073210 +0100 +diff -up shadow-4.8.1/src/usermod.c.audit-update shadow-4.8.1/src/usermod.c +--- shadow-4.8.1/src/usermod.c.audit-update 2020-03-17 16:53:44.370943285 +0100 ++++ shadow-4.8.1/src/usermod.c 2020-03-17 16:53:44.373943325 +0100 @@ -457,8 +457,8 @@ static char *new_pw_passwd (char *pw_pas #ifdef WITH_AUDIT diff --git a/shadow-4.8-manfix.patch b/shadow-4.8.1-manfix.patch similarity index 82% rename from shadow-4.8-manfix.patch rename to shadow-4.8.1-manfix.patch index ecb99a4..29f06a7 100644 --- a/shadow-4.8-manfix.patch +++ b/shadow-4.8.1-manfix.patch @@ -1,6 +1,6 @@ -diff -up shadow-4.8/man/chage.1.xml.manfix shadow-4.8/man/chage.1.xml ---- shadow-4.8/man/chage.1.xml.manfix 2019-10-05 01:28:34.000000000 +0200 -+++ shadow-4.8/man/chage.1.xml 2020-01-13 10:12:48.445155882 +0100 +diff -up shadow-4.8.1/man/chage.1.xml.manfix shadow-4.8.1/man/chage.1.xml +--- shadow-4.8.1/man/chage.1.xml.manfix 2019-10-05 01:28:34.000000000 +0200 ++++ shadow-4.8.1/man/chage.1.xml 2020-03-17 15:34:48.750414984 +0100 @@ -102,6 +102,9 @@ Set the number of days since January 1st, 1970 when the password was last changed. The date may also be expressed in the format @@ -44,9 +44,9 @@ diff -up shadow-4.8/man/chage.1.xml.manfix shadow-4.8/man/chage.1.xml The chage command is restricted to the root user, except for the option, which may be used by an unprivileged user to determine when their password or account is due -diff -up shadow-4.8/man/groupadd.8.xml.manfix shadow-4.8/man/groupadd.8.xml ---- shadow-4.8/man/groupadd.8.xml.manfix 2020-01-13 10:12:48.432156100 +0100 -+++ shadow-4.8/man/groupadd.8.xml 2020-01-13 10:13:06.096859122 +0100 +diff -up shadow-4.8.1/man/groupadd.8.xml.manfix shadow-4.8.1/man/groupadd.8.xml +--- shadow-4.8.1/man/groupadd.8.xml.manfix 2020-03-17 15:34:48.745414917 +0100 ++++ shadow-4.8.1/man/groupadd.8.xml 2020-03-17 15:34:48.750414984 +0100 @@ -320,13 +320,13 @@ 4 @@ -63,15 +63,15 @@ diff -up shadow-4.8/man/groupadd.8.xml.manfix shadow-4.8/man/groupadd.8.xml -diff -up shadow-4.8/man/groupmems.8.xml.manfix shadow-4.8/man/groupmems.8.xml ---- shadow-4.8/man/groupmems.8.xml.manfix 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8/man/groupmems.8.xml 2020-01-13 10:12:48.445155882 +0100 +diff -up shadow-4.8.1/man/groupmems.8.xml.manfix shadow-4.8.1/man/groupmems.8.xml +--- shadow-4.8.1/man/groupmems.8.xml.manfix 2020-03-17 15:34:48.750414984 +0100 ++++ shadow-4.8.1/man/groupmems.8.xml 2020-03-17 15:41:13.383588722 +0100 @@ -179,20 +179,10 @@ SETUP - The groupmems executable should be in mode -- 2770 as user root and in group +- 2710 as user root and in group - groups. The system administrator can add users to - group groups to allow or disallow them using the - groupmems utility to manage their own group @@ -83,16 +83,16 @@ diff -up shadow-4.8/man/groupmems.8.xml.manfix shadow-4.8/man/groupmems.8.xml - - - $ groupadd -r groups -- $ chmod 2770 groupmems +- $ chmod 2710 groupmems - $ chown root.groups groupmems - $ groupmems -g groups -a gk4 - -diff -up shadow-4.8/man/ja/man5/login.defs.5.manfix shadow-4.8/man/ja/man5/login.defs.5 ---- shadow-4.8/man/ja/man5/login.defs.5.manfix 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8/man/ja/man5/login.defs.5 2020-01-13 10:12:48.445155882 +0100 +diff -up shadow-4.8.1/man/ja/man5/login.defs.5.manfix shadow-4.8.1/man/ja/man5/login.defs.5 +--- shadow-4.8.1/man/ja/man5/login.defs.5.manfix 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/man/ja/man5/login.defs.5 2020-03-17 15:34:48.750414984 +0100 @@ -147,10 +147,6 @@ 以下の参照表は、 shadow パスワード機能のどのプログラムが どのパラメータを使用するかを示したものである。 @@ -104,10 +104,10 @@ diff -up shadow-4.8/man/ja/man5/login.defs.5.manfix shadow-4.8/man/ja/man5/login .IP groupadd 12 GID_MAX GID_MIN .IP newusers 12 -diff -up shadow-4.8/man/login.defs.5.xml.manfix shadow-4.8/man/login.defs.5.xml ---- shadow-4.8/man/login.defs.5.xml.manfix 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8/man/login.defs.5.xml 2020-01-13 10:14:10.491776547 +0100 -@@ -163,6 +163,17 @@ +diff -up shadow-4.8.1/man/login.defs.5.xml.manfix shadow-4.8.1/man/login.defs.5.xml +--- shadow-4.8.1/man/login.defs.5.xml.manfix 2020-01-17 16:47:56.000000000 +0100 ++++ shadow-4.8.1/man/login.defs.5.xml 2020-03-17 15:34:48.750414984 +0100 +@@ -164,6 +164,17 @@ long numeric parameters is machine-dependent. @@ -125,7 +125,7 @@ diff -up shadow-4.8/man/login.defs.5.xml.manfix shadow-4.8/man/login.defs.5.xml The following configuration items are provided: -@@ -254,16 +265,6 @@ +@@ -256,16 +267,6 @@ @@ -142,7 +142,7 @@ diff -up shadow-4.8/man/login.defs.5.xml.manfix shadow-4.8/man/login.defs.5.xml chgpasswd -@@ -284,14 +285,6 @@ +@@ -286,14 +287,6 @@ @@ -157,7 +157,7 @@ diff -up shadow-4.8/man/login.defs.5.xml.manfix shadow-4.8/man/login.defs.5.xml -@@ -357,34 +350,6 @@ +@@ -359,34 +352,6 @@ LASTLOG_UID_MAX @@ -192,7 +192,7 @@ diff -up shadow-4.8/man/login.defs.5.xml.manfix shadow-4.8/man/login.defs.5.xml newgrp / sg -@@ -412,17 +377,6 @@ +@@ -415,17 +380,6 @@ @@ -210,7 +210,7 @@ diff -up shadow-4.8/man/login.defs.5.xml.manfix shadow-4.8/man/login.defs.5.xml pwck -@@ -449,32 +403,6 @@ +@@ -452,32 +406,6 @@ @@ -243,9 +243,9 @@ diff -up shadow-4.8/man/login.defs.5.xml.manfix shadow-4.8/man/login.defs.5.xml useradd -diff -up shadow-4.8/man/shadow.5.xml.manfix shadow-4.8/man/shadow.5.xml ---- shadow-4.8/man/shadow.5.xml.manfix 2019-12-01 17:52:32.000000000 +0100 -+++ shadow-4.8/man/shadow.5.xml 2020-01-13 10:12:48.446155865 +0100 +diff -up shadow-4.8.1/man/shadow.5.xml.manfix shadow-4.8.1/man/shadow.5.xml +--- shadow-4.8.1/man/shadow.5.xml.manfix 2019-12-01 17:52:32.000000000 +0100 ++++ shadow-4.8.1/man/shadow.5.xml 2020-03-17 15:34:48.750414984 +0100 @@ -129,7 +129,7 @@ @@ -275,10 +275,10 @@ diff -up shadow-4.8/man/shadow.5.xml.manfix shadow-4.8/man/shadow.5.xml Note that an account expiration differs from a password -diff -up shadow-4.8/man/useradd.8.xml.manfix shadow-4.8/man/useradd.8.xml ---- shadow-4.8/man/useradd.8.xml.manfix 2020-01-13 10:12:48.432156100 +0100 -+++ shadow-4.8/man/useradd.8.xml 2020-01-13 10:12:48.446155865 +0100 -@@ -358,6 +358,11 @@ +diff -up shadow-4.8.1/man/useradd.8.xml.manfix shadow-4.8.1/man/useradd.8.xml +--- shadow-4.8.1/man/useradd.8.xml.manfix 2020-03-17 15:34:48.745414917 +0100 ++++ shadow-4.8.1/man/useradd.8.xml 2020-03-17 15:34:48.751414997 +0100 +@@ -359,6 +359,11 @@ is not enabled, no home directories are created. @@ -290,10 +290,10 @@ diff -up shadow-4.8/man/useradd.8.xml.manfix shadow-4.8/man/useradd.8.xml -diff -up shadow-4.8/man/usermod.8.xml.manfix shadow-4.8/man/usermod.8.xml ---- shadow-4.8/man/usermod.8.xml.manfix 2019-10-05 03:23:58.000000000 +0200 -+++ shadow-4.8/man/usermod.8.xml 2020-01-13 10:12:48.446155865 +0100 -@@ -153,7 +153,8 @@ +diff -up shadow-4.8.1/man/usermod.8.xml.manfix shadow-4.8.1/man/usermod.8.xml +--- shadow-4.8.1/man/usermod.8.xml.manfix 2019-12-20 06:58:23.000000000 +0100 ++++ shadow-4.8.1/man/usermod.8.xml 2020-03-17 15:34:48.751414997 +0100 +@@ -143,7 +143,8 @@ If the option is given, the contents of the current home directory will be moved to the new home directory, which is created if it does @@ -303,7 +303,7 @@ diff -up shadow-4.8/man/usermod.8.xml.manfix shadow-4.8/man/usermod.8.xml -@@ -215,6 +216,12 @@ +@@ -205,6 +206,12 @@ The group ownership of files outside of the user's home directory must be fixed manually. @@ -316,7 +316,7 @@ diff -up shadow-4.8/man/usermod.8.xml.manfix shadow-4.8/man/usermod.8.xml -@@ -277,7 +284,8 @@ +@@ -267,7 +274,8 @@ Move the content of the user's home directory to the new @@ -326,7 +326,7 @@ diff -up shadow-4.8/man/usermod.8.xml.manfix shadow-4.8/man/usermod.8.xml This option is only valid in combination with the -@@ -391,6 +399,12 @@ +@@ -381,6 +389,12 @@ must be fixed manually. diff --git a/shadow-utils.HOME_MODE.xml b/shadow-utils.HOME_MODE.xml new file mode 100644 index 0000000..21aa55f --- /dev/null +++ b/shadow-utils.HOME_MODE.xml @@ -0,0 +1,43 @@ + + + (number) + + + The mode for new home directories. If not specified, + the is used to create the mode. + + + useradd and newusers use this + to set the mode of the home directory they create. + + + diff --git a/shadow-utils.spec b/shadow-utils.spec index 481a534..5b58ae6 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils -Version: 4.8 -Release: 5%{?dist} +Version: 4.8.1 +Release: 1%{?dist} Epoch: 2 URL: http://pkg-shadow.alioth.debian.org/ Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -10,6 +10,7 @@ Source2: shadow-utils.useradd Source3: shadow-utils.login.defs Source4: shadow-bsd.txt Source5: https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +Source6: shadow-utils.HOME_MODE.xml # Misc small changes - most probably non-upstreamable Patch0: shadow-4.6-redhat.patch # Be more lenient with acceptable user/group names - non upstreamable @@ -23,7 +24,7 @@ Patch11: shadow-4.1.5.1-logmsg.patch # SElinux related - upstreamability unknown Patch14: shadow-4.1.5.1-default-range.patch # Misc manual page changes - only some of them could be upstreamed -Patch15: shadow-4.8-manfix.patch +Patch15: shadow-4.8.1-manfix.patch # Userdel usage message change - could be upstreamed Patch17: shadow-4.1.5.1-userdel-helpfix.patch # Date parsing improvement - could be upstreamed @@ -31,7 +32,7 @@ Patch19: shadow-4.2.1-date-parsing.patch # Additional error message - could be upstreamed Patch21: shadow-4.6-move-home.patch # Audit message changes - upstreamability unknown -Patch22: shadow-4.8-audit-update.patch +Patch22: shadow-4.8.1-audit-update.patch # Changes related to password unlocking - could be upstreamed Patch23: shadow-4.5-usermod-unlock.patch # Additional SElinux related changes - upstreamability unknown @@ -48,8 +49,6 @@ Patch33: shadow-4.8-long-entry.patch Patch38: shadow-4.6-sysugid-min-limit.patch # Ignore LOGIN_PLAIN_PROMPT in login.defs - upstreamability unknown Patch40: shadow-4.8-ignore-login-prompt.patch -# Make the missing shell check into warning - could be upstreamed -Patch41: shadow-4.8-invalid-shell-check.patch # Generate /var/spool/mail/$USER with the proper SELinux user identity - already upstreamed Patch42: shadow-4.8-useradd-selinux-mail.patch @@ -99,13 +98,13 @@ are used for managing group accounts. %patch33 -p1 -b .long-entry %patch38 -p1 -b .sysugid-min-limit %patch40 -p1 -b .login-prompt -%patch41 -p1 -b .invalid-shell %patch42 -p1 -b .useradd-selinux-mail iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO cp -a %{SOURCE4} %{SOURCE5} . +cp -a %{SOURCE6} man/login.defs.d/HOME_MODE.xml # Force regeneration of getdate.c rm libmisc/getdate.c @@ -255,7 +254,10 @@ done %{_mandir}/man8/vigr.8* %changelog -* Mon Mar 17 2020 Iker Pedrosa - 2:4.8-5 +* Tue Mar 17 2020 Iker Pedrosa - 2:4.8.1-1 +- updated upstream to 4.8.1 + +* Tue Mar 17 2020 Iker Pedrosa - 2:4.8-5 - synchronized login.defs with upstream file (#1261099 and #1807957) * Mon Feb 24 2020 Iker Pedrosa - 2:4.8-4 diff --git a/sources b/sources index c9450ff..0e0c57a 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (shadow-4.8.tar.xz) = 1c607aec541400fc179d6cbbac7511289c618ab2ce6ee9d7c18a8bfda00421c62d4b9e58aff52b5f82d485468e7db955c186ea0faad9a08003ffc01bdf2ccece -SHA512 (shadow-4.8.tar.xz.asc) = 200f7793e55447cc5c0d11988ee26511167c5fe23e1f6622b6b0c8cb74498052f2df855f02e351fee0da16562f6a6510ad3954b4c5e13dd9a8da0d998f8dc5e6 +SHA512 (shadow-4.8.1.tar.xz) = 780a983483d847ed3c91c82064a0fa902b6f4185225978241bc3bc03fcc3aa143975b46aee43151c6ba43efcfdb1819516b76ba7ad3d1d3c34fcc38ea42e917b +SHA512 (shadow-4.8.1.tar.xz.asc) = ec7686263c81d3feb8ee4314c3323a9a3ada74aafaaf99f4f0d9af9b1341f8c5ff5477ecf98dd94dbb7d921f532d655b0b6a87d94c71893f35dc9bc54c84dd42 From a66f10a891f0da25d064a41c1d7a9cd8ac98a7ca Mon Sep 17 00:00:00 2001 From: ikerexxe Date: Tue, 24 Mar 2020 10:46:27 +0100 Subject: [PATCH 018/134] useradd: clarify the useradd -d parameter behavior in man page --- shadow-4.8.1-useradd-man-clarification.patch | 35 ++++++++++++++++++++ shadow-utils.spec | 8 ++++- 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 shadow-4.8.1-useradd-man-clarification.patch diff --git a/shadow-4.8.1-useradd-man-clarification.patch b/shadow-4.8.1-useradd-man-clarification.patch new file mode 100644 index 0000000..9fdb652 --- /dev/null +++ b/shadow-4.8.1-useradd-man-clarification.patch @@ -0,0 +1,35 @@ +From 6543c600d841e4f7779269412d470e50eae25b13 Mon Sep 17 00:00:00 2001 +From: ikerexxe +Date: Wed, 4 Mar 2020 14:50:04 +0100 +Subject: [PATCH] useradd: clarify the useradd -d parameter behavior in man + page + +Explanation: clarify the useradd -d parameter as it does create directory HOME_DIR if it doesn't exit. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1677005 + +Changelog: [serge] minor tweak to the text +--- + man/useradd.8.xml | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/man/useradd.8.xml b/man/useradd.8.xml +index 03612ce8..023c0d69 100644 +--- a/man/useradd.8.xml ++++ b/man/useradd.8.xml +@@ -181,8 +181,10 @@ + login directory. The default is to append the + LOGIN name to + BASE_DIR and use that as the login +- directory name. The directory HOME_DIR +- does not have to exist but will not be created if it is missing. ++ directory name. If the directory ++ HOME_DIR does not exist, then it ++ will be created unless the option is ++ specified. + + + +-- +2.25.1 + diff --git a/shadow-utils.spec b/shadow-utils.spec index 5b58ae6..b3e4575 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.8.1 -Release: 1%{?dist} +Release: 2%{?dist} Epoch: 2 URL: http://pkg-shadow.alioth.debian.org/ Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -51,6 +51,8 @@ Patch38: shadow-4.6-sysugid-min-limit.patch Patch40: shadow-4.8-ignore-login-prompt.patch # Generate /var/spool/mail/$USER with the proper SELinux user identity - already upstreamed Patch42: shadow-4.8-useradd-selinux-mail.patch +# Clarify useradd man regarding "-d" parameter - already upstreamed +Patch43: shadow-4.8.1-useradd-man-clarification.patch License: BSD and GPLv2+ BuildRequires: gcc @@ -99,6 +101,7 @@ are used for managing group accounts. %patch38 -p1 -b .sysugid-min-limit %patch40 -p1 -b .login-prompt %patch42 -p1 -b .useradd-selinux-mail +%patch43 -p1 -b .useradd-man-clarification iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -254,6 +257,9 @@ done %{_mandir}/man8/vigr.8* %changelog +* Tue Mar 24 2020 Iker Pedrosa - 2:4.8.1-2 +- useradd: clarify the useradd -d parameter behavior in man page + * Tue Mar 17 2020 Iker Pedrosa - 2:4.8.1-1 - updated upstream to 4.8.1 From 59585bb37022498ad26331f11ddb7088745dc2c9 Mon Sep 17 00:00:00 2001 From: ipedrosa Date: Thu, 14 May 2020 14:28:59 +0200 Subject: [PATCH 019/134] check only local groups when adding new supplementary groups to a user --- shadow-4.8.1-check-local-groups.patch | 642 ++++++++++++++++++++++++++ shadow-utils.spec | 8 +- 2 files changed, 649 insertions(+), 1 deletion(-) create mode 100644 shadow-4.8.1-check-local-groups.patch diff --git a/shadow-4.8.1-check-local-groups.patch b/shadow-4.8.1-check-local-groups.patch new file mode 100644 index 0000000..6e9d2bf --- /dev/null +++ b/shadow-4.8.1-check-local-groups.patch @@ -0,0 +1,642 @@ +From 140510de9de4771feb3af1d859c09604043a4c9b Mon Sep 17 00:00:00 2001 +From: ikerexxe +Date: Fri, 27 Mar 2020 14:23:02 +0100 +Subject: [PATCH 1/2] usermod: check only local groups with -G option + +Check only local groups when adding new supplementary groups to a user + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1727236 +--- + src/usermod.c | 220 ++++++++++++++++++++++++++++++++------------------ + 1 file changed, 143 insertions(+), 77 deletions(-) + +diff --git a/src/usermod.c b/src/usermod.c +index 05b98715..ef430296 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -183,6 +183,7 @@ static bool sub_gid_locked = false; + static void date_to_str (/*@unique@*//*@out@*/char *buf, size_t maxsize, + long int date); + static int get_groups (char *); ++static struct group * get_local_group (char * grp_name); + static /*@noreturn@*/void usage (int status); + static void new_pwent (struct passwd *); + static void new_spent (struct spwd *); +@@ -196,7 +197,9 @@ static void grp_update (void); + + static void process_flags (int, char **); + static void close_files (void); ++static void close_group_files (void); + static void open_files (void); ++static void open_group_files (void); + static void usr_update (void); + static void move_home (void); + static void update_lastlog (void); +@@ -253,6 +256,11 @@ static int get_groups (char *list) + return 0; + } + ++ /* ++ * Open the group files ++ */ ++ open_group_files (); ++ + /* + * So long as there is some data to be converted, strip off each + * name and look it up. A mix of numerical and string values for +@@ -272,7 +280,7 @@ static int get_groups (char *list) + * Names starting with digits are treated as numerical GID + * values, otherwise the string is looked up as is. + */ +- grp = prefix_getgr_nam_gid (list); ++ grp = get_local_group (list); + + /* + * There must be a match, either by GID value or by +@@ -322,6 +330,8 @@ static int get_groups (char *list) + gr_free ((struct group *)grp); + } while (NULL != list); + ++ close_group_files (); ++ + user_groups[ngroups] = (char *) 0; + + /* +@@ -334,6 +344,44 @@ static int get_groups (char *list) + return 0; + } + ++/* ++ * get_local_group - checks if a given group name exists locally ++ * ++ * get_local_group() checks if a given group name exists locally. ++ * If the name exists the group information is returned, otherwise NULL is ++ * returned. ++ */ ++static struct group * get_local_group(char * grp_name) ++{ ++ const struct group *grp; ++ struct group *result_grp = NULL; ++ long long int gid; ++ char *endptr; ++ ++ gid = strtoll (grp_name, &endptr, 10); ++ if ( ('\0' != *grp_name) ++ && ('\0' == *endptr) ++ && (ERANGE != errno) ++ && (gid == (gid_t)gid)) { ++ grp = gr_locate_gid ((gid_t) gid); ++ } ++ else { ++ grp = gr_locate(grp_name); ++ } ++ ++ if (grp != NULL) { ++ result_grp = __gr_dup (grp); ++ if (NULL == result_grp) { ++ fprintf (stderr, ++ _("%s: Out of memory. Cannot find group '%s'.\n"), ++ Prog, grp_name); ++ fail_exit (E_GRP_UPDATE); ++ } ++ } ++ ++ return result_grp; ++} ++ + #ifdef ENABLE_SUBIDS + struct ulong_range + { +@@ -1447,50 +1495,7 @@ static void close_files (void) + } + + if (Gflg || lflg) { +- if (gr_close () == 0) { +- fprintf (stderr, +- _("%s: failure while writing changes to %s\n"), +- Prog, gr_dbname ()); +- SYSLOG ((LOG_ERR, +- "failure while writing changes to %s", +- gr_dbname ())); +- fail_exit (E_GRP_UPDATE); +- } +-#ifdef SHADOWGRP +- if (is_shadow_grp) { +- if (sgr_close () == 0) { +- fprintf (stderr, +- _("%s: failure while writing changes to %s\n"), +- Prog, sgr_dbname ()); +- SYSLOG ((LOG_ERR, +- "failure while writing changes to %s", +- sgr_dbname ())); +- fail_exit (E_GRP_UPDATE); +- } +- } +-#endif +-#ifdef SHADOWGRP +- if (is_shadow_grp) { +- if (sgr_unlock () == 0) { +- fprintf (stderr, +- _("%s: failed to unlock %s\n"), +- Prog, sgr_dbname ()); +- SYSLOG ((LOG_ERR, +- "failed to unlock %s", +- sgr_dbname ())); +- /* continue */ +- } +- } +-#endif +- if (gr_unlock () == 0) { +- fprintf (stderr, +- _("%s: failed to unlock %s\n"), +- Prog, gr_dbname ()); +- SYSLOG ((LOG_ERR, +- "failed to unlock %s", +- gr_dbname ())); +- /* continue */ +- } ++ close_group_files (); + } + + if (is_shadow_pwd) { +@@ -1559,6 +1564,60 @@ static void close_files (void) + #endif + } + ++/* ++ * close_group_files - close all of the files that were opened ++ * ++ * close_group_files() closes all of the files that were opened related ++ * with groups. This causes any modified entries to be written out. ++ */ ++static void close_group_files (void) ++{ ++ if (gr_close () == 0) { ++ fprintf (stderr, ++ _("%s: failure while writing changes to %s\n"), ++ Prog, gr_dbname ()); ++ SYSLOG ((LOG_ERR, ++ "failure while writing changes to %s", ++ gr_dbname ())); ++ fail_exit (E_GRP_UPDATE); ++ } ++#ifdef SHADOWGRP ++ if (is_shadow_grp) { ++ if (sgr_close () == 0) { ++ fprintf (stderr, ++ _("%s: failure while writing changes to %s\n"), ++ Prog, sgr_dbname ()); ++ SYSLOG ((LOG_ERR, ++ "failure while writing changes to %s", ++ sgr_dbname ())); ++ fail_exit (E_GRP_UPDATE); ++ } ++ } ++#endif ++#ifdef SHADOWGRP ++ if (is_shadow_grp) { ++ if (sgr_unlock () == 0) { ++ fprintf (stderr, ++ _("%s: failed to unlock %s\n"), ++ Prog, sgr_dbname ()); ++ SYSLOG ((LOG_ERR, ++ "failed to unlock %s", ++ sgr_dbname ())); ++ /* continue */ ++ } ++ } ++#endif ++ if (gr_unlock () == 0) { ++ fprintf (stderr, ++ _("%s: failed to unlock %s\n"), ++ Prog, gr_dbname ()); ++ SYSLOG ((LOG_ERR, ++ "failed to unlock %s", ++ gr_dbname ())); ++ /* continue */ ++ } ++} ++ + /* + * open_files - lock and open the password files + * +@@ -1594,38 +1653,7 @@ static void open_files (void) + } + + if (Gflg || lflg) { +- /* +- * Lock and open the group file. This will load all of the +- * group entries. +- */ +- if (gr_lock () == 0) { +- fprintf (stderr, +- _("%s: cannot lock %s; try again later.\n"), +- Prog, gr_dbname ()); +- fail_exit (E_GRP_UPDATE); +- } +- gr_locked = true; +- if (gr_open (O_CREAT | O_RDWR) == 0) { +- fprintf (stderr, +- _("%s: cannot open %s\n"), +- Prog, gr_dbname ()); +- fail_exit (E_GRP_UPDATE); +- } +-#ifdef SHADOWGRP +- if (is_shadow_grp && (sgr_lock () == 0)) { +- fprintf (stderr, +- _("%s: cannot lock %s; try again later.\n"), +- Prog, sgr_dbname ()); +- fail_exit (E_GRP_UPDATE); +- } +- sgr_locked = true; +- if (is_shadow_grp && (sgr_open (O_CREAT | O_RDWR) == 0)) { +- fprintf (stderr, +- _("%s: cannot open %s\n"), +- Prog, sgr_dbname ()); +- fail_exit (E_GRP_UPDATE); +- } +-#endif ++ open_group_files (); + } + #ifdef ENABLE_SUBIDS + if (vflg || Vflg) { +@@ -1661,6 +1689,44 @@ static void open_files (void) + #endif /* ENABLE_SUBIDS */ + } + ++/* ++ * open_group_files - lock and open the group files ++ * ++ * open_group_files() loads all of the group entries. ++ */ ++static void open_group_files (void) ++{ ++ if (gr_lock () == 0) { ++ fprintf (stderr, ++ _("%s: cannot lock %s; try again later.\n"), ++ Prog, gr_dbname ()); ++ fail_exit (E_GRP_UPDATE); ++ } ++ gr_locked = true; ++ if (gr_open (O_CREAT | O_RDWR) == 0) { ++ fprintf (stderr, ++ _("%s: cannot open %s\n"), ++ Prog, gr_dbname ()); ++ fail_exit (E_GRP_UPDATE); ++ } ++ ++#ifdef SHADOWGRP ++ if (is_shadow_grp && (sgr_lock () == 0)) { ++ fprintf (stderr, ++ _("%s: cannot lock %s; try again later.\n"), ++ Prog, sgr_dbname ()); ++ fail_exit (E_GRP_UPDATE); ++ } ++ sgr_locked = true; ++ if (is_shadow_grp && (sgr_open (O_CREAT | O_RDWR) == 0)) { ++ fprintf (stderr, ++ _("%s: cannot open %s\n"), ++ Prog, sgr_dbname ()); ++ fail_exit (E_GRP_UPDATE); ++ } ++#endif ++} ++ + /* + * usr_update - create the user entries + * +-- +2.25.4 + + +From 8762f465d487a52bf68f9c0b7c3c1eb3caea7bc9 Mon Sep 17 00:00:00 2001 +From: ikerexxe +Date: Mon, 30 Mar 2020 09:08:23 +0200 +Subject: [PATCH 2/2] useradd: check only local groups with -G option + +Check only local groups when adding new supplementary groups to a user + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1727236 +--- + src/useradd.c | 234 +++++++++++++++++++++++++++++++++----------------- + 1 file changed, 157 insertions(+), 77 deletions(-) + +diff --git a/src/useradd.c b/src/useradd.c +index 645d4a40..90210233 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -211,6 +211,7 @@ static void get_defaults (void); + static void show_defaults (void); + static int set_defaults (void); + static int get_groups (char *); ++static struct group * get_local_group (char * grp_name); + static void usage (int status); + static void new_pwent (struct passwd *); + +@@ -220,7 +221,10 @@ static void grp_update (void); + + static void process_flags (int argc, char **argv); + static void close_files (void); ++static void close_group_files (void); ++static void unlock_group_files (void); + static void open_files (void); ++static void open_group_files (void); + static void open_shadow (void); + static void faillog_reset (uid_t); + static void lastlog_reset (uid_t); +@@ -731,6 +735,11 @@ static int get_groups (char *list) + return 0; + } + ++ /* ++ * Open the group files ++ */ ++ open_group_files (); ++ + /* + * So long as there is some data to be converted, strip off + * each name and look it up. A mix of numerical and string +@@ -749,7 +758,7 @@ static int get_groups (char *list) + * Names starting with digits are treated as numerical + * GID values, otherwise the string is looked up as is. + */ +- grp = prefix_getgr_nam_gid (list); ++ grp = get_local_group (list); + + /* + * There must be a match, either by GID value or by +@@ -799,6 +808,9 @@ static int get_groups (char *list) + user_groups[ngroups++] = xstrdup (grp->gr_name); + } while (NULL != list); + ++ close_group_files (); ++ unlock_group_files (); ++ + user_groups[ngroups] = (char *) 0; + + /* +@@ -811,6 +823,44 @@ static int get_groups (char *list) + return 0; + } + ++/* ++ * get_local_group - checks if a given group name exists locally ++ * ++ * get_local_group() checks if a given group name exists locally. ++ * If the name exists the group information is returned, otherwise NULL is ++ * returned. ++ */ ++static struct group * get_local_group(char * grp_name) ++{ ++ const struct group *grp; ++ struct group *result_grp = NULL; ++ long long int gid; ++ char *endptr; ++ ++ gid = strtoll (grp_name, &endptr, 10); ++ if ( ('\0' != *grp_name) ++ && ('\0' == *endptr) ++ && (ERANGE != errno) ++ && (gid == (gid_t)gid)) { ++ grp = gr_locate_gid ((gid_t) gid); ++ } ++ else { ++ grp = gr_locate(grp_name); ++ } ++ ++ if (grp != NULL) { ++ result_grp = __gr_dup (grp); ++ if (NULL == result_grp) { ++ fprintf (stderr, ++ _("%s: Out of memory. Cannot find group '%s'.\n"), ++ Prog, grp_name); ++ fail_exit (E_GRP_UPDATE); ++ } ++ } ++ ++ return result_grp; ++} ++ + /* + * usage - display usage message and exit + */ +@@ -1530,23 +1580,9 @@ static void close_files (void) + SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); + fail_exit (E_PW_UPDATE); + } +- if (do_grp_update) { +- if (gr_close () == 0) { +- fprintf (stderr, +- _("%s: failure while writing changes to %s\n"), Prog, gr_dbname ()); +- SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ())); +- fail_exit (E_GRP_UPDATE); +- } +-#ifdef SHADOWGRP +- if (is_shadow_grp && (sgr_close () == 0)) { +- fprintf (stderr, +- _("%s: failure while writing changes to %s\n"), +- Prog, sgr_dbname ()); +- SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ())); +- fail_exit (E_GRP_UPDATE); +- } +-#endif +- } ++ ++ close_group_files (); ++ + #ifdef ENABLE_SUBIDS + if (is_sub_uid && (sub_uid_close () == 0)) { + fprintf (stderr, +@@ -1587,34 +1623,9 @@ static void close_files (void) + /* continue */ + } + pw_locked = false; +- if (gr_unlock () == 0) { +- fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); +- SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); +-#ifdef WITH_AUDIT +- audit_logger (AUDIT_ADD_USER, Prog, +- "unlocking-group-file", +- user_name, AUDIT_NO_ID, +- SHADOW_AUDIT_FAILURE); +-#endif +- /* continue */ +- } +- gr_locked = false; +-#ifdef SHADOWGRP +- if (is_shadow_grp) { +- if (sgr_unlock () == 0) { +- fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); +- SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); +-#ifdef WITH_AUDIT +- audit_logger (AUDIT_ADD_USER, Prog, +- "unlocking-gshadow-file", +- user_name, AUDIT_NO_ID, +- SHADOW_AUDIT_FAILURE); +-#endif +- /* continue */ +- } +- sgr_locked = false; +- } +-#endif ++ ++ unlock_group_files (); ++ + #ifdef ENABLE_SUBIDS + if (is_sub_uid) { + if (sub_uid_unlock () == 0) { +@@ -1647,6 +1658,71 @@ static void close_files (void) + #endif /* ENABLE_SUBIDS */ + } + ++/* ++ * close_group_files - close all of the files that were opened ++ * ++ * close_group_files() closes all of the files that were opened related ++ * with groups. This causes any modified entries to be written out. ++ */ ++static void close_group_files (void) ++{ ++ if (do_grp_update) { ++ if (gr_close () == 0) { ++ fprintf (stderr, ++ _("%s: failure while writing changes to %s\n"), Prog, gr_dbname ()); ++ SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ())); ++ fail_exit (E_GRP_UPDATE); ++ } ++#ifdef SHADOWGRP ++ if (is_shadow_grp && (sgr_close () == 0)) { ++ fprintf (stderr, ++ _("%s: failure while writing changes to %s\n"), ++ Prog, sgr_dbname ()); ++ SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ())); ++ fail_exit (E_GRP_UPDATE); ++ } ++#endif /* SHADOWGRP */ ++ } ++} ++ ++/* ++ * unlock_group_files - unlock all of the files that were locked ++ * ++ * unlock_group_files() unlocks all of the files that were locked related ++ * with groups. This causes any modified entries to be written out. ++ */ ++static void unlock_group_files (void) ++{ ++ if (gr_unlock () == 0) { ++ fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); ++ SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); ++#ifdef WITH_AUDIT ++ audit_logger (AUDIT_ADD_USER, Prog, ++ "unlocking-group-file", ++ user_name, AUDIT_NO_ID, ++ SHADOW_AUDIT_FAILURE); ++#endif /* WITH_AUDIT */ ++ /* continue */ ++ } ++ gr_locked = false; ++#ifdef SHADOWGRP ++ if (is_shadow_grp) { ++ if (sgr_unlock () == 0) { ++ fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); ++ SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); ++#ifdef WITH_AUDIT ++ audit_logger (AUDIT_ADD_USER, Prog, ++ "unlocking-gshadow-file", ++ user_name, AUDIT_NO_ID, ++ SHADOW_AUDIT_FAILURE); ++#endif /* WITH_AUDIT */ ++ /* continue */ ++ } ++ sgr_locked = false; ++ } ++#endif /* SHADOWGRP */ ++} ++ + /* + * open_files - lock and open the password files + * +@@ -1668,37 +1744,8 @@ static void open_files (void) + + /* shadow file will be opened by open_shadow(); */ + +- /* +- * Lock and open the group file. +- */ +- if (gr_lock () == 0) { +- fprintf (stderr, +- _("%s: cannot lock %s; try again later.\n"), +- Prog, gr_dbname ()); +- fail_exit (E_GRP_UPDATE); +- } +- gr_locked = true; +- if (gr_open (O_CREAT | O_RDWR) == 0) { +- fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ()); +- fail_exit (E_GRP_UPDATE); +- } +-#ifdef SHADOWGRP +- if (is_shadow_grp) { +- if (sgr_lock () == 0) { +- fprintf (stderr, +- _("%s: cannot lock %s; try again later.\n"), +- Prog, sgr_dbname ()); +- fail_exit (E_GRP_UPDATE); +- } +- sgr_locked = true; +- if (sgr_open (O_CREAT | O_RDWR) == 0) { +- fprintf (stderr, +- _("%s: cannot open %s\n"), +- Prog, sgr_dbname ()); +- fail_exit (E_GRP_UPDATE); +- } +- } +-#endif ++ open_group_files (); ++ + #ifdef ENABLE_SUBIDS + if (is_sub_uid) { + if (sub_uid_lock () == 0) { +@@ -1733,6 +1780,39 @@ static void open_files (void) + #endif /* ENABLE_SUBIDS */ + } + ++static void open_group_files (void) ++{ ++ if (gr_lock () == 0) { ++ fprintf (stderr, ++ _("%s: cannot lock %s; try again later.\n"), ++ Prog, gr_dbname ()); ++ fail_exit (E_GRP_UPDATE); ++ } ++ gr_locked = true; ++ if (gr_open (O_CREAT | O_RDWR) == 0) { ++ fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ()); ++ fail_exit (E_GRP_UPDATE); ++ } ++ ++#ifdef SHADOWGRP ++ if (is_shadow_grp) { ++ if (sgr_lock () == 0) { ++ fprintf (stderr, ++ _("%s: cannot lock %s; try again later.\n"), ++ Prog, sgr_dbname ()); ++ fail_exit (E_GRP_UPDATE); ++ } ++ sgr_locked = true; ++ if (sgr_open (O_CREAT | O_RDWR) == 0) { ++ fprintf (stderr, ++ _("%s: cannot open %s\n"), ++ Prog, sgr_dbname ()); ++ fail_exit (E_GRP_UPDATE); ++ } ++ } ++#endif /* SHADOWGRP */ ++} ++ + static void open_shadow (void) + { + if (!is_shadow_pwd) { +-- +2.25.4 + diff --git a/shadow-utils.spec b/shadow-utils.spec index b3e4575..8e5057f 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.8.1 -Release: 2%{?dist} +Release: 3%{?dist} Epoch: 2 URL: http://pkg-shadow.alioth.debian.org/ Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -53,6 +53,8 @@ Patch40: shadow-4.8-ignore-login-prompt.patch Patch42: shadow-4.8-useradd-selinux-mail.patch # Clarify useradd man regarding "-d" parameter - already upstreamed Patch43: shadow-4.8.1-useradd-man-clarification.patch +# Upstreamed +Patch44: shadow-4.8.1-check-local-groups.patch License: BSD and GPLv2+ BuildRequires: gcc @@ -102,6 +104,7 @@ are used for managing group accounts. %patch40 -p1 -b .login-prompt %patch42 -p1 -b .useradd-selinux-mail %patch43 -p1 -b .useradd-man-clarification +%patch44 -p1 -b .check-local-groups iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -257,6 +260,9 @@ done %{_mandir}/man8/vigr.8* %changelog +* Thu May 14 2020 Iker Pedrosa - 2:4.8.1-3 +- check only local groups when adding new supplementary groups to a user (#1727236) + * Tue Mar 24 2020 Iker Pedrosa - 2:4.8.1-2 - useradd: clarify the useradd -d parameter behavior in man page From a222f7e8252b458a555203dc73ee7fe3bc6969e6 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 29 Jul 2020 10:37:48 +0000 Subject: [PATCH 020/134] - Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- shadow-utils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index 8e5057f..c8c4d2c 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.8.1 -Release: 3%{?dist} +Release: 4%{?dist} Epoch: 2 URL: http://pkg-shadow.alioth.debian.org/ Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -260,6 +260,9 @@ done %{_mandir}/man8/vigr.8* %changelog +* Wed Jul 29 2020 Fedora Release Engineering - 2:4.8.1-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + * Thu May 14 2020 Iker Pedrosa - 2:4.8.1-3 - check only local groups when adding new supplementary groups to a user (#1727236) From 9f643a301165a0b1bb1fcb7b9c425809d5791a2f Mon Sep 17 00:00:00 2001 From: Ludwig Nussel Date: Thu, 1 Oct 2020 13:23:15 +0000 Subject: [PATCH 021/134] Add Provides: shadow The upstream source tarball is actually called 'shadow' rather than 'shadow-utils'. Add a compat provides for the former. --- shadow-utils.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/shadow-utils.spec b/shadow-utils.spec index c8c4d2c..fbfe028 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -68,6 +68,7 @@ BuildRequires: /usr/bin/xsltproc, /usr/bin/itstool Requires: libselinux >= 1.25.2-1 Requires: audit-libs >= 1.6.5 Requires: setup +Provides: shadow = %{epoch}:%{version}-%{release} %description The shadow-utils package includes the necessary programs for From b7aa9ac8ec1d0d0e3c8d7a8eeda42db41754bd80 Mon Sep 17 00:00:00 2001 From: Petr Lautrbach Date: Tue, 3 Nov 2020 16:14:35 +0100 Subject: [PATCH 022/134] Rebuild with libsemanage.so.2 --- shadow-utils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index fbfe028..3367171 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.8.1 -Release: 4%{?dist} +Release: 5%{?dist} Epoch: 2 URL: http://pkg-shadow.alioth.debian.org/ Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -261,6 +261,9 @@ done %{_mandir}/man8/vigr.8* %changelog +* Tue Nov 3 2020 Petr Lautrbach - 2:4.8.1-5 +- Rebuild with libsemanage.so.2 + * Wed Jul 29 2020 Fedora Release Engineering - 2:4.8.1-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild From 4f395dd42db2c2f6582ac6b1be90c138e090e09f Mon Sep 17 00:00:00 2001 From: ipedrosa Date: Mon, 9 Nov 2020 10:53:20 +0100 Subject: [PATCH 023/134] commonio: force lock file sync (#1862056) --- ...-4.8.1-commonio-force-lock-file-sync.patch | 39 +++++++++++++++++++ shadow-utils.spec | 11 +++++- 2 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 shadow-4.8.1-commonio-force-lock-file-sync.patch diff --git a/shadow-4.8.1-commonio-force-lock-file-sync.patch b/shadow-4.8.1-commonio-force-lock-file-sync.patch new file mode 100644 index 0000000..5ca7b53 --- /dev/null +++ b/shadow-4.8.1-commonio-force-lock-file-sync.patch @@ -0,0 +1,39 @@ +From fb0f702cbf958a5ee9097c1611212c9880b347ce Mon Sep 17 00:00:00 2001 +From: ikerexxe +Date: Mon, 2 Nov 2020 17:08:55 +0100 +Subject: [PATCH] commonio: force lock file sync + +lib/commonio.c: after writing to the lock file, force a file sync to +the storage system. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1862056 +--- + lib/commonio.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/lib/commonio.c b/lib/commonio.c +index 16fa7e75..c5b3d104 100644 +--- a/lib/commonio.c ++++ b/lib/commonio.c +@@ -157,7 +157,17 @@ static int do_lock_file (const char *file, const char *lock, bool log) + if (write (fd, buf, (size_t) len) != len) { + if (log) { + (void) fprintf (stderr, +- "%s: %s: %s\n", ++ "%s: %s file write error: %s\n", ++ Prog, file, strerror (errno)); ++ } ++ (void) close (fd); ++ unlink (file); ++ return 0; ++ } ++ if (fdatasync (fd) == -1) { ++ if (log) { ++ (void) fprintf (stderr, ++ "%s: %s file sync error: %s\n", + Prog, file, strerror (errno)); + } + (void) close (fd); +-- +2.26.2 + diff --git a/shadow-utils.spec b/shadow-utils.spec index 3367171..9c45824 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.8.1 -Release: 5%{?dist} +Release: 6%{?dist} Epoch: 2 URL: http://pkg-shadow.alioth.debian.org/ Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -53,8 +53,11 @@ Patch40: shadow-4.8-ignore-login-prompt.patch Patch42: shadow-4.8-useradd-selinux-mail.patch # Clarify useradd man regarding "-d" parameter - already upstreamed Patch43: shadow-4.8.1-useradd-man-clarification.patch -# Upstreamed +# https://github.com/shadow-maint/shadow/commit/140510de9de4771feb3af1d859c09604043a4c9b +# https://github.com/shadow-maint/shadow/commit/8762f465d487a52bf68f9c0b7c3c1eb3caea7bc9 Patch44: shadow-4.8.1-check-local-groups.patch +# https://github.com/shadow-maint/shadow/commit/599cc003daf833bffdc9cbe0d33dc8b3e7ec74c8 +Patch45: shadow-4.8.1-commonio-force-lock-file-sync.patch License: BSD and GPLv2+ BuildRequires: gcc @@ -106,6 +109,7 @@ are used for managing group accounts. %patch42 -p1 -b .useradd-selinux-mail %patch43 -p1 -b .useradd-man-clarification %patch44 -p1 -b .check-local-groups +%patch45 -p1 -b .commonio-force-lock-file-sync iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -261,6 +265,9 @@ done %{_mandir}/man8/vigr.8* %changelog +* Mon Nov 9 2020 Iker Pedrosa - 2:4.8.1-6 +- commonio: force lock file sync (#1862056) + * Tue Nov 3 2020 Petr Lautrbach - 2:4.8.1-5 - Rebuild with libsemanage.so.2 From 7abff5646c8f0d1b65db0e953247ccb15b2b42ce Mon Sep 17 00:00:00 2001 From: Robert Scheck Date: Thu, 24 Dec 2020 21:10:44 +0000 Subject: [PATCH 024/134] Spec file cleanup --- shadow-utils.spec | 108 +++++++++++++++++++++++----------------------- 1 file changed, 53 insertions(+), 55 deletions(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index 9c45824..279be00 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -3,7 +3,7 @@ Name: shadow-utils Version: 4.8.1 Release: 6%{?dist} Epoch: 2 -URL: http://pkg-shadow.alioth.debian.org/ +URL: https://github.com/shadow-maint/shadow Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz Source1: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz.asc Source2: shadow-utils.useradd @@ -144,66 +144,65 @@ autoreconf %make_build %install -rm -rf $RPM_BUILD_ROOT -%make_install gnulocaledir=$RPM_BUILD_ROOT/%{_datadir}/locale MKINSTALLDIRS=`pwd`/mkinstalldirs -install -d -m 755 $RPM_BUILD_ROOT/%{_sysconfdir}/default -install -p -c -m 0644 %{SOURCE3} $RPM_BUILD_ROOT/%{_sysconfdir}/login.defs -install -p -c -m 0600 %{SOURCE2} $RPM_BUILD_ROOT/%{_sysconfdir}/default/useradd +%make_install gnulocaledir=$RPM_BUILD_ROOT%{_datadir}/locale MKINSTALLDIRS=`pwd`/mkinstalldirs +install -d -m 755 $RPM_BUILD_ROOT%{_sysconfdir}/default +install -p -c -m 0644 %{SOURCE3} $RPM_BUILD_ROOT%{_sysconfdir}/login.defs +install -p -c -m 0600 %{SOURCE2} $RPM_BUILD_ROOT%{_sysconfdir}/default/useradd ln -s useradd $RPM_BUILD_ROOT%{_sbindir}/adduser -ln -s useradd.8 $RPM_BUILD_ROOT/%{_mandir}/man8/adduser.8 -for subdir in $RPM_BUILD_ROOT/%{_mandir}/{??,??_??,??_??.*}/man* ; do +ln -s useradd.8 $RPM_BUILD_ROOT%{_mandir}/man8/adduser.8 +for subdir in $RPM_BUILD_ROOT%{_mandir}/{??,??_??,??_??.*}/man* ; do test -d $subdir && test -e $subdir/useradd.8 && echo ".so man8/useradd.8" > $subdir/adduser.8 done # Remove binaries we don't use. -rm $RPM_BUILD_ROOT/%{_bindir}/chfn -rm $RPM_BUILD_ROOT/%{_bindir}/chsh -rm $RPM_BUILD_ROOT/%{_bindir}/expiry -rm $RPM_BUILD_ROOT/%{_bindir}/groups -rm $RPM_BUILD_ROOT/%{_bindir}/login -rm $RPM_BUILD_ROOT/%{_bindir}/passwd -rm $RPM_BUILD_ROOT/%{_bindir}/su -rm $RPM_BUILD_ROOT/%{_bindir}/faillog -rm $RPM_BUILD_ROOT/%{_sysconfdir}/login.access -rm $RPM_BUILD_ROOT/%{_sysconfdir}/limits -rm $RPM_BUILD_ROOT/%{_sbindir}/logoutd -rm $RPM_BUILD_ROOT/%{_sbindir}/nologin -rm $RPM_BUILD_ROOT/%{_mandir}/man1/chfn.* -rm $RPM_BUILD_ROOT/%{_mandir}/*/man1/chfn.* -rm $RPM_BUILD_ROOT/%{_mandir}/man1/chsh.* -rm $RPM_BUILD_ROOT/%{_mandir}/*/man1/chsh.* -rm $RPM_BUILD_ROOT/%{_mandir}/man1/expiry.* -rm $RPM_BUILD_ROOT/%{_mandir}/*/man1/expiry.* -rm $RPM_BUILD_ROOT/%{_mandir}/man1/groups.* -rm $RPM_BUILD_ROOT/%{_mandir}/*/man1/groups.* -rm $RPM_BUILD_ROOT/%{_mandir}/man1/login.* -rm $RPM_BUILD_ROOT/%{_mandir}/*/man1/login.* -rm $RPM_BUILD_ROOT/%{_mandir}/man1/passwd.* -rm $RPM_BUILD_ROOT/%{_mandir}/*/man1/passwd.* -rm $RPM_BUILD_ROOT/%{_mandir}/man1/su.* -rm $RPM_BUILD_ROOT/%{_mandir}/*/man1/su.* -rm $RPM_BUILD_ROOT/%{_mandir}/man5/limits.* -rm $RPM_BUILD_ROOT/%{_mandir}/*/man5/limits.* -rm $RPM_BUILD_ROOT/%{_mandir}/man5/login.access.* -rm $RPM_BUILD_ROOT/%{_mandir}/*/man5/login.access.* -rm $RPM_BUILD_ROOT/%{_mandir}/man5/passwd.* -rm $RPM_BUILD_ROOT/%{_mandir}/*/man5/passwd.* -rm $RPM_BUILD_ROOT/%{_mandir}/man5/porttime.* -rm $RPM_BUILD_ROOT/%{_mandir}/*/man5/porttime.* -rm $RPM_BUILD_ROOT/%{_mandir}/man5/suauth.* -rm $RPM_BUILD_ROOT/%{_mandir}/*/man5/suauth.* -rm $RPM_BUILD_ROOT/%{_mandir}/man8/logoutd.* -rm $RPM_BUILD_ROOT/%{_mandir}/*/man8/logoutd.* -rm $RPM_BUILD_ROOT/%{_mandir}/man8/nologin.* -rm $RPM_BUILD_ROOT/%{_mandir}/*/man8/nologin.* -rm $RPM_BUILD_ROOT/%{_mandir}/man3/getspnam.* -rm $RPM_BUILD_ROOT/%{_mandir}/*/man3/getspnam.* -rm $RPM_BUILD_ROOT/%{_mandir}/man5/faillog.* -rm $RPM_BUILD_ROOT/%{_mandir}/*/man5/faillog.* -rm $RPM_BUILD_ROOT/%{_mandir}/man8/faillog.* -rm $RPM_BUILD_ROOT/%{_mandir}/*/man8/faillog.* +rm $RPM_BUILD_ROOT%{_bindir}/chfn +rm $RPM_BUILD_ROOT%{_bindir}/chsh +rm $RPM_BUILD_ROOT%{_bindir}/expiry +rm $RPM_BUILD_ROOT%{_bindir}/groups +rm $RPM_BUILD_ROOT%{_bindir}/login +rm $RPM_BUILD_ROOT%{_bindir}/passwd +rm $RPM_BUILD_ROOT%{_bindir}/su +rm $RPM_BUILD_ROOT%{_bindir}/faillog +rm $RPM_BUILD_ROOT%{_sysconfdir}/login.access +rm $RPM_BUILD_ROOT%{_sysconfdir}/limits +rm $RPM_BUILD_ROOT%{_sbindir}/logoutd +rm $RPM_BUILD_ROOT%{_sbindir}/nologin +rm $RPM_BUILD_ROOT%{_mandir}/man1/chfn.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man1/chfn.* +rm $RPM_BUILD_ROOT%{_mandir}/man1/chsh.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man1/chsh.* +rm $RPM_BUILD_ROOT%{_mandir}/man1/expiry.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man1/expiry.* +rm $RPM_BUILD_ROOT%{_mandir}/man1/groups.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man1/groups.* +rm $RPM_BUILD_ROOT%{_mandir}/man1/login.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man1/login.* +rm $RPM_BUILD_ROOT%{_mandir}/man1/passwd.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man1/passwd.* +rm $RPM_BUILD_ROOT%{_mandir}/man1/su.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man1/su.* +rm $RPM_BUILD_ROOT%{_mandir}/man5/limits.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man5/limits.* +rm $RPM_BUILD_ROOT%{_mandir}/man5/login.access.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man5/login.access.* +rm $RPM_BUILD_ROOT%{_mandir}/man5/passwd.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man5/passwd.* +rm $RPM_BUILD_ROOT%{_mandir}/man5/porttime.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man5/porttime.* +rm $RPM_BUILD_ROOT%{_mandir}/man5/suauth.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man5/suauth.* +rm $RPM_BUILD_ROOT%{_mandir}/man8/logoutd.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man8/logoutd.* +rm $RPM_BUILD_ROOT%{_mandir}/man8/nologin.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man8/nologin.* +rm $RPM_BUILD_ROOT%{_mandir}/man3/getspnam.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man3/getspnam.* +rm $RPM_BUILD_ROOT%{_mandir}/man5/faillog.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man5/faillog.* +rm $RPM_BUILD_ROOT%{_mandir}/man8/faillog.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man8/faillog.* find $RPM_BUILD_ROOT%{_mandir} -depth -type d -empty -delete %find_lang shadow @@ -217,7 +216,6 @@ done %files -f shadow.lang %doc NEWS doc/HOWTO README -%{!?_licensedir:%global license %%doc} %license gpl-2.0.txt shadow-bsd.txt %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/login.defs %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/default/useradd From cc2729413813140e9b1abb153976bc618abf36a6 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Fri, 8 Jan 2021 21:26:08 +0000 Subject: [PATCH 025/134] Add BuildRequires: make https://fedoraproject.org/wiki/Changes/Remove_make_from_BuildRoot --- shadow-utils.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/shadow-utils.spec b/shadow-utils.spec index 279be00..5f23763 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -60,6 +60,7 @@ Patch44: shadow-4.8.1-check-local-groups.patch Patch45: shadow-4.8.1-commonio-force-lock-file-sync.patch License: BSD and GPLv2+ +BuildRequires: make BuildRequires: gcc BuildRequires: libselinux-devel >= 1.25.2-1 BuildRequires: audit-libs-devel >= 1.6.5 From 4e14ecca65608158ec9eb2418361b1c5dbb61a8d Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 27 Jan 2021 20:17:47 +0000 Subject: [PATCH 026/134] - Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- shadow-utils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index 5f23763..0d25632 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.8.1 -Release: 6%{?dist} +Release: 7%{?dist} Epoch: 2 URL: https://github.com/shadow-maint/shadow Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -264,6 +264,9 @@ done %{_mandir}/man8/vigr.8* %changelog +* Wed Jan 27 2021 Fedora Release Engineering - 2:4.8.1-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + * Mon Nov 9 2020 Iker Pedrosa - 2:4.8.1-6 - commonio: force lock file sync (#1862056) From 3e39e1d4e3a095e4aaa1395b4e393cfbd7372755 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Mon, 29 Mar 2021 12:29:20 +0200 Subject: [PATCH 027/134] - man: include lastlog file caveat (#951564) - Upstream links to several patches - Spec file cleanup by Robert Scheck - Add BuildRequires: make by Tom Stellard --- ....8.1-man-include-lastlog-file-caveat.patch | 33 +++++++++++++++++++ shadow-utils.spec | 21 +++++++++--- 2 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 shadow-4.8.1-man-include-lastlog-file-caveat.patch diff --git a/shadow-4.8.1-man-include-lastlog-file-caveat.patch b/shadow-4.8.1-man-include-lastlog-file-caveat.patch new file mode 100644 index 0000000..7be60c5 --- /dev/null +++ b/shadow-4.8.1-man-include-lastlog-file-caveat.patch @@ -0,0 +1,33 @@ +From df6ec1d1693c8c80c323b40d6fc82bb549363db3 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Mon, 29 Mar 2021 05:26:28 +0200 +Subject: [PATCH] man: include lastlog file caveat (#313) + +man/lastlog.8.xml: add another point to the caveats section regarding +the handling of the lastlog file by external tools. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=951564 +--- + man/lastlog.8.xml | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/man/lastlog.8.xml b/man/lastlog.8.xml +index fc096c8f..7e68282f 100644 +--- a/man/lastlog.8.xml ++++ b/man/lastlog.8.xml +@@ -233,5 +233,12 @@ + is no entries for users with UID between 170 and 800 lastlog will appear + to hang as it processes entries with UIDs 171-799). + ++ ++ Having high UIDs can create problems when handling the ++ /var/log/lastlog with external tools. Although the ++ actual file is sparse and does not use too much space, certain ++ applications are not designed to identify sparse files by default and may ++ require a specific option to handle them. ++ + + +-- +2.30.2 + diff --git a/shadow-utils.spec b/shadow-utils.spec index 0d25632..8d1f5ea 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.8.1 -Release: 7%{?dist} +Release: 8%{?dist} Epoch: 2 URL: https://github.com/shadow-maint/shadow Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -15,17 +15,19 @@ Source6: shadow-utils.HOME_MODE.xml Patch0: shadow-4.6-redhat.patch # Be more lenient with acceptable user/group names - non upstreamable Patch1: shadow-4.8-goodname.patch -# Docfix for newusers - could be upstreamed +# https://github.com/shadow-maint/shadow/commit/7384865775b0203b9cf5337a047744f0a4555868 Patch2: shadow-4.1.5.1-info-parent-dir.patch # Misc SElinux related changes - upstreamability unknown Patch6: shadow-4.8-selinux.patch -# Syslog message change - could be upstreamed +# https://github.com/shadow-maint/shadow/commit/a8361e741040cd926c9c93aac89820052531b1a3 Patch11: shadow-4.1.5.1-logmsg.patch # SElinux related - upstreamability unknown Patch14: shadow-4.1.5.1-default-range.patch -# Misc manual page changes - only some of them could be upstreamed +# Misc manual page changes +# https://github.com/shadow-maint/shadow/commit/c0818ab01d1896784245eedec9495e1e6e0260af +# Changes in man/groupmems.8.xml, man/ja/man5/login.defs.5 and man/login.defs.5.xml not upstreamed Patch15: shadow-4.8.1-manfix.patch -# Userdel usage message change - could be upstreamed +# https://github.com/shadow-maint/shadow/commit/f4cbf38ad7801bab6fae50e9b5a2effc3c48a1ea Patch17: shadow-4.1.5.1-userdel-helpfix.patch # Date parsing improvement - could be upstreamed Patch19: shadow-4.2.1-date-parsing.patch @@ -58,6 +60,8 @@ Patch43: shadow-4.8.1-useradd-man-clarification.patch Patch44: shadow-4.8.1-check-local-groups.patch # https://github.com/shadow-maint/shadow/commit/599cc003daf833bffdc9cbe0d33dc8b3e7ec74c8 Patch45: shadow-4.8.1-commonio-force-lock-file-sync.patch +# https://github.com/shadow-maint/shadow/commit/df6ec1d1693c8c80c323b40d6fc82bb549363db3 +Patch46: shadow-4.8.1-man-include-lastlog-file-caveat.patch License: BSD and GPLv2+ BuildRequires: make @@ -111,6 +115,7 @@ are used for managing group accounts. %patch43 -p1 -b .useradd-man-clarification %patch44 -p1 -b .check-local-groups %patch45 -p1 -b .commonio-force-lock-file-sync +%patch46 -p1 -b .man-include-lastlog-file-caveat iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -264,6 +269,12 @@ done %{_mandir}/man8/vigr.8* %changelog +* Mon Mar 29 2021 Iker Pedrosa - 2:4.8.1-8 +- man: include lastlog file caveat (#951564) +- Upstream links to several patches +- Spec file cleanup by Robert Scheck +- Add BuildRequires: make by Tom Stellard + * Wed Jan 27 2021 Fedora Release Engineering - 2:4.8.1-7 - Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild From 5292920d9b991fcfc7edb4dd7d427a8ae93ef092 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Fri, 16 Apr 2021 16:18:35 +0200 Subject: [PATCH 028/134] - libsubid: creation and nsswitch support - Creation of subid and subid-devel subpackages --- shadow-4.8.1-libsubid_creation.patch | 1522 +++++++++++++ shadow-4.8.1-libsubid_nsswitch_support.patch | 2107 ++++++++++++++++++ shadow-utils.spec | 56 +- 3 files changed, 3683 insertions(+), 2 deletions(-) create mode 100644 shadow-4.8.1-libsubid_creation.patch create mode 100644 shadow-4.8.1-libsubid_nsswitch_support.patch diff --git a/shadow-4.8.1-libsubid_creation.patch b/shadow-4.8.1-libsubid_creation.patch new file mode 100644 index 0000000..072ed2e --- /dev/null +++ b/shadow-4.8.1-libsubid_creation.patch @@ -0,0 +1,1522 @@ +From 0a7888b1fad613a052b988b01a71933b67296e68 Mon Sep 17 00:00:00 2001 +From: Serge Hallyn +Date: Sat, 18 Apr 2020 18:03:54 -0500 +Subject: [PATCH] Create a new libsubid + +Closes #154 + +Currently this has three functions: one which returns the +list of subuid ranges for a user, one returning the subgids, +and one which frees the ranges lists. + +I might be mistaken about what -disable-man means; some of +the code suggests it means just don't re-generate them, but +not totally ignore them. But that doesn't seem to really work, +so let's just ignore man/ when -disable-man. + +Remove --disable-shared. I'm not sure why it was there, but it stems +from long, long ago, and I suspect it comes from some ancient +toolchain bug. + +Create a tests/run_some, a shorter version of run_all. I'll +slowly add tests to this as I verify they work, then I can +work on fixing the once which don't. + +Also, don't touch man/ if not -enable-man. + +Changelog: + Apr 22: change the subid list api as recomended by Dan Walsh. + Apr 23: implement get_subid_owner + Apr 24: implement range add/release + Apr 25: finish tests and rebase + May 10: make @owner const + +Signed-off-by: Serge Hallyn +--- + Makefile.am | 13 +- + configure.ac | 3 +- + lib/subordinateio.c | 204 +++++++++++++++- + lib/subordinateio.h | 7 + + libsubid/Makefile.am | 25 ++ + libsubid/api.c | 231 ++++++++++++++++++ + libsubid/api.h | 17 ++ + libsubid/subid.h | 17 ++ + src/Makefile.am | 60 +++++ + src/free_subid_range.c | 50 ++++ + src/get_subid_owners.c | 40 +++ + src/list_subid_ranges.c | 41 ++++ + src/new_subid_range.c | 57 +++++ + tests/libsubid/01_list_ranges/config.txt | 0 + .../libsubid/01_list_ranges/config/etc/subgid | 2 + + .../libsubid/01_list_ranges/config/etc/subuid | 3 + + .../libsubid/01_list_ranges/list_ranges.test | 38 +++ + tests/libsubid/02_get_subid_owners/config.txt | 0 + .../02_get_subid_owners/config/etc/passwd | 20 ++ + .../02_get_subid_owners/config/etc/subgid | 2 + + .../02_get_subid_owners/config/etc/subuid | 4 + + .../02_get_subid_owners/get_subid_owners.test | 52 ++++ + .../03_add_remove/add_remove_subids.test | 59 +++++ + tests/libsubid/03_add_remove/config.txt | 0 + .../libsubid/03_add_remove/config/etc/passwd | 20 ++ + .../libsubid/03_add_remove/config/etc/subgid | 2 + + .../libsubid/03_add_remove/config/etc/subuid | 1 + + tests/run_some | 136 +++++++++++ + 31 files changed, 1105 insertions(+), 17 deletions(-) + create mode 100644 libsubid/Makefile.am + create mode 100644 libsubid/api.c + create mode 100644 libsubid/api.h + create mode 100644 libsubid/subid.h + create mode 100644 src/free_subid_range.c + create mode 100644 src/get_subid_owners.c + create mode 100644 src/list_subid_ranges.c + create mode 100644 src/new_subid_range.c + create mode 100644 tests/libsubid/01_list_ranges/config.txt + create mode 100644 tests/libsubid/01_list_ranges/config/etc/subgid + create mode 100644 tests/libsubid/01_list_ranges/config/etc/subuid + create mode 100755 tests/libsubid/01_list_ranges/list_ranges.test + create mode 100644 tests/libsubid/02_get_subid_owners/config.txt + create mode 100644 tests/libsubid/02_get_subid_owners/config/etc/passwd + create mode 100644 tests/libsubid/02_get_subid_owners/config/etc/subgid + create mode 100644 tests/libsubid/02_get_subid_owners/config/etc/subuid + create mode 100755 tests/libsubid/02_get_subid_owners/get_subid_owners.test + create mode 100755 tests/libsubid/03_add_remove/add_remove_subids.test + create mode 100644 tests/libsubid/03_add_remove/config.txt + create mode 100644 tests/libsubid/03_add_remove/config/etc/passwd + create mode 100644 tests/libsubid/03_add_remove/config/etc/subgid + create mode 100644 tests/libsubid/03_add_remove/config/etc/subuid + create mode 100755 tests/run_some + +diff --git a/Makefile.am b/Makefile.am +index 8851f5d6..b6456cf9 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -2,5 +2,14 @@ + + EXTRA_DIST = NEWS README TODO shadow.spec.in + +-SUBDIRS = po man libmisc lib src \ +- contrib doc etc ++SUBDIRS = libmisc lib ++ ++if ENABLE_SUBIDS ++SUBDIRS += libsubid ++endif ++ ++SUBDIRS += src po contrib doc etc ++ ++if ENABLE_REGENERATE_MAN ++SUBDIRS += man ++endif +diff --git a/configure.ac b/configure.ac +index b8bc2b7a..b766eff0 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -22,8 +22,8 @@ test "$prefix" = "/usr" && exec_prefix="" + + AC_GNU_SOURCE + +-AM_DISABLE_SHARED + AM_ENABLE_STATIC ++AM_ENABLE_SHARED + + AM_MAINTAINER_MODE + +@@ -725,6 +725,7 @@ AC_CONFIG_FILES([ + man/zh_TW/Makefile + libmisc/Makefile + lib/Makefile ++ libsubid/Makefile + src/Makefile + contrib/Makefile + etc/Makefile +diff --git a/lib/subordinateio.c b/lib/subordinateio.c +index 0d89a64e..67202c98 100644 +--- a/lib/subordinateio.c ++++ b/lib/subordinateio.c +@@ -13,14 +13,7 @@ + #include "subordinateio.h" + #include + #include +- +-struct subordinate_range { +- const char *owner; +- unsigned long start; +- unsigned long count; +-}; +- +-#define NFIELDS 3 ++#include + + /* + * subordinate_dup: create a duplicate range +@@ -78,7 +71,7 @@ static void *subordinate_parse (const char *line) + static char rangebuf[1024]; + int i; + char *cp; +- char *fields[NFIELDS]; ++ char *fields[SUBID_NFIELDS]; + + /* + * Copy the string to a temporary buffer so the substrings can +@@ -93,7 +86,7 @@ static void *subordinate_parse (const char *line) + * field. The fields are converted into NUL terminated strings. + */ + +- for (cp = rangebuf, i = 0; (i < NFIELDS) && (NULL != cp); i++) { ++ for (cp = rangebuf, i = 0; (i < SUBID_NFIELDS) && (NULL != cp); i++) { + fields[i] = cp; + while (('\0' != *cp) && (':' != *cp)) { + cp++; +@@ -108,10 +101,10 @@ static void *subordinate_parse (const char *line) + } + + /* +- * There must be exactly NFIELDS colon separated fields or ++ * There must be exactly SUBID_NFIELDS colon separated fields or + * the entry is invalid. Also, fields must be non-blank. + */ +- if (i != NFIELDS || *fields[0] == '\0' || *fields[1] == '\0' || *fields[2] == '\0') ++ if (i != SUBID_NFIELDS || *fields[0] == '\0' || *fields[1] == '\0' || *fields[2] == '\0') + return NULL; + range.owner = fields[0]; + if (getulong (fields[1], &range.start) == 0) +@@ -314,6 +307,39 @@ static bool have_range(struct commonio_db *db, + return false; + } + ++static bool append_range(struct subordinate_range ***ranges, const struct subordinate_range *new, int n) ++{ ++ struct subordinate_range *tmp; ++ if (!*ranges) { ++ *ranges = malloc(2 * sizeof(struct subordinate_range **)); ++ if (!*ranges) ++ return false; ++ } else { ++ struct subordinate_range **new; ++ new = realloc(*ranges, (n + 2) * (sizeof(struct subordinate_range **))); ++ if (!new) ++ return false; ++ *ranges = new; ++ } ++ (*ranges)[n] = (*ranges)[n+1] = NULL; ++ tmp = subordinate_dup(new); ++ if (!tmp) ++ return false; ++ (*ranges)[n] = tmp; ++ return true; ++} ++ ++void free_subordinate_ranges(struct subordinate_range **ranges) ++{ ++ int i; ++ ++ if (!ranges) ++ return; ++ for (i = 0; ranges[i]; i++) ++ subordinate_free(ranges[i]); ++ free(ranges); ++} ++ + /* + * subordinate_range_cmp: compare uid ranges + * +@@ -692,6 +718,160 @@ gid_t sub_gid_find_free_range(gid_t min, gid_t max, unsigned long count) + start = find_free_range (&subordinate_gid_db, min, max, count); + return start == ULONG_MAX ? (gid_t) -1 : start; + } ++ ++/* ++ struct subordinate_range **list_owner_ranges(const char *owner, enum subid_type id_type) ++ * ++ * @owner: username ++ * @id_type: UID or GUID ++ * ++ * Returns the subuid or subgid ranges which are owned by the specified ++ * user. Username may be a username or a string representation of a ++ * UID number. If id_type is UID, then subuids are returned, else ++ * subgids are returned. If there is an error, < 0 is returned. ++ * ++ * The caller must free the subordinate range list. ++ */ ++struct subordinate_range **list_owner_ranges(const char *owner, enum subid_type id_type) ++{ ++ // TODO - need to handle owner being either uid or username ++ const struct subordinate_range *range; ++ struct subordinate_range **ranges = NULL; ++ struct commonio_db *db; ++ int size = 0; ++ ++ if (id_type == ID_TYPE_UID) ++ db = &subordinate_uid_db; ++ else ++ db = &subordinate_gid_db; ++ ++ commonio_rewind(db); ++ while ((range = commonio_next(db)) != NULL) { ++ if (0 == strcmp(range->owner, owner)) { ++ if (!append_range(&ranges, range, size++)) { ++ free_subordinate_ranges(ranges); ++ return NULL; ++ } ++ } ++ } ++ ++ return ranges; ++} ++ ++static bool all_digits(const char *str) ++{ ++ int i; ++ ++ for (i = 0; str[i] != '\0'; i++) ++ if (!isdigit(str[i])) ++ return false; ++ return true; ++} ++ ++static int append_uids(uid_t **uids, const char *owner, int n) ++{ ++ uid_t owner_uid; ++ uid_t *ret; ++ int i; ++ ++ if (all_digits(owner)) { ++ i = sscanf(owner, "%d", &owner_uid); ++ if (i != 1) { ++ // should not happen ++ free(*uids); ++ *uids = NULL; ++ return -1; ++ } ++ } else { ++ struct passwd *pwd = getpwnam(owner); ++ if (NULL == pwd) { ++ /* Username not defined in /etc/passwd, or error occured during lookup */ ++ free(*uids); ++ *uids = NULL; ++ return -1; ++ } ++ owner_uid = pwd->pw_uid; ++ } ++ ++ for (i = 0; i < n; i++) { ++ if (owner_uid == (*uids)[i]) ++ return n; ++ } ++ ++ ret = realloc(*uids, (n + 1) * sizeof(uid_t)); ++ if (!ret) { ++ free(*uids); ++ return -1; ++ } ++ ret[n] = owner_uid; ++ *uids = ret; ++ return n+1; ++} ++ ++int find_subid_owners(unsigned long id, uid_t **uids, enum subid_type id_type) ++{ ++ const struct subordinate_range *range; ++ struct commonio_db *db; ++ int n = 0; ++ ++ *uids = NULL; ++ if (id_type == ID_TYPE_UID) ++ db = &subordinate_uid_db; ++ else ++ db = &subordinate_gid_db; ++ ++ commonio_rewind(db); ++ while ((range = commonio_next(db)) != NULL) { ++ if (id >= range->start && id < range->start + range-> count) { ++ n = append_uids(uids, range->owner, n); ++ if (n < 0) ++ break; ++ } ++ } ++ ++ return n; ++} ++ ++bool new_subid_range(struct subordinate_range *range, enum subid_type id_type, bool reuse) ++{ ++ struct commonio_db *db; ++ const struct subordinate_range *r; ++ ++ if (id_type == ID_TYPE_UID) ++ db = &subordinate_uid_db; ++ else ++ db = &subordinate_gid_db; ++ commonio_rewind(db); ++ if (reuse) { ++ while ((r = commonio_next(db)) != NULL) { ++ // TODO account for username vs uid_t ++ if (0 != strcmp(r->owner, range->owner)) ++ continue; ++ if (r->count >= range->count) { ++ range->count = r->count; ++ range->start = r->start; ++ return true; ++ } ++ } ++ } ++ ++ range->start = find_free_range(db, range->start, ULONG_MAX, range->count); ++ if (range->start == ULONG_MAX) ++ return false; ++ ++ return add_range(db, range->owner, range->start, range->count) == 1; ++} ++ ++bool release_subid_range(struct subordinate_range *range, enum subid_type id_type) ++{ ++ struct commonio_db *db; ++ if (id_type == ID_TYPE_UID) ++ db = &subordinate_uid_db; ++ else ++ db = &subordinate_gid_db; ++ return remove_range(db, range->owner, range->start, range->count) == 1; ++} ++ + #else /* !ENABLE_SUBIDS */ + extern int errno; /* warning: ANSI C forbids an empty source file */ + #endif /* !ENABLE_SUBIDS */ +diff --git a/lib/subordinateio.h b/lib/subordinateio.h +index a21d72b8..13a21341 100644 +--- a/lib/subordinateio.h ++++ b/lib/subordinateio.h +@@ -11,6 +11,8 @@ + + #include + ++#include "../libsubid/subid.h" ++ + extern int sub_uid_close(void); + extern bool have_sub_uids(const char *owner, uid_t start, unsigned long count); + extern bool sub_uid_file_present (void); +@@ -23,6 +25,11 @@ extern int sub_uid_unlock (void); + extern int sub_uid_add (const char *owner, uid_t start, unsigned long count); + extern int sub_uid_remove (const char *owner, uid_t start, unsigned long count); + extern uid_t sub_uid_find_free_range(uid_t min, uid_t max, unsigned long count); ++extern struct subordinate_range **list_owner_ranges(const char *owner, enum subid_type id_type); ++extern bool new_subid_range(struct subordinate_range *range, enum subid_type id_type, bool reuse); ++extern bool release_subid_range(struct subordinate_range *range, enum subid_type id_type); ++extern int find_subid_owners(unsigned long id, uid_t **uids, enum subid_type id_type); ++extern void free_subordinate_ranges(struct subordinate_range **ranges); + + extern int sub_gid_close(void); + extern bool have_sub_gids(const char *owner, gid_t start, unsigned long count); +diff --git a/libsubid/Makefile.am b/libsubid/Makefile.am +new file mode 100644 +index 00000000..bdbc52c3 +--- /dev/null ++++ b/libsubid/Makefile.am +@@ -0,0 +1,25 @@ ++lib_LTLIBRARIES = libsubid.la ++libsubid_la_LDFLAGS = -Wl,-soname,libsubid.so.@LIBSUBID_ABI@ \ ++ -shared -version-info @LIBSUBID_ABI_MAJOR@ ++libsubid_la_SOURCES = api.c ++ ++MISCLIBS = \ ++ $(LIBAUDIT) \ ++ $(LIBSELINUX) \ ++ $(LIBSEMANAGE) \ ++ $(LIBCRYPT_NOPAM) \ ++ $(LIBSKEY) \ ++ $(LIBMD) \ ++ $(LIBECONF) \ ++ $(LIBCRYPT) \ ++ $(LIBTCB) ++ ++libsubid_la_LIBADD = \ ++ $(top_srcdir)/lib/libshadow.la \ ++ $(top_srcdir)/libmisc/libmisc.a \ ++ $(MISCLIBS) ++ ++AM_CPPFLAGS = \ ++ -I${top_srcdir}/lib \ ++ -I${top_srcdir}/libmisc \ ++ -DLOCALEDIR=\"$(datadir)/locale\" +diff --git a/libsubid/api.c b/libsubid/api.c +new file mode 100644 +index 00000000..91d73bed +--- /dev/null ++++ b/libsubid/api.c +@@ -0,0 +1,231 @@ ++/* ++ * Copyright (c) 2020 Serge Hallyn ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The name of the copyright holders or contributors may not be used to ++ * endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A ++ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "subordinateio.h" ++#include "idmapping.h" ++#include "api.h" ++ ++static struct subordinate_range **get_subid_ranges(const char *owner, enum subid_type id_type) ++{ ++ struct subordinate_range **ranges = NULL; ++ ++ switch (id_type) { ++ case ID_TYPE_UID: ++ if (!sub_uid_open(O_RDONLY)) { ++ return NULL; ++ } ++ break; ++ case ID_TYPE_GID: ++ if (!sub_gid_open(O_RDONLY)) { ++ return NULL; ++ } ++ break; ++ default: ++ return NULL; ++ } ++ ++ ranges = list_owner_ranges(owner, id_type); ++ ++ if (id_type == ID_TYPE_UID) ++ sub_uid_close(); ++ else ++ sub_gid_close(); ++ ++ return ranges; ++} ++ ++struct subordinate_range **get_subuid_ranges(const char *owner) ++{ ++ return get_subid_ranges(owner, ID_TYPE_UID); ++} ++ ++struct subordinate_range **get_subgid_ranges(const char *owner) ++{ ++ return get_subid_ranges(owner, ID_TYPE_GID); ++} ++ ++void subid_free_ranges(struct subordinate_range **ranges) ++{ ++ return free_subordinate_ranges(ranges); ++} ++ ++int get_subid_owner(unsigned long id, uid_t **owner, enum subid_type id_type) ++{ ++ int ret = -1; ++ ++ switch (id_type) { ++ case ID_TYPE_UID: ++ if (!sub_uid_open(O_RDONLY)) { ++ return -1; ++ } ++ break; ++ case ID_TYPE_GID: ++ if (!sub_gid_open(O_RDONLY)) { ++ return -1; ++ } ++ break; ++ default: ++ return -1; ++ } ++ ++ ret = find_subid_owners(id, owner, id_type); ++ ++ if (id_type == ID_TYPE_UID) ++ sub_uid_close(); ++ else ++ sub_gid_close(); ++ ++ return ret; ++} ++ ++int get_subuid_owners(uid_t uid, uid_t **owner) ++{ ++ return get_subid_owner((unsigned long)uid, owner, ID_TYPE_UID); ++} ++ ++int get_subgid_owners(gid_t gid, uid_t **owner) ++{ ++ return get_subid_owner((unsigned long)gid, owner, ID_TYPE_GID); ++} ++ ++bool grant_subid_range(struct subordinate_range *range, bool reuse, ++ enum subid_type id_type) ++{ ++ bool ret; ++ ++ switch (id_type) { ++ case ID_TYPE_UID: ++ if (!sub_uid_lock()) { ++ printf("Failed loging subuids (errno %d)\n", errno); ++ return false; ++ } ++ if (!sub_uid_open(O_CREAT | O_RDWR)) { ++ printf("Failed opening subuids (errno %d)\n", errno); ++ sub_uid_unlock(); ++ return false; ++ } ++ break; ++ case ID_TYPE_GID: ++ if (!sub_gid_lock()) { ++ printf("Failed loging subgids (errno %d)\n", errno); ++ return false; ++ } ++ if (!sub_gid_open(O_CREAT | O_RDWR)) { ++ printf("Failed opening subgids (errno %d)\n", errno); ++ sub_gid_unlock(); ++ return false; ++ } ++ break; ++ default: ++ return false; ++ } ++ ++ ret = new_subid_range(range, id_type, reuse); ++ ++ if (id_type == ID_TYPE_UID) { ++ sub_uid_close(); ++ sub_uid_unlock(); ++ } else { ++ sub_gid_close(); ++ sub_gid_unlock(); ++ } ++ ++ return ret; ++} ++ ++bool grant_subuid_range(struct subordinate_range *range, bool reuse) ++{ ++ return grant_subid_range(range, reuse, ID_TYPE_UID); ++} ++ ++bool grant_subgid_range(struct subordinate_range *range, bool reuse) ++{ ++ return grant_subid_range(range, reuse, ID_TYPE_GID); ++} ++ ++bool free_subid_range(struct subordinate_range *range, enum subid_type id_type) ++{ ++ bool ret; ++ ++ switch (id_type) { ++ case ID_TYPE_UID: ++ if (!sub_uid_lock()) { ++ printf("Failed loging subuids (errno %d)\n", errno); ++ return false; ++ } ++ if (!sub_uid_open(O_CREAT | O_RDWR)) { ++ printf("Failed opening subuids (errno %d)\n", errno); ++ sub_uid_unlock(); ++ return false; ++ } ++ break; ++ case ID_TYPE_GID: ++ if (!sub_gid_lock()) { ++ printf("Failed loging subgids (errno %d)\n", errno); ++ return false; ++ } ++ if (!sub_gid_open(O_CREAT | O_RDWR)) { ++ printf("Failed opening subgids (errno %d)\n", errno); ++ sub_gid_unlock(); ++ return false; ++ } ++ break; ++ default: ++ return false; ++ } ++ ++ ret = release_subid_range(range, id_type); ++ ++ if (id_type == ID_TYPE_UID) { ++ sub_uid_close(); ++ sub_uid_unlock(); ++ } else { ++ sub_gid_close(); ++ sub_gid_unlock(); ++ } ++ ++ return ret; ++} ++ ++bool free_subuid_range(struct subordinate_range *range) ++{ ++ return free_subid_range(range, ID_TYPE_UID); ++} ++ ++bool free_subgid_range(struct subordinate_range *range) ++{ ++ return free_subid_range(range, ID_TYPE_GID); ++} +diff --git a/libsubid/api.h b/libsubid/api.h +new file mode 100644 +index 00000000..f65e3ec9 +--- /dev/null ++++ b/libsubid/api.h +@@ -0,0 +1,17 @@ ++#include "subid.h" ++#include ++ ++struct subordinate_range **get_subuid_ranges(const char *owner); ++struct subordinate_range **get_subgid_ranges(const char *owner); ++void subid_free_ranges(struct subordinate_range **ranges); ++ ++int get_subuid_owners(uid_t uid, uid_t **owner); ++int get_subgid_owners(uid_t uid, uid_t **owner); ++ ++/* range should be pre-allocated with owner and count filled in, start is ++ * ignored, can be 0 */ ++bool grant_subuid_range(struct subordinate_range *range, bool reuse); ++bool grant_subgid_range(struct subordinate_range *range, bool reuse); ++ ++bool free_subuid_range(struct subordinate_range *range); ++bool free_subgid_range(struct subordinate_range *range); +diff --git a/libsubid/subid.h b/libsubid/subid.h +new file mode 100644 +index 00000000..ba9a2f6f +--- /dev/null ++++ b/libsubid/subid.h +@@ -0,0 +1,17 @@ ++#include ++ ++#ifndef SUBID_RANGE_DEFINED ++#define SUBID_RANGE_DEFINED 1 ++struct subordinate_range { ++ const char *owner; ++ unsigned long start; ++ unsigned long count; ++}; ++ ++enum subid_type { ++ ID_TYPE_UID = 1, ++ ID_TYPE_GID = 2 ++}; ++ ++#define SUBID_NFIELDS 3 ++#endif +diff --git a/src/Makefile.am b/src/Makefile.am +index f175928a..8499ce08 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -156,4 +156,64 @@ if FCAPS + setcap cap_setuid+ep $(DESTDIR)$(ubindir)/newuidmap + setcap cap_setgid+ep $(DESTDIR)$(ubindir)/newgidmap + endif ++ ++noinst_PROGRAMS += list_subid_ranges \ ++ get_subid_owners \ ++ new_subid_range \ ++ free_subid_range ++ ++MISCLIBS = \ ++ $(LIBAUDIT) \ ++ $(LIBSELINUX) \ ++ $(LIBSEMANAGE) \ ++ $(LIBCRYPT_NOPAM) \ ++ $(LIBSKEY) \ ++ $(LIBMD) \ ++ $(LIBECONF) \ ++ $(LIBCRYPT) \ ++ $(LIBTCB) ++ ++list_subid_ranges_LDADD = \ ++ $(top_builddir)/lib/libshadow.la \ ++ $(top_builddir)/libmisc/libmisc.a \ ++ $(top_builddir)/libsubid/libsubid.la \ ++ $(MISCLIBS) ++ ++list_subid_ranges_CPPFLAGS = \ ++ -I$(top_srcdir)/lib \ ++ -I$(top_srcdir)/libmisc \ ++ -I$(top_srcdir)/libsubid ++ ++get_subid_owners_LDADD = \ ++ $(top_builddir)/lib/libshadow.la \ ++ $(top_builddir)/libmisc/libmisc.a \ ++ $(top_builddir)/libsubid/libsubid.la \ ++ $(MISCLIBS) ++ ++get_subid_owners_CPPFLAGS = \ ++ -I$(top_srcdir)/lib \ ++ -I$(top_srcdir)/libmisc \ ++ -I$(top_srcdir)/libsubid ++ ++new_subid_range_CPPFLAGS = \ ++ -I$(top_srcdir)/lib \ ++ -I$(top_srcdir)/libmisc \ ++ -I$(top_srcdir)/libsubid ++ ++new_subid_range_LDADD = \ ++ $(top_builddir)/lib/libshadow.la \ ++ $(top_builddir)/libmisc/libmisc.a \ ++ $(top_builddir)/libsubid/libsubid.la \ ++ $(MISCLIBS) ++ ++free_subid_range_CPPFLAGS = \ ++ -I$(top_srcdir)/lib \ ++ -I$(top_srcdir)/libmisc \ ++ -I$(top_srcdir)/libsubid ++ ++free_subid_range_LDADD = \ ++ $(top_builddir)/lib/libshadow.la \ ++ $(top_builddir)/libmisc/libmisc.a \ ++ $(top_builddir)/libsubid/libsubid.la \ ++ $(MISCLIBS) + endif +diff --git a/src/free_subid_range.c b/src/free_subid_range.c +new file mode 100644 +index 00000000..36858875 +--- /dev/null ++++ b/src/free_subid_range.c +@@ -0,0 +1,50 @@ ++#include ++#include ++#include "api.h" ++#include "stdlib.h" ++#include "prototypes.h" ++ ++/* Test program for the subid freeing routine */ ++ ++const char *Prog; ++ ++void usage(void) ++{ ++ fprintf(stderr, "Usage: %s [-g] user start count\n", Prog); ++ fprintf(stderr, " Release a user's subuid (or with -g, subgid) range\n"); ++ exit(EXIT_FAILURE); ++} ++ ++int main(int argc, char *argv[]) ++{ ++ int c; ++ bool ok; ++ struct subordinate_range range; ++ bool group = false; // get subuids by default ++ ++ Prog = Basename (argv[0]); ++ while ((c = getopt(argc, argv, "g")) != EOF) { ++ switch(c) { ++ case 'g': group = true; break; ++ default: usage(); ++ } ++ } ++ argv = &argv[optind]; ++ argc = argc - optind; ++ if (argc < 3) ++ usage(); ++ range.owner = argv[0]; ++ range.start = atoi(argv[1]); ++ range.count = atoi(argv[2]); ++ if (group) ++ ok = free_subgid_range(&range); ++ else ++ ok = free_subuid_range(&range); ++ ++ if (!ok) { ++ fprintf(stderr, "Failed freeing id range\n"); ++ exit(EXIT_FAILURE); ++ } ++ ++ return 0; ++} +diff --git a/src/get_subid_owners.c b/src/get_subid_owners.c +new file mode 100644 +index 00000000..a4385540 +--- /dev/null ++++ b/src/get_subid_owners.c +@@ -0,0 +1,40 @@ ++#include ++#include "api.h" ++#include "stdlib.h" ++#include "prototypes.h" ++ ++const char *Prog; ++ ++void usage(void) ++{ ++ fprintf(stderr, "Usage: [-g] %s subuid\n", Prog); ++ fprintf(stderr, " list uids who own the given subuid\n"); ++ fprintf(stderr, " pass -g to query a subgid\n"); ++ exit(EXIT_FAILURE); ++} ++ ++int main(int argc, char *argv[]) ++{ ++ int i, n; ++ uid_t *uids; ++ ++ Prog = Basename (argv[0]); ++ if (argc < 2) { ++ usage(); ++ } ++ if (argc == 3 && strcmp(argv[1], "-g") == 0) ++ n = get_subgid_owners(atoi(argv[2]), &uids); ++ else if (argc == 2 && strcmp(argv[1], "-h") == 0) ++ usage(); ++ else ++ n = get_subuid_owners(atoi(argv[1]), &uids); ++ if (n < 0) { ++ fprintf(stderr, "No owners found\n"); ++ exit(1); ++ } ++ for (i = 0; i < n; i++) { ++ printf("%d\n", uids[i]); ++ } ++ free(uids); ++ return 0; ++} +diff --git a/src/list_subid_ranges.c b/src/list_subid_ranges.c +new file mode 100644 +index 00000000..cdba610e +--- /dev/null ++++ b/src/list_subid_ranges.c +@@ -0,0 +1,41 @@ ++#include ++#include "api.h" ++#include "stdlib.h" ++#include "prototypes.h" ++ ++const char *Prog; ++ ++void usage(void) ++{ ++ fprintf(stderr, "Usage: %s [-g] user\n", Prog); ++ fprintf(stderr, " list subuid ranges for user\n"); ++ fprintf(stderr, " pass -g to list subgid ranges\n"); ++ exit(EXIT_FAILURE); ++} ++ ++int main(int argc, char *argv[]) ++{ ++ int i; ++ struct subordinate_range **ranges; ++ ++ Prog = Basename (argv[0]); ++ if (argc < 2) { ++ usage(); ++ } ++ if (argc == 3 && strcmp(argv[1], "-g") == 0) ++ ranges = get_subgid_ranges(argv[2]); ++ else if (argc == 2 && strcmp(argv[1], "-h") == 0) ++ usage(); ++ else ++ ranges = get_subuid_ranges(argv[1]); ++ if (!ranges) { ++ fprintf(stderr, "Error fetching ranges\n"); ++ exit(1); ++ } ++ for (i = 0; ranges[i]; i++) { ++ printf("%d: %s %lu %lu\n", i, ranges[i]->owner, ++ ranges[i]->start, ranges[i]->count); ++ } ++ subid_free_ranges(ranges); ++ return 0; ++} +diff --git a/src/new_subid_range.c b/src/new_subid_range.c +new file mode 100644 +index 00000000..6d7b033b +--- /dev/null ++++ b/src/new_subid_range.c +@@ -0,0 +1,57 @@ ++#include ++#include ++#include "api.h" ++#include "stdlib.h" ++#include "prototypes.h" ++ ++/* Test program for the subid creation routine */ ++ ++const char *Prog; ++ ++void usage(void) ++{ ++ fprintf(stderr, "Usage: %s [-g] [-n] user count\n", Prog); ++ fprintf(stderr, " Find a subuid (or with -g, subgid) range for user\n"); ++ fprintf(stderr, " If -n is given, a new range will be created even if one exists\n"); ++ fprintf(stderr, " count defaults to 65536\n"); ++ exit(EXIT_FAILURE); ++} ++ ++int main(int argc, char *argv[]) ++{ ++ int c; ++ struct subordinate_range range; ++ bool makenew = false; // reuse existing by default ++ bool group = false; // get subuids by default ++ bool ok; ++ ++ Prog = Basename (argv[0]); ++ while ((c = getopt(argc, argv, "gn")) != EOF) { ++ switch(c) { ++ case 'n': makenew = true; break; ++ case 'g': group = true; break; ++ default: usage(); ++ } ++ } ++ argv = &argv[optind]; ++ argc = argc - optind; ++ if (argc == 0) ++ usage(); ++ range.owner = argv[0]; ++ range.start = 0; ++ range.count = 65536; ++ if (argc > 1) ++ range.count = atoi(argv[1]); ++ if (group) ++ ok = grant_subgid_range(&range, !makenew); ++ else ++ ok = grant_subuid_range(&range, !makenew); ++ ++ if (!ok) { ++ fprintf(stderr, "Failed creating new id range\n"); ++ exit(EXIT_FAILURE); ++ } ++ printf("Subuid range %lu:%lu\n", range.start, range.count); ++ ++ return 0; ++} +diff --git a/tests/libsubid/01_list_ranges/config.txt b/tests/libsubid/01_list_ranges/config.txt +new file mode 100644 +index 00000000..e69de29b +diff --git a/tests/libsubid/01_list_ranges/config/etc/subgid b/tests/libsubid/01_list_ranges/config/etc/subgid +new file mode 100644 +index 00000000..b9495cfc +--- /dev/null ++++ b/tests/libsubid/01_list_ranges/config/etc/subgid +@@ -0,0 +1,2 @@ ++foo:200000:10000 ++root:500000:1000 +diff --git a/tests/libsubid/01_list_ranges/config/etc/subuid b/tests/libsubid/01_list_ranges/config/etc/subuid +new file mode 100644 +index 00000000..e5c537be +--- /dev/null ++++ b/tests/libsubid/01_list_ranges/config/etc/subuid +@@ -0,0 +1,3 @@ ++foo:300000:10000 ++foo:400000:10000 ++root:500000:1000 +diff --git a/tests/libsubid/01_list_ranges/list_ranges.test b/tests/libsubid/01_list_ranges/list_ranges.test +new file mode 100755 +index 00000000..b131303b +--- /dev/null ++++ b/tests/libsubid/01_list_ranges/list_ranges.test +@@ -0,0 +1,38 @@ ++#!/bin/sh ++ ++set -e ++ ++cd $(dirname $0) ++ ++. ../../common/config.sh ++. ../../common/log.sh ++ ++log_start "$0" "list_ranges shows subid ranges" ++ ++save_config ++ ++# restore the files on exit ++trap 'log_status "$0" "FAILURE"; restore_config' 0 ++ ++change_config ++ ++echo -n "list foo's ranges..." ++${build_path}/src/list_subid_ranges foo > /tmp/subuidlistout ++${build_path}/src/list_subid_ranges -g foo > /tmp/subgidlistout ++echo "OK" ++ ++echo -n "Check the subuid ranges..." ++[ $(wc -l /tmp/subuidlistout | awk '{ print $1 }') -eq 2 ] ++grep "0: foo 300000 10000" /tmp/subuidlistout ++grep "1: foo 400000 10000" /tmp/subuidlistout ++echo "OK" ++ ++echo -n "Check the subgid ranges..." ++[ $(wc -l /tmp/subgidlistout | awk '{ print $1 }') -eq 1 ] ++grep "0: foo 200000 10000" /tmp/subgidlistout ++echo "OK" ++ ++log_status "$0" "SUCCESS" ++restore_config ++trap '' 0 ++ +diff --git a/tests/libsubid/02_get_subid_owners/config.txt b/tests/libsubid/02_get_subid_owners/config.txt +new file mode 100644 +index 00000000..e69de29b +diff --git a/tests/libsubid/02_get_subid_owners/config/etc/passwd b/tests/libsubid/02_get_subid_owners/config/etc/passwd +new file mode 100644 +index 00000000..bf52df00 +--- /dev/null ++++ b/tests/libsubid/02_get_subid_owners/config/etc/passwd +@@ -0,0 +1,20 @@ ++root:x:0:0:root:/root:/bin/bash ++daemon:x:1:1:daemon:/usr/sbin:/bin/sh ++bin:x:2:2:bin:/bin:/bin/sh ++sys:x:3:3:sys:/dev:/bin/sh ++sync:x:4:65534:sync:/bin:/bin/sync ++games:x:5:60:games:/usr/games:/bin/sh ++man:x:6:12:man:/var/cache/man:/bin/sh ++lp:x:7:7:lp:/var/spool/lpd:/bin/sh ++mail:x:8:8:mail:/var/mail:/bin/sh ++news:x:9:9:news:/var/spool/news:/bin/sh ++uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh ++proxy:x:13:13:proxy:/bin:/bin/sh ++www-data:x:33:33:www-data:/var/www:/bin/sh ++backup:x:34:34:backup:/var/backups:/bin/sh ++list:x:38:38:Mailing List Manager:/var/list:/bin/sh ++irc:x:39:39:ircd:/var/run/ircd:/bin/sh ++gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh ++nobody:x:65534:65534:nobody:/nonexistent:/bin/sh ++Debian-exim:x:102:102::/var/spool/exim4:/bin/false ++foo:x:1000:1000::/home/foo:/bin/false +diff --git a/tests/libsubid/02_get_subid_owners/config/etc/subgid b/tests/libsubid/02_get_subid_owners/config/etc/subgid +new file mode 100644 +index 00000000..b9495cfc +--- /dev/null ++++ b/tests/libsubid/02_get_subid_owners/config/etc/subgid +@@ -0,0 +1,2 @@ ++foo:200000:10000 ++root:500000:1000 +diff --git a/tests/libsubid/02_get_subid_owners/config/etc/subuid b/tests/libsubid/02_get_subid_owners/config/etc/subuid +new file mode 100644 +index 00000000..dd11875a +--- /dev/null ++++ b/tests/libsubid/02_get_subid_owners/config/etc/subuid +@@ -0,0 +1,4 @@ ++foo:300000:10000 ++foo:400000:10000 ++foo:500000:10000 ++root:500000:1000 +diff --git a/tests/libsubid/02_get_subid_owners/get_subid_owners.test b/tests/libsubid/02_get_subid_owners/get_subid_owners.test +new file mode 100755 +index 00000000..145477cb +--- /dev/null ++++ b/tests/libsubid/02_get_subid_owners/get_subid_owners.test +@@ -0,0 +1,52 @@ ++#!/bin/sh ++ ++set -e ++ ++cd $(dirname $0) ++ ++. ../../common/config.sh ++. ../../common/log.sh ++ ++log_start "$0" "get subid owners" ++ ++save_config ++ ++# restore the files on exit ++trap 'log_status "$0" "FAILURE"; restore_config' 0 ++ ++change_config ++ ++echo -n "Noone owns 0 as a subid..." ++[ -z "$(${build_path}/src/get_subid_owners 0)" ] ++echo "OK" ++ ++echo -n "foo owns subuid 300000..." ++[ "$(${build_path}/src/get_subid_owners 300000)" = "1000" ] ++echo "OK" ++ ++echo -n "foo owns subgid 200000..." ++[ "$(${build_path}/src/get_subid_owners -g 200000)" = "1000" ] ++echo "OK" ++ ++echo -n "Noone owns subuid 200000..." ++[ -z "$(${build_path}/src/get_subid_owners -g 300000)" ] ++echo "OK" ++ ++echo -n "Noone owns subgid 300000..." ++[ -z "$(${build_path}/src/get_subid_owners -g 300000)" ] ++echo "OK" ++ ++echo -n "Both foo and root own subuid 500000..." ++cat > /tmp/expected << EOF ++1000 ++0 ++EOF ++${build_path}/src/get_subid_owners 500000 > /tmp/actual ++diff /tmp/expected /tmp/actual ++ ++echo "OK" ++ ++log_status "$0" "SUCCESS" ++restore_config ++trap '' 0 ++ +diff --git a/tests/libsubid/03_add_remove/add_remove_subids.test b/tests/libsubid/03_add_remove/add_remove_subids.test +new file mode 100755 +index 00000000..a24a9752 +--- /dev/null ++++ b/tests/libsubid/03_add_remove/add_remove_subids.test +@@ -0,0 +1,59 @@ ++#!/bin/sh ++ ++set -e ++ ++cd $(dirname $0) ++ ++. ../../common/config.sh ++. ../../common/log.sh ++ ++log_start "$0" "add and remove subid ranges" ++ ++save_config ++ ++# restore the files on exit ++trap 'log_status "$0" "FAILURE"; restore_config' 0 ++ ++change_config ++ ++echo -n "Existing ranges returned when possible..." ++res=$(${build_path}/src/new_subid_range foo 500) ++echo "debug" ++echo "res is $res" ++echo "wanted Subuid range 300000:10000" ++echo "end debug" ++[ "$res" = "Subuid range 300000:10000" ] ++[ $(grep -c foo /etc/subuid) -eq 1 ] ++echo "OK" ++ ++echo -n "New range returned if requested..." ++res=$(${build_path}/src/new_subid_range foo 500 -n) ++[ "$res" = "Subuid range 310000:500" ] ++[ $(grep -c foo /etc/subuid) -eq 2 ] ++echo "OK" ++ ++echo -n "Free works..." ++res=$(${build_path}/src/free_subid_range foo 310000 500) ++[ $(grep -c foo /etc/subuid) -eq 1 ] ++echo "OK" ++ ++echo -n "Subgids work too..." ++res=$(${build_path}/src/new_subid_range -g foo 100000) ++echo "DEBUG: res is ${res}" ++[ "$res" = "Subuid range 501000:100000" ] ++echo "DEBUG: subgid is:" ++cat /etc/subgid ++[ $(grep -c foo /etc/subgid) -eq 2 ] ++ ++echo -n "Subgid free works..." ++res=$(${build_path}/src/free_subid_range -g foo 501000 100000) ++echo "DEBUG: res is ${res}" ++echo "DEBUG: subgid is:" ++cat /etc/subgid ++[ $(grep -c foo /etc/subgid) -eq 1 ] ++echo "OK" ++ ++log_status "$0" "SUCCESS" ++restore_config ++trap '' 0 ++ +diff --git a/tests/libsubid/03_add_remove/config.txt b/tests/libsubid/03_add_remove/config.txt +new file mode 100644 +index 00000000..e69de29b +diff --git a/tests/libsubid/03_add_remove/config/etc/passwd b/tests/libsubid/03_add_remove/config/etc/passwd +new file mode 100644 +index 00000000..bf52df00 +--- /dev/null ++++ b/tests/libsubid/03_add_remove/config/etc/passwd +@@ -0,0 +1,20 @@ ++root:x:0:0:root:/root:/bin/bash ++daemon:x:1:1:daemon:/usr/sbin:/bin/sh ++bin:x:2:2:bin:/bin:/bin/sh ++sys:x:3:3:sys:/dev:/bin/sh ++sync:x:4:65534:sync:/bin:/bin/sync ++games:x:5:60:games:/usr/games:/bin/sh ++man:x:6:12:man:/var/cache/man:/bin/sh ++lp:x:7:7:lp:/var/spool/lpd:/bin/sh ++mail:x:8:8:mail:/var/mail:/bin/sh ++news:x:9:9:news:/var/spool/news:/bin/sh ++uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh ++proxy:x:13:13:proxy:/bin:/bin/sh ++www-data:x:33:33:www-data:/var/www:/bin/sh ++backup:x:34:34:backup:/var/backups:/bin/sh ++list:x:38:38:Mailing List Manager:/var/list:/bin/sh ++irc:x:39:39:ircd:/var/run/ircd:/bin/sh ++gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh ++nobody:x:65534:65534:nobody:/nonexistent:/bin/sh ++Debian-exim:x:102:102::/var/spool/exim4:/bin/false ++foo:x:1000:1000::/home/foo:/bin/false +diff --git a/tests/libsubid/03_add_remove/config/etc/subgid b/tests/libsubid/03_add_remove/config/etc/subgid +new file mode 100644 +index 00000000..b9495cfc +--- /dev/null ++++ b/tests/libsubid/03_add_remove/config/etc/subgid +@@ -0,0 +1,2 @@ ++foo:200000:10000 ++root:500000:1000 +diff --git a/tests/libsubid/03_add_remove/config/etc/subuid b/tests/libsubid/03_add_remove/config/etc/subuid +new file mode 100644 +index 00000000..cf80c2f7 +--- /dev/null ++++ b/tests/libsubid/03_add_remove/config/etc/subuid +@@ -0,0 +1 @@ ++foo:300000:10000 +diff --git a/tests/run_some b/tests/run_some +new file mode 100755 +index 00000000..2d085d59 +--- /dev/null ++++ b/tests/run_some +@@ -0,0 +1,136 @@ ++#!/bin/sh ++ ++set -e ++ ++export LC_ALL=C ++unset LANG ++unset LANGUAGE ++. common/config.sh ++ ++USE_PAM="yes" ++FAILURE_TESTS="yes" ++ ++succeeded=0 ++failed=0 ++failed_tests="" ++ ++run_test() ++{ ++ [ -f RUN_TEST.STOP ] && exit 1 ++ ++ if $1 > $1.log ++ then ++ succeeded=$((succeeded+1)) ++ echo -n "+" ++ else ++ failed=$((failed+1)) ++ failed_tests="$failed_tests $1" ++ echo -n "-" ++ fi ++ cat $1.log >> testsuite.log ++ [ -f /etc/passwd.lock ] && echo $1 /etc/passwd.lock || true ++ [ -f /etc/group.lock ] && echo $1 /etc/group.lock || true ++ [ -f /etc/shadow.lock ] && echo $1 /etc/shadow.lock || true ++ [ -f /etc/gshadow.lock ] && echo $1 /etc/gshadow.lock || true ++ if [ "$(stat -c"%G" /etc/shadow)" != "shadow" ] ++ then ++ echo $1 ++ ls -l /etc/shadow ++ chgrp shadow /etc/shadow ++ fi ++ if [ -d /nonexistent ] ++ then ++ echo $1 /nonexistent ++ rmdir /nonexistent ++ fi ++} ++ ++echo "+: test passed" ++echo "-: test failed" ++ ++# Empty the complete log. ++> testsuite.log ++ ++find ${build_path} -name "*.gcda" -delete ++run_test ./su/01/su_root.test ++run_test ./su/01/su_user.test ++find ${build_path} -name "*.gcda" -exec chmod a+rw {} \; ++run_test ./su/02/env_FOO-options_--login ++run_test ./su/02/env_FOO-options_--login_bash ++run_test ./su/02/env_FOO-options_--preserve-environment ++run_test ./su/02/env_FOO-options_--preserve-environment_bash ++run_test ./su/02/env_FOO-options_- ++run_test ./su/02/env_FOO-options_-_bash ++run_test ./su/02/env_FOO-options_-l-m ++run_test ./su/02/env_FOO-options_-l-m_bash ++run_test ./su/02/env_FOO-options_-l ++run_test ./su/02/env_FOO-options_-l_bash ++run_test ./su/02/env_FOO-options_-m_bash ++run_test ./su/02/env_FOO-options_-m ++run_test ./su/02/env_FOO-options_-p ++run_test ./su/02/env_FOO-options_-p_bash ++run_test ./su/02/env_FOO-options__bash ++run_test ./su/02/env_FOO-options_ ++run_test ./su/02/env_FOO-options_-p- ++run_test ./su/02/env_FOO-options_-p-_bash ++run_test ./su/02/env_special-options_-l-p ++run_test ./su/02/env_special-options_-l ++run_test ./su/02/env_special-options_-l-p_bash ++run_test ./su/02/env_special-options_-l_bash ++run_test ./su/02/env_special-options_-p ++run_test ./su/02/env_special-options_-p_bash ++run_test ./su/02/env_special-options_ ++run_test ./su/02/env_special-options__bash ++run_test ./su/02/env_special_root-options_-l-p ++run_test ./su/02/env_special_root-options_-l-p_bash ++run_test ./su/02/env_special_root-options_-l ++run_test ./su/02/env_special_root-options_-l_bash ++run_test ./su/02/env_special_root-options_-p ++run_test ./su/02/env_special_root-options_-p_bash ++run_test ./su/02/env_special_root-options_ ++run_test ./su/02/env_special_root-options__bash ++run_test ./su/03/su_run_command01.test ++run_test ./su/03/su_run_command02.test ++run_test ./su/03/su_run_command03.test ++run_test ./su/03/su_run_command04.test ++run_test ./su/03/su_run_command05.test ++run_test ./su/03/su_run_command06.test ++run_test ./su/03/su_run_command07.test ++run_test ./su/03/su_run_command08.test ++run_test ./su/03/su_run_command09.test ++run_test ./su/03/su_run_command10.test ++run_test ./su/03/su_run_command11.test ++run_test ./su/03/su_run_command12.test ++run_test ./su/03/su_run_command13.test ++run_test ./su/03/su_run_command14.test ++run_test ./su/03/su_run_command15.test ++run_test ./su/03/su_run_command16.test ++run_test ./su/03/su_run_command17.test ++run_test ./su/04/su_wrong_user.test ++run_test ./su/04/su_user_wrong_passwd.test ++run_test ./su/04/su_user_wrong_passwd_syslog.test ++run_test ./su/05/su_user_wrong_passwd_syslog.test ++run_test ./su/06/su_user_syslog.test ++run_test ./su/07/su_user_syslog.test ++run_test ./su/08/env_special-options_ ++run_test ./su/08/env_special_root-options_ ++run_test ./su/09/env_special-options_ ++run_test ./su/09/env_special_root-options_ ++run_test ./su/10_su_sulog_success/su.test ++run_test ./su/11_su_sulog_failure/su.test ++run_test ./su/12_su_child_failure/su.test ++run_test ./su/13_su_child_success/su.test ++run_test ./libsubid/01_list_ranges/list_ranges.test ++run_test ./libsubid/02_get_subid_owners/get_subid_owners.test ++run_test ./libsubid/03_add_remove/add_remove_subids.test ++ ++echo ++echo "$succeeded test(s) passed" ++echo "$failed test(s) failed" ++echo "log written in 'testsuite.log'" ++if [ "$failed" != "0" ] ++then ++ echo "the following tests failed:" ++ echo $failed_tests ++fi ++ +-- +2.30.2 + +From 607f1dd549cf9abc87af1cf29275f0d2d11eea29 Mon Sep 17 00:00:00 2001 +From: Serge Hallyn +Date: Fri, 19 Jun 2020 22:09:20 -0500 +Subject: [PATCH] libsubid: fix a prototype in api.h + +Signed-off-by: Serge Hallyn +--- + libsubid/api.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libsubid/api.h b/libsubid/api.h +index f65e3ec9..fbdf0f9e 100644 +--- a/libsubid/api.h ++++ b/libsubid/api.h +@@ -6,7 +6,7 @@ struct subordinate_range **get_subgid_ranges(const char *owner); + void subid_free_ranges(struct subordinate_range **ranges); + + int get_subuid_owners(uid_t uid, uid_t **owner); +-int get_subgid_owners(uid_t uid, uid_t **owner); ++int get_subgid_owners(gid_t gid, uid_t **owner); + + /* range should be pre-allocated with owner and count filled in, start is + * ignored, can be 0 */ +-- +2.30.2 + +From b5fb1b38eea2fb0489ed088c82daf6700e72363e Mon Sep 17 00:00:00 2001 +From: Serge Hallyn +Date: Fri, 1 Jan 2021 13:01:54 -0600 +Subject: [PATCH] libsubid: move libmisc.a to last LIBADD entry + +Closes #297 + +Signed-off-by: Serge Hallyn +--- + libsubid/Makefile.am | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libsubid/Makefile.am b/libsubid/Makefile.am +index bdbc52c3..8bef1ecc 100644 +--- a/libsubid/Makefile.am ++++ b/libsubid/Makefile.am +@@ -16,8 +16,8 @@ MISCLIBS = \ + + libsubid_la_LIBADD = \ + $(top_srcdir)/lib/libshadow.la \ +- $(top_srcdir)/libmisc/libmisc.a \ +- $(MISCLIBS) ++ $(MISCLIBS) \ ++ $(top_srcdir)/libmisc/libmisc.a + + AM_CPPFLAGS = \ + -I${top_srcdir}/lib \ +-- +2.30.2 + +From 43a917cce54019799a8de037fd63780a2b640afc Mon Sep 17 00:00:00 2001 +From: Serge Hallyn +Date: Sat, 18 Apr 2020 14:57:56 -0500 +Subject: [PATCH] configure: define abi versions + +Signed-off-by: Serge Hallyn +--- + configure.ac | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/configure.ac b/configure.ac +index e4c6aaec..b8bc2b7a 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1,11 +1,21 @@ + dnl Process this file with autoconf to produce a configure script. +-AC_PREREQ([2.64]) ++AC_PREREQ([2.69]) ++m4_define([libsubid_abi_major], 1) ++m4_define([libsubid_abi_minor], 0) ++m4_define([libsubid_abi_micro], 0) ++m4_define([libsubid_abi], [libsubid_abi_major.libsubid_abi_minor.libsubid_abi_micro]) + AC_INIT([shadow], [4.8.1], [pkg-shadow-devel@lists.alioth.debian.org], [], + [https://github.com/shadow-maint/shadow]) + AM_INIT_AUTOMAKE([1.11 foreign dist-xz]) ++AC_CONFIG_MACRO_DIRS([m4]) + AM_SILENT_RULES([yes]) + AC_CONFIG_HEADERS([config.h]) + ++AC_SUBST([LIBSUBID_ABI_MAJOR], [libsubid_abi_major]) ++AC_SUBST([LIBSUBID_ABI_MINOR], [libsubid_abi_minor]) ++AC_SUBST([LIBSUBID_ABI_MICRO], [libsubid_abi_micro]) ++AC_SUBST([LIBSUBID_ABI], [libsubid_abi]) ++ + dnl Some hacks... + test "$prefix" = "NONE" && prefix="/usr" + test "$prefix" = "/usr" && exec_prefix="" +-- +2.30.2 + diff --git a/shadow-4.8.1-libsubid_nsswitch_support.patch b/shadow-4.8.1-libsubid_nsswitch_support.patch new file mode 100644 index 0000000..eafa7c1 --- /dev/null +++ b/shadow-4.8.1-libsubid_nsswitch_support.patch @@ -0,0 +1,2107 @@ +From 514c1328b6c90d817ae0a9f7addfb3c9a11a275a Mon Sep 17 00:00:00 2001 +From: Serge Hallyn +Date: Sun, 31 Jan 2021 22:44:09 -0600 +Subject: [PATCH 1/6] try again to fix libmisc sharing problem + +Issue #297 reported seeing + +*** Warning: Linking the shared library libsubid.la against the +*** static library ../libmisc/libmisc.a is not portable! + +which commit b5fb1b38eea2fb0489ed088c82daf6700e72363e was supposed +to fix. But a few commits later it's back. So try to fix it +in the way the bug reporter suggested. This broke builds some +other ways, namely a few missing library specifications, so add +those. + +Signed-off-by: Serge Hallyn +--- + configure.ac | 2 +- + libmisc/Makefile.am | 6 +++--- + libsubid/Makefile.am | 6 ++++-- + src/Makefile.am | 37 +++++++++++++++++++++++-------------- + 4 files changed, 31 insertions(+), 20 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 6aaae6b7..7884bfb6 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -55,7 +55,7 @@ AC_CHECK_FUNCS(l64a fchmod fchown fsync futimes getgroups gethostname getspnam \ + gettimeofday getusershell getutent initgroups lchown lckpwdf lstat \ + lutimes memcpy memset setgroups sigaction strchr updwtmp updwtmpx innetgr \ + getpwnam_r getpwuid_r getgrnam_r getgrgid_r getspnam_r getaddrinfo \ +- ruserok) ++ ruserok dlopen) + AC_SYS_LARGEFILE + + dnl Checks for typedefs, structures, and compiler characteristics. +diff --git a/libmisc/Makefile.am b/libmisc/Makefile.am +index 7f43161f..9766a7ec 100644 +--- a/libmisc/Makefile.am ++++ b/libmisc/Makefile.am +@@ -3,9 +3,9 @@ EXTRA_DIST = .indent.pro xgetXXbyYY.c + + AM_CPPFLAGS = -I$(top_srcdir)/lib $(ECONF_CPPFLAGS) + +-noinst_LIBRARIES = libmisc.a ++noinst_LTLIBRARIES = libmisc.la + +-libmisc_a_SOURCES = \ ++libmisc_la_SOURCES = \ + addgrps.c \ + age.c \ + audit_help.c \ +@@ -74,6 +74,6 @@ libmisc_a_SOURCES = \ + yesno.c + + if WITH_BTRFS +-libmisc_a_SOURCES += btrfs.c ++libmisc_la_SOURCES += btrfs.c + endif + +diff --git a/libsubid/Makefile.am b/libsubid/Makefile.am +index 8bef1ecc..f24dbb94 100644 +--- a/libsubid/Makefile.am ++++ b/libsubid/Makefile.am +@@ -12,12 +12,14 @@ MISCLIBS = \ + $(LIBMD) \ + $(LIBECONF) \ + $(LIBCRYPT) \ ++ $(LIBACL) \ ++ $(LIBATTR) \ + $(LIBTCB) + + libsubid_la_LIBADD = \ + $(top_srcdir)/lib/libshadow.la \ +- $(MISCLIBS) \ +- $(top_srcdir)/libmisc/libmisc.a ++ $(top_srcdir)/libmisc/libmisc.la \ ++ $(MISCLIBS) + + AM_CPPFLAGS = \ + -I${top_srcdir}/lib \ +diff --git a/src/Makefile.am b/src/Makefile.am +index 8499ce08..e9d354fd 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -78,7 +78,7 @@ shadowsgidubins = passwd + endif + + LDADD = $(INTLLIBS) \ +- $(top_builddir)/libmisc/libmisc.a \ ++ $(top_builddir)/libmisc/libmisc.la \ + $(top_builddir)/lib/libshadow.la \ + $(LIBTCB) + +@@ -95,28 +95,37 @@ LIBCRYPT_NOPAM = $(LIBCRYPT) + endif + + chage_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) +-newuidmap_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP) +-newgidmap_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP) ++newuidmap_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP) -ldl ++newgidmap_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP) -ldl + chfn_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF) + chgpasswd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF) + chsh_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF) + chpasswd_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF) + expiry_LDADD = $(LDADD) $(LIBECONF) + gpasswd_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF) +-groupadd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) +-groupdel_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) ++groupadd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) -ldl ++groupdel_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) -ldl + groupmems_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) +-groupmod_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) ++groupmod_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) -ldl + grpck_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) + grpconv_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) + grpunconv_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) + lastlog_LDADD = $(LDADD) $(LIBAUDIT) $(LIBECONF) ++newuidmap_SOURCES = newuidmap.c ../libmisc/nss.c ++newgidmap_SOURCES = newgidmap.c ../libmisc/nss.c ++groupadd_SOURCES = groupadd.c ../libmisc/nss.c ++groupmod_SOURCES = groupmod.c ../libmisc/nss.c ++groupdel_SOURCES = groupdel.c ../libmisc/nss.c ++newusers_SOURCES = newusers.c ../libmisc/nss.c ++useradd_SOURCES = useradd.c ../libmisc/nss.c ++usermod_SOURCES = usermod.c ../libmisc/nss.c ++userdel_SOURCES = userdel.c ../libmisc/nss.c + login_SOURCES = \ + login.c \ + login_nopam.c + login_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF) + newgrp_LDADD = $(LDADD) $(LIBAUDIT) $(LIBCRYPT) $(LIBECONF) +-newusers_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF) ++newusers_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF) -ldl + nologin_LDADD = + passwd_LDADD = $(LDADD) $(LIBPAM) $(LIBCRACK) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBECONF) + pwck_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) +@@ -127,9 +136,9 @@ su_SOURCES = \ + suauth.c + su_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF) + sulogin_LDADD = $(LDADD) $(LIBCRYPT) $(LIBECONF) +-useradd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBACL) $(LIBATTR) $(LIBECONF) +-userdel_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBECONF) +-usermod_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBACL) $(LIBATTR) $(LIBECONF) ++useradd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBACL) $(LIBATTR) $(LIBECONF) -ldl ++userdel_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBECONF) -ldl ++usermod_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBACL) $(LIBATTR) $(LIBECONF) -ldl + vipw_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) + + install-am: all-am +@@ -175,7 +184,7 @@ MISCLIBS = \ + + list_subid_ranges_LDADD = \ + $(top_builddir)/lib/libshadow.la \ +- $(top_builddir)/libmisc/libmisc.a \ ++ $(top_builddir)/libmisc/libmisc.la \ + $(top_builddir)/libsubid/libsubid.la \ + $(MISCLIBS) + +@@ -186,7 +195,7 @@ list_subid_ranges_CPPFLAGS = \ + + get_subid_owners_LDADD = \ + $(top_builddir)/lib/libshadow.la \ +- $(top_builddir)/libmisc/libmisc.a \ ++ $(top_builddir)/libmisc/libmisc.la \ + $(top_builddir)/libsubid/libsubid.la \ + $(MISCLIBS) + +@@ -202,7 +211,7 @@ new_subid_range_CPPFLAGS = \ + + new_subid_range_LDADD = \ + $(top_builddir)/lib/libshadow.la \ +- $(top_builddir)/libmisc/libmisc.a \ ++ $(top_builddir)/libmisc/libmisc.la \ + $(top_builddir)/libsubid/libsubid.la \ + $(MISCLIBS) + +@@ -213,7 +222,7 @@ free_subid_range_CPPFLAGS = \ + + free_subid_range_LDADD = \ + $(top_builddir)/lib/libshadow.la \ +- $(top_builddir)/libmisc/libmisc.a \ ++ $(top_builddir)/libmisc/libmisc.la \ + $(top_builddir)/libsubid/libsubid.la \ + $(MISCLIBS) + endif +-- +2.30.2 + + +From 8492dee6632e340dee76eee895c3e30877bebf45 Mon Sep 17 00:00:00 2001 +From: Serge Hallyn +Date: Sun, 31 Jan 2021 17:38:20 -0600 +Subject: [PATCH 2/6] subids: support nsswitch + +Closes #154 + +When starting any operation to do with subuid delegation, check +nsswitch for a module to use. If none is specified, then use +the traditional /etc/subuid and /etc/subgid files. + +Currently only one module is supported, and there is no fallback +to the files on errors. Several possibilities could be considered: + +1. in case of connection error, fall back to files +2. in case of unknown user, also fall back to files + +etc... + +When non-files nss module is used, functions to edit the range +are not supported. It may make sense to support it, but it also +may make sense to require another tool to be used. + +libsubordinateio also uses the nss_ helpers. This is how for instance +lxc could easily be converted to supporting nsswitch. + +Add a set of test cases, including a dummy libsubid_zzz module. This +hardcodes values such that: + +'ubuntu' gets 200000 - 300000 +'user1' gets 100000 - 165536 +'error' emulates an nss module error +'unknown' emulates a user unknown to the nss module +'conn' emulates a connection error ot the nss module + +Changes to libsubid: + +Change the list_owner_ranges api: return a count instead of making the array +null terminated. + +This is a breaking change, so bump the libsubid abi major number. + +Rename free_subuid_range and free_subgid_range to ungrant_subuid_range, +because otherwise it's confusing with free_subid_ranges which frees + memory. + +Run libsubid tests in jenkins + +Switch argument order in find_subid_owners + +Move the db locking into subordinateio.c + +Signed-off-by: Serge Hallyn +--- + configure.ac | 2 +- + lib/Makefile.am | 1 + + lib/nss.c | 157 ++++++++++++++++ + lib/prototypes.h | 69 ++++++++ + lib/subordinateio.c | 256 ++++++++++++++++++++++++--- + lib/subordinateio.h | 6 +- + libmisc/idmapping.h | 2 + + libsubid/Makefile.am | 2 +- + libsubid/api.c | 168 +++--------------- + libsubid/api.h | 10 +- + libsubid/subid.h | 8 + + src/Makefile.am | 29 +-- + src/check_subid_range.c | 48 +++++ + src/free_subid_range.c | 4 +- + src/list_subid_ranges.c | 10 +- + tests/libsubid/04_nss/Makefile | 12 ++ + tests/libsubid/04_nss/empty | 0 + tests/libsubid/04_nss/libsubid_zzz.c | 146 +++++++++++++++ + tests/libsubid/04_nss/nsswitch1.conf | 20 +++ + tests/libsubid/04_nss/nsswitch2.conf | 22 +++ + tests/libsubid/04_nss/nsswitch3.conf | 22 +++ + tests/libsubid/04_nss/subidnss.test | 22 +++ + tests/libsubid/04_nss/test_nss.c | 72 ++++++++ + tests/libsubid/04_nss/test_range | 50 ++++++ + tests/run_some | 1 + + 26 files changed, 935 insertions(+), 205 deletions(-) + create mode 100644 lib/nss.c + create mode 100644 src/check_subid_range.c + create mode 100644 tests/libsubid/04_nss/Makefile + create mode 100644 tests/libsubid/04_nss/empty + create mode 100644 tests/libsubid/04_nss/libsubid_zzz.c + create mode 100644 tests/libsubid/04_nss/nsswitch1.conf + create mode 100644 tests/libsubid/04_nss/nsswitch2.conf + create mode 100644 tests/libsubid/04_nss/nsswitch3.conf + create mode 100755 tests/libsubid/04_nss/subidnss.test + create mode 100644 tests/libsubid/04_nss/test_nss.c + create mode 100755 tests/libsubid/04_nss/test_range + +diff --git a/configure.ac b/configure.ac +index 7884bfb6..7f7e8784 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1,6 +1,6 @@ + dnl Process this file with autoconf to produce a configure script. + AC_PREREQ([2.69]) +-m4_define([libsubid_abi_major], 1) ++m4_define([libsubid_abi_major], 2) + m4_define([libsubid_abi_minor], 0) + m4_define([libsubid_abi_micro], 0) + m4_define([libsubid_abi], [libsubid_abi_major.libsubid_abi_minor.libsubid_abi_micro]) +diff --git a/lib/Makefile.am b/lib/Makefile.am +index bd9d6bfb..ecf3ee25 100644 +--- a/lib/Makefile.am ++++ b/lib/Makefile.am +@@ -31,6 +31,7 @@ libshadow_la_SOURCES = \ + groupio.h \ + gshadow.c \ + lockpw.c \ ++ nss.c \ + nscd.c \ + nscd.h \ + sssd.c \ +diff --git a/lib/nss.c b/lib/nss.c +new file mode 100644 +index 00000000..2f924740 +--- /dev/null ++++ b/lib/nss.c +@@ -0,0 +1,157 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "prototypes.h" ++#include "../libsubid/subid.h" ++ ++#define NSSWITCH "/etc/nsswitch.conf" ++ ++// NSS plugin handling for subids ++// If nsswitch has a line like ++// subid: sssd ++// then sssd will be consulted for subids. Unlike normal NSS dbs, ++// only one db is supported at a time. That's open to debate, but ++// the subids are a pretty limited resource, and local files seem ++// bound to step on any other allocations leading to insecure ++// conditions. ++static atomic_flag nss_init_started; ++static atomic_bool nss_init_completed; ++ ++static struct subid_nss_ops *subid_nss; ++ ++bool nss_is_initialized() { ++ return atomic_load(&nss_init_completed); ++} ++ ++void nss_exit() { ++ if (nss_is_initialized() && subid_nss) { ++ dlclose(subid_nss->handle); ++ free(subid_nss); ++ subid_nss = NULL; ++ } ++} ++ ++// nsswitch_path is an argument only to support testing. ++void nss_init(char *nsswitch_path) { ++ FILE *nssfp = NULL; ++ char *line = NULL, *p, *token, *saveptr; ++ size_t len = 0; ++ ++ if (atomic_flag_test_and_set(&nss_init_started)) { ++ // Another thread has started nss_init, wait for it to complete ++ while (!atomic_load(&nss_init_completed)) ++ usleep(100); ++ return; ++ } ++ ++ if (!nsswitch_path) ++ nsswitch_path = NSSWITCH; ++ ++ // read nsswitch.conf to check for a line like: ++ // subid: files ++ nssfp = fopen(nsswitch_path, "r"); ++ if (!nssfp) { ++ fprintf(stderr, "Failed opening %s: %m", nsswitch_path); ++ atomic_store(&nss_init_completed, true); ++ return; ++ } ++ while ((getline(&line, &len, nssfp)) != -1) { ++ if (line[0] == '\0' || line[0] == '#') ++ continue; ++ if (strlen(line) < 8) ++ continue; ++ if (strncasecmp(line, "subid:", 6) != 0) ++ continue; ++ p = &line[6]; ++ while ((*p) && isspace(*p)) ++ p++; ++ if (!*p) ++ continue; ++ for (token = strtok_r(p, " \n\t", &saveptr); ++ token; ++ token = strtok_r(NULL, " \n\t", &saveptr)) { ++ char libname[65]; ++ void *h; ++ if (strcmp(token, "files") == 0) { ++ subid_nss = NULL; ++ goto done; ++ } ++ if (strlen(token) > 50) { ++ fprintf(stderr, "Subid NSS module name too long (longer than 50 characters): %s\n", token); ++ fprintf(stderr, "Using files\n"); ++ subid_nss = NULL; ++ goto done; ++ } ++ snprintf(libname, 64, "libsubid_%s.so", token); ++ h = dlopen(libname, RTLD_LAZY); ++ if (!h) { ++ fprintf(stderr, "Error opening %s: %s\n", libname, dlerror()); ++ fprintf(stderr, "Using files\n"); ++ subid_nss = NULL; ++ goto done; ++ } ++ subid_nss = malloc(sizeof(*subid_nss)); ++ if (!subid_nss) { ++ dlclose(h); ++ goto done; ++ } ++ subid_nss->has_range = dlsym(h, "shadow_subid_has_range"); ++ if (!subid_nss->has_range) { ++ fprintf(stderr, "%s did not provide @has_range@\n", libname); ++ dlclose(h); ++ free(subid_nss); ++ subid_nss = NULL; ++ goto done; ++ } ++ subid_nss->list_owner_ranges = dlsym(h, "shadow_subid_list_owner_ranges"); ++ if (!subid_nss->list_owner_ranges) { ++ fprintf(stderr, "%s did not provide @list_owner_ranges@\n", libname); ++ dlclose(h); ++ free(subid_nss); ++ subid_nss = NULL; ++ goto done; ++ } ++ subid_nss->has_any_range = dlsym(h, "shadow_subid_has_any_range"); ++ if (!subid_nss->has_any_range) { ++ fprintf(stderr, "%s did not provide @has_any_range@\n", libname); ++ dlclose(h); ++ free(subid_nss); ++ subid_nss = NULL; ++ goto done; ++ } ++ subid_nss->find_subid_owners = dlsym(h, "shadow_subid_find_subid_owners"); ++ if (!subid_nss->find_subid_owners) { ++ fprintf(stderr, "%s did not provide @find_subid_owners@\n", libname); ++ dlclose(h); ++ free(subid_nss); ++ subid_nss = NULL; ++ goto done; ++ } ++ subid_nss->handle = h; ++ goto done; ++ } ++ fprintf(stderr, "No usable subid NSS module found, using files\n"); ++ // subid_nss has to be null here, but to ease reviews: ++ free(subid_nss); ++ subid_nss = NULL; ++ goto done; ++ } ++ ++done: ++ atomic_store(&nss_init_completed, true); ++ free(line); ++ if (nssfp) { ++ atexit(nss_exit); ++ fclose(nssfp); ++ } ++} ++ ++struct subid_nss_ops *get_subid_nss_handle() { ++ nss_init(NULL); ++ return subid_nss; ++} +diff --git a/lib/prototypes.h b/lib/prototypes.h +index ac9ad274..0c42bcc2 100644 +--- a/lib/prototypes.h ++++ b/lib/prototypes.h +@@ -262,6 +262,75 @@ extern void motd (void); + /* myname.c */ + extern /*@null@*//*@only@*/struct passwd *get_my_pwent (void); + ++/* nss.c */ ++#include ++extern void nss_init(char *nsswitch_path); ++extern bool nss_is_initialized(); ++ ++struct subid_nss_ops { ++ /* ++ * nss_has_any_range: does a user own any subid range ++ * ++ * @owner: username ++ * @idtype: subuid or subgid ++ * @result: true if a subid allocation was found for @owner ++ * ++ * returns success if the module was able to determine an answer (true or false), ++ * else an error status. ++ */ ++ enum subid_status (*has_any_range)(const char *owner, enum subid_type idtype, bool *result); ++ ++ /* ++ * nss_has_range: does a user own a given subid range ++ * ++ * @owner: username ++ * @start: first subid in queried range ++ * @count: number of subids in queried range ++ * @idtype: subuid or subgid ++ * @result: true if @owner has been allocated the subid range. ++ * ++ * returns success if the module was able to determine an answer (true or false), ++ * else an error status. ++ */ ++ enum subid_status (*has_range)(const char *owner, unsigned long start, unsigned long count, enum subid_type idtype, bool *result); ++ ++ /* ++ * nss_list_owner_ranges: list the subid ranges delegated to a user. ++ * ++ * @owner - string representing username being queried ++ * @id_type - subuid or subgid ++ * @ranges - pointer to an array of struct subordinate_range pointers, or ++ * NULL. The returned array of struct subordinate_range and its ++ * members must be freed by the caller. ++ * @count - pointer to an integer into which the number of returned ranges ++ * is written. ++ ++ * returns success if the module was able to determine an answer, ++ * else an error status. ++ */ ++ enum subid_status (*list_owner_ranges)(const char *owner, enum subid_type id_type, struct subordinate_range ***ranges, int *count); ++ ++ /* ++ * nss_find_subid_owners: find uids who own a given subuid or subgid. ++ * ++ * @id - the delegated id (subuid or subgid) being queried ++ * @id_type - subuid or subgid ++ * @uids - pointer to an array of uids which will be allocated by ++ * nss_find_subid_owners() ++ * @count - number of uids found ++ * ++ * returns success if the module was able to determine an answer, ++ * else an error status. ++ */ ++ enum subid_status (*find_subid_owners)(unsigned long id, enum subid_type id_type, uid_t **uids, int *count); ++ ++ /* The dlsym handle to close */ ++ void *handle; ++}; ++ ++extern struct subid_nss_ops *get_subid_nss_handle(); ++ ++ + /* pam_pass_non_interactive.c */ + #ifdef USE_PAM + extern int do_pam_passwd_non_interactive (const char *pam_service, +diff --git a/lib/subordinateio.c b/lib/subordinateio.c +index 67202c98..0bb29958 100644 +--- a/lib/subordinateio.c ++++ b/lib/subordinateio.c +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + + /* + * subordinate_dup: create a duplicate range +@@ -311,17 +312,17 @@ static bool append_range(struct subordinate_range ***ranges, const struct subord + { + struct subordinate_range *tmp; + if (!*ranges) { +- *ranges = malloc(2 * sizeof(struct subordinate_range **)); ++ *ranges = malloc(sizeof(struct subordinate_range *)); + if (!*ranges) + return false; + } else { + struct subordinate_range **new; +- new = realloc(*ranges, (n + 2) * (sizeof(struct subordinate_range **))); ++ new = realloc(*ranges, (n + 1) * (sizeof(struct subordinate_range *))); + if (!new) + return false; + *ranges = new; + } +- (*ranges)[n] = (*ranges)[n+1] = NULL; ++ (*ranges)[n] = NULL; + tmp = subordinate_dup(new); + if (!tmp) + return false; +@@ -329,13 +330,13 @@ static bool append_range(struct subordinate_range ***ranges, const struct subord + return true; + } + +-void free_subordinate_ranges(struct subordinate_range **ranges) ++void free_subordinate_ranges(struct subordinate_range **ranges, int count) + { + int i; + + if (!ranges) + return; +- for (i = 0; ranges[i]; i++) ++ for (i = 0; i < count; i++) + subordinate_free(ranges[i]); + free(ranges); + } +@@ -602,21 +603,46 @@ int sub_uid_open (int mode) + + bool sub_uid_assigned(const char *owner) + { ++ struct subid_nss_ops *h; ++ bool found; ++ enum subid_status status; ++ h = get_subid_nss_handle(); ++ if (h) { ++ status = h->has_any_range(owner, ID_TYPE_UID, &found); ++ if (status == SUBID_STATUS_SUCCESS && found) ++ return true; ++ return false; ++ } ++ + return range_exists (&subordinate_uid_db, owner); + } + + bool have_sub_uids(const char *owner, uid_t start, unsigned long count) + { ++ struct subid_nss_ops *h; ++ bool found; ++ enum subid_status status; ++ h = get_subid_nss_handle(); ++ if (h) { ++ status = h->has_range(owner, start, count, ID_TYPE_UID, &found); ++ if (status == SUBID_STATUS_SUCCESS && found) ++ return true; ++ return false; ++ } + return have_range (&subordinate_uid_db, owner, start, count); + } + + int sub_uid_add (const char *owner, uid_t start, unsigned long count) + { ++ if (get_subid_nss_handle()) ++ return -EOPNOTSUPP; + return add_range (&subordinate_uid_db, owner, start, count); + } + + int sub_uid_remove (const char *owner, uid_t start, unsigned long count) + { ++ if (get_subid_nss_handle()) ++ return -EOPNOTSUPP; + return remove_range (&subordinate_uid_db, owner, start, count); + } + +@@ -684,21 +710,45 @@ int sub_gid_open (int mode) + + bool have_sub_gids(const char *owner, gid_t start, unsigned long count) + { ++ struct subid_nss_ops *h; ++ bool found; ++ enum subid_status status; ++ h = get_subid_nss_handle(); ++ if (h) { ++ status = h->has_range(owner, start, count, ID_TYPE_GID, &found); ++ if (status == SUBID_STATUS_SUCCESS && found) ++ return true; ++ return false; ++ } + return have_range(&subordinate_gid_db, owner, start, count); + } + + bool sub_gid_assigned(const char *owner) + { ++ struct subid_nss_ops *h; ++ bool found; ++ enum subid_status status; ++ h = get_subid_nss_handle(); ++ if (h) { ++ status = h->has_any_range(owner, ID_TYPE_GID, &found); ++ if (status == SUBID_STATUS_SUCCESS && found) ++ return true; ++ return false; ++ } + return range_exists (&subordinate_gid_db, owner); + } + + int sub_gid_add (const char *owner, gid_t start, unsigned long count) + { ++ if (get_subid_nss_handle()) ++ return -EOPNOTSUPP; + return add_range (&subordinate_gid_db, owner, start, count); + } + + int sub_gid_remove (const char *owner, gid_t start, unsigned long count) + { ++ if (get_subid_nss_handle()) ++ return -EOPNOTSUPP; + return remove_range (&subordinate_gid_db, owner, start, count); + } + +@@ -720,42 +770,78 @@ gid_t sub_gid_find_free_range(gid_t min, gid_t max, unsigned long count) + } + + /* +- struct subordinate_range **list_owner_ranges(const char *owner, enum subid_type id_type) ++ * int list_owner_ranges(const char *owner, enum subid_type id_type, struct subordinate_range ***ranges) + * + * @owner: username + * @id_type: UID or GUID ++ * @ranges: pointer to array of ranges into which results will be placed. + * +- * Returns the subuid or subgid ranges which are owned by the specified ++ * Fills in the subuid or subgid ranges which are owned by the specified + * user. Username may be a username or a string representation of a + * UID number. If id_type is UID, then subuids are returned, else +- * subgids are returned. If there is an error, < 0 is returned. ++ * subgids are given. ++ ++ * Returns the number of ranges found, or < 0 on error. + * + * The caller must free the subordinate range list. + */ +-struct subordinate_range **list_owner_ranges(const char *owner, enum subid_type id_type) ++int list_owner_ranges(const char *owner, enum subid_type id_type, struct subordinate_range ***in_ranges) + { + // TODO - need to handle owner being either uid or username +- const struct subordinate_range *range; + struct subordinate_range **ranges = NULL; ++ const struct subordinate_range *range; + struct commonio_db *db; +- int size = 0; ++ enum subid_status status; ++ int count = 0; ++ struct subid_nss_ops *h; + +- if (id_type == ID_TYPE_UID) ++ *in_ranges = NULL; ++ ++ h = get_subid_nss_handle(); ++ if (h) { ++ status = h->list_owner_ranges(owner, id_type, in_ranges, &count); ++ if (status == SUBID_STATUS_SUCCESS) ++ return count; ++ return -1; ++ } ++ ++ switch (id_type) { ++ case ID_TYPE_UID: ++ if (!sub_uid_open(O_RDONLY)) { ++ return -1; ++ } + db = &subordinate_uid_db; +- else ++ break; ++ case ID_TYPE_GID: ++ if (!sub_gid_open(O_RDONLY)) { ++ return -1; ++ } + db = &subordinate_gid_db; ++ break; ++ default: ++ return -1; ++ } + + commonio_rewind(db); + while ((range = commonio_next(db)) != NULL) { + if (0 == strcmp(range->owner, owner)) { +- if (!append_range(&ranges, range, size++)) { +- free_subordinate_ranges(ranges); +- return NULL; ++ if (!append_range(&ranges, range, count++)) { ++ free_subordinate_ranges(ranges, count-1); ++ ranges = NULL; ++ count = -1; ++ goto out; + } + } + } + +- return ranges; ++out: ++ if (id_type == ID_TYPE_UID) ++ sub_uid_close(); ++ else ++ sub_gid_close(); ++ ++ *in_ranges = ranges; ++ return count; + } + + static bool all_digits(const char *str) +@@ -808,17 +894,41 @@ static int append_uids(uid_t **uids, const char *owner, int n) + return n+1; + } + +-int find_subid_owners(unsigned long id, uid_t **uids, enum subid_type id_type) ++int find_subid_owners(unsigned long id, enum subid_type id_type, uid_t **uids) + { + const struct subordinate_range *range; ++ struct subid_nss_ops *h; ++ enum subid_status status; + struct commonio_db *db; + int n = 0; + +- *uids = NULL; +- if (id_type == ID_TYPE_UID) ++ h = get_subid_nss_handle(); ++ if (h) { ++ status = h->find_subid_owners(id, id_type, uids, &n); ++ // Several ways we could handle the error cases here. ++ if (status != SUBID_STATUS_SUCCESS) ++ return -1; ++ return n; ++ } ++ ++ switch (id_type) { ++ case ID_TYPE_UID: ++ if (!sub_uid_open(O_RDONLY)) { ++ return -1; ++ } + db = &subordinate_uid_db; +- else ++ break; ++ case ID_TYPE_GID: ++ if (!sub_gid_open(O_RDONLY)) { ++ return -1; ++ } + db = &subordinate_gid_db; ++ break; ++ default: ++ return -1; ++ } ++ ++ *uids = NULL; + + commonio_rewind(db); + while ((range = commonio_next(db)) != NULL) { +@@ -829,6 +939,11 @@ int find_subid_owners(unsigned long id, uid_t **uids, enum subid_type id_type) + } + } + ++ if (id_type == ID_TYPE_UID) ++ sub_uid_close(); ++ else ++ sub_gid_close(); ++ + return n; + } + +@@ -836,11 +951,40 @@ bool new_subid_range(struct subordinate_range *range, enum subid_type id_type, b + { + struct commonio_db *db; + const struct subordinate_range *r; ++ bool ret; + +- if (id_type == ID_TYPE_UID) ++ if (get_subid_nss_handle()) ++ return false; ++ ++ switch (id_type) { ++ case ID_TYPE_UID: ++ if (!sub_uid_lock()) { ++ printf("Failed loging subuids (errno %d)\n", errno); ++ return false; ++ } ++ if (!sub_uid_open(O_CREAT | O_RDWR)) { ++ printf("Failed opening subuids (errno %d)\n", errno); ++ sub_uid_unlock(); ++ return false; ++ } + db = &subordinate_uid_db; +- else ++ break; ++ case ID_TYPE_GID: ++ if (!sub_gid_lock()) { ++ printf("Failed loging subgids (errno %d)\n", errno); ++ return false; ++ } ++ if (!sub_gid_open(O_CREAT | O_RDWR)) { ++ printf("Failed opening subgids (errno %d)\n", errno); ++ sub_gid_unlock(); ++ return false; ++ } + db = &subordinate_gid_db; ++ break; ++ default: ++ return false; ++ } ++ + commonio_rewind(db); + if (reuse) { + while ((r = commonio_next(db)) != NULL) { +@@ -856,20 +1000,74 @@ bool new_subid_range(struct subordinate_range *range, enum subid_type id_type, b + } + + range->start = find_free_range(db, range->start, ULONG_MAX, range->count); +- if (range->start == ULONG_MAX) +- return false; + +- return add_range(db, range->owner, range->start, range->count) == 1; ++ if (range->start == ULONG_MAX) { ++ ret = false; ++ goto out; ++ } ++ ++ ret = add_range(db, range->owner, range->start, range->count) == 1; ++ ++out: ++ if (id_type == ID_TYPE_UID) { ++ sub_uid_close(); ++ sub_uid_unlock(); ++ } else { ++ sub_gid_close(); ++ sub_gid_unlock(); ++ } ++ ++ return ret; + } + + bool release_subid_range(struct subordinate_range *range, enum subid_type id_type) + { + struct commonio_db *db; +- if (id_type == ID_TYPE_UID) ++ bool ret; ++ ++ if (get_subid_nss_handle()) ++ return false; ++ ++ switch (id_type) { ++ case ID_TYPE_UID: ++ if (!sub_uid_lock()) { ++ printf("Failed loging subuids (errno %d)\n", errno); ++ return false; ++ } ++ if (!sub_uid_open(O_CREAT | O_RDWR)) { ++ printf("Failed opening subuids (errno %d)\n", errno); ++ sub_uid_unlock(); ++ return false; ++ } + db = &subordinate_uid_db; +- else ++ break; ++ case ID_TYPE_GID: ++ if (!sub_gid_lock()) { ++ printf("Failed loging subgids (errno %d)\n", errno); ++ return false; ++ } ++ if (!sub_gid_open(O_CREAT | O_RDWR)) { ++ printf("Failed opening subgids (errno %d)\n", errno); ++ sub_gid_unlock(); ++ return false; ++ } + db = &subordinate_gid_db; +- return remove_range(db, range->owner, range->start, range->count) == 1; ++ break; ++ default: ++ return false; ++ } ++ ++ ret = remove_range(db, range->owner, range->start, range->count) == 1; ++ ++ if (id_type == ID_TYPE_UID) { ++ sub_uid_close(); ++ sub_uid_unlock(); ++ } else { ++ sub_gid_close(); ++ sub_gid_unlock(); ++ } ++ ++ return ret; + } + + #else /* !ENABLE_SUBIDS */ +diff --git a/lib/subordinateio.h b/lib/subordinateio.h +index 13a21341..e4be482c 100644 +--- a/lib/subordinateio.h ++++ b/lib/subordinateio.h +@@ -25,11 +25,11 @@ extern int sub_uid_unlock (void); + extern int sub_uid_add (const char *owner, uid_t start, unsigned long count); + extern int sub_uid_remove (const char *owner, uid_t start, unsigned long count); + extern uid_t sub_uid_find_free_range(uid_t min, uid_t max, unsigned long count); +-extern struct subordinate_range **list_owner_ranges(const char *owner, enum subid_type id_type); ++extern int list_owner_ranges(const char *owner, enum subid_type id_type, struct subordinate_range ***ranges); + extern bool new_subid_range(struct subordinate_range *range, enum subid_type id_type, bool reuse); + extern bool release_subid_range(struct subordinate_range *range, enum subid_type id_type); +-extern int find_subid_owners(unsigned long id, uid_t **uids, enum subid_type id_type); +-extern void free_subordinate_ranges(struct subordinate_range **ranges); ++extern int find_subid_owners(unsigned long id, enum subid_type id_type, uid_t **uids); ++extern void free_subordinate_ranges(struct subordinate_range **ranges, int count); + + extern int sub_gid_close(void); + extern bool have_sub_gids(const char *owner, gid_t start, unsigned long count); +diff --git a/libmisc/idmapping.h b/libmisc/idmapping.h +index 3f32db68..1a8efe68 100644 +--- a/libmisc/idmapping.h ++++ b/libmisc/idmapping.h +@@ -40,5 +40,7 @@ extern struct map_range *get_map_ranges(int ranges, int argc, char **argv); + extern void write_mapping(int proc_dir_fd, int ranges, + struct map_range *mappings, const char *map_file, uid_t ruid); + ++extern void nss_init(char *nsswitch_path); ++ + #endif /* _ID_MAPPING_H_ */ + +diff --git a/libsubid/Makefile.am b/libsubid/Makefile.am +index f24dbb94..f543b5eb 100644 +--- a/libsubid/Makefile.am ++++ b/libsubid/Makefile.am +@@ -19,7 +19,7 @@ MISCLIBS = \ + libsubid_la_LIBADD = \ + $(top_srcdir)/lib/libshadow.la \ + $(top_srcdir)/libmisc/libmisc.la \ +- $(MISCLIBS) ++ $(MISCLIBS) -ldl + + AM_CPPFLAGS = \ + -I${top_srcdir}/lib \ +diff --git a/libsubid/api.c b/libsubid/api.c +index 91d73bed..737e1c8b 100644 +--- a/libsubid/api.c ++++ b/libsubid/api.c +@@ -38,132 +38,48 @@ + #include "idmapping.h" + #include "api.h" + +-static struct subordinate_range **get_subid_ranges(const char *owner, enum subid_type id_type) ++static ++int get_subid_ranges(const char *owner, enum subid_type id_type, struct subordinate_range ***ranges) + { +- struct subordinate_range **ranges = NULL; +- +- switch (id_type) { +- case ID_TYPE_UID: +- if (!sub_uid_open(O_RDONLY)) { +- return NULL; +- } +- break; +- case ID_TYPE_GID: +- if (!sub_gid_open(O_RDONLY)) { +- return NULL; +- } +- break; +- default: +- return NULL; +- } +- +- ranges = list_owner_ranges(owner, id_type); +- +- if (id_type == ID_TYPE_UID) +- sub_uid_close(); +- else +- sub_gid_close(); +- +- return ranges; ++ return list_owner_ranges(owner, id_type, ranges); + } + +-struct subordinate_range **get_subuid_ranges(const char *owner) ++int get_subuid_ranges(const char *owner, struct subordinate_range ***ranges) + { +- return get_subid_ranges(owner, ID_TYPE_UID); ++ return get_subid_ranges(owner, ID_TYPE_UID, ranges); + } + +-struct subordinate_range **get_subgid_ranges(const char *owner) ++int get_subgid_ranges(const char *owner, struct subordinate_range ***ranges) + { +- return get_subid_ranges(owner, ID_TYPE_GID); ++ return get_subid_ranges(owner, ID_TYPE_GID, ranges); + } + +-void subid_free_ranges(struct subordinate_range **ranges) ++void subid_free_ranges(struct subordinate_range **ranges, int count) + { +- return free_subordinate_ranges(ranges); ++ return free_subordinate_ranges(ranges, count); + } + +-int get_subid_owner(unsigned long id, uid_t **owner, enum subid_type id_type) ++static ++int get_subid_owner(unsigned long id, enum subid_type id_type, uid_t **owner) + { +- int ret = -1; +- +- switch (id_type) { +- case ID_TYPE_UID: +- if (!sub_uid_open(O_RDONLY)) { +- return -1; +- } +- break; +- case ID_TYPE_GID: +- if (!sub_gid_open(O_RDONLY)) { +- return -1; +- } +- break; +- default: +- return -1; +- } +- +- ret = find_subid_owners(id, owner, id_type); +- +- if (id_type == ID_TYPE_UID) +- sub_uid_close(); +- else +- sub_gid_close(); +- +- return ret; ++ return find_subid_owners(id, id_type, owner); + } + + int get_subuid_owners(uid_t uid, uid_t **owner) + { +- return get_subid_owner((unsigned long)uid, owner, ID_TYPE_UID); ++ return get_subid_owner((unsigned long)uid, ID_TYPE_UID, owner); + } + + int get_subgid_owners(gid_t gid, uid_t **owner) + { +- return get_subid_owner((unsigned long)gid, owner, ID_TYPE_GID); ++ return get_subid_owner((unsigned long)gid, ID_TYPE_GID, owner); + } + ++static + bool grant_subid_range(struct subordinate_range *range, bool reuse, + enum subid_type id_type) + { +- bool ret; +- +- switch (id_type) { +- case ID_TYPE_UID: +- if (!sub_uid_lock()) { +- printf("Failed loging subuids (errno %d)\n", errno); +- return false; +- } +- if (!sub_uid_open(O_CREAT | O_RDWR)) { +- printf("Failed opening subuids (errno %d)\n", errno); +- sub_uid_unlock(); +- return false; +- } +- break; +- case ID_TYPE_GID: +- if (!sub_gid_lock()) { +- printf("Failed loging subgids (errno %d)\n", errno); +- return false; +- } +- if (!sub_gid_open(O_CREAT | O_RDWR)) { +- printf("Failed opening subgids (errno %d)\n", errno); +- sub_gid_unlock(); +- return false; +- } +- break; +- default: +- return false; +- } +- +- ret = new_subid_range(range, id_type, reuse); +- +- if (id_type == ID_TYPE_UID) { +- sub_uid_close(); +- sub_uid_unlock(); +- } else { +- sub_gid_close(); +- sub_gid_unlock(); +- } +- +- return ret; ++ return new_subid_range(range, id_type, reuse); + } + + bool grant_subuid_range(struct subordinate_range *range, bool reuse) +@@ -176,56 +92,18 @@ bool grant_subgid_range(struct subordinate_range *range, bool reuse) + return grant_subid_range(range, reuse, ID_TYPE_GID); + } + +-bool free_subid_range(struct subordinate_range *range, enum subid_type id_type) ++static ++bool ungrant_subid_range(struct subordinate_range *range, enum subid_type id_type) + { +- bool ret; +- +- switch (id_type) { +- case ID_TYPE_UID: +- if (!sub_uid_lock()) { +- printf("Failed loging subuids (errno %d)\n", errno); +- return false; +- } +- if (!sub_uid_open(O_CREAT | O_RDWR)) { +- printf("Failed opening subuids (errno %d)\n", errno); +- sub_uid_unlock(); +- return false; +- } +- break; +- case ID_TYPE_GID: +- if (!sub_gid_lock()) { +- printf("Failed loging subgids (errno %d)\n", errno); +- return false; +- } +- if (!sub_gid_open(O_CREAT | O_RDWR)) { +- printf("Failed opening subgids (errno %d)\n", errno); +- sub_gid_unlock(); +- return false; +- } +- break; +- default: +- return false; +- } +- +- ret = release_subid_range(range, id_type); +- +- if (id_type == ID_TYPE_UID) { +- sub_uid_close(); +- sub_uid_unlock(); +- } else { +- sub_gid_close(); +- sub_gid_unlock(); +- } +- +- return ret; ++ return release_subid_range(range, id_type); + } + +-bool free_subuid_range(struct subordinate_range *range) ++bool ungrant_subuid_range(struct subordinate_range *range) + { +- return free_subid_range(range, ID_TYPE_UID); ++ return ungrant_subid_range(range, ID_TYPE_UID); + } + +-bool free_subgid_range(struct subordinate_range *range) ++bool ungrant_subgid_range(struct subordinate_range *range) + { +- return free_subid_range(range, ID_TYPE_GID); ++ return ungrant_subid_range(range, ID_TYPE_GID); + } +diff --git a/libsubid/api.h b/libsubid/api.h +index fbdf0f9e..97b04e25 100644 +--- a/libsubid/api.h ++++ b/libsubid/api.h +@@ -1,9 +1,9 @@ + #include "subid.h" + #include + +-struct subordinate_range **get_subuid_ranges(const char *owner); +-struct subordinate_range **get_subgid_ranges(const char *owner); +-void subid_free_ranges(struct subordinate_range **ranges); ++int get_subuid_ranges(const char *owner, struct subordinate_range ***ranges); ++int get_subgid_ranges(const char *owner, struct subordinate_range ***ranges); ++void subid_free_ranges(struct subordinate_range **ranges, int count); + + int get_subuid_owners(uid_t uid, uid_t **owner); + int get_subgid_owners(gid_t gid, uid_t **owner); +@@ -13,5 +13,5 @@ int get_subgid_owners(gid_t gid, uid_t **owner); + bool grant_subuid_range(struct subordinate_range *range, bool reuse); + bool grant_subgid_range(struct subordinate_range *range, bool reuse); + +-bool free_subuid_range(struct subordinate_range *range); +-bool free_subgid_range(struct subordinate_range *range); ++bool ungrant_subuid_range(struct subordinate_range *range); ++bool ungrant_subgid_range(struct subordinate_range *range); +diff --git a/libsubid/subid.h b/libsubid/subid.h +index ba9a2f6f..2f27ad8a 100644 +--- a/libsubid/subid.h ++++ b/libsubid/subid.h +@@ -1,4 +1,5 @@ + #include ++#include + + #ifndef SUBID_RANGE_DEFINED + #define SUBID_RANGE_DEFINED 1 +@@ -13,5 +14,12 @@ enum subid_type { + ID_TYPE_GID = 2 + }; + ++enum subid_status { ++ SUBID_STATUS_SUCCESS = 0, ++ SUBID_STATUS_UNKNOWN_USER = 1, ++ SUBID_STATUS_ERROR_CONN = 2, ++ SUBID_STATUS_ERROR = 3, ++}; ++ + #define SUBID_NFIELDS 3 + #endif +diff --git a/src/Makefile.am b/src/Makefile.am +index e9d354fd..35027013 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -111,15 +111,6 @@ grpck_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) + grpconv_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) + grpunconv_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) + lastlog_LDADD = $(LDADD) $(LIBAUDIT) $(LIBECONF) +-newuidmap_SOURCES = newuidmap.c ../libmisc/nss.c +-newgidmap_SOURCES = newgidmap.c ../libmisc/nss.c +-groupadd_SOURCES = groupadd.c ../libmisc/nss.c +-groupmod_SOURCES = groupmod.c ../libmisc/nss.c +-groupdel_SOURCES = groupdel.c ../libmisc/nss.c +-newusers_SOURCES = newusers.c ../libmisc/nss.c +-useradd_SOURCES = useradd.c ../libmisc/nss.c +-usermod_SOURCES = usermod.c ../libmisc/nss.c +-userdel_SOURCES = userdel.c ../libmisc/nss.c + login_SOURCES = \ + login.c \ + login_nopam.c +@@ -169,7 +160,8 @@ endif + noinst_PROGRAMS += list_subid_ranges \ + get_subid_owners \ + new_subid_range \ +- free_subid_range ++ free_subid_range \ ++ check_subid_range + + MISCLIBS = \ + $(LIBAUDIT) \ +@@ -186,7 +178,7 @@ list_subid_ranges_LDADD = \ + $(top_builddir)/lib/libshadow.la \ + $(top_builddir)/libmisc/libmisc.la \ + $(top_builddir)/libsubid/libsubid.la \ +- $(MISCLIBS) ++ $(MISCLIBS) -ldl + + list_subid_ranges_CPPFLAGS = \ + -I$(top_srcdir)/lib \ +@@ -197,7 +189,7 @@ get_subid_owners_LDADD = \ + $(top_builddir)/lib/libshadow.la \ + $(top_builddir)/libmisc/libmisc.la \ + $(top_builddir)/libsubid/libsubid.la \ +- $(MISCLIBS) ++ $(MISCLIBS) -ldl + + get_subid_owners_CPPFLAGS = \ + -I$(top_srcdir)/lib \ +@@ -213,7 +205,7 @@ new_subid_range_LDADD = \ + $(top_builddir)/lib/libshadow.la \ + $(top_builddir)/libmisc/libmisc.la \ + $(top_builddir)/libsubid/libsubid.la \ +- $(MISCLIBS) ++ $(MISCLIBS) -ldl + + free_subid_range_CPPFLAGS = \ + -I$(top_srcdir)/lib \ +@@ -224,5 +216,14 @@ free_subid_range_LDADD = \ + $(top_builddir)/lib/libshadow.la \ + $(top_builddir)/libmisc/libmisc.la \ + $(top_builddir)/libsubid/libsubid.la \ +- $(MISCLIBS) ++ $(MISCLIBS) -ldl ++ ++check_subid_range_CPPFLAGS = \ ++ -I$(top_srcdir)/lib \ ++ -I$(top_srcdir)/libmisc ++ ++check_subid_range_LDADD = \ ++ $(top_builddir)/lib/libshadow.la \ ++ $(top_builddir)/libmisc/libmisc.la \ ++ $(MISCLIBS) -ldl + endif +diff --git a/src/check_subid_range.c b/src/check_subid_range.c +new file mode 100644 +index 00000000..fb1c2cfc +--- /dev/null ++++ b/src/check_subid_range.c +@@ -0,0 +1,48 @@ ++// This program is for testing purposes only. ++// usage is "[program] owner [u|g] start count ++// Exits 0 if owner has subid range starting start, of size count ++// Exits 1 otherwise. ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "defines.h" ++#include "prototypes.h" ++#include "subordinateio.h" ++#include "idmapping.h" ++ ++const char *Prog; ++ ++int main(int argc, char **argv) ++{ ++ char *owner; ++ unsigned long start, count; ++ bool check_uids; ++ Prog = Basename (argv[0]); ++ ++ if (argc != 5) ++ exit(1); ++ ++ owner = argv[1]; ++ check_uids = argv[2][0] == 'u'; ++ start = strtoul(argv[3], NULL, 10); ++ if (start == ULONG_MAX && errno == ERANGE) ++ exit(1); ++ count = strtoul(argv[4], NULL, 10); ++ if (count == ULONG_MAX && errno == ERANGE) ++ exit(1); ++ if (check_uids) { ++ if (have_sub_uids(owner, start, count)) ++ exit(0); ++ exit(1); ++ } ++ if (have_sub_gids(owner, start, count)) ++ exit(0); ++ exit(1); ++} +diff --git a/src/free_subid_range.c b/src/free_subid_range.c +index 36858875..de6bc58f 100644 +--- a/src/free_subid_range.c ++++ b/src/free_subid_range.c +@@ -37,9 +37,9 @@ int main(int argc, char *argv[]) + range.start = atoi(argv[1]); + range.count = atoi(argv[2]); + if (group) +- ok = free_subgid_range(&range); ++ ok = ungrant_subgid_range(&range); + else +- ok = free_subuid_range(&range); ++ ok = ungrant_subuid_range(&range); + + if (!ok) { + fprintf(stderr, "Failed freeing id range\n"); +diff --git a/src/list_subid_ranges.c b/src/list_subid_ranges.c +index cdba610e..440ef911 100644 +--- a/src/list_subid_ranges.c ++++ b/src/list_subid_ranges.c +@@ -15,7 +15,7 @@ void usage(void) + + int main(int argc, char *argv[]) + { +- int i; ++ int i, count=0; + struct subordinate_range **ranges; + + Prog = Basename (argv[0]); +@@ -23,19 +23,19 @@ int main(int argc, char *argv[]) + usage(); + } + if (argc == 3 && strcmp(argv[1], "-g") == 0) +- ranges = get_subgid_ranges(argv[2]); ++ count = get_subgid_ranges(argv[2], &ranges); + else if (argc == 2 && strcmp(argv[1], "-h") == 0) + usage(); + else +- ranges = get_subuid_ranges(argv[1]); ++ count = get_subuid_ranges(argv[1], &ranges); + if (!ranges) { + fprintf(stderr, "Error fetching ranges\n"); + exit(1); + } +- for (i = 0; ranges[i]; i++) { ++ for (i = 0; i < count; i++) { + printf("%d: %s %lu %lu\n", i, ranges[i]->owner, + ranges[i]->start, ranges[i]->count); + } +- subid_free_ranges(ranges); ++ subid_free_ranges(ranges, count); + return 0; + } +diff --git a/tests/libsubid/04_nss/Makefile b/tests/libsubid/04_nss/Makefile +new file mode 100644 +index 00000000..6cd3225f +--- /dev/null ++++ b/tests/libsubid/04_nss/Makefile +@@ -0,0 +1,12 @@ ++all: test_nss libsubid_zzz.so ++ ++test_nss: test_nss.c ../../../lib/nss.c ++ gcc -c -I../../../lib/ -I../../.. -o test_nss.o test_nss.c ++ gcc -o test_nss test_nss.o ../../../libmisc/.libs/libmisc.a ../../../lib/.libs/libshadow.a -ldl ++ ++libsubid_zzz.so: libsubid_zzz.c ++ gcc -c -I../../../lib/ -I../../.. -I../../../libmisc -I../../../libsubid libsubid_zzz.c ++ gcc -L../../../libsubid -shared -o libsubid_zzz.so libsubid_zzz.o ../../../lib/.libs/libshadow.a -ldl ++ ++clean: ++ rm -f *.o *.so test_nss +diff --git a/tests/libsubid/04_nss/empty b/tests/libsubid/04_nss/empty +new file mode 100644 +index 00000000..e69de29b +diff --git a/tests/libsubid/04_nss/libsubid_zzz.c b/tests/libsubid/04_nss/libsubid_zzz.c +new file mode 100644 +index 00000000..b56a4bae +--- /dev/null ++++ b/tests/libsubid/04_nss/libsubid_zzz.c +@@ -0,0 +1,146 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++enum subid_status shadow_subid_has_any_range(const char *owner, enum subid_type t, bool *result) ++{ ++ if (strcmp(owner, "ubuntu") == 0) { ++ *result = true; ++ return SUBID_STATUS_SUCCESS; ++ } ++ if (strcmp(owner, "error") == 0) { ++ *result = false; ++ return SUBID_STATUS_ERROR; ++ } ++ if (strcmp(owner, "unknown") == 0) { ++ *result = false; ++ return SUBID_STATUS_UNKNOWN_USER; ++ } ++ if (strcmp(owner, "conn") == 0) { ++ *result = false; ++ return SUBID_STATUS_ERROR_CONN; ++ } ++ if (t == ID_TYPE_UID) { ++ *result = strcmp(owner, "user1") == 0; ++ return SUBID_STATUS_SUCCESS; ++ } ++ ++ *result = strcmp(owner, "group1") == 0; ++ return SUBID_STATUS_SUCCESS; ++} ++ ++enum subid_status shadow_subid_has_range(const char *owner, unsigned long start, unsigned long count, enum subid_type t, bool *result) ++{ ++ if (strcmp(owner, "ubuntu") == 0 && ++ start >= 200000 && ++ count <= 100000) { ++ *result = true; ++ return SUBID_STATUS_SUCCESS; ++ } ++ *result = false; ++ if (strcmp(owner, "error") == 0) ++ return SUBID_STATUS_ERROR; ++ if (strcmp(owner, "unknown") == 0) ++ return SUBID_STATUS_UNKNOWN_USER; ++ if (strcmp(owner, "conn") == 0) ++ return SUBID_STATUS_ERROR_CONN; ++ ++ if (t == ID_TYPE_UID && strcmp(owner, "user1") != 0) ++ return SUBID_STATUS_SUCCESS; ++ if (t == ID_TYPE_GID && strcmp(owner, "group1") != 0) ++ return SUBID_STATUS_SUCCESS; ++ ++ if (start < 100000) ++ return SUBID_STATUS_SUCCESS; ++ if (count >= 65536) ++ return SUBID_STATUS_SUCCESS; ++ *result = true; ++ return SUBID_STATUS_SUCCESS; ++} ++ ++// So if 'user1' or 'ubuntu' is defined in passwd, we'll return those values, ++// to ease manual testing. For automated testing, if you return those values, ++// we'll return 1000 for ubuntu and 1001 otherwise. ++static uid_t getnamuid(const char *name) { ++ struct passwd *pw; ++ ++ pw = getpwnam(name); ++ if (pw) ++ return pw->pw_uid; ++ ++ // For testing purposes ++ return strcmp(name, "ubuntu") == 0 ? (uid_t)1000 : (uid_t)1001; ++} ++ ++static int alloc_uid(uid_t **uids, uid_t id) { ++ *uids = malloc(sizeof(uid_t)); ++ if (!*uids) ++ return -1; ++ *uids[0] = id; ++ return 1; ++} ++ ++enum subid_status shadow_subid_find_subid_owners(unsigned long id, enum subid_type id_type, uid_t **uids, int *count) ++{ ++ if (id >= 100000 && id < 165536) { ++ *count = alloc_uid(uids, getnamuid("user1")); ++ if (*count == 1) ++ return SUBID_STATUS_SUCCESS; ++ return SUBID_STATUS_ERROR; // out of memory ++ } ++ if (id >= 200000 && id < 300000) { ++ *count = alloc_uid(uids, getnamuid("ubuntu")); ++ if (*count == 1) ++ return SUBID_STATUS_SUCCESS; ++ return SUBID_STATUS_ERROR; // out of memory ++ } ++ *count = 0; // nothing found ++ return SUBID_STATUS_SUCCESS; ++} ++ ++enum subid_status shadow_subid_list_owner_ranges(const char *owner, enum subid_type id_type, struct subordinate_range ***in_ranges, int *count) ++{ ++ struct subordinate_range **ranges; ++ ++ *count = 0; ++ if (strcmp(owner, "error") == 0) ++ return SUBID_STATUS_ERROR; ++ if (strcmp(owner, "unknown") == 0) ++ return SUBID_STATUS_UNKNOWN_USER; ++ if (strcmp(owner, "conn") == 0) ++ return SUBID_STATUS_ERROR_CONN; ++ ++ *ranges = NULL; ++ if (strcmp(owner, "user1") != 0 && strcmp(owner, "ubuntu") != 0 && ++ strcmp(owner, "group1") != 0) ++ return SUBID_STATUS_SUCCESS; ++ if (id_type == ID_TYPE_GID && strcmp(owner, "user1") == 0) ++ return SUBID_STATUS_SUCCESS; ++ if (id_type == ID_TYPE_UID && strcmp(owner, "group1") == 0) ++ return SUBID_STATUS_SUCCESS; ++ ranges = (struct subordinate_range **)malloc(sizeof(struct subordinate_range *)); ++ if (!*ranges) ++ return SUBID_STATUS_ERROR; ++ ranges[0] = (struct subordinate_range *)malloc(sizeof(struct subordinate_range)); ++ if (!ranges[0]) { ++ free(*ranges); ++ *ranges = NULL; ++ return SUBID_STATUS_ERROR; ++ } ++ ranges[0]->owner = strdup(owner); ++ if (strcmp(owner, "user1") == 0 || strcmp(owner, "group1") == 0) { ++ ranges[0]->start = 100000; ++ ranges[0]->count = 65536; ++ } else { ++ ranges[0]->start = 200000; ++ ranges[0]->count = 100000; ++ } ++ ++ *count = 1; ++ *in_ranges = ranges; ++ ++ return SUBID_STATUS_SUCCESS; ++} +diff --git a/tests/libsubid/04_nss/nsswitch1.conf b/tests/libsubid/04_nss/nsswitch1.conf +new file mode 100644 +index 00000000..43764a39 +--- /dev/null ++++ b/tests/libsubid/04_nss/nsswitch1.conf +@@ -0,0 +1,20 @@ ++# /etc/nsswitch.conf ++# ++# Example configuration of GNU Name Service Switch functionality. ++# If you have the `glibc-doc-reference' and `info' packages installed, try: ++# `info libc "Name Service Switch"' for information about this file. ++ ++passwd: files systemd ++group: files systemd ++shadow: files ++gshadow: files ++ ++hosts: files mdns4_minimal [NOTFOUND=return] dns ++networks: files ++ ++protocols: db files ++services: db files ++ethers: db files ++rpc: db files ++ ++netgroup: nis +diff --git a/tests/libsubid/04_nss/nsswitch2.conf b/tests/libsubid/04_nss/nsswitch2.conf +new file mode 100644 +index 00000000..d371a36c +--- /dev/null ++++ b/tests/libsubid/04_nss/nsswitch2.conf +@@ -0,0 +1,22 @@ ++# /etc/nsswitch.conf ++# ++# Example configuration of GNU Name Service Switch functionality. ++# If you have the `glibc-doc-reference' and `info' packages installed, try: ++# `info libc "Name Service Switch"' for information about this file. ++ ++passwd: files systemd ++group: files systemd ++shadow: files ++gshadow: files ++ ++hosts: files mdns4_minimal [NOTFOUND=return] dns ++networks: files ++ ++protocols: db files ++services: db files ++ethers: db files ++rpc: db files ++ ++netgroup: nis ++ ++subid: files +diff --git a/tests/libsubid/04_nss/nsswitch3.conf b/tests/libsubid/04_nss/nsswitch3.conf +new file mode 100644 +index 00000000..19f2d934 +--- /dev/null ++++ b/tests/libsubid/04_nss/nsswitch3.conf +@@ -0,0 +1,22 @@ ++# /etc/nsswitch.conf ++# ++# Example configuration of GNU Name Service Switch functionality. ++# If you have the `glibc-doc-reference' and `info' packages installed, try: ++# `info libc "Name Service Switch"' for information about this file. ++ ++passwd: files systemd ++group: files systemd ++shadow: files ++gshadow: files ++ ++hosts: files mdns4_minimal [NOTFOUND=return] dns ++networks: files ++ ++protocols: db files ++services: db files ++ethers: db files ++rpc: db files ++ ++netgroup: nis ++ ++subid: zzz +diff --git a/tests/libsubid/04_nss/subidnss.test b/tests/libsubid/04_nss/subidnss.test +new file mode 100755 +index 00000000..3d40dc8c +--- /dev/null ++++ b/tests/libsubid/04_nss/subidnss.test +@@ -0,0 +1,22 @@ ++#!/bin/sh ++ ++set -e ++ ++cd $(dirname $0) ++ ++. ../../common/config.sh ++. ../../common/log.sh ++ ++make ++ ++export LD_LIBRARY_PATH=.:../../../lib/.libs:$LD_LIBRARY_PATH ++ ++./test_nss 1 ++./test_nss 2 ++./test_nss 3 ++ ++unshare -Urm ./test_range ++ ++log_status "$0" "SUCCESS" ++ ++trap '' 0 +diff --git a/tests/libsubid/04_nss/test_nss.c b/tests/libsubid/04_nss/test_nss.c +new file mode 100644 +index 00000000..5d903ab4 +--- /dev/null ++++ b/tests/libsubid/04_nss/test_nss.c +@@ -0,0 +1,72 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++extern bool nss_is_initialized(); ++extern struct subid_nss_ops *get_subid_nss_handle(); ++ ++void test1() { ++ // nsswitch1 has no subid: entry ++ setenv("LD_LIBRARY_PATH", ".", 1); ++ printf("Test with no subid entry\n"); ++ nss_init("./nsswitch1.conf"); ++ if (!nss_is_initialized() || get_subid_nss_handle()) ++ exit(1); ++ // second run should change nothing ++ printf("Test with no subid entry, second run\n"); ++ nss_init("./nsswitch1.conf"); ++ if (!nss_is_initialized() || get_subid_nss_handle()) ++ exit(1); ++} ++ ++void test2() { ++ // nsswitch2 has a subid: files entry ++ printf("test with 'files' subid entry\n"); ++ nss_init("./nsswitch2.conf"); ++ if (!nss_is_initialized() || get_subid_nss_handle()) ++ exit(1); ++ // second run should change nothing ++ printf("test with 'files' subid entry, second run\n"); ++ nss_init("./nsswitch2.conf"); ++ if (!nss_is_initialized() || get_subid_nss_handle()) ++ exit(1); ++} ++ ++void test3() { ++ // nsswitch3 has a subid: testnss entry ++ printf("test with 'test' subid entry\n"); ++ nss_init("./nsswitch3.conf"); ++ if (!nss_is_initialized() || !get_subid_nss_handle()) ++ exit(1); ++ // second run should change nothing ++ printf("test with 'test' subid entry, second run\n"); ++ nss_init("./nsswitch3.conf"); ++ if (!nss_is_initialized() || !get_subid_nss_handle()) ++ exit(1); ++} ++ ++const char *Prog; ++ ++int main(int argc, char *argv[]) ++{ ++ int which; ++ ++ Prog = Basename(argv[0]); ++ ++ if (argc < 1) ++ exit(1); ++ ++ which = atoi(argv[1]); ++ switch(which) { ++ case 1: test1(); break; ++ case 2: test2(); break; ++ case 3: test3(); break; ++ default: exit(1); ++ } ++ ++ printf("nss parsing tests done\n"); ++ exit(0); ++} +diff --git a/tests/libsubid/04_nss/test_range b/tests/libsubid/04_nss/test_range +new file mode 100755 +index 00000000..356764fb +--- /dev/null ++++ b/tests/libsubid/04_nss/test_range +@@ -0,0 +1,50 @@ ++#!/bin/sh ++ ++set -x ++ ++echo "starting check_range tests" ++ ++export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ++mount --bind ./nsswitch3.conf /etc/nsswitch.conf ++cleanup1() { ++ umount /etc/nsswitch.conf ++} ++trap cleanup1 EXIT HUP INT TERM ++../../../src/check_subid_range user1 u 100000 65535 ++if [ $? -ne 0 ]; then ++ exit 1 ++fi ++../../../src/check_subid_range user2 u 100000 65535 ++if [ $? -eq 0 ]; then ++ exit 1 ++fi ++../../../src/check_subid_range unknown u 100000 65535 ++if [ $? -eq 0 ]; then ++ exit 1 ++fi ++../../../src/check_subid_range error u 100000 65535 ++if [ $? -eq 0 ]; then ++ exit 1 ++fi ++../../../src/check_subid_range user1 u 1000 65535 ++if [ $? -eq 0 ]; then ++ exit 1 ++fi ++ ++umount /etc/nsswitch.conf ++ ++mount --bind ./nsswitch1.conf /etc/nsswitch.conf ++mount --bind ./empty /etc/subuid ++ ++cleanup2() { ++ umount /etc/subuid ++ umount /etc/nsswitch.conf ++} ++trap cleanup2 EXIT HUP INT TERM ++../../../src/check_subid_range user1 u 100000 65535 ++if [ $? -eq 0 ]; then ++ exit 1 ++fi ++ ++echo "check_range tests complete" ++exit 0 +diff --git a/tests/run_some b/tests/run_some +index 15b4816a..e6f6eb5a 100755 +--- a/tests/run_some ++++ b/tests/run_some +@@ -127,6 +127,7 @@ run_test ./newuidmap/01_newuidmap/newuidmap.test + run_test ./libsubid/01_list_ranges/list_ranges.test + run_test ./libsubid/02_get_subid_owners/get_subid_owners.test + run_test ./libsubid/03_add_remove/add_remove_subids.test ++run_test ./libsubid/04_nss/subidnss.test + + echo + echo "$succeeded test(s) passed" +-- +2.30.2 + + +From 0f4347d1483191b2142546416a9eefe0c9459600 Mon Sep 17 00:00:00 2001 +From: Serge Hallyn +Date: Thu, 15 Apr 2021 09:52:29 -0500 +Subject: [PATCH 3/6] clean up libsubid headers + +Move libsubid/api.h into libsubid/subid.h, and document the api in subid.h + +Signed-off-by: Serge Hallyn +--- + libsubid/api.c | 2 +- + libsubid/api.h | 17 ------- + libsubid/subid.h | 105 ++++++++++++++++++++++++++++++++++++++++ + src/free_subid_range.c | 2 +- + src/get_subid_owners.c | 2 +- + src/list_subid_ranges.c | 2 +- + src/new_subid_range.c | 2 +- + 7 files changed, 110 insertions(+), 22 deletions(-) + delete mode 100644 libsubid/api.h + +diff --git a/libsubid/api.c b/libsubid/api.c +index 737e1c8b..a1b5bb3f 100644 +--- a/libsubid/api.c ++++ b/libsubid/api.c +@@ -36,7 +36,7 @@ + #include + #include "subordinateio.h" + #include "idmapping.h" +-#include "api.h" ++#include "subid.h" + + static + int get_subid_ranges(const char *owner, enum subid_type id_type, struct subordinate_range ***ranges) +diff --git a/libsubid/api.h b/libsubid/api.h +deleted file mode 100644 +index 97b04e25..00000000 +--- a/libsubid/api.h ++++ /dev/null +@@ -1,17 +0,0 @@ +-#include "subid.h" +-#include +- +-int get_subuid_ranges(const char *owner, struct subordinate_range ***ranges); +-int get_subgid_ranges(const char *owner, struct subordinate_range ***ranges); +-void subid_free_ranges(struct subordinate_range **ranges, int count); +- +-int get_subuid_owners(uid_t uid, uid_t **owner); +-int get_subgid_owners(gid_t gid, uid_t **owner); +- +-/* range should be pre-allocated with owner and count filled in, start is +- * ignored, can be 0 */ +-bool grant_subuid_range(struct subordinate_range *range, bool reuse); +-bool grant_subgid_range(struct subordinate_range *range, bool reuse); +- +-bool ungrant_subuid_range(struct subordinate_range *range); +-bool ungrant_subgid_range(struct subordinate_range *range); +diff --git a/libsubid/subid.h b/libsubid/subid.h +index 2f27ad8a..769463f6 100644 +--- a/libsubid/subid.h ++++ b/libsubid/subid.h +@@ -21,5 +21,110 @@ enum subid_status { + SUBID_STATUS_ERROR = 3, + }; + ++/* ++ * get_subuid_ranges: return a list of UID ranges for a user ++ * ++ * @owner: username being queried ++ * @ranges: a pointer to a subordinate range ** in which the result will be ++ * returned. ++ * ++ * returns: number of ranges found, ir < 0 on error. ++ */ ++int get_subuid_ranges(const char *owner, struct subordinate_range ***ranges); ++ ++/* ++ * get_subgid_ranges: return a list of GID ranges for a user ++ * ++ * @owner: username being queried ++ * @ranges: a pointer to a subordinate range ** in which the result will be ++ * returned. ++ * ++ * returns: number of ranges found, ir < 0 on error. ++ */ ++int get_subgid_ranges(const char *owner, struct subordinate_range ***ranges); ++ ++/* ++ * subid_free_ranges: free an array of subordinate_ranges returned by either ++ * get_subuid_ranges() or get_subgid_ranges(). ++ * ++ * @ranges: the ranges to free ++ * @count: the number of ranges in @ranges ++ */ ++void subid_free_ranges(struct subordinate_range **ranges, int count); ++ ++/* ++ * get_subuid_owners: return a list of uids to which the given uid has been ++ * delegated. ++ * ++ * @uid: The subuid being queried ++ * @owners: a pointer to an array of uids into which the results are placed. ++ * The returned array must be freed by the caller. ++ * ++ * Returns the number of uids returned, or < 0 on error. ++ */ ++int get_subuid_owners(uid_t uid, uid_t **owner); ++ ++/* ++ * get_subgid_owners: return a list of uids to which the given gid has been ++ * delegated. ++ * ++ * @uid: The subgid being queried ++ * @owners: a pointer to an array of uids into which the results are placed. ++ * The returned array must be freed by the caller. ++ * ++ * Returns the number of uids returned, or < 0 on error. ++ */ ++int get_subgid_owners(gid_t gid, uid_t **owner); ++ ++/* ++ * grant_subuid_range: assign a subuid range to a user ++ * ++ * @range: pointer to a struct subordinate_range detailing the UID range ++ * to allocate. ->owner must be the username, and ->count must be ++ * filled in. ->start is ignored, and will contain the start ++ * of the newly allocated range, upon success. ++ * ++ * Returns true if the delegation succeeded, false otherwise. If true, ++ * then the range from (range->start, range->start + range->count) will ++ * be delegated to range->owner. ++ */ ++bool grant_subuid_range(struct subordinate_range *range, bool reuse); ++ ++/* ++ * grant_subsid_range: assign a subgid range to a user ++ * ++ * @range: pointer to a struct subordinate_range detailing the GID range ++ * to allocate. ->owner must be the username, and ->count must be ++ * filled in. ->start is ignored, and will contain the start ++ * of the newly allocated range, upon success. ++ * ++ * Returns true if the delegation succeeded, false otherwise. If true, ++ * then the range from (range->start, range->start + range->count) will ++ * be delegated to range->owner. ++ */ ++bool grant_subgid_range(struct subordinate_range *range, bool reuse); ++ ++/* ++ * ungrant_subuid_range: remove a subuid allocation. ++ * ++ * @range: pointer to a struct subordinate_range detailing the UID allocation ++ * to remove. ++ * ++ * Returns true if successful, false if it failed, for instance if the ++ * delegation did not exist. ++ */ ++bool ungrant_subuid_range(struct subordinate_range *range); ++ ++/* ++ * ungrant_subuid_range: remove a subgid allocation. ++ * ++ * @range: pointer to a struct subordinate_range detailing the GID allocation ++ * to remove. ++ * ++ * Returns true if successful, false if it failed, for instance if the ++ * delegation did not exist. ++ */ ++bool ungrant_subgid_range(struct subordinate_range *range); ++ + #define SUBID_NFIELDS 3 + #endif +diff --git a/src/free_subid_range.c b/src/free_subid_range.c +index de6bc58f..3701a262 100644 +--- a/src/free_subid_range.c ++++ b/src/free_subid_range.c +@@ -1,6 +1,6 @@ + #include + #include +-#include "api.h" ++#include "subid.h" + #include "stdlib.h" + #include "prototypes.h" + +diff --git a/src/get_subid_owners.c b/src/get_subid_owners.c +index a4385540..409e3fea 100644 +--- a/src/get_subid_owners.c ++++ b/src/get_subid_owners.c +@@ -1,5 +1,5 @@ + #include +-#include "api.h" ++#include "subid.h" + #include "stdlib.h" + #include "prototypes.h" + +diff --git a/src/list_subid_ranges.c b/src/list_subid_ranges.c +index 440ef911..21b2c192 100644 +--- a/src/list_subid_ranges.c ++++ b/src/list_subid_ranges.c +@@ -1,5 +1,5 @@ + #include +-#include "api.h" ++#include "subid.h" + #include "stdlib.h" + #include "prototypes.h" + +diff --git a/src/new_subid_range.c b/src/new_subid_range.c +index 6d7b033b..dde196b3 100644 +--- a/src/new_subid_range.c ++++ b/src/new_subid_range.c +@@ -1,6 +1,6 @@ + #include + #include +-#include "api.h" ++#include "subid.h" + #include "stdlib.h" + #include "prototypes.h" + +-- +2.30.2 + diff --git a/shadow-utils.spec b/shadow-utils.spec index 8d1f5ea..551de7a 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.8.1 -Release: 8%{?dist} +Release: 9%{?dist} Epoch: 2 URL: https://github.com/shadow-maint/shadow Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -11,6 +11,11 @@ Source3: shadow-utils.login.defs Source4: shadow-bsd.txt Source5: https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt Source6: shadow-utils.HOME_MODE.xml + +### Globals ### +%global includesubiddir %{_includedir}/subid + +### Patches ### # Misc small changes - most probably non-upstreamable Patch0: shadow-4.6-redhat.patch # Be more lenient with acceptable user/group names - non upstreamable @@ -62,6 +67,15 @@ Patch44: shadow-4.8.1-check-local-groups.patch Patch45: shadow-4.8.1-commonio-force-lock-file-sync.patch # https://github.com/shadow-maint/shadow/commit/df6ec1d1693c8c80c323b40d6fc82bb549363db3 Patch46: shadow-4.8.1-man-include-lastlog-file-caveat.patch +# https://github.com/shadow-maint/shadow/commit/0a7888b1fad613a052b988b01a71933b67296e68 +# https://github.com/shadow-maint/shadow/commit/607f1dd549cf9abc87af1cf29275f0d2d11eea29 +# https://github.com/shadow-maint/shadow/commit/b5fb1b38eea2fb0489ed088c82daf6700e72363e +# https://github.com/shadow-maint/shadow/commit/43a917cce54019799a8de037fd63780a2b640afc +Patch47: shadow-4.8.1-libsubid_creation.patch +# https://github.com/shadow-maint/shadow/commit/514c1328b6c90d817ae0a9f7addfb3c9a11a275a +# https://github.com/shadow-maint/shadow/commit/8492dee6632e340dee76eee895c3e30877bebf45 +# https://github.com/shadow-maint/shadow/commit/0f4347d1483191b2142546416a9eefe0c9459600 +Patch48: shadow-4.8.1-libsubid_nsswitch_support.patch License: BSD and GPLv2+ BuildRequires: make @@ -90,6 +104,23 @@ for all users. The useradd, userdel, and usermod commands are used for managing user accounts. The groupadd, groupdel, and groupmod commands are used for managing group accounts. + +### Subpackages ### +%package subid +Summary: A library to manage subordinate uid and gid ranges +License: BSD and GPLv2+ + +%description subid +Utility library that provides a way to manage subid ranges. + + +%package subid-devel +Summary: Development package for shadow-utils-subid +License: BSD and GPLv2+ + +%description subid-devel +Development files for shadow-utils-subid. + %prep %setup -q -n shadow-%{version} %patch0 -p1 -b .redhat @@ -116,6 +147,8 @@ are used for managing group accounts. %patch44 -p1 -b .check-local-groups %patch45 -p1 -b .commonio-force-lock-file-sync %patch46 -p1 -b .man-include-lastlog-file-caveat +%patch47 -p1 -b .libsubid_creation +%patch48 -p1 -b .libsubid_nsswitch_support iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -145,7 +178,7 @@ autoreconf --with-selinux \ --without-libcrack \ --without-libpam \ - --disable-shared \ + --enable-shared \ --with-group-name-max-length=32 %make_build @@ -220,6 +253,14 @@ for dir in $(ls -1d $RPM_BUILD_ROOT%{_mandir}/{??,??_??}) ; do echo "%%lang($lang) $dir/man*/*" >> shadow.lang done +# Move header files to its own folder +echo $(ls) +mkdir -p $RPM_BUILD_ROOT/%{includesubiddir} +install -m 644 libsubid/subid.h $RPM_BUILD_ROOT/%{includesubiddir}/ + +# Remove .la files created by libsubid +rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la + %files -f shadow.lang %doc NEWS doc/HOWTO README %license gpl-2.0.txt shadow-bsd.txt @@ -268,7 +309,18 @@ done %{_mandir}/man8/vipw.8* %{_mandir}/man8/vigr.8* +%files subid +%{_libdir}/libsubid.so.* + +%files subid-devel +%{includesubiddir}/subid.h +%{_libdir}/libsubid.so + %changelog +* Fri Apr 16 2021 Iker Pedrosa - 2:4.8.1-9 +- libsubid: creation and nsswitch support +- Creation of subid and subid-devel subpackages + * Mon Mar 29 2021 Iker Pedrosa - 2:4.8.1-8 - man: include lastlog file caveat (#951564) - Upstream links to several patches From 1ec508822531eeeac9ec6ddd1f18ad24cfdc98ba Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Thu, 6 May 2021 11:41:05 +0200 Subject: [PATCH 029/134] - man: mention NSS in new[ug]idmap manpages - libsubid: move development header to shadow folder --- ...w-4.8.1-man-mention-nss-in-newuidmap.patch | 44 +++++++++++++++++++ shadow-utils.spec | 11 ++++- 2 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 shadow-4.8.1-man-mention-nss-in-newuidmap.patch diff --git a/shadow-4.8.1-man-mention-nss-in-newuidmap.patch b/shadow-4.8.1-man-mention-nss-in-newuidmap.patch new file mode 100644 index 0000000..e26cfa7 --- /dev/null +++ b/shadow-4.8.1-man-mention-nss-in-newuidmap.patch @@ -0,0 +1,44 @@ +From 186b1b7ac1a68d0fcc618a22da1a99232b420911 Mon Sep 17 00:00:00 2001 +From: Serge Hallyn +Date: Tue, 4 May 2021 14:39:26 -0500 +Subject: [PATCH] manpages: mention NSS in new[ug]idmap manpages + +Closes #328 + +Signed-off-by: Serge Hallyn +--- + man/newgidmap.1.xml | 3 ++- + man/newuidmap.1.xml | 3 ++- + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/man/newgidmap.1.xml b/man/newgidmap.1.xml +index 71b03e56..76fc1e30 100644 +--- a/man/newgidmap.1.xml ++++ b/man/newgidmap.1.xml +@@ -88,7 +88,8 @@ + DESCRIPTION + + The newgidmap sets /proc/[pid]/gid_map based on its +- command line arguments and the gids allowed in /etc/subgid. ++ command line arguments and the gids allowed (either in /etc/subgid or ++ through the configured NSS subid module). + Note that the root user is not exempted from the requirement for a valid + /etc/subgid entry. + +diff --git a/man/newuidmap.1.xml b/man/newuidmap.1.xml +index a6f1f085..44eca50a 100644 +--- a/man/newuidmap.1.xml ++++ b/man/newuidmap.1.xml +@@ -88,7 +88,8 @@ + DESCRIPTION + + The newuidmap sets /proc/[pid]/uid_map based on its +- command line arguments and the uids allowed in /etc/subuid. ++ command line arguments and the uids allowed (either in /etc/subuid or ++ through the configured NSS subid module). + Note that the root user is not exempted from the requirement for a valid + /etc/subuid entry. + +-- +2.30.2 + diff --git a/shadow-utils.spec b/shadow-utils.spec index 551de7a..3a8e510 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.8.1 -Release: 9%{?dist} +Release: 10%{?dist} Epoch: 2 URL: https://github.com/shadow-maint/shadow Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -13,7 +13,7 @@ Source5: https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt Source6: shadow-utils.HOME_MODE.xml ### Globals ### -%global includesubiddir %{_includedir}/subid +%global includesubiddir %{_includedir}/shadow ### Patches ### # Misc small changes - most probably non-upstreamable @@ -76,6 +76,8 @@ Patch47: shadow-4.8.1-libsubid_creation.patch # https://github.com/shadow-maint/shadow/commit/8492dee6632e340dee76eee895c3e30877bebf45 # https://github.com/shadow-maint/shadow/commit/0f4347d1483191b2142546416a9eefe0c9459600 Patch48: shadow-4.8.1-libsubid_nsswitch_support.patch +# https://github.com/shadow-maint/shadow/commit/186b1b7ac1a68d0fcc618a22da1a99232b420911 +Patch49: shadow-4.8.1-man-mention-nss-in-newuidmap.patch License: BSD and GPLv2+ BuildRequires: make @@ -149,6 +151,7 @@ Development files for shadow-utils-subid. %patch46 -p1 -b .man-include-lastlog-file-caveat %patch47 -p1 -b .libsubid_creation %patch48 -p1 -b .libsubid_nsswitch_support +%patch49 -p1 -b .man-mention-nss-in-newuidmap iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -317,6 +320,10 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la %{_libdir}/libsubid.so %changelog +* Thu May 6 2021 Iker Pedrosa - 2:4.8.1-10 +- man: mention NSS in new[ug]idmap manpages +- libsubid: move development header to shadow folder + * Fri Apr 16 2021 Iker Pedrosa - 2:4.8.1-9 - libsubid: creation and nsswitch support - Creation of subid and subid-devel subpackages From cbc60528c36bf3d3d802813d7e1ac04b66b14a69 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Mon, 21 Jun 2021 13:24:36 +0200 Subject: [PATCH 030/134] libsubid improvements - libsubid: don't print error messages on stderr by default - libsubid: libsubid_init return false if out of memory - useradd: fix SUB_UID_COUNT=0 - libsubid: don't return owner in list_owner_ranges API call - libsubid: libsubid_init don't print messages on error - libsubid: fix newusers when nss provides subids - man: clarify subid delegation - libsubid: make shadow_logfd not extern --- ...bid_fix_newusers_nss_provides_subids.patch | 151 + ...bsubid_init_not_print_error_messages.patch | 40 + shadow-4.8.1-libsubid_init_return_false.patch | 37 + ...4.8.1-libsubid_make_logfd_not_extern.patch | 41 + ....1-libsubid_not_print_error_messages.patch | 2443 +++++++++++++++++ ....1-libsubid_simplify_ranges_variable.patch | 264 ++ ...w-4.8.1-man_clarify_subid_delegation.patch | 246 ++ shadow-4.8.1-useradd_SUB_UID_COUNT-0.patch | 44 + shadow-utils.spec | 37 +- 9 files changed, 3302 insertions(+), 1 deletion(-) create mode 100644 shadow-4.8.1-libsubid_fix_newusers_nss_provides_subids.patch create mode 100644 shadow-4.8.1-libsubid_init_not_print_error_messages.patch create mode 100644 shadow-4.8.1-libsubid_init_return_false.patch create mode 100644 shadow-4.8.1-libsubid_make_logfd_not_extern.patch create mode 100644 shadow-4.8.1-libsubid_not_print_error_messages.patch create mode 100644 shadow-4.8.1-libsubid_simplify_ranges_variable.patch create mode 100644 shadow-4.8.1-man_clarify_subid_delegation.patch create mode 100644 shadow-4.8.1-useradd_SUB_UID_COUNT-0.patch diff --git a/shadow-4.8.1-libsubid_fix_newusers_nss_provides_subids.patch b/shadow-4.8.1-libsubid_fix_newusers_nss_provides_subids.patch new file mode 100644 index 0000000..c0ca905 --- /dev/null +++ b/shadow-4.8.1-libsubid_fix_newusers_nss_provides_subids.patch @@ -0,0 +1,151 @@ +diff -up shadow-4.8.1/lib/nss.c.libsubid_fix_newusers_nss_provides_subids shadow-4.8.1/lib/nss.c +--- shadow-4.8.1/lib/nss.c.libsubid_fix_newusers_nss_provides_subids 2021-05-25 09:37:14.772741048 +0200 ++++ shadow-4.8.1/lib/nss.c 2021-05-25 09:37:14.782741188 +0200 +@@ -116,14 +116,6 @@ void nss_init(char *nsswitch_path) { + subid_nss = NULL; + goto done; + } +- subid_nss->has_any_range = dlsym(h, "shadow_subid_has_any_range"); +- if (!subid_nss->has_any_range) { +- fprintf(shadow_logfd, "%s did not provide @has_any_range@\n", libname); +- dlclose(h); +- free(subid_nss); +- subid_nss = NULL; +- goto done; +- } + subid_nss->find_subid_owners = dlsym(h, "shadow_subid_find_subid_owners"); + if (!subid_nss->find_subid_owners) { + fprintf(shadow_logfd, "%s did not provide @find_subid_owners@\n", libname); +diff -up shadow-4.8.1/lib/prototypes.h.libsubid_fix_newusers_nss_provides_subids shadow-4.8.1/lib/prototypes.h +--- shadow-4.8.1/lib/prototypes.h.libsubid_fix_newusers_nss_provides_subids 2021-05-25 09:37:14.780741160 +0200 ++++ shadow-4.8.1/lib/prototypes.h 2021-05-25 09:37:14.782741188 +0200 +@@ -279,18 +279,6 @@ extern bool nss_is_initialized(); + + struct subid_nss_ops { + /* +- * nss_has_any_range: does a user own any subid range +- * +- * @owner: username +- * @idtype: subuid or subgid +- * @result: true if a subid allocation was found for @owner +- * +- * returns success if the module was able to determine an answer (true or false), +- * else an error status. +- */ +- enum subid_status (*has_any_range)(const char *owner, enum subid_type idtype, bool *result); +- +- /* + * nss_has_range: does a user own a given subid range + * + * @owner: username +diff -up shadow-4.8.1/lib/subordinateio.c.libsubid_fix_newusers_nss_provides_subids shadow-4.8.1/lib/subordinateio.c +--- shadow-4.8.1/lib/subordinateio.c.libsubid_fix_newusers_nss_provides_subids 2021-05-25 09:37:14.780741160 +0200 ++++ shadow-4.8.1/lib/subordinateio.c 2021-05-25 09:37:14.782741188 +0200 +@@ -598,19 +598,8 @@ int sub_uid_open (int mode) + return commonio_open (&subordinate_uid_db, mode); + } + +-bool sub_uid_assigned(const char *owner) ++bool local_sub_uid_assigned(const char *owner) + { +- struct subid_nss_ops *h; +- bool found; +- enum subid_status status; +- h = get_subid_nss_handle(); +- if (h) { +- status = h->has_any_range(owner, ID_TYPE_UID, &found); +- if (status == SUBID_STATUS_SUCCESS && found) +- return true; +- return false; +- } +- + return range_exists (&subordinate_uid_db, owner); + } + +@@ -720,18 +709,8 @@ bool have_sub_gids(const char *owner, gi + return have_range(&subordinate_gid_db, owner, start, count); + } + +-bool sub_gid_assigned(const char *owner) ++bool local_sub_gid_assigned(const char *owner) + { +- struct subid_nss_ops *h; +- bool found; +- enum subid_status status; +- h = get_subid_nss_handle(); +- if (h) { +- status = h->has_any_range(owner, ID_TYPE_GID, &found); +- if (status == SUBID_STATUS_SUCCESS && found) +- return true; +- return false; +- } + return range_exists (&subordinate_gid_db, owner); + } + +diff -up shadow-4.8.1/lib/subordinateio.h.libsubid_fix_newusers_nss_provides_subids shadow-4.8.1/lib/subordinateio.h +--- shadow-4.8.1/lib/subordinateio.h.libsubid_fix_newusers_nss_provides_subids 2021-05-25 09:37:14.780741160 +0200 ++++ shadow-4.8.1/lib/subordinateio.h 2021-05-25 09:37:14.782741188 +0200 +@@ -16,7 +16,7 @@ + extern int sub_uid_close(void); + extern bool have_sub_uids(const char *owner, uid_t start, unsigned long count); + extern bool sub_uid_file_present (void); +-extern bool sub_uid_assigned(const char *owner); ++extern bool local_sub_uid_assigned(const char *owner); + extern int sub_uid_lock (void); + extern int sub_uid_setdbname (const char *filename); + extern /*@observer@*/const char *sub_uid_dbname (void); +@@ -34,7 +34,7 @@ extern void free_subordinate_ranges(stru + extern int sub_gid_close(void); + extern bool have_sub_gids(const char *owner, gid_t start, unsigned long count); + extern bool sub_gid_file_present (void); +-extern bool sub_gid_assigned(const char *owner); ++extern bool local_sub_gid_assigned(const char *owner); + extern int sub_gid_lock (void); + extern int sub_gid_setdbname (const char *filename); + extern /*@observer@*/const char *sub_gid_dbname (void); +diff -up shadow-4.8.1/src/newusers.c.libsubid_fix_newusers_nss_provides_subids shadow-4.8.1/src/newusers.c +--- shadow-4.8.1/src/newusers.c.libsubid_fix_newusers_nss_provides_subids 2021-05-25 09:37:14.776741104 +0200 ++++ shadow-4.8.1/src/newusers.c 2021-05-25 09:37:25.955897160 +0200 +@@ -1021,6 +1021,24 @@ static void close_files (void) + #endif /* ENABLE_SUBIDS */ + } + ++static bool want_subuids(void) ++{ ++ if (get_subid_nss_handle() != NULL) ++ return false; ++ if (getdef_ulong ("SUB_UID_COUNT", 65536) == 0) ++ return false; ++ return true; ++} ++ ++static bool want_subgids(void) ++{ ++ if (get_subid_nss_handle() != NULL) ++ return false; ++ if (getdef_ulong ("SUB_GID_COUNT", 65536) == 0) ++ return false; ++ return true; ++} ++ + int main (int argc, char **argv) + { + char buf[BUFSIZ]; +@@ -1250,7 +1268,7 @@ int main (int argc, char **argv) + /* + * Add subordinate uids if the user does not have them. + */ +- if (is_sub_uid && !sub_uid_assigned(fields[0])) { ++ if (is_sub_uid && want_subuids() && !local_sub_uid_assigned(fields[0])) { + uid_t sub_uid_start = 0; + unsigned long sub_uid_count = 0; + if (find_new_sub_uids(fields[0], &sub_uid_start, &sub_uid_count) == 0) { +@@ -1270,7 +1288,7 @@ int main (int argc, char **argv) + /* + * Add subordinate gids if the user does not have them. + */ +- if (is_sub_gid && !sub_gid_assigned(fields[0])) { ++ if (is_sub_gid && want_subgids() && !local_sub_gid_assigned(fields[0])) { + gid_t sub_gid_start = 0; + unsigned long sub_gid_count = 0; + if (find_new_sub_gids(fields[0], &sub_gid_start, &sub_gid_count) == 0) { diff --git a/shadow-4.8.1-libsubid_init_not_print_error_messages.patch b/shadow-4.8.1-libsubid_init_not_print_error_messages.patch new file mode 100644 index 0000000..820a043 --- /dev/null +++ b/shadow-4.8.1-libsubid_init_not_print_error_messages.patch @@ -0,0 +1,40 @@ +From b0e86b959fe5c086ffb5e7eaf3c1b1e9219411e9 Mon Sep 17 00:00:00 2001 +From: Serge Hallyn +Date: Sun, 23 May 2021 08:03:10 -0500 +Subject: [PATCH] libsubid_init: don't print messages on error + +Signed-off-by: Serge Hallyn +--- + libsubid/api.c | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +diff --git a/libsubid/api.c b/libsubid/api.c +index c4848142..b477b271 100644 +--- a/libsubid/api.c ++++ b/libsubid/api.c +@@ -46,12 +46,10 @@ bool libsubid_init(const char *progname, FILE * logfd) + { + if (progname) { + progname = strdup(progname); +- if (progname) { ++ if (progname) + Prog = progname; +- } else { +- fprintf(stderr, "Out of memory"); ++ else + return false; +- } + } + + if (logfd) { +@@ -60,7 +58,6 @@ bool libsubid_init(const char *progname, FILE * logfd) + } + shadow_logfd = fopen("/dev/null", "w"); + if (!shadow_logfd) { +- fprintf(stderr, "ERROR opening /dev/null for error messages. Using stderr."); + shadow_logfd = stderr; + return false; + } +-- +2.30.2 + diff --git a/shadow-4.8.1-libsubid_init_return_false.patch b/shadow-4.8.1-libsubid_init_return_false.patch new file mode 100644 index 0000000..4d02d0d --- /dev/null +++ b/shadow-4.8.1-libsubid_init_return_false.patch @@ -0,0 +1,37 @@ +From e34f49c1966fcaa9390a544a0136ec189a3c870e Mon Sep 17 00:00:00 2001 +From: Serge Hallyn +Date: Mon, 17 May 2021 08:48:03 -0500 +Subject: [PATCH] libsubid_init: return false if out of memory + +The rest of the run isn't likely to get much better, is it? + +Thanks to Alexey for pointing this out. + +Signed-off-by: Serge Hallyn +Cc: Alexey Tikhonov +--- + libsubid/api.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/libsubid/api.c b/libsubid/api.c +index 8ca09859..8618e500 100644 +--- a/libsubid/api.c ++++ b/libsubid/api.c +@@ -46,10 +46,12 @@ bool libsubid_init(const char *progname, FILE * logfd) + { + if (progname) { + progname = strdup(progname); +- if (progname) ++ if (progname) { + Prog = progname; +- else ++ } else { + fprintf(stderr, "Out of memory"); ++ return false; ++ } + } + + if (logfd) { +-- +2.30.2 + diff --git a/shadow-4.8.1-libsubid_make_logfd_not_extern.patch b/shadow-4.8.1-libsubid_make_logfd_not_extern.patch new file mode 100644 index 0000000..2994442 --- /dev/null +++ b/shadow-4.8.1-libsubid_make_logfd_not_extern.patch @@ -0,0 +1,41 @@ +From 1d767fb779d7b203ad609540d1dc605cf62d1050 Mon Sep 17 00:00:00 2001 +From: Serge Hallyn +Date: Fri, 28 May 2021 22:02:16 -0500 +Subject: [PATCH] libsubid/api.c: make shadow_logfd not extern + +Closes #346 + +Also #include stdio.h + +Signed-off-by: Serge Hallyn +--- + libsubid/api.c | 2 +- + libsubid/subid.h | 1 + + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libsubid/api.c b/libsubid/api.c +index b477b271..a7b904d0 100644 +--- a/libsubid/api.c ++++ b/libsubid/api.c +@@ -40,7 +40,7 @@ + #include "subid.h" + + const char *Prog = "(libsubid)"; +-extern FILE * shadow_logfd; ++FILE *shadow_logfd; + + bool libsubid_init(const char *progname, FILE * logfd) + { +diff --git a/libsubid/subid.h b/libsubid/subid.h +index 5fef2572..eabafe4d 100644 +--- a/libsubid/subid.h ++++ b/libsubid/subid.h +@@ -1,4 +1,5 @@ + #include ++#include + #include + + #ifndef SUBID_RANGE_DEFINED +-- +2.31.1 + diff --git a/shadow-4.8.1-libsubid_not_print_error_messages.patch b/shadow-4.8.1-libsubid_not_print_error_messages.patch new file mode 100644 index 0000000..3cef98c --- /dev/null +++ b/shadow-4.8.1-libsubid_not_print_error_messages.patch @@ -0,0 +1,2443 @@ +diff -up shadow-4.8.1/lib/commonio.c.libsubid_not_print_error_messages shadow-4.8.1/lib/commonio.c +--- shadow-4.8.1/lib/commonio.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.919268967 +0200 ++++ shadow-4.8.1/lib/commonio.c 2021-05-24 13:04:19.928269091 +0200 +@@ -144,7 +144,7 @@ static int do_lock_file (const char *fil + fd = open (file, O_CREAT | O_TRUNC | O_WRONLY, 0600); + if (-1 == fd) { + if (log) { +- (void) fprintf (stderr, ++ (void) fprintf (shadow_logfd, + "%s: %s: %s\n", + Prog, file, strerror (errno)); + } +@@ -156,7 +156,7 @@ static int do_lock_file (const char *fil + len = (ssize_t) strlen (buf) + 1; + if (write (fd, buf, (size_t) len) != len) { + if (log) { +- (void) fprintf (stderr, ++ (void) fprintf (shadow_logfd, + "%s: %s file write error: %s\n", + Prog, file, strerror (errno)); + } +@@ -166,7 +166,7 @@ static int do_lock_file (const char *fil + } + if (fdatasync (fd) == -1) { + if (log) { +- (void) fprintf (stderr, ++ (void) fprintf (shadow_logfd, + "%s: %s file sync error: %s\n", + Prog, file, strerror (errno)); + } +@@ -179,7 +179,7 @@ static int do_lock_file (const char *fil + if (link (file, lock) == 0) { + retval = check_link_count (file); + if ((0==retval) && log) { +- (void) fprintf (stderr, ++ (void) fprintf (shadow_logfd, + "%s: %s: lock file already used\n", + Prog, file); + } +@@ -190,7 +190,7 @@ static int do_lock_file (const char *fil + fd = open (lock, O_RDWR); + if (-1 == fd) { + if (log) { +- (void) fprintf (stderr, ++ (void) fprintf (shadow_logfd, + "%s: %s: %s\n", + Prog, lock, strerror (errno)); + } +@@ -202,7 +202,7 @@ static int do_lock_file (const char *fil + close (fd); + if (len <= 0) { + if (log) { +- (void) fprintf (stderr, ++ (void) fprintf (shadow_logfd, + "%s: existing lock file %s without a PID\n", + Prog, lock); + } +@@ -213,7 +213,7 @@ static int do_lock_file (const char *fil + buf[len] = '\0'; + if (get_pid (buf, &pid) == 0) { + if (log) { +- (void) fprintf (stderr, ++ (void) fprintf (shadow_logfd, + "%s: existing lock file %s with an invalid PID '%s'\n", + Prog, lock, buf); + } +@@ -223,7 +223,7 @@ static int do_lock_file (const char *fil + } + if (kill (pid, 0) == 0) { + if (log) { +- (void) fprintf (stderr, ++ (void) fprintf (shadow_logfd, + "%s: lock %s already used by PID %lu\n", + Prog, lock, (unsigned long) pid); + } +@@ -233,7 +233,7 @@ static int do_lock_file (const char *fil + } + if (unlink (lock) != 0) { + if (log) { +- (void) fprintf (stderr, ++ (void) fprintf (shadow_logfd, + "%s: cannot get lock %s: %s\n", + Prog, lock, strerror (errno)); + } +@@ -245,13 +245,13 @@ static int do_lock_file (const char *fil + if (link (file, lock) == 0) { + retval = check_link_count (file); + if ((0==retval) && log) { +- (void) fprintf (stderr, ++ (void) fprintf (shadow_logfd, + "%s: %s: lock file already used\n", + Prog, file); + } + } else { + if (log) { +- (void) fprintf (stderr, ++ (void) fprintf (shadow_logfd, + "%s: cannot get lock %s: %s\n", + Prog, lock, strerror (errno)); + } +@@ -442,7 +442,7 @@ int commonio_lock (struct commonio_db *d + if (0 == lock_count) { + if (lckpwdf () == -1) { + if (geteuid () != 0) { +- (void) fprintf (stderr, ++ (void) fprintf (shadow_logfd, + "%s: Permission denied.\n", + Prog); + } +@@ -478,7 +478,7 @@ int commonio_lock (struct commonio_db *d + } + /* no unnecessary retries on "permission denied" errors */ + if (geteuid () != 0) { +- (void) fprintf (stderr, "%s: Permission denied.\n", ++ (void) fprintf (shadow_logfd, "%s: Permission denied.\n", + Prog); + return 0; + } +@@ -1109,7 +1109,7 @@ int commonio_update (struct commonio_db + p = find_entry_by_name (db, db->ops->getname (eptr)); + if (NULL != p) { + if (next_entry_by_name (db, p->next, db->ops->getname (eptr)) != NULL) { +- fprintf (stderr, _("Multiple entries named '%s' in %s. Please fix this with pwck or grpck.\n"), db->ops->getname (eptr), db->filename); ++ fprintf (shadow_logfd, _("Multiple entries named '%s' in %s. Please fix this with pwck or grpck.\n"), db->ops->getname (eptr), db->filename); + db->ops->free (nentry); + return 0; + } +@@ -1214,7 +1214,7 @@ int commonio_remove (struct commonio_db + return 0; + } + if (next_entry_by_name (db, p->next, name) != NULL) { +- fprintf (stderr, _("Multiple entries named '%s' in %s. Please fix this with pwck or grpck.\n"), name, db->filename); ++ fprintf (shadow_logfd, _("Multiple entries named '%s' in %s. Please fix this with pwck or grpck.\n"), name, db->filename); + return 0; + } + +diff -up shadow-4.8.1/lib/encrypt.c.libsubid_not_print_error_messages shadow-4.8.1/lib/encrypt.c +--- shadow-4.8.1/lib/encrypt.c.libsubid_not_print_error_messages 2019-12-01 18:02:43.000000000 +0100 ++++ shadow-4.8.1/lib/encrypt.c 2021-05-24 13:04:19.928269091 +0200 +@@ -81,7 +81,7 @@ + method = &nummethod[0]; + } + } +- (void) fprintf (stderr, ++ (void) fprintf (shadow_logfd, + _("crypt method not supported by libcrypt? (%s)\n"), + method); + exit (EXIT_FAILURE); +diff -up shadow-4.8.1/lib/getdef.c.libsubid_not_print_error_messages shadow-4.8.1/lib/getdef.c +--- shadow-4.8.1/lib/getdef.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.915268912 +0200 ++++ shadow-4.8.1/lib/getdef.c 2021-05-24 13:04:19.928269091 +0200 +@@ -250,7 +250,7 @@ int getdef_num (const char *item, int df + if ( (getlong (d->value, &val) == 0) + || (val > INT_MAX) + || (val < INT_MIN)) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("configuration error - cannot parse %s value: '%s'"), + item, d->value); + return dflt; +@@ -285,7 +285,7 @@ unsigned int getdef_unum (const char *it + if ( (getlong (d->value, &val) == 0) + || (val < 0) + || (val > INT_MAX)) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("configuration error - cannot parse %s value: '%s'"), + item, d->value); + return dflt; +@@ -318,7 +318,7 @@ long getdef_long (const char *item, long + } + + if (getlong (d->value, &val) == 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("configuration error - cannot parse %s value: '%s'"), + item, d->value); + return dflt; +@@ -351,7 +351,7 @@ unsigned long getdef_ulong (const char * + + if (getulong (d->value, &val) == 0) { + /* FIXME: we should have a getulong */ +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("configuration error - cannot parse %s value: '%s'"), + item, d->value); + return dflt; +@@ -389,7 +389,7 @@ int putdef_str (const char *name, const + cp = strdup (value); + if (NULL == cp) { + (void) fputs (_("Could not allocate space for config info.\n"), +- stderr); ++ shadow_logfd); + SYSLOG ((LOG_ERR, "could not allocate space for config info")); + return -1; + } +@@ -434,7 +434,7 @@ static /*@observer@*/ /*@null@*/struct i + goto out; + } + } +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("configuration error - unknown item '%s' (notify administrator)\n"), + name); + SYSLOG ((LOG_CRIT, "unknown configuration item `%s'", name)); +diff -up shadow-4.8.1/libmisc/addgrps.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/addgrps.c +--- shadow-4.8.1/libmisc/addgrps.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/libmisc/addgrps.c 2021-05-24 13:04:19.929269104 +0200 +@@ -93,7 +93,7 @@ int add_groups (const char *list) + + grp = getgrnam (token); /* local, no need for xgetgrnam */ + if (NULL == grp) { +- fprintf (stderr, _("Warning: unknown group %s\n"), ++ fprintf (shadow_logfd, _("Warning: unknown group %s\n"), + token); + continue; + } +@@ -105,7 +105,7 @@ int add_groups (const char *list) + } + + if (ngroups >= sysconf (_SC_NGROUPS_MAX)) { +- fputs (_("Warning: too many groups\n"), stderr); ++ fputs (_("Warning: too many groups\n"), shadow_logfd); + break; + } + tmp = (gid_t *) realloc (grouplist, (size_t)(ngroups + 1) * sizeof (GETGROUPS_T)); +diff -up shadow-4.8.1/libmisc/audit_help.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/audit_help.c +--- shadow-4.8.1/libmisc/audit_help.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.905268774 +0200 ++++ shadow-4.8.1/libmisc/audit_help.c 2021-05-24 13:04:19.929269104 +0200 +@@ -59,7 +59,7 @@ void audit_help_open (void) + return; + } + (void) fputs (_("Cannot open audit interface - aborting.\n"), +- stderr); ++ shadow_logfd); + exit (EXIT_FAILURE); + } + } +diff -up shadow-4.8.1/libmisc/chowntty.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/chowntty.c +--- shadow-4.8.1/libmisc/chowntty.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/libmisc/chowntty.c 2021-05-24 13:04:19.929269104 +0200 +@@ -75,7 +75,7 @@ void chown_tty (const struct passwd *inf + || (fchmod (STDIN_FILENO, (mode_t)getdef_num ("TTYPERM", 0600)) != 0)) { + int err = errno; + +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("Unable to change owner or mode of tty stdin: %s"), + strerror (err)); + SYSLOG ((LOG_WARN, +diff -up shadow-4.8.1/libmisc/cleanup_group.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/cleanup_group.c +--- shadow-4.8.1/libmisc/cleanup_group.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.905268774 +0200 ++++ shadow-4.8.1/libmisc/cleanup_group.c 2021-05-24 13:04:19.929269104 +0200 +@@ -203,7 +203,7 @@ void cleanup_report_del_group_gshadow (v + void cleanup_unlock_group (unused void *arg) + { + if (gr_unlock () == 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: failed to unlock %s\n"), + Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); +@@ -223,7 +223,7 @@ void cleanup_unlock_group (unused void * + void cleanup_unlock_gshadow (unused void *arg) + { + if (sgr_unlock () == 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: failed to unlock %s\n"), + Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); +diff -up shadow-4.8.1/libmisc/cleanup_user.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/cleanup_user.c +--- shadow-4.8.1/libmisc/cleanup_user.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.905268774 +0200 ++++ shadow-4.8.1/libmisc/cleanup_user.c 2021-05-24 13:04:19.929269104 +0200 +@@ -120,7 +120,7 @@ void cleanup_report_add_user_shadow (voi + void cleanup_unlock_passwd (unused void *arg) + { + if (pw_unlock () == 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: failed to unlock %s\n"), + Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); +@@ -139,7 +139,7 @@ void cleanup_unlock_passwd (unused void + void cleanup_unlock_shadow (unused void *arg) + { + if (spw_unlock () == 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: failed to unlock %s\n"), + Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); +diff -up shadow-4.8.1/libmisc/copydir.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/copydir.c +--- shadow-4.8.1/libmisc/copydir.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.898268677 +0200 ++++ shadow-4.8.1/libmisc/copydir.c 2021-05-24 13:04:19.929269104 +0200 +@@ -125,11 +125,11 @@ static void error_acl (struct error_cont + } + + va_start (ap, fmt); +- (void) fprintf (stderr, _("%s: "), Prog); +- if (vfprintf (stderr, fmt, ap) != 0) { +- (void) fputs (_(": "), stderr); ++ (void) fprintf (shadow_logfd, _("%s: "), Prog); ++ if (vfprintf (shadow_logfd, fmt, ap) != 0) { ++ (void) fputs (_(": "), shadow_logfd); + } +- (void) fprintf (stderr, "%s\n", strerror (errno)); ++ (void) fprintf (shadow_logfd, "%s\n", strerror (errno)); + va_end (ap); + } + +@@ -248,7 +248,7 @@ int copy_tree (const char *src_root, con + } + + if (!S_ISDIR (sb.st_mode)) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + "%s: %s is not a directory", + Prog, src_root); + return -1; +diff -up shadow-4.8.1/libmisc/env.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/env.c +--- shadow-4.8.1/libmisc/env.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/libmisc/env.c 2021-05-24 13:04:19.929269104 +0200 +@@ -171,7 +171,7 @@ void addenv (const char *string, /*@null + } + newenvp = __newenvp; + } else { +- (void) fputs (_("Environment overflow\n"), stderr); ++ (void) fputs (_("Environment overflow\n"), shadow_logfd); + newenvc--; + free (newenvp[newenvc]); + } +diff -up shadow-4.8.1/libmisc/find_new_gid.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/find_new_gid.c +--- shadow-4.8.1/libmisc/find_new_gid.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.914268898 +0200 ++++ shadow-4.8.1/libmisc/find_new_gid.c 2021-05-24 13:04:19.929269104 +0200 +@@ -74,7 +74,7 @@ static int get_ranges (bool sys_group, g + + /* Check that the ranges make sense */ + if (*max_id < *min_id) { +- (void) fprintf (stderr, ++ (void) fprintf (shadow_logfd, + _("%s: Invalid configuration: SYS_GID_MIN (%lu), " + "GID_MIN (%lu), SYS_GID_MAX (%lu)\n"), + Prog, (unsigned long) *min_id, +@@ -104,7 +104,7 @@ static int get_ranges (bool sys_group, g + + /* Check that the ranges make sense */ + if (*max_id < *min_id) { +- (void) fprintf (stderr, ++ (void) fprintf (shadow_logfd, + _("%s: Invalid configuration: GID_MIN (%lu), " + "GID_MAX (%lu)\n"), + Prog, (unsigned long) *min_id, +@@ -220,7 +220,7 @@ int find_new_gid (bool sys_group, + * more likely to want to stop and address the + * issue. + */ +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Encountered error attempting to use " + "preferred GID: %s\n"), + Prog, strerror (result)); +@@ -250,7 +250,7 @@ int find_new_gid (bool sys_group, + /* Create an array to hold all of the discovered GIDs */ + used_gids = malloc (sizeof (bool) * (gid_max +1)); + if (NULL == used_gids) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: failed to allocate memory: %s\n"), + Prog, strerror (errno)); + return -1; +@@ -330,7 +330,7 @@ int find_new_gid (bool sys_group, + * + */ + if (!nospam) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Can't get unique system GID (%s). " + "Suppressing additional messages.\n"), + Prog, strerror (result)); +@@ -373,7 +373,7 @@ int find_new_gid (bool sys_group, + * + */ + if (!nospam) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Can't get unique system GID (%s). " + "Suppressing additional messages.\n"), + Prog, strerror (result)); +@@ -433,7 +433,7 @@ int find_new_gid (bool sys_group, + * + */ + if (!nospam) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Can't get unique GID (%s). " + "Suppressing additional messages.\n"), + Prog, strerror (result)); +@@ -476,7 +476,7 @@ int find_new_gid (bool sys_group, + * + */ + if (!nospam) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Can't get unique GID (%s). " + "Suppressing additional messages.\n"), + Prog, strerror (result)); +@@ -495,7 +495,7 @@ int find_new_gid (bool sys_group, + } + + /* The code reached here and found no available IDs in the range */ +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Can't get unique GID (no more available GIDs)\n"), + Prog); + SYSLOG ((LOG_WARN, "no more available GIDs on the system")); +diff -up shadow-4.8.1/libmisc/find_new_sub_gids.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/find_new_sub_gids.c +--- shadow-4.8.1/libmisc/find_new_sub_gids.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/libmisc/find_new_sub_gids.c 2021-05-24 13:04:19.930269118 +0200 +@@ -61,7 +61,7 @@ int find_new_sub_gids (const char *owner + count = getdef_ulong ("SUB_GID_COUNT", 65536); + + if (min > max || count >= max || (min + count - 1) > max) { +- (void) fprintf (stderr, ++ (void) fprintf (shadow_logfd, + _("%s: Invalid configuration: SUB_GID_MIN (%lu)," + " SUB_GID_MAX (%lu), SUB_GID_COUNT (%lu)\n"), + Prog, min, max, count); +@@ -70,7 +70,7 @@ int find_new_sub_gids (const char *owner + + start = sub_gid_find_free_range(min, max, count); + if (start == (gid_t)-1) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Can't get unique subordinate GID range\n"), + Prog); + SYSLOG ((LOG_WARN, "no more available subordinate GIDs on the system")); +diff -up shadow-4.8.1/libmisc/find_new_sub_uids.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/find_new_sub_uids.c +--- shadow-4.8.1/libmisc/find_new_sub_uids.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/libmisc/find_new_sub_uids.c 2021-05-24 13:04:19.930269118 +0200 +@@ -61,7 +61,7 @@ int find_new_sub_uids (const char *owner + count = getdef_ulong ("SUB_UID_COUNT", 65536); + + if (min > max || count >= max || (min + count - 1) > max) { +- (void) fprintf (stderr, ++ (void) fprintf (shadow_logfd, + _("%s: Invalid configuration: SUB_UID_MIN (%lu)," + " SUB_UID_MAX (%lu), SUB_UID_COUNT (%lu)\n"), + Prog, min, max, count); +@@ -70,7 +70,7 @@ int find_new_sub_uids (const char *owner + + start = sub_uid_find_free_range(min, max, count); + if (start == (uid_t)-1) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Can't get unique subordinate UID range\n"), + Prog); + SYSLOG ((LOG_WARN, "no more available subordinate UIDs on the system")); +diff -up shadow-4.8.1/libmisc/find_new_uid.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/find_new_uid.c +--- shadow-4.8.1/libmisc/find_new_uid.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.914268898 +0200 ++++ shadow-4.8.1/libmisc/find_new_uid.c 2021-05-24 13:04:19.930269118 +0200 +@@ -74,7 +74,7 @@ static int get_ranges (bool sys_user, ui + + /* Check that the ranges make sense */ + if (*max_id < *min_id) { +- (void) fprintf (stderr, ++ (void) fprintf (shadow_logfd, + _("%s: Invalid configuration: SYS_UID_MIN (%lu), " + "UID_MIN (%lu), SYS_UID_MAX (%lu)\n"), + Prog, (unsigned long) *min_id, +@@ -104,7 +104,7 @@ static int get_ranges (bool sys_user, ui + + /* Check that the ranges make sense */ + if (*max_id < *min_id) { +- (void) fprintf (stderr, ++ (void) fprintf (shadow_logfd, + _("%s: Invalid configuration: UID_MIN (%lu), " + "UID_MAX (%lu)\n"), + Prog, (unsigned long) *min_id, +@@ -220,7 +220,7 @@ int find_new_uid(bool sys_user, + * more likely to want to stop and address the + * issue. + */ +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Encountered error attempting to use " + "preferred UID: %s\n"), + Prog, strerror (result)); +@@ -250,7 +250,7 @@ int find_new_uid(bool sys_user, + /* Create an array to hold all of the discovered UIDs */ + used_uids = malloc (sizeof (bool) * (uid_max +1)); + if (NULL == used_uids) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: failed to allocate memory: %s\n"), + Prog, strerror (errno)); + return -1; +@@ -330,7 +330,7 @@ int find_new_uid(bool sys_user, + * + */ + if (!nospam) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Can't get unique system UID (%s). " + "Suppressing additional messages.\n"), + Prog, strerror (result)); +@@ -373,7 +373,7 @@ int find_new_uid(bool sys_user, + * + */ + if (!nospam) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Can't get unique system UID (%s). " + "Suppressing additional messages.\n"), + Prog, strerror (result)); +@@ -433,7 +433,7 @@ int find_new_uid(bool sys_user, + * + */ + if (!nospam) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Can't get unique UID (%s). " + "Suppressing additional messages.\n"), + Prog, strerror (result)); +@@ -476,7 +476,7 @@ int find_new_uid(bool sys_user, + * + */ + if (!nospam) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Can't get unique UID (%s). " + "Suppressing additional messages.\n"), + Prog, strerror (result)); +@@ -495,7 +495,7 @@ int find_new_uid(bool sys_user, + } + + /* The code reached here and found no available IDs in the range */ +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Can't get unique UID (no more available UIDs)\n"), + Prog); + SYSLOG ((LOG_WARN, "no more available UIDs on the system")); +diff -up shadow-4.8.1/libmisc/gettime.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/gettime.c +--- shadow-4.8.1/libmisc/gettime.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/libmisc/gettime.c 2021-05-24 13:04:19.930269118 +0200 +@@ -61,23 +61,23 @@ + epoch = strtoull (source_date_epoch, &endptr, 10); + if ((errno == ERANGE && (epoch == ULLONG_MAX || epoch == 0)) + || (errno != 0 && epoch == 0)) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("Environment variable $SOURCE_DATE_EPOCH: strtoull: %s\n"), + strerror(errno)); + } else if (endptr == source_date_epoch) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("Environment variable $SOURCE_DATE_EPOCH: No digits were found: %s\n"), + endptr); + } else if (*endptr != '\0') { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("Environment variable $SOURCE_DATE_EPOCH: Trailing garbage: %s\n"), + endptr); + } else if (epoch > ULONG_MAX) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("Environment variable $SOURCE_DATE_EPOCH: value must be smaller than or equal to %lu but was found to be: %llu\n"), + ULONG_MAX, epoch); + } else if (epoch > fallback) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("Environment variable $SOURCE_DATE_EPOCH: value must be smaller than or equal to the current time (%lu) but was found to be: %llu\n"), + fallback, epoch); + } else { +diff -up shadow-4.8.1/libmisc/idmapping.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/idmapping.c +--- shadow-4.8.1/libmisc/idmapping.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/libmisc/idmapping.c 2021-05-24 13:20:06.679312187 +0200 +@@ -47,19 +47,19 @@ struct map_range *get_map_ranges(int ran + int idx, argidx; + + if (ranges < 0 || argc < 0) { +- fprintf(stderr, "%s: error calculating number of arguments\n", Prog); ++ fprintf(shadow_logfd, "%s: error calculating number of arguments\n", Prog); + return NULL; + } + + if (ranges != ((argc + 2) / 3)) { +- fprintf(stderr, "%s: ranges: %u is wrong for argc: %d\n", Prog, ranges, argc); ++ fprintf(shadow_logfd, "%s: ranges: %u is wrong for argc: %d\n", Prog, ranges, argc); + return NULL; + } + + if ((ranges * 3) > argc) { +- fprintf(stderr, "ranges: %u argc: %d\n", ++ fprintf(shadow_logfd, "ranges: %u argc: %d\n", + ranges, argc); +- fprintf(stderr, ++ fprintf(shadow_logfd, + _( "%s: Not enough arguments to form %u mappings\n"), + Prog, ranges); + return NULL; +@@ -67,7 +67,7 @@ struct map_range *get_map_ranges(int ran + + mappings = calloc(ranges, sizeof(*mappings)); + if (!mappings) { +- fprintf(stderr, _( "%s: Memory allocation failure\n"), ++ fprintf(shadow_logfd, _( "%s: Memory allocation failure\n"), + Prog); + exit(EXIT_FAILURE); + } +@@ -88,24 +88,24 @@ struct map_range *get_map_ranges(int ran + return NULL; + } + if (ULONG_MAX - mapping->upper <= mapping->count || ULONG_MAX - mapping->lower <= mapping->count) { +- fprintf(stderr, _( "%s: subuid overflow detected.\n"), Prog); ++ fprintf(shadow_logfd, _( "%s: subuid overflow detected.\n"), Prog); + exit(EXIT_FAILURE); + } + if (mapping->upper > UINT_MAX || + mapping->lower > UINT_MAX || + mapping->count > UINT_MAX) { +- fprintf(stderr, _( "%s: subuid overflow detected.\n"), Prog); ++ fprintf(shadow_logfd, _( "%s: subuid overflow detected.\n"), Prog); + exit(EXIT_FAILURE); + } + if (mapping->lower + mapping->count > UINT_MAX || + mapping->upper + mapping->count > UINT_MAX) { +- fprintf(stderr, _( "%s: subuid overflow detected.\n"), Prog); ++ fprintf(shadow_logfd, _( "%s: subuid overflow detected.\n"), Prog); + exit(EXIT_FAILURE); + } + if (mapping->lower + mapping->count < mapping->lower || + mapping->upper + mapping->count < mapping->upper) { + /* this one really shouldn't be possible given previous checks */ +- fprintf(stderr, _( "%s: subuid overflow detected.\n"), Prog); ++ fprintf(shadow_logfd, _( "%s: subuid overflow detected.\n"), Prog); + exit(EXIT_FAILURE); + } + } +@@ -157,19 +157,19 @@ void write_mapping(int proc_dir_fd, int + } else if (strcmp(map_file, "gid_map") == 0) { + cap = CAP_SETGID; + } else { +- fprintf(stderr, _("%s: Invalid map file %s specified\n"), Prog, map_file); ++ fprintf(shadow_logfd, _("%s: Invalid map file %s specified\n"), Prog, map_file); + exit(EXIT_FAILURE); + } + + /* Align setuid- and fscaps-based new{g,u}idmap behavior. */ + if (geteuid() == 0 && geteuid() != ruid) { + if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) { +- fprintf(stderr, _("%s: Could not prctl(PR_SET_KEEPCAPS)\n"), Prog); ++ fprintf(shadow_logfd, _("%s: Could not prctl(PR_SET_KEEPCAPS)\n"), Prog); + exit(EXIT_FAILURE); + } + + if (seteuid(ruid) < 0) { +- fprintf(stderr, _("%s: Could not seteuid to %d\n"), Prog, ruid); ++ fprintf(shadow_logfd, _("%s: Could not seteuid to %d\n"), Prog, ruid); + exit(EXIT_FAILURE); + } + } +@@ -179,7 +179,7 @@ void write_mapping(int proc_dir_fd, int + data[0].effective = CAP_TO_MASK(cap); + data[0].permitted = data[0].effective; + if (capset(&hdr, data) < 0) { +- fprintf(stderr, _("%s: Could not set caps\n"), Prog); ++ fprintf(shadow_logfd, _("%s: Could not set caps\n"), Prog); + exit(EXIT_FAILURE); + } + #endif +@@ -197,7 +197,7 @@ void write_mapping(int proc_dir_fd, int + mapping->lower, + mapping->count); + if ((written <= 0) || (written >= (bufsize - (pos - buf)))) { +- fprintf(stderr, _("%s: snprintf failed!\n"), Prog); ++ fprintf(shadow_logfd, _("%s: snprintf failed!\n"), Prog); + exit(EXIT_FAILURE); + } + pos += written; +@@ -206,12 +206,12 @@ void write_mapping(int proc_dir_fd, int + /* Write the mapping to the mapping file */ + fd = openat(proc_dir_fd, map_file, O_WRONLY); + if (fd < 0) { +- fprintf(stderr, _("%s: open of %s failed: %s\n"), ++ fprintf(shadow_logfd, _("%s: open of %s failed: %s\n"), + Prog, map_file, strerror(errno)); + exit(EXIT_FAILURE); + } + if (write(fd, buf, pos - buf) != (pos - buf)) { +- fprintf(stderr, _("%s: write to %s failed: %s\n"), ++ fprintf(shadow_logfd, _("%s: write to %s failed: %s\n"), + Prog, map_file, strerror(errno)); + exit(EXIT_FAILURE); + } +diff -up shadow-4.8.1/libmisc/limits.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/limits.c +--- shadow-4.8.1/libmisc/limits.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/libmisc/limits.c 2021-05-24 13:04:19.930269118 +0200 +@@ -548,7 +548,7 @@ void setup_limits (const struct passwd * + #ifdef LIMITS + if (info->pw_uid != 0) { + if ((setup_user_limits (info->pw_name) & LOGIN_ERROR_LOGIN) != 0) { +- (void) fputs (_("Too many logins.\n"), stderr); ++ (void) fputs (_("Too many logins.\n"), shadow_logfd); + (void) sleep (2); /* XXX: Should be FAIL_DELAY */ + exit (EXIT_FAILURE); + } +diff -up shadow-4.8.1/libmisc/pam_pass.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/pam_pass.c +--- shadow-4.8.1/libmisc/pam_pass.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/libmisc/pam_pass.c 2021-05-24 13:04:19.930269118 +0200 +@@ -59,20 +59,20 @@ void do_pam_passwd (const char *user, bo + + ret = pam_start ("passwd", user, &conv, &pamh); + if (ret != PAM_SUCCESS) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("passwd: pam_start() failed, error %d\n"), ret); + exit (10); /* XXX */ + } + + ret = pam_chauthtok (pamh, flags); + if (ret != PAM_SUCCESS) { +- fprintf (stderr, _("passwd: %s\n"), pam_strerror (pamh, ret)); +- fputs (_("passwd: password unchanged\n"), stderr); ++ fprintf (shadow_logfd, _("passwd: %s\n"), pam_strerror (pamh, ret)); ++ fputs (_("passwd: password unchanged\n"), shadow_logfd); + pam_end (pamh, ret); + exit (10); /* XXX */ + } + +- fputs (_("passwd: password updated successfully\n"), stderr); ++ fputs (_("passwd: password updated successfully\n"), shadow_logfd); + (void) pam_end (pamh, PAM_SUCCESS); + } + #else /* !USE_PAM */ +diff -up shadow-4.8.1/libmisc/pam_pass_non_interactive.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/pam_pass_non_interactive.c +--- shadow-4.8.1/libmisc/pam_pass_non_interactive.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/libmisc/pam_pass_non_interactive.c 2021-05-24 13:04:19.930269118 +0200 +@@ -76,7 +76,7 @@ static int ni_conv (int num_msg, + + switch (msg[count]->msg_style) { + case PAM_PROMPT_ECHO_ON: +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: PAM modules requesting echoing are not supported.\n"), + Prog); + goto failed_conversation; +@@ -88,7 +88,7 @@ static int ni_conv (int num_msg, + break; + case PAM_ERROR_MSG: + if ( (NULL == msg[count]->msg) +- || (fprintf (stderr, "%s\n", msg[count]->msg) <0)) { ++ || (fprintf (shadow_logfd, "%s\n", msg[count]->msg) <0)) { + goto failed_conversation; + } + responses[count].resp = NULL; +@@ -101,7 +101,7 @@ static int ni_conv (int num_msg, + responses[count].resp = NULL; + break; + default: +- (void) fprintf (stderr, ++ (void) fprintf (shadow_logfd, + _("%s: conversation type %d not supported.\n"), + Prog, msg[count]->msg_style); + goto failed_conversation; +@@ -143,7 +143,7 @@ int do_pam_passwd_non_interactive (const + + ret = pam_start (pam_service, username, &non_interactive_pam_conv, &pamh); + if (ret != PAM_SUCCESS) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: (user %s) pam_start failure %d\n"), + Prog, username, ret); + return 1; +@@ -152,7 +152,7 @@ int do_pam_passwd_non_interactive (const + non_interactive_password = password; + ret = pam_chauthtok (pamh, 0); + if (ret != PAM_SUCCESS) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: (user %s) pam_chauthtok() failed, error:\n" + "%s\n"), + Prog, username, pam_strerror (pamh, ret)); +diff -up shadow-4.8.1/libmisc/prefix_flag.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/prefix_flag.c +--- shadow-4.8.1/libmisc/prefix_flag.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.930269118 +0200 ++++ shadow-4.8.1/libmisc/prefix_flag.c 2021-05-24 13:21:11.538205727 +0200 +@@ -80,14 +80,14 @@ extern const char* process_prefix_flag ( + if ( (strcmp (argv[i], "--prefix") == 0) + || (strcmp (argv[i], short_opt) == 0)) { + if (NULL != prefix) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: multiple --prefix options\n"), + Prog); + exit (E_BAD_ARG); + } + + if (i + 1 == argc) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: option '%s' requires an argument\n"), + Prog, argv[i]); + exit (E_BAD_ARG); +diff -up shadow-4.8.1/libmisc/pwdcheck.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/pwdcheck.c +--- shadow-4.8.1/libmisc/pwdcheck.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/libmisc/pwdcheck.c 2021-05-24 13:04:19.930269118 +0200 +@@ -51,7 +51,7 @@ void passwd_check (const char *user, con + if (pw_auth (passwd, user, PW_LOGIN, (char *) 0) != 0) { + SYSLOG ((LOG_WARN, "incorrect password for `%s'", user)); + (void) sleep (1); +- fprintf (stderr, _("Incorrect password for %s.\n"), user); ++ fprintf (shadow_logfd, _("Incorrect password for %s.\n"), user); + exit (EXIT_FAILURE); + } + } +diff -up shadow-4.8.1/libmisc/root_flag.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/root_flag.c +--- shadow-4.8.1/libmisc/root_flag.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/libmisc/root_flag.c 2021-05-24 14:39:04.286481468 +0200 +@@ -62,14 +62,14 @@ extern void process_root_flag (const cha + if ( (strcmp (argv[i], "--root") == 0) + || (strcmp (argv[i], short_opt) == 0)) { + if (NULL != newroot) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: multiple --root options\n"), + Prog); + exit (E_BAD_ARG); + } + + if (i + 1 == argc) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: option '%s' requires an argument\n"), + Prog, argv[i]); + exit (E_BAD_ARG); +@@ -88,34 +88,34 @@ static void change_root (const char* new + /* Drop privileges */ + if ( (setregid (getgid (), getgid ()) != 0) + || (setreuid (getuid (), getuid ()) != 0)) { +- fprintf (stderr, _("%s: failed to drop privileges (%s)\n"), ++ fprintf (shadow_logfd, _("%s: failed to drop privileges (%s)\n"), + Prog, strerror (errno)); + exit (EXIT_FAILURE); + } + + if ('/' != newroot[0]) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: invalid chroot path '%s'\n"), + Prog, newroot); + exit (E_BAD_ARG); + } + + if (access (newroot, F_OK) != 0) { +- fprintf(stderr, ++ fprintf(shadow_logfd, + _("%s: cannot access chroot directory %s: %s\n"), + Prog, newroot, strerror (errno)); + exit (E_BAD_ARG); + } + + if (chdir (newroot) != 0) { +- fprintf(stderr, ++ fprintf(shadow_logfd, + _("%s: cannot chdir to chroot directory %s: %s\n"), + Prog, newroot, strerror (errno)); + exit (E_BAD_ARG); + } + + if (chroot (newroot) != 0) { +- fprintf(stderr, ++ fprintf(shadow_logfd, + _("%s: unable to chroot to directory %s: %s\n"), + Prog, newroot, strerror (errno)); + exit (E_BAD_ARG); +diff -up shadow-4.8.1/libmisc/salt.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/salt.c +--- shadow-4.8.1/libmisc/salt.c.libsubid_not_print_error_messages 2019-12-01 18:02:43.000000000 +0100 ++++ shadow-4.8.1/libmisc/salt.c 2021-05-24 13:04:19.930269118 +0200 +@@ -344,7 +344,7 @@ static /*@observer@*/const char *gensalt + salt_len = (size_t) shadow_random (8, 16); + #endif /* USE_SHA_CRYPT */ + } else if (0 != strcmp (method, "DES")) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("Invalid ENCRYPT_METHOD value: '%s'.\n" + "Defaulting to DES.\n"), + method); +diff -up shadow-4.8.1/libmisc/setupenv.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/setupenv.c +--- shadow-4.8.1/libmisc/setupenv.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/libmisc/setupenv.c 2021-05-24 13:04:19.930269118 +0200 +@@ -219,7 +219,7 @@ void setup_env (struct passwd *info) + static char temp_pw_dir[] = "/"; + + if (!getdef_bool ("DEFAULT_HOME") || chdir ("/") == -1) { +- fprintf (stderr, _("Unable to cd to '%s'\n"), ++ fprintf (shadow_logfd, _("Unable to cd to '%s'\n"), + info->pw_dir); + SYSLOG ((LOG_WARN, + "unable to cd to `%s' for user `%s'\n", +diff -up shadow-4.8.1/libmisc/user_busy.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/user_busy.c +--- shadow-4.8.1/libmisc/user_busy.c.libsubid_not_print_error_messages 2020-01-23 19:04:44.000000000 +0100 ++++ shadow-4.8.1/libmisc/user_busy.c 2021-05-24 13:04:19.931269132 +0200 +@@ -96,7 +96,7 @@ static int user_busy_utmp (const char *n + continue; + } + +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: user %s is currently logged in\n"), + Prog, name); + return 1; +@@ -249,7 +249,7 @@ static int user_busy_processes (const ch + #ifdef ENABLE_SUBIDS + sub_uid_close(); + #endif +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: user %s is currently used by process %d\n"), + Prog, name, pid); + return 1; +@@ -272,7 +272,7 @@ static int user_busy_processes (const ch + #ifdef ENABLE_SUBIDS + sub_uid_close(); + #endif +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: user %s is currently used by process %d\n"), + Prog, name, pid); + return 1; +diff -up shadow-4.8.1/libmisc/xgetXXbyYY.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/xgetXXbyYY.c +--- shadow-4.8.1/libmisc/xgetXXbyYY.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/libmisc/xgetXXbyYY.c 2021-05-24 13:04:19.931269132 +0200 +@@ -74,7 +74,7 @@ + + result = malloc(sizeof(LOOKUP_TYPE)); + if (NULL == result) { +- fprintf (stderr, _("%s: out of memory\n"), ++ fprintf (shadow_logfd, _("%s: out of memory\n"), + "x" STRINGIZE(FUNCTION_NAME)); + exit (13); + } +@@ -84,7 +84,7 @@ + LOOKUP_TYPE *resbuf = NULL; + buffer = (char *)realloc (buffer, length); + if (NULL == buffer) { +- fprintf (stderr, _("%s: out of memory\n"), ++ fprintf (shadow_logfd, _("%s: out of memory\n"), + "x" STRINGIZE(FUNCTION_NAME)); + exit (13); + } +@@ -132,7 +132,7 @@ + if (result) { + result = DUP_FUNCTION(result); + if (NULL == result) { +- fprintf (stderr, _("%s: out of memory\n"), ++ fprintf (shadow_logfd, _("%s: out of memory\n"), + "x" STRINGIZE(FUNCTION_NAME)); + exit (13); + } +diff -up shadow-4.8.1/libmisc/xmalloc.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/xmalloc.c +--- shadow-4.8.1/libmisc/xmalloc.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/libmisc/xmalloc.c 2021-05-24 13:04:19.931269132 +0200 +@@ -54,7 +54,7 @@ + + ptr = (char *) malloc (size); + if (NULL == ptr) { +- (void) fprintf (stderr, ++ (void) fprintf (shadow_logfd, + _("%s: failed to allocate memory: %s\n"), + Prog, strerror (errno)); + exit (13); +diff -up shadow-4.8.1/lib/nscd.c.libsubid_not_print_error_messages shadow-4.8.1/lib/nscd.c +--- shadow-4.8.1/lib/nscd.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/lib/nscd.c 2021-05-24 13:04:19.928269091 +0200 +@@ -25,13 +25,13 @@ int nscd_flush_cache (const char *servic + + if (run_command (cmd, spawnedArgs, spawnedEnv, &status) != 0) { + /* run_command writes its own more detailed message. */ +- (void) fprintf (stderr, _(MSG_NSCD_FLUSH_CACHE_FAILED), Prog); ++ (void) fprintf (shadow_logfd, _(MSG_NSCD_FLUSH_CACHE_FAILED), Prog); + return -1; + } + + code = WEXITSTATUS (status); + if (!WIFEXITED (status)) { +- (void) fprintf (stderr, ++ (void) fprintf (shadow_logfd, + _("%s: nscd did not terminate normally (signal %d)\n"), + Prog, WTERMSIG (status)); + return -1; +@@ -43,9 +43,9 @@ int nscd_flush_cache (const char *servic + /* nscd is installed, but it isn't active. */ + return 0; + } else if (code != 0) { +- (void) fprintf (stderr, _("%s: nscd exited with status %d\n"), ++ (void) fprintf (shadow_logfd, _("%s: nscd exited with status %d\n"), + Prog, code); +- (void) fprintf (stderr, _(MSG_NSCD_FLUSH_CACHE_FAILED), Prog); ++ (void) fprintf (shadow_logfd, _(MSG_NSCD_FLUSH_CACHE_FAILED), Prog); + return -1; + } + +diff -up shadow-4.8.1/lib/nss.c.libsubid_not_print_error_messages shadow-4.8.1/lib/nss.c +--- shadow-4.8.1/lib/nss.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.924269036 +0200 ++++ shadow-4.8.1/lib/nss.c 2021-05-24 13:04:19.928269091 +0200 +@@ -56,7 +56,7 @@ void nss_init(char *nsswitch_path) { + // subid: files + nssfp = fopen(nsswitch_path, "r"); + if (!nssfp) { +- fprintf(stderr, "Failed opening %s: %m", nsswitch_path); ++ fprintf(shadow_logfd, "Failed opening %s: %m", nsswitch_path); + atomic_store(&nss_init_completed, true); + return; + } +@@ -82,16 +82,16 @@ void nss_init(char *nsswitch_path) { + goto done; + } + if (strlen(token) > 50) { +- fprintf(stderr, "Subid NSS module name too long (longer than 50 characters): %s\n", token); +- fprintf(stderr, "Using files\n"); ++ fprintf(shadow_logfd, "Subid NSS module name too long (longer than 50 characters): %s\n", token); ++ fprintf(shadow_logfd, "Using files\n"); + subid_nss = NULL; + goto done; + } + snprintf(libname, 64, "libsubid_%s.so", token); + h = dlopen(libname, RTLD_LAZY); + if (!h) { +- fprintf(stderr, "Error opening %s: %s\n", libname, dlerror()); +- fprintf(stderr, "Using files\n"); ++ fprintf(shadow_logfd, "Error opening %s: %s\n", libname, dlerror()); ++ fprintf(shadow_logfd, "Using files\n"); + subid_nss = NULL; + goto done; + } +@@ -102,7 +102,7 @@ void nss_init(char *nsswitch_path) { + } + subid_nss->has_range = dlsym(h, "shadow_subid_has_range"); + if (!subid_nss->has_range) { +- fprintf(stderr, "%s did not provide @has_range@\n", libname); ++ fprintf(shadow_logfd, "%s did not provide @has_range@\n", libname); + dlclose(h); + free(subid_nss); + subid_nss = NULL; +@@ -110,7 +110,7 @@ void nss_init(char *nsswitch_path) { + } + subid_nss->list_owner_ranges = dlsym(h, "shadow_subid_list_owner_ranges"); + if (!subid_nss->list_owner_ranges) { +- fprintf(stderr, "%s did not provide @list_owner_ranges@\n", libname); ++ fprintf(shadow_logfd, "%s did not provide @list_owner_ranges@\n", libname); + dlclose(h); + free(subid_nss); + subid_nss = NULL; +@@ -118,7 +118,7 @@ void nss_init(char *nsswitch_path) { + } + subid_nss->has_any_range = dlsym(h, "shadow_subid_has_any_range"); + if (!subid_nss->has_any_range) { +- fprintf(stderr, "%s did not provide @has_any_range@\n", libname); ++ fprintf(shadow_logfd, "%s did not provide @has_any_range@\n", libname); + dlclose(h); + free(subid_nss); + subid_nss = NULL; +@@ -126,7 +126,7 @@ void nss_init(char *nsswitch_path) { + } + subid_nss->find_subid_owners = dlsym(h, "shadow_subid_find_subid_owners"); + if (!subid_nss->find_subid_owners) { +- fprintf(stderr, "%s did not provide @find_subid_owners@\n", libname); ++ fprintf(shadow_logfd, "%s did not provide @find_subid_owners@\n", libname); + dlclose(h); + free(subid_nss); + subid_nss = NULL; +@@ -135,7 +135,7 @@ void nss_init(char *nsswitch_path) { + subid_nss->handle = h; + goto done; + } +- fprintf(stderr, "No usable subid NSS module found, using files\n"); ++ fprintf(shadow_logfd, "No usable subid NSS module found, using files\n"); + // subid_nss has to be null here, but to ease reviews: + free(subid_nss); + subid_nss = NULL; +diff -up shadow-4.8.1/lib/prototypes.h.libsubid_not_print_error_messages shadow-4.8.1/lib/prototypes.h +--- shadow-4.8.1/lib/prototypes.h.libsubid_not_print_error_messages 2021-05-24 13:04:19.924269036 +0200 ++++ shadow-4.8.1/lib/prototypes.h 2021-05-24 13:04:19.928269091 +0200 +@@ -59,7 +59,8 @@ + #include "defines.h" + #include "commonio.h" + +-extern /*@observer@*/ const char *Prog; ++extern /*@observer@*/ const char *Prog; /* Program name showed in error messages */ ++extern FILE *shadow_logfd; /* file descripter to which error messages are printed */ + + /* addgrps.c */ + #if defined (HAVE_SETGROUPS) && ! defined (USE_PAM) +diff -up shadow-4.8.1/lib/selinux.c.libsubid_not_print_error_messages shadow-4.8.1/lib/selinux.c +--- shadow-4.8.1/lib/selinux.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.911268857 +0200 ++++ shadow-4.8.1/lib/selinux.c 2021-05-24 13:04:32.746445679 +0200 +@@ -135,7 +135,7 @@ static int selinux_log_cb (int type, con + && (errno != EAFNOSUPPORT)) { + + (void) fputs (_("Cannot open audit interface.\n"), +- stderr); ++ shadow_logfd); + SYSLOG ((LOG_WARN, "Cannot open audit interface.")); + } + } +@@ -188,7 +188,7 @@ int check_selinux_permit (const char *pe + selinux_set_callback (SELINUX_CB_LOG, (union selinux_callback) selinux_log_cb); + + if (getprevcon (&user_context_str) != 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: can not get previous SELinux process context: %s\n"), + Prog, strerror (errno)); + SYSLOG ((LOG_WARN, +diff -up shadow-4.8.1/lib/semanage.c.libsubid_not_print_error_messages shadow-4.8.1/lib/semanage.c +--- shadow-4.8.1/lib/semanage.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.900268705 +0200 ++++ shadow-4.8.1/lib/semanage.c 2021-05-24 13:05:24.747162090 +0200 +@@ -69,7 +69,7 @@ static void semanage_error_callback (unu + switch (semanage_msg_get_level (handle)) { + case SEMANAGE_MSG_ERR: + case SEMANAGE_MSG_WARN: +- fprintf (stderr, _("[libsemanage]: %s\n"), message); ++ fprintf (shadow_logfd, _("[libsemanage]: %s\n"), message); + break; + case SEMANAGE_MSG_INFO: + /* nop */ +@@ -87,7 +87,7 @@ static semanage_handle_t *semanage_init + + handle = semanage_handle_create (); + if (NULL == handle) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("Cannot create SELinux management handle\n")); + return NULL; + } +@@ -96,26 +96,26 @@ static semanage_handle_t *semanage_init + + ret = semanage_is_managed (handle); + if (ret != 1) { +- fprintf (stderr, _("SELinux policy not managed\n")); ++ fprintf (shadow_logfd, _("SELinux policy not managed\n")); + goto fail; + } + + ret = semanage_access_check (handle); + if (ret < SEMANAGE_CAN_READ) { +- fprintf (stderr, _("Cannot read SELinux policy store\n")); ++ fprintf (shadow_logfd, _("Cannot read SELinux policy store\n")); + goto fail; + } + + ret = semanage_connect (handle); + if (ret != 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("Cannot establish SELinux management connection\n")); + goto fail; + } + + ret = semanage_begin_transaction (handle); + if (ret != 0) { +- fprintf (stderr, _("Cannot begin SELinux transaction\n")); ++ fprintf (shadow_logfd, _("Cannot begin SELinux transaction\n")); + goto fail; + } + +@@ -137,7 +137,7 @@ static int semanage_user_mod (semanage_h + + semanage_seuser_query (handle, key, &seuser); + if (NULL == seuser) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("Could not query seuser for %s\n"), login_name); + ret = 1; + goto done; +@@ -146,7 +146,7 @@ static int semanage_user_mod (semanage_h + #if 0 + ret = semanage_seuser_set_mlsrange (handle, seuser, DEFAULT_SERANGE); + if (ret != 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("Could not set serange for %s\n"), login_name); + ret = 1; + goto done; +@@ -155,7 +155,7 @@ static int semanage_user_mod (semanage_h + + ret = semanage_seuser_set_sename (handle, seuser, seuser_name); + if (ret != 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("Could not set sename for %s\n"), + login_name); + ret = 1; +@@ -164,7 +164,7 @@ static int semanage_user_mod (semanage_h + + ret = semanage_seuser_modify_local (handle, key, seuser); + if (ret != 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("Could not modify login mapping for %s\n"), + login_name); + ret = 1; +@@ -188,7 +188,7 @@ static int semanage_user_add (semanage_h + + ret = semanage_seuser_create (handle, &seuser); + if (ret != 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("Cannot create SELinux login mapping for %s\n"), + login_name); + ret = 1; +@@ -197,7 +197,7 @@ static int semanage_user_add (semanage_h + + ret = semanage_seuser_set_name (handle, seuser, login_name); + if (ret != 0) { +- fprintf (stderr, _("Could not set name for %s\n"), login_name); ++ fprintf (shadow_logfd, _("Could not set name for %s\n"), login_name); + ret = 1; + goto done; + } +@@ -205,7 +205,7 @@ static int semanage_user_add (semanage_h + #if 0 + ret = semanage_seuser_set_mlsrange (handle, seuser, DEFAULT_SERANGE); + if (ret != 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("Could not set serange for %s\n"), + login_name); + ret = 1; +@@ -215,7 +215,7 @@ static int semanage_user_add (semanage_h + + ret = semanage_seuser_set_sename (handle, seuser, seuser_name); + if (ret != 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("Could not set SELinux user for %s\n"), + login_name); + ret = 1; +@@ -224,7 +224,7 @@ static int semanage_user_add (semanage_h + + ret = semanage_seuser_modify_local (handle, key, seuser); + if (ret != 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("Could not add login mapping for %s\n"), + login_name); + ret = 1; +@@ -252,21 +252,21 @@ int set_seuser (const char *login_name, + + handle = semanage_init (); + if (NULL == handle) { +- fprintf (stderr, _("Cannot init SELinux management\n")); ++ fprintf (shadow_logfd, _("Cannot init SELinux management\n")); + ret = 1; + goto done; + } + + ret = semanage_seuser_key_create (handle, login_name, &key); + if (ret != 0) { +- fprintf (stderr, _("Cannot create SELinux user key\n")); ++ fprintf (shadow_logfd, _("Cannot create SELinux user key\n")); + ret = 1; + goto done; + } + + ret = semanage_seuser_exists (handle, key, &seuser_exists); + if (ret < 0) { +- fprintf (stderr, _("Cannot verify the SELinux user\n")); ++ fprintf (shadow_logfd, _("Cannot verify the SELinux user\n")); + ret = 1; + goto done; + } +@@ -274,7 +274,7 @@ int set_seuser (const char *login_name, + if (0 != seuser_exists) { + ret = semanage_user_mod (handle, key, login_name, seuser_name); + if (ret != 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("Cannot modify SELinux user mapping\n")); + ret = 1; + goto done; +@@ -282,7 +282,7 @@ int set_seuser (const char *login_name, + } else { + ret = semanage_user_add (handle, key, login_name, seuser_name); + if (ret != 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("Cannot add SELinux user mapping\n")); + ret = 1; + goto done; +@@ -291,7 +291,7 @@ int set_seuser (const char *login_name, + + ret = semanage_commit (handle); + if (ret < 0) { +- fprintf (stderr, _("Cannot commit SELinux transaction\n")); ++ fprintf (shadow_logfd, _("Cannot commit SELinux transaction\n")); + ret = 1; + goto done; + } +@@ -317,27 +317,27 @@ int del_seuser (const char *login_name) + + handle = semanage_init (); + if (NULL == handle) { +- fprintf (stderr, _("Cannot init SELinux management\n")); ++ fprintf (shadow_logfd, _("Cannot init SELinux management\n")); + ret = 1; + goto done; + } + + ret = semanage_seuser_key_create (handle, login_name, &key); + if (ret != 0) { +- fprintf (stderr, _("Cannot create SELinux user key\n")); ++ fprintf (shadow_logfd, _("Cannot create SELinux user key\n")); + ret = 1; + goto done; + } + + ret = semanage_seuser_exists (handle, key, &exists); + if (ret < 0) { +- fprintf (stderr, _("Cannot verify the SELinux user\n")); ++ fprintf (shadow_logfd, _("Cannot verify the SELinux user\n")); + ret = 1; + goto done; + } + + if (0 == exists) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("Login mapping for %s is not defined, OK if default mapping was used\n"), + login_name); + ret = 0; /* probably default mapping */ +@@ -346,13 +346,13 @@ int del_seuser (const char *login_name) + + ret = semanage_seuser_exists_local (handle, key, &exists); + if (ret < 0) { +- fprintf (stderr, _("Cannot verify the SELinux user\n")); ++ fprintf (shadow_logfd, _("Cannot verify the SELinux user\n")); + ret = 1; + goto done; + } + + if (0 == exists) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("Login mapping for %s is defined in policy, cannot be deleted\n"), + login_name); + ret = 0; /* Login mapping defined in policy can't be deleted */ +@@ -361,7 +361,7 @@ int del_seuser (const char *login_name) + + ret = semanage_seuser_del_local (handle, key); + if (ret != 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("Could not delete login mapping for %s"), + login_name); + ret = 1; +@@ -370,7 +370,7 @@ int del_seuser (const char *login_name) + + ret = semanage_commit (handle); + if (ret < 0) { +- fprintf (stderr, _("Cannot commit SELinux transaction\n")); ++ fprintf (shadow_logfd, _("Cannot commit SELinux transaction\n")); + ret = 1; + goto done; + } +diff -up shadow-4.8.1/lib/spawn.c.libsubid_not_print_error_messages shadow-4.8.1/lib/spawn.c +--- shadow-4.8.1/lib/spawn.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/lib/spawn.c 2021-05-24 13:04:19.929269104 +0200 +@@ -48,7 +48,7 @@ int run_command (const char *cmd, const + } + + (void) fflush (stdout); +- (void) fflush (stderr); ++ (void) fflush (shadow_logfd); + + pid = fork (); + if (0 == pid) { +@@ -57,11 +57,11 @@ int run_command (const char *cmd, const + if (ENOENT == errno) { + exit (E_CMD_NOTFOUND); + } +- fprintf (stderr, "%s: cannot execute %s: %s\n", ++ fprintf (shadow_logfd, "%s: cannot execute %s: %s\n", + Prog, cmd, strerror (errno)); + exit (E_CMD_NOEXEC); + } else if ((pid_t)-1 == pid) { +- fprintf (stderr, "%s: cannot execute %s: %s\n", ++ fprintf (shadow_logfd, "%s: cannot execute %s: %s\n", + Prog, cmd, strerror (errno)); + return -1; + } +@@ -74,7 +74,7 @@ int run_command (const char *cmd, const + || ((pid_t)-1 != wpid && wpid != pid)); + + if ((pid_t)-1 == wpid) { +- fprintf (stderr, "%s: waitpid (status: %d): %s\n", ++ fprintf (shadow_logfd, "%s: waitpid (status: %d): %s\n", + Prog, *status, strerror (errno)); + return -1; + } +diff -up shadow-4.8.1/libsubid/api.c.libsubid_not_print_error_messages shadow-4.8.1/libsubid/api.c +--- shadow-4.8.1/libsubid/api.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.926269063 +0200 ++++ shadow-4.8.1/libsubid/api.c 2021-05-24 13:04:19.931269132 +0200 +@@ -32,12 +32,39 @@ + #include + #include + #include ++#include + #include + #include + #include "subordinateio.h" + #include "idmapping.h" + #include "subid.h" + ++const char *Prog = "(libsubid)"; ++extern FILE * shadow_logfd; ++ ++bool libsubid_init(const char *progname, FILE * logfd) ++{ ++ if (progname) { ++ progname = strdup(progname); ++ if (progname) ++ Prog = progname; ++ else ++ fprintf(stderr, "Out of memory"); ++ } ++ ++ if (logfd) { ++ shadow_logfd = logfd; ++ return true; ++ } ++ shadow_logfd = fopen("/dev/null", "w"); ++ if (!shadow_logfd) { ++ fprintf(stderr, "ERROR opening /dev/null for error messages. Using stderr."); ++ shadow_logfd = stderr; ++ return false; ++ } ++ return true; ++} ++ + static + int get_subid_ranges(const char *owner, enum subid_type id_type, struct subordinate_range ***ranges) + { +diff -up shadow-4.8.1/libsubid/subid.h.libsubid_not_print_error_messages shadow-4.8.1/libsubid/subid.h +--- shadow-4.8.1/libsubid/subid.h.libsubid_not_print_error_messages 2021-05-24 13:04:19.926269063 +0200 ++++ shadow-4.8.1/libsubid/subid.h 2021-05-24 13:04:19.931269132 +0200 +@@ -22,6 +22,22 @@ enum subid_status { + }; + + /* ++ * libsubid_init: initialize libsubid ++ * ++ * @progname: Name to display as program. If NULL, then "(libsubid)" will be ++ * shown in error messages. ++ * @logfd: Open file pointer to pass error messages to. If NULL, then ++ * /dev/null will be opened and messages will be sent there. The ++ * default if libsubid_init() is not called is stderr (2). ++ * ++ * This function does not need to be called. If not called, then the defaults ++ * will be used. ++ * ++ * Returns false if an error occurred. ++ */ ++bool libsubid_init(const char *progname, FILE *logfd); ++ ++/* + * get_subuid_ranges: return a list of UID ranges for a user + * + * @owner: username being queried +diff -up shadow-4.8.1/lib/tcbfuncs.c.libsubid_not_print_error_messages shadow-4.8.1/lib/tcbfuncs.c +--- shadow-4.8.1/lib/tcbfuncs.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/lib/tcbfuncs.c 2021-05-24 13:04:19.929269104 +0200 +@@ -72,8 +72,8 @@ shadowtcb_status shadowtcb_gain_priv (vo + * to exit soon. + */ + #define OUT_OF_MEMORY do { \ +- fprintf (stderr, _("%s: out of memory\n"), Prog); \ +- (void) fflush (stderr); \ ++ fprintf (shadow_logfd, _("%s: out of memory\n"), Prog); \ ++ (void) fflush (shadow_logfd); \ + } while (false) + + /* Returns user's tcb directory path relative to TCB_DIR. */ +@@ -116,7 +116,7 @@ static /*@null@*/ char *shadowtcb_path_r + return NULL; + } + if (lstat (path, &st) != 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Cannot stat %s: %s\n"), + Prog, path, strerror (errno)); + free (path); +@@ -132,7 +132,7 @@ static /*@null@*/ char *shadowtcb_path_r + return rval; + } + if (!S_ISLNK (st.st_mode)) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: %s is neither a directory, nor a symlink.\n"), + Prog, path); + free (path); +@@ -140,7 +140,7 @@ static /*@null@*/ char *shadowtcb_path_r + } + ret = readlink (path, link, sizeof (link) - 1); + if (-1 == ret) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Cannot read symbolic link %s: %s\n"), + Prog, path, strerror (errno)); + free (path); +@@ -149,7 +149,7 @@ static /*@null@*/ char *shadowtcb_path_r + free (path); + if ((size_t)ret >= sizeof(link) - 1) { + link[sizeof(link) - 1] = '\0'; +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Suspiciously long symlink: %s\n"), + Prog, link); + return NULL; +@@ -207,7 +207,7 @@ static shadowtcb_status mkdir_leading (c + } + ptr = path; + if (stat (TCB_DIR, &st) != 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Cannot stat %s: %s\n"), + Prog, TCB_DIR, strerror (errno)); + goto out_free_path; +@@ -219,19 +219,19 @@ static shadowtcb_status mkdir_leading (c + return SHADOWTCB_FAILURE; + } + if ((mkdir (dir, 0700) != 0) && (errno != EEXIST)) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Cannot create directory %s: %s\n"), + Prog, dir, strerror (errno)); + goto out_free_dir; + } + if (chown (dir, 0, st.st_gid) != 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Cannot change owner of %s: %s\n"), + Prog, dir, strerror (errno)); + goto out_free_dir; + } + if (chmod (dir, 0711) != 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Cannot change mode of %s: %s\n"), + Prog, dir, strerror (errno)); + goto out_free_dir; +@@ -261,7 +261,7 @@ static shadowtcb_status unlink_suffs (co + return SHADOWTCB_FAILURE; + } + if ((unlink (tmp) != 0) && (errno != ENOENT)) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: unlink: %s: %s\n"), + Prog, tmp, strerror (errno)); + free (tmp); +@@ -286,7 +286,7 @@ static shadowtcb_status rmdir_leading (c + } + if (rmdir (dir) != 0) { + if (errno != ENOTEMPTY) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Cannot remove directory %s: %s\n"), + Prog, dir, strerror (errno)); + ret = SHADOWTCB_FAILURE; +@@ -315,7 +315,7 @@ static shadowtcb_status move_dir (const + goto out_free_nomem; + } + if (stat (olddir, &oldmode) != 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Cannot stat %s: %s\n"), + Prog, olddir, strerror (errno)); + goto out_free; +@@ -342,7 +342,7 @@ static shadowtcb_status move_dir (const + goto out_free; + } + if (rename (real_old_dir, real_new_dir) != 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Cannot rename %s to %s: %s\n"), + Prog, real_old_dir, real_new_dir, strerror (errno)); + goto out_free; +@@ -351,7 +351,7 @@ static shadowtcb_status move_dir (const + goto out_free; + } + if ((unlink (olddir) != 0) && (errno != ENOENT)) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Cannot remove %s: %s\n"), + Prog, olddir, strerror (errno)); + goto out_free; +@@ -365,7 +365,7 @@ static shadowtcb_status move_dir (const + } + if ( (strcmp (real_new_dir, newdir) != 0) + && (symlink (real_new_dir_rel, newdir) != 0)) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Cannot create symbolic link %s: %s\n"), + Prog, real_new_dir_rel, strerror (errno)); + goto out_free; +@@ -464,37 +464,37 @@ shadowtcb_status shadowtcb_move (/*@NULL + return SHADOWTCB_FAILURE; + } + if (stat (tcbdir, &dirmode) != 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Cannot stat %s: %s\n"), + Prog, tcbdir, strerror (errno)); + goto out_free; + } + if (chown (tcbdir, 0, 0) != 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Cannot change owners of %s: %s\n"), + Prog, tcbdir, strerror (errno)); + goto out_free; + } + if (chmod (tcbdir, 0700) != 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Cannot change mode of %s: %s\n"), + Prog, tcbdir, strerror (errno)); + goto out_free; + } + if (lstat (shadow, &filemode) != 0) { + if (errno != ENOENT) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Cannot lstat %s: %s\n"), + Prog, shadow, strerror (errno)); + goto out_free; + } +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Warning, user %s has no tcb shadow file.\n"), + Prog, user_newname); + } else { + if (!S_ISREG (filemode.st_mode) || + filemode.st_nlink != 1) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Emergency: %s's tcb shadow is not a " + "regular file with st_nlink=1.\n" + "The account is left locked.\n"), +@@ -502,13 +502,13 @@ shadowtcb_status shadowtcb_move (/*@NULL + goto out_free; + } + if (chown (shadow, user_newid, filemode.st_gid) != 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Cannot change owner of %s: %s\n"), + Prog, shadow, strerror (errno)); + goto out_free; + } + if (chmod (shadow, filemode.st_mode & 07777) != 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Cannot change mode of %s: %s\n"), + Prog, shadow, strerror (errno)); + goto out_free; +@@ -518,7 +518,7 @@ shadowtcb_status shadowtcb_move (/*@NULL + goto out_free; + } + if (chown (tcbdir, user_newid, dirmode.st_gid) != 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Cannot change owner of %s: %s\n"), + Prog, tcbdir, strerror (errno)); + goto out_free; +@@ -543,7 +543,7 @@ shadowtcb_status shadowtcb_create (const + return SHADOWTCB_SUCCESS; + } + if (stat (TCB_DIR, &tcbdir_stat) != 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Cannot stat %s: %s\n"), + Prog, TCB_DIR, strerror (errno)); + return SHADOWTCB_FAILURE; +@@ -563,39 +563,39 @@ shadowtcb_status shadowtcb_create (const + return SHADOWTCB_FAILURE; + } + if (mkdir (dir, 0700) != 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: mkdir: %s: %s\n"), + Prog, dir, strerror (errno)); + goto out_free; + } + fd = open (shadow, O_RDWR | O_CREAT | O_TRUNC, 0600); + if (fd < 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Cannot open %s: %s\n"), + Prog, shadow, strerror (errno)); + goto out_free; + } + close (fd); + if (chown (shadow, 0, authgid) != 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Cannot change owner of %s: %s\n"), + Prog, shadow, strerror (errno)); + goto out_free; + } + if (chmod (shadow, (mode_t) ((authgid == shadowgid) ? 0600 : 0640)) != 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Cannot change mode of %s: %s\n"), + Prog, shadow, strerror (errno)); + goto out_free; + } + if (chown (dir, 0, authgid) != 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Cannot change owner of %s: %s\n"), + Prog, dir, strerror (errno)); + goto out_free; + } + if (chmod (dir, (mode_t) ((authgid == shadowgid) ? 02700 : 02710)) != 0) { +- fprintf (stderr, ++ fprintf (shadow_logfd, + _("%s: Cannot change mode of %s: %s\n"), + Prog, dir, strerror (errno)); + goto out_free; +diff -up shadow-4.8.1/src/chage.c.libsubid_not_print_error_messages shadow-4.8.1/src/chage.c +--- shadow-4.8.1/src/chage.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.910268843 +0200 ++++ shadow-4.8.1/src/chage.c 2021-05-24 13:04:19.931269132 +0200 +@@ -62,6 +62,7 @@ + * Global variables + */ + const char *Prog; ++FILE *shadow_logfd = NULL; + + static bool + dflg = false, /* set last password change date */ +@@ -816,6 +817,7 @@ int main (int argc, char **argv) + * Get the program name so that error messages can use it. + */ + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + + sanitize_env (); + (void) setlocale (LC_ALL, ""); +diff -up shadow-4.8.1/src/check_subid_range.c.libsubid_not_print_error_messages shadow-4.8.1/src/check_subid_range.c +--- shadow-4.8.1/src/check_subid_range.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.925269050 +0200 ++++ shadow-4.8.1/src/check_subid_range.c 2021-05-24 13:04:19.931269132 +0200 +@@ -18,6 +18,7 @@ + #include "idmapping.h" + + const char *Prog; ++FILE *shadow_logfd = NULL; + + int main(int argc, char **argv) + { +@@ -25,6 +26,7 @@ int main(int argc, char **argv) + unsigned long start, count; + bool check_uids; + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + + if (argc != 5) + exit(1); +diff -up shadow-4.8.1/src/chfn.c.libsubid_not_print_error_messages shadow-4.8.1/src/chfn.c +--- shadow-4.8.1/src/chfn.c.libsubid_not_print_error_messages 2019-11-12 01:18:25.000000000 +0100 ++++ shadow-4.8.1/src/chfn.c 2021-05-24 13:04:19.931269132 +0200 +@@ -57,6 +57,7 @@ + * Global variables. + */ + const char *Prog; ++FILE *shadow_logfd = NULL; + static char fullnm[BUFSIZ]; + static char roomno[BUFSIZ]; + static char workph[BUFSIZ]; +@@ -634,6 +635,7 @@ int main (int argc, char **argv) + * prefix to most error messages. + */ + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + + sanitize_env (); + (void) setlocale (LC_ALL, ""); +diff -up shadow-4.8.1/src/chgpasswd.c.libsubid_not_print_error_messages shadow-4.8.1/src/chgpasswd.c +--- shadow-4.8.1/src/chgpasswd.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.909268829 +0200 ++++ shadow-4.8.1/src/chgpasswd.c 2021-05-24 14:40:13.975427046 +0200 +@@ -66,6 +66,7 @@ + * Global variables + */ + const char *Prog; ++FILE *shadow_logfd = NULL; + static bool eflg = false; + static bool md5flg = false; + #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) +@@ -499,6 +500,7 @@ int main (int argc, char **argv) + int line = 0; + + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.8.1/src/chpasswd.c.libsubid_not_print_error_messages shadow-4.8.1/src/chpasswd.c +--- shadow-4.8.1/src/chpasswd.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.909268829 +0200 ++++ shadow-4.8.1/src/chpasswd.c 2021-05-24 14:43:57.102454551 +0200 +@@ -63,6 +63,7 @@ + * Global variables + */ + const char *Prog; ++FILE *shadow_logfd = NULL; + static bool eflg = false; + static bool md5flg = false; + #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) +@@ -487,6 +488,7 @@ int main (int argc, char **argv) + int line = 0; + + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.8.1/src/chsh.c.libsubid_not_print_error_messages shadow-4.8.1/src/chsh.c +--- shadow-4.8.1/src/chsh.c.libsubid_not_print_error_messages 2019-11-12 01:18:25.000000000 +0100 ++++ shadow-4.8.1/src/chsh.c 2021-05-24 13:04:19.931269132 +0200 +@@ -59,6 +59,7 @@ + * Global variables + */ + const char *Prog; /* Program name */ ++FILE *shadow_logfd = NULL; + static bool amroot; /* Real UID is root */ + static char loginsh[BUFSIZ]; /* Name of new login shell */ + /* command line options */ +@@ -441,6 +442,7 @@ int main (int argc, char **argv) + * most error messages. + */ + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.8.1/src/expiry.c.libsubid_not_print_error_messages shadow-4.8.1/src/expiry.c +--- shadow-4.8.1/src/expiry.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/src/expiry.c 2021-05-24 13:04:19.931269132 +0200 +@@ -46,6 +46,7 @@ + + /* Global variables */ + const char *Prog; ++FILE *shadow_logfd = NULL; + static bool cflg = false; + + /* local function prototypes */ +@@ -144,6 +145,7 @@ int main (int argc, char **argv) + struct spwd *spwd; + + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + + sanitize_env (); + +diff -up shadow-4.8.1/src/faillog.c.libsubid_not_print_error_messages shadow-4.8.1/src/faillog.c +--- shadow-4.8.1/src/faillog.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.910268843 +0200 ++++ shadow-4.8.1/src/faillog.c 2021-05-24 13:04:19.932269146 +0200 +@@ -62,6 +62,7 @@ static void reset (void); + * Global variables + */ + const char *Prog; /* Program name */ ++FILE *shadow_logfd = NULL; + static FILE *fail; /* failure file stream */ + static time_t seconds; /* that number of days in seconds */ + static unsigned long umin; /* if uflg and has_umin, only display users with uid >= umin */ +@@ -573,6 +574,7 @@ int main (int argc, char **argv) + * most error messages. + */ + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.8.1/src/free_subid_range.c.libsubid_not_print_error_messages shadow-4.8.1/src/free_subid_range.c +--- shadow-4.8.1/src/free_subid_range.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.926269063 +0200 ++++ shadow-4.8.1/src/free_subid_range.c 2021-05-24 13:04:19.932269146 +0200 +@@ -7,6 +7,7 @@ + /* Test program for the subid freeing routine */ + + const char *Prog; ++FILE *shadow_logfd = NULL; + + void usage(void) + { +@@ -23,6 +24,7 @@ int main(int argc, char *argv[]) + bool group = false; // get subuids by default + + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + while ((c = getopt(argc, argv, "g")) != EOF) { + switch(c) { + case 'g': group = true; break; +diff -up shadow-4.8.1/src/get_subid_owners.c.libsubid_not_print_error_messages shadow-4.8.1/src/get_subid_owners.c +--- shadow-4.8.1/src/get_subid_owners.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.926269063 +0200 ++++ shadow-4.8.1/src/get_subid_owners.c 2021-05-24 13:04:19.932269146 +0200 +@@ -4,6 +4,7 @@ + #include "prototypes.h" + + const char *Prog; ++FILE *shadow_logfd = NULL; + + void usage(void) + { +@@ -19,6 +20,7 @@ int main(int argc, char *argv[]) + uid_t *uids; + + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + if (argc < 2) { + usage(); + } +diff -up shadow-4.8.1/src/gpasswd.c.libsubid_not_print_error_messages shadow-4.8.1/src/gpasswd.c +--- shadow-4.8.1/src/gpasswd.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.906268788 +0200 ++++ shadow-4.8.1/src/gpasswd.c 2021-05-24 13:04:19.932269146 +0200 +@@ -58,6 +58,7 @@ + */ + /* The name of this command, as it is invoked */ + const char *Prog; ++FILE *shadow_logfd = NULL; + + #ifdef SHADOWGRP + /* Indicate if shadow groups are enabled on the system +@@ -926,6 +927,7 @@ int main (int argc, char **argv) + */ + bywho = getuid (); + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + + OPENLOG ("gpasswd"); + setbuf (stdout, NULL); +diff -up shadow-4.8.1/src/groupadd.c.libsubid_not_print_error_messages shadow-4.8.1/src/groupadd.c +--- shadow-4.8.1/src/groupadd.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.906268788 +0200 ++++ shadow-4.8.1/src/groupadd.c 2021-05-24 13:04:19.932269146 +0200 +@@ -72,6 +72,7 @@ + * Global variables + */ + const char *Prog; ++FILE *shadow_logfd = NULL; + + static /*@null@*/char *group_name; + static gid_t group_id; +@@ -582,6 +583,7 @@ int main (int argc, char **argv) + * Get my name so that I can use it to report errors. + */ + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.8.1/src/groupdel.c.libsubid_not_print_error_messages shadow-4.8.1/src/groupdel.c +--- shadow-4.8.1/src/groupdel.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.906268788 +0200 ++++ shadow-4.8.1/src/groupdel.c 2021-05-24 13:04:19.932269146 +0200 +@@ -58,6 +58,7 @@ + * Global variables + */ + const char *Prog; ++FILE *shadow_logfd = NULL; + + static char *group_name; + static gid_t group_id = -1; +@@ -377,6 +378,7 @@ int main (int argc, char **argv) + * Get my name so that I can use it to report errors. + */ + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.8.1/src/groupmems.c.libsubid_not_print_error_messages shadow-4.8.1/src/groupmems.c +--- shadow-4.8.1/src/groupmems.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/src/groupmems.c 2021-05-24 13:04:19.932269146 +0200 +@@ -65,6 +65,7 @@ + * Global variables + */ + const char *Prog; ++FILE *shadow_logfd = NULL; + + static char *adduser = NULL; + static char *deluser = NULL; +@@ -595,6 +596,7 @@ int main (int argc, char **argv) + * Get my name so that I can use it to report errors. + */ + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.8.1/src/groupmod.c.libsubid_not_print_error_messages shadow-4.8.1/src/groupmod.c +--- shadow-4.8.1/src/groupmod.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.906268788 +0200 ++++ shadow-4.8.1/src/groupmod.c 2021-05-24 13:04:19.932269146 +0200 +@@ -76,6 +76,7 @@ + * Global variables + */ + const char *Prog; ++FILE *shadow_logfd = NULL; + + #ifdef SHADOWGRP + static bool is_shadow_grp; +@@ -799,6 +800,7 @@ int main (int argc, char **argv) + * Get my name so that I can use it to report errors. + */ + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.8.1/src/groups.c.libsubid_not_print_error_messages shadow-4.8.1/src/groups.c +--- shadow-4.8.1/src/groups.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/src/groups.c 2021-05-24 13:04:19.932269146 +0200 +@@ -43,6 +43,7 @@ + * Global variables + */ + const char *Prog; ++FILE *shadow_logfd = NULL; + + /* local function prototypes */ + static void print_groups (const char *member); +@@ -126,6 +127,7 @@ int main (int argc, char **argv) + * Get the program name so that error messages can use it. + */ + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + + if (argc == 1) { + +diff -up shadow-4.8.1/src/grpck.c.libsubid_not_print_error_messages shadow-4.8.1/src/grpck.c +--- shadow-4.8.1/src/grpck.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/src/grpck.c 2021-05-24 13:04:19.932269146 +0200 +@@ -68,6 +68,7 @@ + * Global variables + */ + const char *Prog; ++FILE *shadow_logfd = NULL; + + static const char *grp_file = GROUP_FILE; + static bool use_system_grp_file = true; +@@ -836,6 +837,7 @@ int main (int argc, char **argv) + * Get my name so that I can use it to report errors. + */ + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.8.1/src/grpconv.c.libsubid_not_print_error_messages shadow-4.8.1/src/grpconv.c +--- shadow-4.8.1/src/grpconv.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/src/grpconv.c 2021-05-24 13:04:19.932269146 +0200 +@@ -59,6 +59,7 @@ + * Global variables + */ + const char *Prog; ++FILE *shadow_logfd = NULL; + + static bool gr_locked = false; + static bool sgr_locked = false; +@@ -146,6 +147,7 @@ int main (int argc, char **argv) + struct sgrp sgent; + + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.8.1/src/grpunconv.c.libsubid_not_print_error_messages shadow-4.8.1/src/grpunconv.c +--- shadow-4.8.1/src/grpunconv.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/src/grpunconv.c 2021-05-24 13:04:19.932269146 +0200 +@@ -59,6 +59,7 @@ + * Global variables + */ + const char *Prog; ++FILE *shadow_logfd = NULL; + + static bool gr_locked = false; + static bool sgr_locked = false; +@@ -145,6 +146,7 @@ int main (int argc, char **argv) + const struct sgrp *sg; + + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.8.1/src/lastlog.c.libsubid_not_print_error_messages shadow-4.8.1/src/lastlog.c +--- shadow-4.8.1/src/lastlog.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.910268843 +0200 ++++ shadow-4.8.1/src/lastlog.c 2021-05-24 13:04:19.932269146 +0200 +@@ -59,6 +59,7 @@ + * Global variables + */ + const char *Prog; /* Program name */ ++FILE *shadow_logfd = NULL; + static FILE *lastlogfile; /* lastlog file stream */ + static unsigned long umin; /* if uflg and has_umin, only display users with uid >= umin */ + static bool has_umin = false; +@@ -304,6 +305,7 @@ int main (int argc, char **argv) + * most error messages. + */ + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.8.1/src/list_subid_ranges.c.libsubid_not_print_error_messages shadow-4.8.1/src/list_subid_ranges.c +--- shadow-4.8.1/src/list_subid_ranges.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.926269063 +0200 ++++ shadow-4.8.1/src/list_subid_ranges.c 2021-05-24 13:04:19.932269146 +0200 +@@ -4,6 +4,7 @@ + #include "prototypes.h" + + const char *Prog; ++FILE *shadow_logfd = NULL; + + void usage(void) + { +@@ -19,6 +20,7 @@ int main(int argc, char *argv[]) + struct subordinate_range **ranges; + + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + if (argc < 2) { + usage(); + } +diff -up shadow-4.8.1/src/login.c.libsubid_not_print_error_messages shadow-4.8.1/src/login.c +--- shadow-4.8.1/src/login.c.libsubid_not_print_error_messages 2020-01-12 14:58:49.000000000 +0100 ++++ shadow-4.8.1/src/login.c 2021-05-24 13:04:19.933269160 +0200 +@@ -83,6 +83,7 @@ static pam_handle_t *pamh = NULL; + * Global variables + */ + const char *Prog; ++FILE *shadow_logfd = NULL; + + static const char *hostname = ""; + static /*@null@*/ /*@only@*/char *username = NULL; +@@ -577,6 +578,7 @@ int main (int argc, char **argv) + + amroot = (getuid () == 0); + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + + if (geteuid() != 0) { + fprintf (stderr, _("%s: Cannot possibly work without effective root\n"), Prog); +diff -up shadow-4.8.1/src/logoutd.c.libsubid_not_print_error_messages shadow-4.8.1/src/logoutd.c +--- shadow-4.8.1/src/logoutd.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/src/logoutd.c 2021-05-24 13:04:19.933269160 +0200 +@@ -44,6 +44,7 @@ + * Global variables + */ + const char *Prog; ++FILE *shadow_logfd = NULL; + + #ifndef DEFAULT_HUP_MESG + #define DEFAULT_HUP_MESG _("login time exceeded\n\n") +@@ -187,6 +188,7 @@ int main (int argc, char **argv) + * Start syslogging everything + */ + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + + OPENLOG ("logoutd"); + +diff -up shadow-4.8.1/src/newgidmap.c.libsubid_not_print_error_messages shadow-4.8.1/src/newgidmap.c +--- shadow-4.8.1/src/newgidmap.c.libsubid_not_print_error_messages 2019-10-13 04:52:08.000000000 +0200 ++++ shadow-4.8.1/src/newgidmap.c 2021-05-24 13:04:19.933269160 +0200 +@@ -45,6 +45,7 @@ + * Global variables + */ + const char *Prog; ++FILE *shadow_logfd = NULL; + + + static bool verify_range(struct passwd *pw, struct map_range *range, bool *allow_setgroups) +@@ -175,6 +176,7 @@ int main(int argc, char **argv) + bool allow_setgroups = false; + + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + + /* + * The valid syntax are +diff -up shadow-4.8.1/src/newgrp.c.libsubid_not_print_error_messages shadow-4.8.1/src/newgrp.c +--- shadow-4.8.1/src/newgrp.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.906268788 +0200 ++++ shadow-4.8.1/src/newgrp.c 2021-05-24 14:45:30.372720097 +0200 +@@ -49,6 +49,7 @@ + * Global variables + */ + const char *Prog; ++FILE *shadow_logfd = NULL; + + extern char **newenvp; + extern char **environ; +@@ -444,6 +445,7 @@ int main (int argc, char **argv) + * don't need to re-exec anything. -- JWP + */ + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + is_newgrp = (strcmp (Prog, "newgrp") == 0); + OPENLOG (is_newgrp ? "newgrp" : "sg"); + gid = getgid (); +diff -up shadow-4.8.1/src/new_subid_range.c.libsubid_not_print_error_messages shadow-4.8.1/src/new_subid_range.c +--- shadow-4.8.1/src/new_subid_range.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.926269063 +0200 ++++ shadow-4.8.1/src/new_subid_range.c 2021-05-24 13:04:19.933269160 +0200 +@@ -7,6 +7,7 @@ + /* Test program for the subid creation routine */ + + const char *Prog; ++FILE *shadow_logfd = NULL; + + void usage(void) + { +@@ -26,6 +27,7 @@ int main(int argc, char *argv[]) + bool ok; + + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + while ((c = getopt(argc, argv, "gn")) != EOF) { + switch(c) { + case 'n': makenew = true; break; +diff -up shadow-4.8.1/src/newuidmap.c.libsubid_not_print_error_messages shadow-4.8.1/src/newuidmap.c +--- shadow-4.8.1/src/newuidmap.c.libsubid_not_print_error_messages 2019-10-13 04:52:08.000000000 +0200 ++++ shadow-4.8.1/src/newuidmap.c 2021-05-24 13:04:19.933269160 +0200 +@@ -45,6 +45,7 @@ + * Global variables + */ + const char *Prog; ++FILE *shadow_logfd = NULL; + + static bool verify_range(struct passwd *pw, struct map_range *range) + { +@@ -105,6 +106,7 @@ int main(int argc, char **argv) + int written; + + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + + /* + * The valid syntax are +diff -up shadow-4.8.1/src/newusers.c.libsubid_not_print_error_messages shadow-4.8.1/src/newusers.c +--- shadow-4.8.1/src/newusers.c.libsubid_not_print_error_messages 2020-01-17 16:47:56.000000000 +0100 ++++ shadow-4.8.1/src/newusers.c 2021-05-24 13:04:19.933269160 +0200 +@@ -75,6 +75,7 @@ + * Global variables + */ + const char *Prog; ++FILE *shadow_logfd = NULL; + + static bool rflg = false; /* create a system account */ + #ifndef USE_PAM +@@ -1040,6 +1041,7 @@ int main (int argc, char **argv) + #endif /* USE_PAM */ + + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.8.1/src/passwd.c.libsubid_not_print_error_messages shadow-4.8.1/src/passwd.c +--- shadow-4.8.1/src/passwd.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.910268843 +0200 ++++ shadow-4.8.1/src/passwd.c 2021-05-24 13:04:19.933269160 +0200 +@@ -66,6 +66,7 @@ + * Global variables + */ + const char *Prog; /* Program name */ ++FILE *shadow_logfd = NULL; + + static char *name; /* The name of user whose password is being changed */ + static char *myname; /* The current user's name */ +@@ -752,6 +753,7 @@ int main (int argc, char **argv) + * most error messages. + */ + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.8.1/src/pwck.c.libsubid_not_print_error_messages shadow-4.8.1/src/pwck.c +--- shadow-4.8.1/src/pwck.c.libsubid_not_print_error_messages 2019-10-13 02:56:08.000000000 +0200 ++++ shadow-4.8.1/src/pwck.c 2021-05-24 13:04:19.933269160 +0200 +@@ -70,6 +70,7 @@ + * Global variables + */ + const char *Prog; ++FILE *shadow_logfd = NULL; + + static bool use_system_pw_file = true; + static bool use_system_spw_file = true; +diff -up shadow-4.8.1/src/pwconv.c.libsubid_not_print_error_messages shadow-4.8.1/src/pwconv.c +--- shadow-4.8.1/src/pwconv.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/src/pwconv.c 2021-05-24 13:04:19.933269160 +0200 +@@ -89,6 +89,7 @@ + * Global variables + */ + const char *Prog; ++FILE *shadow_logfd = NULL; + + static bool spw_locked = false; + static bool pw_locked = false; +@@ -176,6 +177,7 @@ int main (int argc, char **argv) + struct spwd spent; + + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.8.1/src/pwunconv.c.libsubid_not_print_error_messages shadow-4.8.1/src/pwunconv.c +--- shadow-4.8.1/src/pwunconv.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/src/pwunconv.c 2021-05-24 13:04:19.933269160 +0200 +@@ -53,6 +53,7 @@ + * Global variables + */ + const char *Prog; ++FILE *shadow_logfd = NULL; + + static bool spw_locked = false; + static bool pw_locked = false; +@@ -137,6 +138,7 @@ int main (int argc, char **argv) + const struct spwd *spwd; + + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.8.1/src/su.c.libsubid_not_print_error_messages shadow-4.8.1/src/su.c +--- shadow-4.8.1/src/su.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/src/su.c 2021-05-24 13:04:19.934269173 +0200 +@@ -82,6 +82,7 @@ + * Global variables + */ + const char *Prog; ++FILE *shadow_logfd = NULL; + static /*@observer@*/const char *caller_tty = NULL; /* Name of tty SU is run from */ + static bool caller_is_root = false; + static uid_t caller_uid; +@@ -699,6 +700,7 @@ static void save_caller_context (char ** + * most error messages. + */ + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + + caller_uid = getuid (); + caller_is_root = (caller_uid == 0); +diff -up shadow-4.8.1/src/sulogin.c.libsubid_not_print_error_messages shadow-4.8.1/src/sulogin.c +--- shadow-4.8.1/src/sulogin.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/src/sulogin.c 2021-05-24 13:04:19.934269173 +0200 +@@ -50,6 +50,7 @@ + * Global variables + */ + const char *Prog; ++FILE *shadow_logfd = NULL; + + static char name[BUFSIZ]; + static char pass[BUFSIZ]; +@@ -106,6 +107,7 @@ static RETSIGTYPE catch_signals (unused + #endif + + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); + (void) textdomain (PACKAGE); +diff -up shadow-4.8.1/src/useradd.c.libsubid_not_print_error_messages shadow-4.8.1/src/useradd.c +--- shadow-4.8.1/src/useradd.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.918268953 +0200 ++++ shadow-4.8.1/src/useradd.c 2021-05-24 13:04:19.934269173 +0200 +@@ -92,6 +92,7 @@ + * Global variables + */ + const char *Prog; ++FILE *shadow_logfd = NULL; + + /* + * These defaults are used if there is no defaults file. +@@ -2301,6 +2302,7 @@ int main (int argc, char **argv) + * Get my name so that I can use it to report errors. + */ + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.8.1/src/userdel.c.libsubid_not_print_error_messages shadow-4.8.1/src/userdel.c +--- shadow-4.8.1/src/userdel.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.907268801 +0200 ++++ shadow-4.8.1/src/userdel.c 2021-05-24 13:04:19.934269173 +0200 +@@ -89,6 +89,7 @@ + * Global variables + */ + const char *Prog; ++FILE *shadow_logfd = NULL; + + static char *user_name; + static uid_t user_id; +@@ -941,6 +942,7 @@ int main (int argc, char **argv) + * Get my name so that I can use it to report errors. + */ + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); + (void) textdomain (PACKAGE); +diff -up shadow-4.8.1/src/usermod.c.libsubid_not_print_error_messages shadow-4.8.1/src/usermod.c +--- shadow-4.8.1/src/usermod.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.917268939 +0200 ++++ shadow-4.8.1/src/usermod.c 2021-05-24 13:04:19.934269173 +0200 +@@ -102,6 +102,7 @@ + * Global variables + */ + const char *Prog; ++FILE *shadow_logfd = NULL; + + static char *user_name; + static char *user_newname; +@@ -2214,6 +2215,7 @@ int main (int argc, char **argv) + * Get my name so that I can use it to report errors. + */ + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.8.1/src/vipw.c.libsubid_not_print_error_messages shadow-4.8.1/src/vipw.c +--- shadow-4.8.1/src/vipw.c.libsubid_not_print_error_messages 2019-12-01 17:52:32.000000000 +0100 ++++ shadow-4.8.1/src/vipw.c 2021-05-24 13:04:19.934269173 +0200 +@@ -63,6 +63,7 @@ + * Global variables + */ + const char *Prog; ++FILE *shadow_logfd = NULL; + + static const char *filename, *fileeditname; + static bool filelocked = false; +@@ -481,6 +482,7 @@ int main (int argc, char **argv) + bool do_vipw; + + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); diff --git a/shadow-4.8.1-libsubid_simplify_ranges_variable.patch b/shadow-4.8.1-libsubid_simplify_ranges_variable.patch new file mode 100644 index 0000000..4cd848b --- /dev/null +++ b/shadow-4.8.1-libsubid_simplify_ranges_variable.patch @@ -0,0 +1,264 @@ +diff -up shadow-4.8.1/configure.ac.libsubid_simplify_ranges_variable shadow-4.8.1/configure.ac +--- shadow-4.8.1/configure.ac.libsubid_simplify_ranges_variable 2021-05-24 15:02:56.165917066 +0200 ++++ shadow-4.8.1/configure.ac 2021-05-24 15:02:56.184917324 +0200 +@@ -1,6 +1,6 @@ + dnl Process this file with autoconf to produce a configure script. + AC_PREREQ([2.69]) +-m4_define([libsubid_abi_major], 2) ++m4_define([libsubid_abi_major], 3) + m4_define([libsubid_abi_minor], 0) + m4_define([libsubid_abi_micro], 0) + m4_define([libsubid_abi], [libsubid_abi_major.libsubid_abi_minor.libsubid_abi_micro]) +diff -up shadow-4.8.1/lib/prototypes.h.libsubid_simplify_ranges_variable shadow-4.8.1/lib/prototypes.h +--- shadow-4.8.1/lib/prototypes.h.libsubid_simplify_ranges_variable 2021-05-24 15:02:56.184917324 +0200 ++++ shadow-4.8.1/lib/prototypes.h 2021-05-24 16:38:57.610619467 +0200 +@@ -309,16 +309,15 @@ struct subid_nss_ops { + * + * @owner - string representing username being queried + * @id_type - subuid or subgid +- * @ranges - pointer to an array of struct subordinate_range pointers, or +- * NULL. The returned array of struct subordinate_range and its +- * members must be freed by the caller. ++ * @ranges - pointer to an array of struct subid_range, or NULL. The ++ * returned array must be freed by the caller. + * @count - pointer to an integer into which the number of returned ranges + * is written. + + * returns success if the module was able to determine an answer, + * else an error status. + */ +- enum subid_status (*list_owner_ranges)(const char *owner, enum subid_type id_type, struct subordinate_range ***ranges, int *count); ++ enum subid_status (*list_owner_ranges)(const char *owner, enum subid_type id_type, struct subid_range **ranges, int *count); + + /* + * nss_find_subid_owners: find uids who own a given subuid or subgid. +diff -up shadow-4.8.1/libsubid/api.c.libsubid_simplify_ranges_variable shadow-4.8.1/libsubid/api.c +--- shadow-4.8.1/libsubid/api.c.libsubid_simplify_ranges_variable 2021-05-24 15:03:01.467989079 +0200 ++++ shadow-4.8.1/libsubid/api.c 2021-05-24 16:42:32.091584531 +0200 +@@ -68,26 +68,21 @@ bool libsubid_init(const char *progname, + } + + static +-int get_subid_ranges(const char *owner, enum subid_type id_type, struct subordinate_range ***ranges) ++int get_subid_ranges(const char *owner, enum subid_type id_type, struct subid_range **ranges) + { + return list_owner_ranges(owner, id_type, ranges); + } + +-int get_subuid_ranges(const char *owner, struct subordinate_range ***ranges) ++int get_subuid_ranges(const char *owner, struct subid_range **ranges) + { + return get_subid_ranges(owner, ID_TYPE_UID, ranges); + } + +-int get_subgid_ranges(const char *owner, struct subordinate_range ***ranges) ++int get_subgid_ranges(const char *owner, struct subid_range **ranges) + { + return get_subid_ranges(owner, ID_TYPE_GID, ranges); + } + +-void subid_free_ranges(struct subordinate_range **ranges, int count) +-{ +- return free_subordinate_ranges(ranges, count); +-} +- + static + int get_subid_owner(unsigned long id, enum subid_type id_type, uid_t **owner) + { +diff -up shadow-4.8.1/libsubid/subid.h.libsubid_simplify_ranges_variable shadow-4.8.1/libsubid/subid.h +--- shadow-4.8.1/libsubid/subid.h.libsubid_simplify_ranges_variable 2021-05-24 15:03:01.468989093 +0200 ++++ shadow-4.8.1/libsubid/subid.h 2021-05-24 16:43:49.697657383 +0200 +@@ -3,6 +3,15 @@ + + #ifndef SUBID_RANGE_DEFINED + #define SUBID_RANGE_DEFINED 1 ++ ++/* subid_range is just a starting point and size of a range */ ++struct subid_range { ++ unsigned long start; ++ unsigned long count; ++}; ++ ++/* subordinage_range is a subid_range plus an owner, representing ++ * a range in /etc/subuid or /etc/subgid */ + struct subordinate_range { + const char *owner; + unsigned long start; +@@ -41,32 +50,27 @@ bool libsubid_init(const char *progname, + * get_subuid_ranges: return a list of UID ranges for a user + * + * @owner: username being queried +- * @ranges: a pointer to a subordinate range ** in which the result will be +- * returned. ++ * @ranges: a pointer to an array of subid_range structs in which the result ++ * will be returned. ++ * ++ * The caller must free(ranges) when done. + * + * returns: number of ranges found, ir < 0 on error. + */ +-int get_subuid_ranges(const char *owner, struct subordinate_range ***ranges); ++int get_subuid_ranges(const char *owner, struct subid_range **ranges); + + /* + * get_subgid_ranges: return a list of GID ranges for a user + * + * @owner: username being queried +- * @ranges: a pointer to a subordinate range ** in which the result will be +- * returned. ++ * @ranges: a pointer to an array of subid_range structs in which the result ++ * will be returned. + * +- * returns: number of ranges found, ir < 0 on error. +- */ +-int get_subgid_ranges(const char *owner, struct subordinate_range ***ranges); +- +-/* +- * subid_free_ranges: free an array of subordinate_ranges returned by either +- * get_subuid_ranges() or get_subgid_ranges(). ++ * The caller must free(ranges) when done. + * +- * @ranges: the ranges to free +- * @count: the number of ranges in @ranges ++ * returns: number of ranges found, ir < 0 on error. + */ +-void subid_free_ranges(struct subordinate_range **ranges, int count); ++int get_subgid_ranges(const char *owner, struct subid_range **ranges); + + /* + * get_subuid_owners: return a list of uids to which the given uid has been +diff -up shadow-4.8.1/lib/subordinateio.c.libsubid-simplify shadow-4.8.1/lib/subordinateio.c +--- shadow-4.8.1/lib/subordinateio.c.libsubid-simplify 2021-05-24 17:27:38.721035241 +0200 ++++ shadow-4.8.1/lib/subordinateio.c 2021-05-24 17:28:06.481420946 +0200 +@@ -11,6 +11,7 @@ + #include + #include "commonio.h" + #include "subordinateio.h" ++#include "../libsubid/subid.h" + #include + #include + #include +@@ -308,25 +309,21 @@ static bool have_range(struct commonio_d + return false; + } + +-static bool append_range(struct subordinate_range ***ranges, const struct subordinate_range *new, int n) ++static bool append_range(struct subid_range **ranges, const struct subordinate_range *new, int n) + { +- struct subordinate_range *tmp; + if (!*ranges) { +- *ranges = malloc(sizeof(struct subordinate_range *)); ++ *ranges = malloc(sizeof(struct subid_range)); + if (!*ranges) + return false; + } else { +- struct subordinate_range **new; +- new = realloc(*ranges, (n + 1) * (sizeof(struct subordinate_range *))); +- if (!new) ++ struct subid_range *alloced; ++ alloced = realloc(*ranges, (n + 1) * (sizeof(struct subid_range))); ++ if (!alloced) + return false; +- *ranges = new; ++ *ranges = alloced; + } +- (*ranges)[n] = NULL; +- tmp = subordinate_dup(new); +- if (!tmp) +- return false; +- (*ranges)[n] = tmp; ++ (*ranges)[n].start = new->start; ++ (*ranges)[n].count = new->count; + return true; + } + +@@ -785,10 +782,10 @@ gid_t sub_gid_find_free_range(gid_t min, + * + * The caller must free the subordinate range list. + */ +-int list_owner_ranges(const char *owner, enum subid_type id_type, struct subordinate_range ***in_ranges) ++int list_owner_ranges(const char *owner, enum subid_type id_type, struct subid_range **in_ranges) + { + // TODO - need to handle owner being either uid or username +- struct subordinate_range **ranges = NULL; ++ struct subid_range *ranges = NULL; + const struct subordinate_range *range; + struct commonio_db *db; + enum subid_status status; +@@ -826,7 +823,7 @@ int list_owner_ranges(const char *owner, + while ((range = commonio_next(db)) != NULL) { + if (0 == strcmp(range->owner, owner)) { + if (!append_range(&ranges, range, count++)) { +- free_subordinate_ranges(ranges, count-1); ++ free(ranges); + ranges = NULL; + count = -1; + goto out; +diff -up shadow-4.8.1/lib/subordinateio.h.libsubid_simplify_ranges_variable shadow-4.8.1/lib/subordinateio.h +--- shadow-4.8.1/lib/subordinateio.h.libsubid_simplify_ranges_variable 2021-05-24 15:03:01.467989079 +0200 ++++ shadow-4.8.1/lib/subordinateio.h 2021-05-24 16:40:56.978269647 +0200 +@@ -25,7 +25,7 @@ extern int sub_uid_unlock (void); + extern int sub_uid_add (const char *owner, uid_t start, unsigned long count); + extern int sub_uid_remove (const char *owner, uid_t start, unsigned long count); + extern uid_t sub_uid_find_free_range(uid_t min, uid_t max, unsigned long count); +-extern int list_owner_ranges(const char *owner, enum subid_type id_type, struct subordinate_range ***ranges); ++extern int list_owner_ranges(const char *owner, enum subid_type id_type, struct subid_range **ranges); + extern bool new_subid_range(struct subordinate_range *range, enum subid_type id_type, bool reuse); + extern bool release_subid_range(struct subordinate_range *range, enum subid_type id_type); + extern int find_subid_owners(unsigned long id, enum subid_type id_type, uid_t **uids); +diff -up shadow-4.8.1/src/list_subid_ranges.c.libsubid_simplify_ranges_variable shadow-4.8.1/src/list_subid_ranges.c +--- shadow-4.8.1/src/list_subid_ranges.c.libsubid_simplify_ranges_variable 2021-05-24 15:03:01.468989093 +0200 ++++ shadow-4.8.1/src/list_subid_ranges.c 2021-05-24 16:45:10.884779740 +0200 +@@ -17,27 +17,29 @@ void usage(void) + int main(int argc, char *argv[]) + { + int i, count=0; +- struct subordinate_range **ranges; ++ struct subid_range *ranges; ++ const char *owner; + + Prog = Basename (argv[0]); + shadow_logfd = stderr; +- if (argc < 2) { ++ if (argc < 2) + usage(); +- } +- if (argc == 3 && strcmp(argv[1], "-g") == 0) +- count = get_subgid_ranges(argv[2], &ranges); +- else if (argc == 2 && strcmp(argv[1], "-h") == 0) ++ owner = argv[1]; ++ if (argc == 3 && strcmp(argv[1], "-g") == 0) { ++ owner = argv[2]; ++ count = get_subgid_ranges(owner, &ranges); ++ } else if (argc == 2 && strcmp(argv[1], "-h") == 0) { + usage(); +- else +- count = get_subuid_ranges(argv[1], &ranges); ++ } else { ++ count = get_subuid_ranges(owner, &ranges); ++ } + if (!ranges) { + fprintf(stderr, "Error fetching ranges\n"); + exit(1); + } + for (i = 0; i < count; i++) { +- printf("%d: %s %lu %lu\n", i, ranges[i]->owner, +- ranges[i]->start, ranges[i]->count); ++ printf("%d: %s %lu %lu\n", i, owner, ++ ranges[i].start, ranges[i].count); + } +- subid_free_ranges(ranges, count); + return 0; + } +diff -up shadow-4.8.1/tests/libsubid/04_nss/libsubid_zzz.c.libsubid_simplify_ranges_variable shadow-4.8.1/tests/libsubid/04_nss/libsubid_zzz.c +--- shadow-4.8.1/tests/libsubid/04_nss/libsubid_zzz.c.libsubid_simplify_ranges_variable 2021-05-24 15:02:56.166917079 +0200 ++++ shadow-4.8.1/tests/libsubid/04_nss/libsubid_zzz.c 2021-05-24 15:03:01.469989106 +0200 +@@ -113,7 +113,7 @@ enum subid_status shadow_subid_list_owne + if (strcmp(owner, "conn") == 0) + return SUBID_STATUS_ERROR_CONN; + +- *ranges = NULL; ++ *in_ranges = NULL; + if (strcmp(owner, "user1") != 0 && strcmp(owner, "ubuntu") != 0 && + strcmp(owner, "group1") != 0) + return SUBID_STATUS_SUCCESS; diff --git a/shadow-4.8.1-man_clarify_subid_delegation.patch b/shadow-4.8.1-man_clarify_subid_delegation.patch new file mode 100644 index 0000000..b7d01b8 --- /dev/null +++ b/shadow-4.8.1-man_clarify_subid_delegation.patch @@ -0,0 +1,246 @@ +From d5b15f8633d0eabed885cd16feda224ec2d59072 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Mon, 24 May 2021 12:14:43 +0200 +Subject: [PATCH] man: clarify subid delegation + +Clarify that the subid delegation can only come from one source. +Moreover, add an example of what might happen if the subid source is NSS +and useradd is executed. + +Related: https://github.com/shadow-maint/shadow/issues/331 +--- + man/newgidmap.1.xml | 12 +++++++++--- + man/newuidmap.1.xml | 10 ++++++++-- + 2 files changed, 17 insertions(+), 5 deletions(-) + +diff --git a/man/newgidmap.1.xml b/man/newgidmap.1.xml +index 76fc1e30..7aaf34bf 100644 +--- a/man/newgidmap.1.xml ++++ b/man/newgidmap.1.xml +@@ -88,9 +88,15 @@ + DESCRIPTION + + The newgidmap sets /proc/[pid]/gid_map based on its +- command line arguments and the gids allowed (either in /etc/subgid or +- through the configured NSS subid module). +- Note that the root user is not exempted from the requirement for a valid ++ command line arguments and the gids allowed. The subid delegation can come either from files ++ (/etc/subgid) or from the configured NSS subid module. Only one of them ++ can be chosen at a time. So, for example, if the subid source is configured as NSS and ++ groupadd is executed, then the command will fail and the entry will not be ++ created in /etc/subgid. ++ ++ ++ ++ Note that the root group is not exempted from the requirement for a valid + /etc/subgid entry. + + +diff --git a/man/newuidmap.1.xml b/man/newuidmap.1.xml +index 44eca50a..4bc1ef7a 100644 +--- a/man/newuidmap.1.xml ++++ b/man/newuidmap.1.xml +@@ -88,8 +88,14 @@ + DESCRIPTION + + The newuidmap sets /proc/[pid]/uid_map based on its +- command line arguments and the uids allowed (either in /etc/subuid or +- through the configured NSS subid module). ++ command line arguments and the uids allowed. The subid delegation can come either from files ++ (/etc/subuid) or from the configured NSS subid module. Only one of them ++ can be chosen at a time. So, for example, if the subid source is configured as NSS and ++ useradd is executed, then the command will fail and the entry will not be ++ created in /etc/subuid. ++ ++ ++ + Note that the root user is not exempted from the requirement for a valid + /etc/subuid entry. + +-- +2.30.2 + +From 68ebbf936038e4e4c8b5105bd3246ef9709b6354 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Mon, 7 Jun 2021 11:50:56 +0200 +Subject: [PATCH 1/2] man: clarify subid delegation behaviour + +Following the discussion https://github.com/shadow-maint/shadow/pull/345 +I have changed the documentation to clarify the behaviour of subid +delegation when any subid source except files is configured. +--- + man/newgidmap.1.xml | 11 +++++------ + man/newuidmap.1.xml | 11 +++++------ + 2 files changed, 10 insertions(+), 12 deletions(-) + +diff --git a/man/newgidmap.1.xml b/man/newgidmap.1.xml +index 7aaf34bf..681aefcb 100644 +--- a/man/newgidmap.1.xml ++++ b/man/newgidmap.1.xml +@@ -87,12 +87,11 @@ + + DESCRIPTION + +- The newgidmap sets /proc/[pid]/gid_map based on its +- command line arguments and the gids allowed. The subid delegation can come either from files +- (/etc/subgid) or from the configured NSS subid module. Only one of them +- can be chosen at a time. So, for example, if the subid source is configured as NSS and +- groupadd is executed, then the command will fail and the entry will not be +- created in /etc/subgid. ++ The newgidmap sets /proc/[pid]/gid_map ++ based on its command line arguments and the gids allowed. Subgid ++ delegation can either be managed via /etc/subgid ++ or through the configured NSS subid module. These options are mutually ++ exclusive. + + + +diff --git a/man/newuidmap.1.xml b/man/newuidmap.1.xml +index 4bc1ef7a..09e65d80 100644 +--- a/man/newuidmap.1.xml ++++ b/man/newuidmap.1.xml +@@ -87,12 +87,11 @@ + + DESCRIPTION + +- The newuidmap sets /proc/[pid]/uid_map based on its +- command line arguments and the uids allowed. The subid delegation can come either from files +- (/etc/subuid) or from the configured NSS subid module. Only one of them +- can be chosen at a time. So, for example, if the subid source is configured as NSS and +- useradd is executed, then the command will fail and the entry will not be +- created in /etc/subuid. ++ The newuidmap sets /proc/[pid]/uid_map ++ based on its command line arguments and the uids allowed. Subuid ++ delegation can either be managed via /etc/subuid or ++ through the configured NSS subid module. These options are mutually ++ exclusive. + + + +-- +2.31.1 + + +From 0faec51bf0ec24e6e3d098cc55ed42584dd24efe Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Fri, 11 Jun 2021 15:25:42 +0200 +Subject: [PATCH 2/2] man: definition and configuration of subid + +Define the subid functionality and explain the way to configure its +delegation. +--- + man/subgid.5.xml | 32 +++++++++++++++++++++++++++++++- + man/subuid.5.xml | 32 +++++++++++++++++++++++++++++++- + 2 files changed, 62 insertions(+), 2 deletions(-) + +diff --git a/man/subgid.5.xml b/man/subgid.5.xml +index 70c561c4..02f421ab 100644 +--- a/man/subgid.5.xml ++++ b/man/subgid.5.xml +@@ -38,6 +38,11 @@ + Biederman + Creation, 2013 + ++ ++ Iker ++ Pedrosa ++ Developer, 2021 ++ + + + subgid +@@ -48,11 +53,36 @@ + + + subgid +- the subordinate gid file ++ the configuration for subordinate group ids + + + + DESCRIPTION ++ ++ Subgid authorizes a group id to map ranges of group ids from its namespace ++ into child namespaces. ++ ++ ++ The delegation of the subordinate gids can be configured via the ++ subid field in ++ /etc/nsswitch.conf file. Only one value can be set ++ as the delegation source. Setting this field to ++ files configures the delegation of gids to ++ /etc/subgid. Setting any other value treats ++ the delegation as a plugin following with a name of the form ++ libsubid_$value.so. If the value or plugin is ++ missing, then the subordinate gid delegation falls back to ++ files. ++ ++ ++ Note, that groupadd will only create entries in ++ /etc/subgid if subid delegation is managed via subid ++ files. ++ ++ ++ ++ ++ LOCAL SUBORDINATE DELEGATION + + Each line in /etc/subgid contains + a user name and a range of subordinate group ids that user +diff --git a/man/subuid.5.xml b/man/subuid.5.xml +index ec6a85f5..990d162e 100644 +--- a/man/subuid.5.xml ++++ b/man/subuid.5.xml +@@ -38,6 +38,11 @@ + Biederman + Creation, 2013 + ++ ++ Iker ++ Pedrosa ++ Developer, 2021 ++ + + + subuid +@@ -48,11 +53,36 @@ + + + subuid +- the subordinate uid file ++ the configuration for subordinate user ids + + + + DESCRIPTION ++ ++ Subuid authorizes a user id to map ranges of user ids from its namespace ++ into child namespaces. ++ ++ ++ The delegation of the subordinate uids can be configured via the ++ subid field in ++ /etc/nsswitch.conf file. Only one value can be set ++ as the delegation source. Setting this field to ++ files configures the delegation of uids to ++ /etc/subuid. Setting any other value treats ++ the delegation as a plugin following with a name of the form ++ libsubid_$value.so. If the value or plugin is ++ missing, then the subordinate uid delegation falls back to ++ files. ++ ++ ++ Note, that useradd will only create entries in ++ /etc/subuid if subid delegation is managed via subid ++ files. ++ ++ ++ ++ ++ LOCAL SUBORDINATE DELEGATION + + Each line in /etc/subuid contains + a user name and a range of subordinate user ids that user +-- +2.31.1 + diff --git a/shadow-4.8.1-useradd_SUB_UID_COUNT-0.patch b/shadow-4.8.1-useradd_SUB_UID_COUNT-0.patch new file mode 100644 index 0000000..f393368 --- /dev/null +++ b/shadow-4.8.1-useradd_SUB_UID_COUNT-0.patch @@ -0,0 +1,44 @@ +From 663824ef4ca927aa2b4319b69e0bfa68282ec719 Mon Sep 17 00:00:00 2001 +From: Serge Hallyn +Date: Sat, 22 May 2021 11:42:02 -0500 +Subject: [PATCH] Fix useradd with SUB_UID_COUNT=0 + +Closes #298 + +Fix useradd when SUB_UID_COUNT=0 in login.defs. + +Signed-off-by: Serge Hallyn +--- + src/useradd.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/useradd.c b/src/useradd.c +index 06accb2f..9862ae55 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -2386,6 +2386,8 @@ int main (int argc, char **argv) + #ifdef ENABLE_SUBIDS + uid_t uid_min; + uid_t uid_max; ++ unsigned long subuid_count; ++ unsigned long subgid_count; + #endif + + /* +@@ -2427,9 +2429,11 @@ int main (int argc, char **argv) + #ifdef ENABLE_SUBIDS + uid_min = (uid_t) getdef_ulong ("UID_MIN", 1000UL); + uid_max = (uid_t) getdef_ulong ("UID_MAX", 60000UL); +- is_sub_uid = sub_uid_file_present () && !rflg && ++ subuid_count = getdef_ulong ("SUB_UID_COUNT", 65536); ++ subgid_count = getdef_ulong ("SUB_GID_COUNT", 65536); ++ is_sub_uid = subuid_count > 0 && sub_uid_file_present () && !rflg && + (!user_id || (user_id <= uid_max && user_id >= uid_min)); +- is_sub_gid = sub_gid_file_present () && !rflg && ++ is_sub_gid = subgid_count > 0 && sub_gid_file_present () && !rflg && + (!user_id || (user_id <= uid_max && user_id >= uid_min)); + #endif /* ENABLE_SUBIDS */ + +-- +2.30.2 + diff --git a/shadow-utils.spec b/shadow-utils.spec index 3a8e510..164c0d7 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.8.1 -Release: 10%{?dist} +Release: 11%{?dist} Epoch: 2 URL: https://github.com/shadow-maint/shadow Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -78,6 +78,23 @@ Patch47: shadow-4.8.1-libsubid_creation.patch Patch48: shadow-4.8.1-libsubid_nsswitch_support.patch # https://github.com/shadow-maint/shadow/commit/186b1b7ac1a68d0fcc618a22da1a99232b420911 Patch49: shadow-4.8.1-man-mention-nss-in-newuidmap.patch +# https://github.com/shadow-maint/shadow/commit/f9831a4a1a20b0e8fe47cc72ec20018ec04dbb90 +Patch50: shadow-4.8.1-libsubid_not_print_error_messages.patch +# https://github.com/shadow-maint/shadow/commit/c6cab4a7bafa18d9d65a333cac1261e7b5e32bc9 +Patch51: shadow-4.8.1-libsubid_init_return_false.patch +# https://github.com/shadow-maint/shadow/commit/2f1f45d64fc7c10e7a3cbe00e89f63714343e526 +Patch52: shadow-4.8.1-useradd_SUB_UID_COUNT-0.patch +# https://github.com/shadow-maint/shadow/commit/ea7af4e1543c63590d4107ae075fea385028997d +Patch53: shadow-4.8.1-libsubid_simplify_ranges_variable.patch +# https://github.com/shadow-maint/shadow/commit/0fe42f571c69f0105d31305f995c9887aeb9525e +Patch54: shadow-4.8.1-libsubid_init_not_print_error_messages.patch +# https://github.com/shadow-maint/shadow/commit/ec1951c181faed188464396b2cfdd2efb726c7f3 +Patch55: shadow-4.8.1-libsubid_fix_newusers_nss_provides_subids.patch +# https://github.com/shadow-maint/shadow/commit/087112244327be50abc24f9ec8afbf60ae8b2dec +# https://github.com/shadow-maint/shadow/pull/353 +Patch56: shadow-4.8.1-man_clarify_subid_delegation.patch +# https://github.com/shadow-maint/shadow/commit/bd920ab36a6c641e4a8769f8c7f8ca738ec61820 +Patch57: shadow-4.8.1-libsubid_make_logfd_not_extern.patch License: BSD and GPLv2+ BuildRequires: make @@ -152,6 +169,14 @@ Development files for shadow-utils-subid. %patch47 -p1 -b .libsubid_creation %patch48 -p1 -b .libsubid_nsswitch_support %patch49 -p1 -b .man-mention-nss-in-newuidmap +%patch50 -p1 -b .libsubid_not_print_error_messages +%patch51 -p1 -b .libsubid_init_return_false +%patch52 -p1 -b .useradd_SUB_UID_COUNT-0 +%patch53 -p1 -b .libsubid_simplify_ranges_variable +%patch54 -p1 -b .libsubid_init_not_print_error_messages +%patch55 -p1 -b .libsubid_fix_newusers_nss_provides_subids +%patch56 -p1 -b .man_clarify_subid_delegation +%patch57 -p1 -b .libsubid_make_logfd_not_extern iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -320,6 +345,16 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la %{_libdir}/libsubid.so %changelog +* Mon Jun 21 2021 Iker Pedrosa - 2:4.8.1-11 +- libsubid: don't print error messages on stderr by default +- libsubid: libsubid_init return false if out of memory +- useradd: fix SUB_UID_COUNT=0 +- libsubid: don't return owner in list_owner_ranges API call +- libsubid: libsubid_init don't print messages on error +- libsubid: fix newusers when nss provides subids +- man: clarify subid delegation +- libsubid: make shadow_logfd not extern + * Thu May 6 2021 Iker Pedrosa - 2:4.8.1-10 - man: mention NSS in new[ug]idmap manpages - libsubid: move development header to shadow folder From cb2f54a2c1acc479e370af2480471e87fc29f750 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= Date: Thu, 3 Jun 2021 15:53:35 +0200 Subject: [PATCH 031/134] Backport support for yescrypt hash method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Esser --- shadow-4.8.1-yescrypt-support.patch | 960 ++++++++++++++++++++++++++++ shadow-utils.login.defs | 18 +- shadow-utils.spec | 9 +- 3 files changed, 984 insertions(+), 3 deletions(-) create mode 100644 shadow-4.8.1-yescrypt-support.patch diff --git a/shadow-4.8.1-yescrypt-support.patch b/shadow-4.8.1-yescrypt-support.patch new file mode 100644 index 0000000..aff941b --- /dev/null +++ b/shadow-4.8.1-yescrypt-support.patch @@ -0,0 +1,960 @@ +From 5cd04d03f94622c12220d4a6352824af081b8531 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rodolphe=20Br=C3=A9ard?= +Date: Sun, 27 Dec 2020 21:09:25 +0100 +Subject: [PATCH] Add yescrypt support + +--- + configure.ac | 13 +++++ + etc/login.defs | 14 +++++ + lib/encrypt.c | 3 ++ + lib/getdef.c | 3 ++ + libmisc/obscure.c | 3 ++ + libmisc/salt.c | 94 +++++++++++++++++++++++++++++++- + src/chgpasswd.c | 113 ++++++++++++++++++++------------------ + src/chpasswd.c | 107 +++++++++++++++++++----------------- + src/newusers.c | 134 +++++++++++++++++++++++++--------------------- + src/passwd.c | 3 ++ + 10 files changed, 322 insertions(+), 165 deletions(-) + +Index: shadow-4.8.1/configure.ac +=================================================================== +--- shadow-4.8.1.orig/configure.ac ++++ shadow-4.8.1/configure.ac +@@ -290,6 +290,9 @@ AC_ARG_WITH(sha-crypt, + AC_ARG_WITH(bcrypt, + [AC_HELP_STRING([--with-bcrypt], [allow the bcrypt password encryption algorithm @<:@default=no@:>@])], + [with_bcrypt=$withval], [with_bcrypt=no]) ++AC_ARG_WITH(yescrypt, ++ [AC_HELP_STRING([--with-yescrypt], [allow the yescrypt password encryption algorithm @<:@default=no@:>@])], ++ [with_yescrypt=$withval], [with_yescrypt=no]) + AC_ARG_WITH(nscd, + [AC_HELP_STRING([--with-nscd], [enable support for nscd @<:@default=yes@:>@])], + [with_nscd=$withval], [with_nscd=yes]) +@@ -322,6 +325,11 @@ if test "$with_bcrypt" = "yes"; then + AC_DEFINE(USE_BCRYPT, 1, [Define to allow the bcrypt password encryption algorithm]) + fi + ++AM_CONDITIONAL(USE_YESCRYPT, test "x$with_yescrypt" = "xyes") ++if test "$with_yescrypt" = "yes"; then ++ AC_DEFINE(USE_YESCRYPT, 1, [Define to allow the yescrypt password encryption algorithm]) ++fi ++ + if test "$with_nscd" = "yes"; then + AC_CHECK_FUNC(posix_spawn, + [AC_DEFINE(USE_NSCD, 1, [Define to support flushing of nscd caches])], +@@ -402,6 +410,10 @@ AC_SUBST(LIBCRYPT) + AC_CHECK_LIB(crypt, crypt, [LIBCRYPT=-lcrypt], + [AC_MSG_ERROR([crypt() not found])]) + ++AC_SUBST(LIYESCRYPT) ++AC_CHECK_LIB(crypt, crypt, [LIYESCRYPT=-lcrypt], ++ [AC_MSG_ERROR([crypt() not found])]) ++ + AC_SUBST(LIBACL) + if test "$with_acl" != "no"; then + AC_CHECK_HEADERS(acl/libacl.h attr/error_context.h, [acl_header="yes"], [acl_header="no"]) +@@ -752,6 +764,7 @@ echo " shadow group support: $enable_sh + echo " S/Key support: $with_skey" + echo " SHA passwords encryption: $with_sha_crypt" + echo " bcrypt passwords encryption: $with_bcrypt" ++echo " yescrypt passwords encryption: $with_yescrypt" + echo " nscd support: $with_nscd" + echo " sssd support: $with_sssd" + echo " subordinate IDs support: $enable_subids" +Index: shadow-4.8.1/etc/login.defs +=================================================================== +--- shadow-4.8.1.orig/etc/login.defs ++++ shadow-4.8.1/etc/login.defs +@@ -326,6 +326,7 @@ CHFN_RESTRICT rwh + # If set to SHA256, SHA256-based algorithm will be used for encrypting password + # If set to SHA512, SHA512-based algorithm will be used for encrypting password + # If set to BCRYPT, BCRYPT-based algorithm will be used for encrypting password ++# If set to YESCRYPT, YESCRYPT-based algorithm will be used for encrypting password + # If set to DES, DES-based algorithm will be used for encrypting password (default) + # Overrides the MD5_CRYPT_ENAB option + # +@@ -366,6 +367,19 @@ CHFN_RESTRICT rwh + #BCRYPT_MAX_ROUNDS 13 + + # ++# Only works if ENCRYPT_METHOD is set to YESCRYPT. ++# ++# Define the YESCRYPT cost factor. ++# With a higher cost factor, it is more difficult to brute-force the password. ++# However, more CPU time and more memory will be needed to authenticate users ++# if this value is increased. ++# ++# If not specified, a cost factor of 5 will be used. ++# The value must be within the 1-11 range. ++# ++#YESCRYPT_COST_FACTOR 5 ++ ++# + # List of groups to add to the user's supplementary group set + # when logging in from the console (as determined by the CONSOLE + # setting). Default is none. +Index: shadow-4.8.1/lib/encrypt.c +=================================================================== +--- shadow-4.8.1.orig/lib/encrypt.c ++++ shadow-4.8.1/lib/encrypt.c +@@ -74,6 +74,9 @@ + case '6': + method = "SHA512"; + break; ++ case 'y': ++ method = "YESCRYPT"; ++ break; + default: + { + static char nummethod[4] = "$x$"; +Index: shadow-4.8.1/lib/getdef.c +=================================================================== +--- shadow-4.8.1.orig/lib/getdef.c ++++ shadow-4.8.1/lib/getdef.c +@@ -117,6 +117,9 @@ static struct itemdef def_table[] = { + {"BCRYPT_MAX_ROUNDS", NULL}, + {"BCRYPT_MIN_ROUNDS", NULL}, + #endif ++#ifdef USE_YESCRYPT ++ {"YESCRYPT_COST_FACTOR", NULL}, ++#endif + {"SUB_GID_COUNT", NULL}, + {"SUB_GID_MAX", NULL}, + {"SUB_GID_MIN", NULL}, +Index: shadow-4.8.1/libmisc/obscure.c +=================================================================== +--- shadow-4.8.1.orig/libmisc/obscure.c ++++ shadow-4.8.1/libmisc/obscure.c +@@ -272,6 +272,9 @@ static /*@observer@*//*@null@*/const cha + #ifdef USE_BCRYPT + || (strcmp (result, "BCRYPT") == 0) + #endif ++#ifdef USE_YESCRYPT ++ || (strcmp (result, "YESCRYPT") == 0) ++#endif + ) { + return NULL; + } +Index: shadow-4.8.1/libmisc/salt.c +=================================================================== +--- shadow-4.8.1.orig/libmisc/salt.c ++++ shadow-4.8.1/libmisc/salt.c +@@ -32,6 +32,10 @@ static /*@observer@*/const char *SHA_sal + static /*@observer@*/const char *gensalt_bcrypt (void); + static /*@observer@*/const char *BCRYPT_salt_rounds (/*@null@*/int *prefered_rounds); + #endif /* USE_BCRYPT */ ++#ifdef USE_YESCRYPT ++static /*@observer@*/const char *gensalt_yescrypt (void); ++static /*@observer@*/const char *YESCRYPT_salt_cost (/*@null@*/long *prefered_rounds); ++#endif /* USE_YESCRYPT */ + + #ifndef HAVE_L64A + static /*@observer@*/char *l64a(long value) +@@ -263,6 +267,78 @@ static /*@observer@*/const char *gensalt + } + #endif /* USE_BCRYPT */ + ++#ifdef USE_YESCRYPT ++/* Default cost if not explicitly specified. */ ++#define Y_COST_DEFAULT 5 ++/* Minimum cost. */ ++#define Y_COST_MIN 1 ++/* Maximum cost. */ ++#define Y_COST_MAX 11 ++/* ++ * Return a salt prefix specifying the cost for the YESCRYPT method. ++ */ ++static /*@observer@*/const char *YESCRYPT_salt_cost (/*@null@*/long *prefered_cost) ++{ ++ static char cost_prefix[5]; ++ long cost; ++ ++ if (NULL == prefered_cost) { ++ cost = getdef_num ("YESCRYPT_COST_FACTOR", Y_COST_DEFAULT); ++ } else { ++ cost = *prefered_cost; ++ } ++ ++ if (cost < Y_COST_MIN) { ++ cost = Y_COST_MIN; ++ } ++ if (cost > Y_COST_MAX) { ++ cost = Y_COST_MAX; ++ } ++ ++ cost_prefix[0] = 'j'; ++ if (cost < 3) { ++ cost_prefix[1] = 0x36 + cost; ++ } else if (cost < 6) { ++ cost_prefix[1] = 0x34 + cost; ++ } else { ++ cost_prefix[1] = 0x3b + cost; ++ } ++ cost_prefix[2] = cost >= 3 ? 'T' : '5'; ++ cost_prefix[3] = '$'; ++ cost_prefix[4] = 0; ++ ++ return cost_prefix; ++} ++ ++/* ++ * Default number of base64 characters used for the salt. ++ * 24 characters gives a 144 bits (18 bytes) salt. Unlike the more ++ * traditional 128 bits (16 bytes) salt, this 144 bits salt is always ++ * represented by the same number of base64 characters without padding ++ * issue, even with a non-standard base64 encoding scheme. ++ */ ++#define YESCRYPT_SALT_SIZE 24 ++/* ++ * Generate a 22 character salt string for yescrypt. ++ */ ++static /*@observer@*/const char *gensalt_yescrypt (void) ++{ ++ static char salt[32]; ++ ++ salt[0] = '\0'; ++ ++ seedRNG (); ++ strcat (salt, l64a (random())); ++ do { ++ strcat (salt, l64a (random())); ++ } while (strlen (salt) < YESCRYPT_SALT_SIZE); ++ ++ salt[YESCRYPT_SALT_SIZE] = '\0'; ++ ++ return salt; ++} ++#endif /* USE_YESCRYPT */ ++ + /* + * Generate salt of size salt_size. + */ +@@ -302,6 +378,7 @@ static /*@observer@*/const char *gensalt + * If meth is specified, an additional parameter can be provided. + * * For the SHA256 and SHA512 method, this specifies the number of rounds + * (if not NULL). ++ * * For the YESCRYPT method, this specifies the cost factor (if not NULL). + */ + /*@observer@*/const char *crypt_make_salt (/*@null@*//*@observer@*/const char *meth, /*@null@*/void *arg) + { +@@ -333,6 +410,11 @@ static /*@observer@*/const char *gensalt + BCRYPTMAGNUM(result); + strcat(result, BCRYPT_salt_rounds((int *)arg)); + #endif /* USE_BCRYPT */ ++#ifdef USE_YESCRYPT ++ } else if (0 == strcmp (method, "YESCRYPT")) { ++ MAGNUM(result, 'y'); ++ strcat(result, YESCRYPT_salt_cost((int *)arg)); ++#endif /* USE_YESCRYPT */ + #ifdef USE_SHA_CRYPT + } else if (0 == strcmp (method, "SHA256")) { + MAGNUM(result, '5'); +@@ -362,11 +444,21 @@ static /*@observer@*/const char *gensalt + return result; + } else { + #endif /* USE_BCRYPT */ ++#ifdef USE_YESCRYPT ++ if (0 == strcmp (method, "YESCRYPT")) { ++ strncat (result, gensalt_yescrypt (), ++ sizeof (result) - strlen (result) - 1); ++ return result; ++ } else { ++#endif /* USE_YESCRYPT */ + strncat (result, gensalt (salt_len), + sizeof (result) - strlen (result) - 1); ++#ifdef USE_YESCRYPT ++ } ++#endif /* USE_YESCRYPT */ + #ifdef USE_BCRYPT + } +-#endif /* USE_BCRYPT */ ++#endif /* USE_BCRYPT */ + + return result; + } +Index: shadow-4.8.1/src/chgpasswd.c +=================================================================== +--- shadow-4.8.1.orig/src/chgpasswd.c ++++ shadow-4.8.1/src/chgpasswd.c +@@ -69,9 +69,9 @@ const char *Prog; + FILE *shadow_logfd = NULL; + static bool eflg = false; + static bool md5flg = false; +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) + static bool sflg = false; +-#endif /* USE_SHA_CRYPT || USE_BCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ + + static /*@null@*//*@observer@*/const char *crypt_method = NULL; + #define cflg (NULL != crypt_method) +@@ -81,6 +81,9 @@ static long sha_rounds = 5000; + #ifdef USE_BCRYPT + static long bcrypt_rounds = 13; + #endif ++#ifdef USE_YESCRYPT ++static long yescrypt_cost = 5; ++#endif + + #ifdef SHADOWGRP + static bool is_shadow_grp; +@@ -139,14 +142,15 @@ static /*@noreturn@*/void usage (int sta + Prog); + (void) fprintf (usageout, + _(" -c, --crypt-method METHOD the crypt method (one of %s)\n"), +-#if !defined(USE_SHA_CRYPT) && !defined(USE_BCRYPT) + "NONE DES MD5" +-#elif defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) +- "NONE DES MD5 SHA256 SHA512 BCRYPT" +-#elif defined(USE_SHA_CRYPT) +- "NONE DES MD5 SHA256 SHA512" +-#else +- "NONE DES MD5 BCRYPT" ++#if defined(USE_SHA_CRYPT) ++ " SHA256 SHA512" ++#endif ++#if defined(USE_BCRYPT) ++ " BCRYPT" ++#endif ++#if defined(USE_YESCRYPT) ++ " YESCRYPT" + #endif + ); + (void) fputs (_(" -e, --encrypted supplied passwords are encrypted\n"), usageout); +@@ -155,11 +159,11 @@ static /*@noreturn@*/void usage (int sta + " the MD5 algorithm\n"), + usageout); + (void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout); +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) +- (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA or BCRYPT\n" +- " crypt algorithms\n"), ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) ++ (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT\n" ++ " or YESCRYPT crypt algorithms\n"), + usageout); +-#endif /* USE_SHA_CRYPT || USE_BCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ + (void) fputs ("\n", usageout); + + exit (status); +@@ -173,19 +177,22 @@ static /*@noreturn@*/void usage (int sta + static void process_flags (int argc, char **argv) + { + int c; ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) ++ int bad_s; ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ + static struct option long_options[] = { + {"crypt-method", required_argument, NULL, 'c'}, + {"encrypted", no_argument, NULL, 'e'}, + {"help", no_argument, NULL, 'h'}, + {"md5", no_argument, NULL, 'm'}, + {"root", required_argument, NULL, 'R'}, +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) + {"sha-rounds", required_argument, NULL, 's'}, +-#endif /* USE_SHA_CRYPT || USE_BCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ + {NULL, 0, NULL, '\0'} + }; + while ((c = getopt_long (argc, argv, +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) + "c:ehmR:s:", + #else + "c:ehmR:", +@@ -206,40 +213,36 @@ static void process_flags (int argc, cha + break; + case 'R': /* no-op, handled in process_root_flag () */ + break; +-#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) + case 's': + sflg = true; ++ bad_s = 0; ++#if defined(USE_SHA_CRYPT) + if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512"))) +- && (0 == getlong(optarg, &sha_rounds))) +- || ( (0 == strcmp (crypt_method, "BCRYPT")) ++ && (0 == getlong(optarg, &sha_rounds)))) { ++ bad_s = 1; ++ } ++#endif /* USE_SHA_CRYPT */ ++#if defined(USE_BCRYPT) ++ if (( (0 == strcmp (crypt_method, "BCRYPT")) + && (0 == getlong(optarg, &bcrypt_rounds)))) { ++ bad_s = 1; ++ } ++#endif /* USE_BCRYPT */ ++#if defined(USE_YESCRYPT) ++ if (( (0 == strcmp (crypt_method, "YESCRYPT")) ++ && (0 == getlong(optarg, &yescrypt_cost)))) { ++ bad_s = 1; ++ } ++#endif /* USE_YESCRYPT */ ++ if (bad_s != 0) { + fprintf (stderr, + _("%s: invalid numeric argument '%s'\n"), + Prog, optarg); + usage (E_USAGE); + } + break; +-#elif defined(USE_SHA_CRYPT) +- case 's': +- sflg = true; +- if (0 == getlong(optarg, &sha_rounds)) { +- fprintf (stderr, +- _("%s: invalid numeric argument '%s'\n"), +- Prog, optarg); +- usage (E_USAGE); +- } +- break; +-#elif defined(USE_BCRYPT) +- case 's': +- sflg = true; +- if (0 == getlong(optarg, &bcrypt_rounds)) { +- fprintf (stderr, +- _("%s: invalid numeric argument '%s'\n"), +- Prog, optarg); +- usage (E_USAGE); +- } +- break; +-#endif ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ + + default: + usage (E_USAGE); +@@ -258,7 +261,7 @@ static void process_flags (int argc, cha + */ + static void check_flags (void) + { +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) + if (sflg && !cflg) { + fprintf (stderr, + _("%s: %s flag is only allowed with the %s flag\n"), +@@ -282,10 +285,13 @@ static void check_flags (void) + #ifdef USE_SHA_CRYPT + && (0 != strcmp (crypt_method, "SHA256")) + && (0 != strcmp (crypt_method, "SHA512")) +-#endif ++#endif /* USE_SHA_CRYPT */ + #ifdef USE_BCRYPT + && (0 != strcmp (crypt_method, "BCRYPT")) +-#endif ++#endif /* USE_BCRYPT */ ++#ifdef USE_YESCRYPT ++ && (0 != strcmp (crypt_method, "YESCRYPT")) ++#endif /* USE_YESCRYPT */ + ) { + fprintf (stderr, + _("%s: unsupported crypt method: %s\n"), +@@ -592,23 +598,24 @@ int main (int argc, char **argv) + if (md5flg) { + crypt_method = "MD5"; + } +-#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) + if (sflg) { ++#if defined(USE_SHA_CRYPT) + if ( (0 == strcmp (crypt_method, "SHA256")) + || (0 == strcmp (crypt_method, "SHA512"))) { + arg = &sha_rounds; + } +- else if (0 == strcmp (crypt_method, "BCRYPT")) { ++#endif /* USE_SHA_CRYPT */ ++#if defined(USE_BCRYPT) ++ if (0 == strcmp (crypt_method, "BCRYPT")) { + arg = &bcrypt_rounds; + } +- } +-#elif defined(USE_SHA_CRYPT) +- if (sflg) { +- arg = &sha_rounds; +- } +-#elif defined(USE_BCRYPT) +- if (sflg) { +- arg = &bcrypt_rounds; ++#endif /* USE_BCRYPT */ ++#if defined(USE_YESCRYPT) ++ if (0 == strcmp (crypt_method, "YESCRYPT")) { ++ arg = &yescrypt_cost; ++ } ++#endif /* USE_YESCRYPT */ + } + #endif + salt = crypt_make_salt (crypt_method, arg); +Index: shadow-4.8.1/src/chpasswd.c +=================================================================== +--- shadow-4.8.1.orig/src/chpasswd.c ++++ shadow-4.8.1/src/chpasswd.c +@@ -66,7 +66,7 @@ const char *Prog; + FILE *shadow_logfd = NULL; + static bool eflg = false; + static bool md5flg = false; +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) + static bool sflg = false; + #endif + +@@ -78,6 +78,9 @@ static long sha_rounds = 5000; + #ifdef USE_BCRYPT + static long bcrypt_rounds = 13; + #endif ++#ifdef USE_YESCRYPT ++static long yescrypt_cost = 5; ++#endif + + static bool is_shadow_pwd; + static bool pw_locked = false; +@@ -129,14 +132,15 @@ static /*@noreturn@*/void usage (int sta + Prog); + (void) fprintf (usageout, + _(" -c, --crypt-method METHOD the crypt method (one of %s)\n"), +-#if !defined(USE_SHA_CRYPT) && !defined(USE_BCRYPT) + "NONE DES MD5" +-#elif defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) +- "NONE DES MD5 SHA256 SHA512 BCRYPT" +-#elif defined(USE_SHA_CRYPT) +- "NONE DES MD5 SHA256 SHA512" +-#else +- "NONE DES MD5 BCRYPT" ++#if defined(USE_SHA_CRYPT) ++ " SHA256 SHA512" ++#endif ++#if defined(USE_BCRYPT) ++ " BCRYPT" ++#endif ++#if defined(USE_YESCRYPT) ++ " YESCRYPT" + #endif + ); + (void) fputs (_(" -e, --encrypted supplied passwords are encrypted\n"), usageout); +@@ -145,11 +149,11 @@ static /*@noreturn@*/void usage (int sta + " the MD5 algorithm\n"), + usageout); + (void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout); +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) +- (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA or BCRYPT\n" +- " crypt algorithms\n"), ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) ++ (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT\n" ++ " or YESCRYPT crypt algorithms\n"), + usageout); +-#endif /* USE_SHA_CRYPT || USE_BCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ + (void) fputs ("\n", usageout); + + exit (status); +@@ -163,20 +167,23 @@ static /*@noreturn@*/void usage (int sta + static void process_flags (int argc, char **argv) + { + int c; ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) ++ int bad_s; ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ + static struct option long_options[] = { + {"crypt-method", required_argument, NULL, 'c'}, + {"encrypted", no_argument, NULL, 'e'}, + {"help", no_argument, NULL, 'h'}, + {"md5", no_argument, NULL, 'm'}, + {"root", required_argument, NULL, 'R'}, +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) + {"sha-rounds", required_argument, NULL, 's'}, +-#endif /* USE_SHA_CRYPT || USE_BCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ + {NULL, 0, NULL, '\0'} + }; + + while ((c = getopt_long (argc, argv, +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) + "c:ehmR:s:", + #else + "c:ehmR:", +@@ -197,40 +204,36 @@ static void process_flags (int argc, cha + break; + case 'R': /* no-op, handled in process_root_flag () */ + break; +-#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) + case 's': + sflg = true; ++ bad_s = 0; ++#if defined(USE_SHA_CRYPT) + if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512"))) +- && (0 == getlong(optarg, &sha_rounds))) +- || ( (0 == strcmp (crypt_method, "BCRYPT")) ++ && (0 == getlong(optarg, &sha_rounds)))) { ++ bad_s = 1; ++ } ++#endif /* USE_SHA_CRYPT */ ++#if defined(USE_BCRYPT) ++ if (( (0 == strcmp (crypt_method, "BCRYPT")) + && (0 == getlong(optarg, &bcrypt_rounds)))) { ++ bad_s = 1; ++ } ++#endif /* USE_BCRYPT */ ++#if defined(USE_YESCRYPT) ++ if (( (0 == strcmp (crypt_method, "YESCRYPT")) ++ && (0 == getlong(optarg, &yescrypt_cost)))) { ++ bad_s = 1; ++ } ++#endif /* USE_YESCRYPT */ ++ if (bad_s != 0) { + fprintf (stderr, + _("%s: invalid numeric argument '%s'\n"), + Prog, optarg); + usage (E_USAGE); + } + break; +-#elif defined(USE_SHA_CRYPT) +- case 's': +- sflg = true; +- if (0 == getlong(optarg, &sha_rounds)) { +- fprintf (stderr, +- _("%s: invalid numeric argument '%s'\n"), +- Prog, optarg); +- usage (E_USAGE); +- } +- break; +-#elif defined(USE_BCRYPT) +- case 's': +- sflg = true; +- if (0 == getlong(optarg, &bcrypt_rounds)) { +- fprintf (stderr, +- _("%s: invalid numeric argument '%s'\n"), +- Prog, optarg); +- usage (E_USAGE); +- } +- break; +-#endif ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ + + default: + usage (E_USAGE); +@@ -249,7 +252,7 @@ static void process_flags (int argc, cha + */ + static void check_flags (void) + { +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) + if (sflg && !cflg) { + fprintf (stderr, + _("%s: %s flag is only allowed with the %s flag\n"), +@@ -277,6 +280,9 @@ static void check_flags (void) + #ifdef USE_BCRYPT + && (0 != strcmp (crypt_method, "BCRYPT")) + #endif /* USE_BCRYPT */ ++#ifdef USE_YESCRYPT ++ && (0 != strcmp (crypt_method, "YESCRYPT")) ++#endif /* USE_YESCRYPT */ + ) { + fprintf (stderr, + _("%s: unsupported crypt method: %s\n"), +@@ -604,23 +610,24 @@ int main (int argc, char **argv) + if (md5flg) { + crypt_method = "MD5"; + } +-#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) + if (sflg) { ++#if defined(USE_SHA_CRYPT) + if ( (0 == strcmp (crypt_method, "SHA256")) + || (0 == strcmp (crypt_method, "SHA512"))) { + arg = &sha_rounds; + } +- else if (0 == strcmp (crypt_method, "BCRYPT")) { ++#endif /* USE_SHA_CRYPT */ ++#if defined(USE_BCRYPT) ++ if (0 == strcmp (crypt_method, "BCRYPT")) { + arg = &bcrypt_rounds; + } +- } +-#elif defined(USE_SHA_CRYPT) +- if (sflg) { +- arg = &sha_rounds; +- } +-#elif defined(USE_BCRYPT) +- if (sflg) { +- arg = &bcrypt_rounds; ++#endif /* USE_BCRYPT */ ++#if defined(USE_YESCRYPT) ++ if (0 == strcmp (crypt_method, "YESCRYPT")) { ++ arg = &yescrypt_cost; ++ } ++#endif /* USE_YESCRYPT */ + } + #endif + salt = crypt_make_salt (crypt_method, arg); +Index: shadow-4.8.1/src/newusers.c +=================================================================== +--- shadow-4.8.1.orig/src/newusers.c ++++ shadow-4.8.1/src/newusers.c +@@ -90,6 +90,9 @@ static long sha_rounds = 5000; + #ifdef USE_BCRYPT + static long bcrypt_rounds = 13; + #endif /* USE_BCRYPT */ ++#ifdef USE_YESCRYPT ++static long yescrypt_cost = 5; ++#endif /* USE_YESCRYPT */ + #endif /* !USE_PAM */ + + static bool is_shadow; +@@ -140,14 +143,15 @@ static void usage (int status) + #ifndef USE_PAM + (void) fprintf (usageout, + _(" -c, --crypt-method METHOD the crypt method (one of %s)\n"), +-#if !defined(USE_SHA_CRYPT) && !defined(USE_BCRYPT) +- "NONE DES MD5" +-#elif defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) +- "NONE DES MD5 SHA256 SHA512 BCRYPT" +-#elif defined(USE_SHA_CRYPT) +- "NONE DES MD5 SHA256 SHA512" +-#else +- "NONE DES MD5 BCRYPT" ++ "NONE DES MD5" ++#if defined(USE_SHA_CRYPT) ++ " SHA256 SHA512" ++#endif ++#if defined(USE_BCRYPT) ++ " BCRYPT" ++#endif ++#if defined(USE_YESCRYPT) ++ " YESCRYPT" + #endif + ); + #endif /* !USE_PAM */ +@@ -155,11 +159,11 @@ static void usage (int status) + (void) fputs (_(" -r, --system create system accounts\n"), usageout); + (void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout); + #ifndef USE_PAM +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) +- (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA or BCRYPT\n" +- " crypt algorithms\n"), ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) ++ (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT\n" ++ " or YESCRYPT crypt algorithms\n"), + usageout); +-#endif /* USE_SHA_CRYPT || USE_BCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ + #endif /* !USE_PAM */ + (void) fputs ("\n", usageout); + +@@ -434,25 +438,28 @@ static int update_passwd (struct passwd + void *crypt_arg = NULL; + char *cp; + if (NULL != crypt_method) { +-#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) + if (sflg) { + if ( (0 == strcmp (crypt_method, "SHA256")) + || (0 == strcmp (crypt_method, "SHA512"))) { + crypt_arg = &sha_rounds; + } +- else if (0 == strcmp (crypt_method, "BCRYPT")) { +- crypt_arg = &bcrypt_rounds; +- } + } +-#elif defined(USE_SHA_CRYPT) ++#endif /* USE_SHA_CRYPT */ ++#if defined(USE_BCRYPT) + if (sflg) { +- crypt_arg = &sha_rounds; ++ if (0 == strcmp (crypt_method, "BCRYPT")) { ++ crypt_arg = &bcrypt_rounds; ++ } + } +-#elif defined(USE_BCRYPT) ++#endif /* USE_BCRYPT */ ++#if defined(USE_YESCRYPT) + if (sflg) { +- crypt_arg = &bcrypt_rounds; ++ if (0 == strcmp (crypt_method, "YESCRYPT")) { ++ crypt_arg = &yescrypt_cost; ++ } + } +-#endif ++#endif /* USE_YESCRYPT */ + } + + if ((NULL != crypt_method) && (0 == strcmp(crypt_method, "NONE"))) { +@@ -485,25 +492,28 @@ static int add_passwd (struct passwd *pw + #ifndef USE_PAM + void *crypt_arg = NULL; + if (NULL != crypt_method) { +-#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) + if (sflg) { + if ( (0 == strcmp (crypt_method, "SHA256")) + || (0 == strcmp (crypt_method, "SHA512"))) { + crypt_arg = &sha_rounds; + } +- else if (0 == strcmp (crypt_method, "BCRYPT")) { +- crypt_arg = &bcrypt_rounds; +- } + } +-#elif defined(USE_SHA_CRYPT) ++#endif /* USE_SHA_CRYPT */ ++#if defined(USE_BCRYPT) + if (sflg) { +- crypt_arg = &sha_rounds; ++ if (0 == strcmp (crypt_method, "BCRYPT")) { ++ crypt_arg = &bcrypt_rounds; ++ } + } +-#elif defined(USE_BCRYPT) ++#endif /* USE_BCRYPT */ ++#if defined(USE_YESCRYPT) + if (sflg) { +- crypt_arg = &bcrypt_rounds; ++ if (0 == strcmp (crypt_method, "YESCRYPT")) { ++ crypt_arg = &yescrypt_cost; ++ } + } +-#endif ++#endif /* USE_PAM */ + } + + /* +@@ -620,6 +630,9 @@ static int add_passwd (struct passwd *pw + static void process_flags (int argc, char **argv) + { + int c; ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) ++ int bad_s; ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ + static struct option long_options[] = { + {"badnames", no_argument, NULL, 'b'}, + #ifndef USE_PAM +@@ -629,20 +642,20 @@ static void process_flags (int argc, cha + {"system", no_argument, NULL, 'r'}, + {"root", required_argument, NULL, 'R'}, + #ifndef USE_PAM +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) + {"sha-rounds", required_argument, NULL, 's'}, +-#endif /* USE_SHA_CRYPT || USE_BCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ + #endif /* !USE_PAM */ + {NULL, 0, NULL, '\0'} + }; + + while ((c = getopt_long (argc, argv, + #ifndef USE_PAM +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) + "c:bhrs:", +-#else /* !USE_SHA_CRYPT && !USE_BCRYPT */ ++#else /* !USE_SHA_CRYPT && !USE_BCRYPT && !USE_YESCRYPT */ + "c:bhr", +-#endif /* USE_SHA_CRYPT || USE_BCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ + #else /* USE_PAM */ + "bhr", + #endif +@@ -665,40 +678,36 @@ static void process_flags (int argc, cha + case 'R': /* no-op, handled in process_root_flag () */ + break; + #ifndef USE_PAM +-#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) + case 's': + sflg = true; ++ bad_s = 0; ++#if defined(USE_SHA_CRYPT) + if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512"))) +- && (0 == getlong(optarg, &sha_rounds))) +- || ( (0 == strcmp (crypt_method, "BCRYPT")) ++ && (0 == getlong(optarg, &sha_rounds)))) { ++ bad_s = 1; ++ } ++#endif /* USE_SHA_CRYPT */ ++#if defined(USE_BCRYPT) ++ if (( (0 == strcmp (crypt_method, "BCRYPT")) + && (0 == getlong(optarg, &bcrypt_rounds)))) { ++ bad_s = 1; ++ } ++#endif /* USE_BCRYPT */ ++#if defined(USE_YESCRYPT) ++ if (( (0 == strcmp (crypt_method, "YESCRYPT")) ++ && (0 == getlong(optarg, &yescrypt_cost)))) { ++ bad_s = 1; ++ } ++#endif /* USE_YESCRYPT */ ++ if (bad_s != 0) { + fprintf (stderr, + _("%s: invalid numeric argument '%s'\n"), + Prog, optarg); + usage (EXIT_FAILURE); + } + break; +-#elif defined(USE_SHA_CRYPT) +- case 's': +- sflg = true; +- if (0 == getlong(optarg, &sha_rounds)) { +- fprintf (stderr, +- _("%s: invalid numeric argument '%s'\n"), +- Prog, optarg); +- usage (EXIT_FAILURE); +- } +- break; +-#elif defined(USE_BCRYPT) +- case 's': +- sflg = true; +- if (0 == getlong(optarg, &bcrypt_rounds)) { +- fprintf (stderr, +- _("%s: invalid numeric argument '%s'\n"), +- Prog, optarg); +- usage (EXIT_FAILURE); +- } +- break; +-#endif ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ + #endif /* !USE_PAM */ + default: + usage (EXIT_FAILURE); +@@ -732,14 +741,14 @@ static void process_flags (int argc, cha + static void check_flags (void) + { + #ifndef USE_PAM +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) + if (sflg && !cflg) { + fprintf (stderr, + _("%s: %s flag is only allowed with the %s flag\n"), + Prog, "-s", "-c"); + usage (EXIT_FAILURE); + } +-#endif ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ + + if (cflg) { + if ( (0 != strcmp (crypt_method, "DES")) +@@ -752,6 +761,9 @@ static void check_flags (void) + #ifdef USE_BCRYPT + && (0 != strcmp (crypt_method, "BCRYPT")) + #endif /* USE_BCRYPT */ ++#ifdef USE_YESCRYPT ++ && (0 != strcmp (crypt_method, "YESCRYPT")) ++#endif /* USE_YESCRYPT */ + ) { + fprintf (stderr, + _("%s: unsupported crypt method: %s\n"), +Index: shadow-4.8.1/src/passwd.c +=================================================================== +--- shadow-4.8.1.orig/src/passwd.c ++++ shadow-4.8.1/src/passwd.c +@@ -283,7 +283,10 @@ static int new_password (const struct pa + #endif /* USE_SHA_CRYPT */ + #ifdef USE_BCRYPT + || (strcmp (method, "BCRYPT") == 0) +-#endif /* USE_SHA_CRYPT */ ++#endif /* USE_BCRYPT*/ ++#ifdef USE_YESCRYPT ++ || (strcmp (method, "YESCRYPT") == 0) ++#endif /* USE_YESCRYPT*/ + + ) { + pass_max_len = -1; diff --git a/shadow-utils.login.defs b/shadow-utils.login.defs index 7f1c0e4..67845ce 100644 --- a/shadow-utils.login.defs +++ b/shadow-utils.login.defs @@ -198,10 +198,11 @@ SUB_GID_COUNT 65536 # If set to MD5, MD5-based algorithm will be used for encrypting password # If set to SHA256, SHA256-based algorithm will be used for encrypting password # If set to SHA512, SHA512-based algorithm will be used for encrypting password -# If set to BLOWFISH, BLOWFISH-based algorithm will be used for encrypting password +# If set to BCRYPT, BCRYPT-based algorithm will be used for encrypting password +# If set to YESCRYPT, YESCRYPT-based algorithm will be used for encrypting password # If set to DES, DES-based algorithm will be used for encrypting password (default) # -ENCRYPT_METHOD SHA512 +ENCRYPT_METHOD YESCRYPT # # Only works if ENCRYPT_METHOD is set to SHA256 or SHA512. @@ -220,6 +221,19 @@ ENCRYPT_METHOD SHA512 # Currently BCRYPT_MIN_ROUNDS and BCRYPT_MAX_ROUNDS are not supported +# +# Only works if ENCRYPT_METHOD is set to YESCRYPT. +# +# Define the YESCRYPT cost factor. +# With a higher cost factor, it is more difficult to brute-force the password. +# However, more CPU time and more memory will be needed to authenticate users +# if this value is increased. +# +# If not specified, a cost factor of 5 will be used. +# The value must be within the 1-11 range. +# +#YESCRYPT_COST_FACTOR 5 + # Currently CONSOLE_GROUPS is not supported # diff --git a/shadow-utils.spec b/shadow-utils.spec index 164c0d7..5511d03 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.8.1 -Release: 11%{?dist} +Release: 12%{?dist} Epoch: 2 URL: https://github.com/shadow-maint/shadow Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -95,6 +95,8 @@ Patch55: shadow-4.8.1-libsubid_fix_newusers_nss_provides_subids.patch Patch56: shadow-4.8.1-man_clarify_subid_delegation.patch # https://github.com/shadow-maint/shadow/commit/bd920ab36a6c641e4a8769f8c7f8ca738ec61820 Patch57: shadow-4.8.1-libsubid_make_logfd_not_extern.patch +# https://github.com/shadow-maint/shadow/commit/5cd04d03f94622c12220d4a6352824af081b8531 +Patch58: shadow-4.8.1-yescrypt-support.patch License: BSD and GPLv2+ BuildRequires: make @@ -177,6 +179,7 @@ Development files for shadow-utils-subid. %patch55 -p1 -b .libsubid_fix_newusers_nss_provides_subids %patch56 -p1 -b .man_clarify_subid_delegation %patch57 -p1 -b .libsubid_make_logfd_not_extern +%patch58 -p1 -b .yescrypt iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -203,6 +206,7 @@ autoreconf --enable-man \ --with-audit \ --with-sha-crypt \ + --with-yescrypt \ --with-selinux \ --without-libcrack \ --without-libpam \ @@ -345,6 +349,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la %{_libdir}/libsubid.so %changelog +* Mon Jun 21 2021 Björn Esser - 2:4.8.1-12 +- Backport support for yescrypt hash method + * Mon Jun 21 2021 Iker Pedrosa - 2:4.8.1-11 - libsubid: don't print error messages on stderr by default - libsubid: libsubid_init return false if out of memory From 0946f2a3b0a425180b61fceda0d763b55baf9949 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= Date: Mon, 21 Jun 2021 14:49:14 +0200 Subject: [PATCH 032/134] Add a patch to fix the parameter type of YESCRYPT_salt_cost() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Esser --- ....1-fix_YESCRYPT_salt_cost_param_type.patch | 39 +++++++++++++++++++ shadow-utils.spec | 4 ++ 2 files changed, 43 insertions(+) create mode 100644 shadow-4.8.1-fix_YESCRYPT_salt_cost_param_type.patch diff --git a/shadow-4.8.1-fix_YESCRYPT_salt_cost_param_type.patch b/shadow-4.8.1-fix_YESCRYPT_salt_cost_param_type.patch new file mode 100644 index 0000000..a3aadd2 --- /dev/null +++ b/shadow-4.8.1-fix_YESCRYPT_salt_cost_param_type.patch @@ -0,0 +1,39 @@ +From 8d987bc55ccb65a3ef3a541cc5e351cfcbef0c90 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= +Date: Sat, 12 Jun 2021 19:05:07 +0200 +Subject: [PATCH] libmisc/salt.c: Use int pointer for YESCRYPT_salt_cost(). +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The corresponding functions for the other hash methods all take +a pointer to an integer value as the only paramater, so this +particular function should do so as well. + +Signed-off-by: Björn Esser +--- + libmisc/salt.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libmisc/salt.c b/libmisc/salt.c +index c35c6797..1bfa015b 100644 +--- a/libmisc/salt.c ++++ b/libmisc/salt.c +@@ -34,7 +34,7 @@ static /*@observer@*/const char *BCRYPT_salt_rounds (/*@null@*/int *prefered_rou + #endif /* USE_BCRYPT */ + #ifdef USE_YESCRYPT + static /*@observer@*/const char *gensalt_yescrypt (void); +-static /*@observer@*/const char *YESCRYPT_salt_cost (/*@null@*/long *prefered_rounds); ++static /*@observer@*/const char *YESCRYPT_salt_cost (/*@null@*/int *prefered_cost); + #endif /* USE_YESCRYPT */ + + #ifndef HAVE_L64A +@@ -277,7 +277,7 @@ static /*@observer@*/const char *gensalt_bcrypt (void) + /* + * Return a salt prefix specifying the cost for the YESCRYPT method. + */ +-static /*@observer@*/const char *YESCRYPT_salt_cost (/*@null@*/long *prefered_cost) ++static /*@observer@*/const char *YESCRYPT_salt_cost (/*@null@*/int *prefered_cost) + { + static char cost_prefix[5]; + long cost; diff --git a/shadow-utils.spec b/shadow-utils.spec index 5511d03..0f8a51e 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -97,6 +97,8 @@ Patch56: shadow-4.8.1-man_clarify_subid_delegation.patch Patch57: shadow-4.8.1-libsubid_make_logfd_not_extern.patch # https://github.com/shadow-maint/shadow/commit/5cd04d03f94622c12220d4a6352824af081b8531 Patch58: shadow-4.8.1-yescrypt-support.patch +# https://github.com/shadow-maint/shadow/pull/358 +Patch59: shadow-4.8.1-fix_YESCRYPT_salt_cost_param_type.patch License: BSD and GPLv2+ BuildRequires: make @@ -180,6 +182,7 @@ Development files for shadow-utils-subid. %patch56 -p1 -b .man_clarify_subid_delegation %patch57 -p1 -b .libsubid_make_logfd_not_extern %patch58 -p1 -b .yescrypt +%patch59 -p1 -b .YESCRYPT_salt_cost_param_type iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -351,6 +354,7 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la %changelog * Mon Jun 21 2021 Björn Esser - 2:4.8.1-12 - Backport support for yescrypt hash method +- Add a patch to fix the parameter type of YESCRYPT_salt_cost() * Mon Jun 21 2021 Iker Pedrosa - 2:4.8.1-11 - libsubid: don't print error messages on stderr by default From e967948ce81e6d64b718d32ead16ece478536b27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= Date: Tue, 22 Jun 2021 21:59:30 +0200 Subject: [PATCH 033/134] Reference actual upstream commit for Patch59 --- shadow-utils.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index 0f8a51e..2817429 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -97,7 +97,7 @@ Patch56: shadow-4.8.1-man_clarify_subid_delegation.patch Patch57: shadow-4.8.1-libsubid_make_logfd_not_extern.patch # https://github.com/shadow-maint/shadow/commit/5cd04d03f94622c12220d4a6352824af081b8531 Patch58: shadow-4.8.1-yescrypt-support.patch -# https://github.com/shadow-maint/shadow/pull/358 +# https://github.com/shadow-maint/shadow/commit/7a3bb4d0ea8166acc539c788a8ce943acf4a6aa7 Patch59: shadow-4.8.1-fix_YESCRYPT_salt_cost_param_type.patch License: BSD and GPLv2+ From c5fd8d4a0a703f07b39e23909e7e5a4b4ef30592 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Mon, 28 Jun 2021 10:53:45 +0200 Subject: [PATCH 034/134] Covscan fixes --- shadow-4.8.1-covscan_fixes.patch | 802 +++++++++++++++++++++++++++++++ shadow-utils.spec | 13 +- 2 files changed, 814 insertions(+), 1 deletion(-) create mode 100644 shadow-4.8.1-covscan_fixes.patch diff --git a/shadow-4.8.1-covscan_fixes.patch b/shadow-4.8.1-covscan_fixes.patch new file mode 100644 index 0000000..ea78ced --- /dev/null +++ b/shadow-4.8.1-covscan_fixes.patch @@ -0,0 +1,802 @@ +From fd9d79a1a3438ba7703939cfcd45fc266782c64e Mon Sep 17 00:00:00 2001 +From: whzhe +Date: Thu, 17 Dec 2020 03:27:15 -0500 +Subject: [PATCH] useradd.c:fix memleak in get_groups + +Signed-off-by: whzhe +--- + src/useradd.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/useradd.c b/src/useradd.c +index 107e65f8..822b67f5 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -793,6 +793,7 @@ static int get_groups (char *list) + fprintf (stderr, + _("%s: group '%s' is a NIS group.\n"), + Prog, grp->gr_name); ++ gr_free(grp); + continue; + } + #endif +@@ -801,6 +802,7 @@ static int get_groups (char *list) + fprintf (stderr, + _("%s: too many groups specified (max %d).\n"), + Prog, ngroups); ++ gr_free(grp); + break; + } + +@@ -808,6 +810,7 @@ static int get_groups (char *list) + * Add the group name to the user's list of groups. + */ + user_groups[ngroups++] = xstrdup (grp->gr_name); ++ gr_free (grp); + } while (NULL != list); + + close_group_files (); +-- +2.31.1 + +From c44b71cec25d60efc51aec9de3abce1f6efbfcf5 Mon Sep 17 00:00:00 2001 +From: whzhe51 +Date: Sat, 19 Dec 2020 04:29:06 -0500 +Subject: [PATCH] useradd.c:fix memleaks of grp Signed-off-by: whzhe51 + + +--- + src/useradd.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/useradd.c b/src/useradd.c +index 107e65f8..29c54e44 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -411,6 +411,7 @@ static void get_defaults (void) + } else { + def_group = grp->gr_gid; + def_gname = xstrdup (grp->gr_name); ++ gr_free(grp); + } + } + +-- +2.31.1 + +From 1aed7ae945aafaeb253fc89a7ecedeaedf72654e Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Thu, 10 Jun 2021 13:05:03 +0200 +Subject: [PATCH] useradd.c: fix covscan RESOURCE_LEAK + +Error: RESOURCE_LEAK (CWE-772): [#def28] +shadow-4.8.1/src/useradd.c:1905: open_fn: Returning handle opened by "open". [Note: The source code implementation of the function has been overridden by a user model.] +shadow-4.8.1/src/useradd.c:1905: var_assign: Assigning: "fd" = handle returned from "open("/var/log/faillog", 2)". +shadow-4.8.1/src/useradd.c:1906: noescape: Resource "fd" is not freed or pointed-to in "lseek". +shadow-4.8.1/src/useradd.c:1917: leaked_handle: Handle variable "fd" going out of scope leaks the handle. + 1915| /* continue */ + 1916| } + 1917|-> } + 1918| + 1919| static void lastlog_reset (uid_t uid) + +Error: RESOURCE_LEAK (CWE-772): [#def29] +shadow-4.8.1/src/useradd.c:1938: open_fn: Returning handle opened by "open". [Note: The source code implementation of the function has been overridden by a user model.] +shadow-4.8.1/src/useradd.c:1938: var_assign: Assigning: "fd" = handle returned from "open("/var/log/lastlog", 2)". +shadow-4.8.1/src/useradd.c:1939: noescape: Resource "fd" is not freed or pointed-to in "lseek". +shadow-4.8.1/src/useradd.c:1950: leaked_handle: Handle variable "fd" going out of scope leaks the handle. + 1948| /* continue */ + 1949| } + 1950|-> } + 1951| + 1952| static void tallylog_reset (const char *user_name) + +Error: RESOURCE_LEAK (CWE-772): [#def30] +shadow-4.8.1/src/useradd.c:2109: alloc_fn: Storage is returned from allocation function "strdup". +shadow-4.8.1/src/useradd.c:2109: var_assign: Assigning: "bhome" = storage returned from "strdup(prefix_user_home)". +shadow-4.8.1/src/useradd.c:2131: noescape: Resource "bhome" is not freed or pointed-to in "strtok". +shadow-4.8.1/src/useradd.c:2207: leaked_storage: Variable "bhome" going out of scope leaks the storage it points to. + 2205| } + 2206| #endif + 2207|-> } + 2208| } + 2209| +--- + src/useradd.c | 41 ++++++++++++++++++++++++++++++++--------- + 1 file changed, 32 insertions(+), 9 deletions(-) + +diff --git a/src/useradd.c b/src/useradd.c +index 4248b62c..127177e2 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -1964,16 +1964,26 @@ static void faillog_reset (uid_t uid) + memzero (&fl, sizeof (fl)); + + fd = open (FAILLOG_FILE, O_RDWR); +- if ( (-1 == fd) +- || (lseek (fd, offset_uid, SEEK_SET) != offset_uid) ++ if (-1 == fd) { ++ fprintf (stderr, ++ _("%s: failed to open the faillog file for UID %lu: %s\n"), ++ Prog, (unsigned long) uid, strerror (errno)); ++ SYSLOG ((LOG_WARN, "failed to open the faillog file for UID %lu", (unsigned long) uid)); ++ return; ++ } ++ if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid) + || (write (fd, &fl, sizeof (fl)) != (ssize_t) sizeof (fl)) +- || (fsync (fd) != 0) +- || (close (fd) != 0)) { ++ || (fsync (fd) != 0)) { + fprintf (stderr, + _("%s: failed to reset the faillog entry of UID %lu: %s\n"), + Prog, (unsigned long) uid, strerror (errno)); + SYSLOG ((LOG_WARN, "failed to reset the faillog entry of UID %lu", (unsigned long) uid)); +- /* continue */ ++ } ++ if (close (fd) != 0) { ++ fprintf (stderr, ++ _("%s: failed to close the faillog file for UID %lu: %s\n"), ++ Prog, (unsigned long) uid, strerror (errno)); ++ SYSLOG ((LOG_WARN, "failed to close the faillog file for UID %lu", (unsigned long) uid)); + } + } + +@@ -1997,17 +2007,29 @@ static void lastlog_reset (uid_t uid) + memzero (&ll, sizeof (ll)); + + fd = open (LASTLOG_FILE, O_RDWR); +- if ( (-1 == fd) +- || (lseek (fd, offset_uid, SEEK_SET) != offset_uid) ++ if (-1 == fd) { ++ fprintf (stderr, ++ _("%s: failed to open the lastlog file for UID %lu: %s\n"), ++ Prog, (unsigned long) uid, strerror (errno)); ++ SYSLOG ((LOG_WARN, "failed to open the lastlog file for UID %lu", (unsigned long) uid)); ++ return; ++ } ++ if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid) + || (write (fd, &ll, sizeof (ll)) != (ssize_t) sizeof (ll)) +- || (fsync (fd) != 0) +- || (close (fd) != 0)) { ++ || (fsync (fd) != 0)) { + fprintf (stderr, + _("%s: failed to reset the lastlog entry of UID %lu: %s\n"), + Prog, (unsigned long) uid, strerror (errno)); + SYSLOG ((LOG_WARN, "failed to reset the lastlog entry of UID %lu", (unsigned long) uid)); + /* continue */ + } ++ if (close (fd) != 0) { ++ fprintf (stderr, ++ _("%s: failed to close the lastlog file for UID %lu: %s\n"), ++ Prog, (unsigned long) uid, strerror (errno)); ++ SYSLOG ((LOG_WARN, "failed to close the lastlog file for UID %lu", (unsigned long) uid)); ++ /* continue */ ++ } + } + + static void tallylog_reset (const char *user_name) +@@ -2254,6 +2276,7 @@ static void create_home (void) + } + cp = strtok (NULL, "/"); + } ++ free (bhome); + + (void) chown (prefix_user_home, user_id, user_gid); + mode_t mode = getdef_num ("HOME_MODE", +-- +2.31.1 + +From 8281c82e324b57b3a4b520afad26b43ce128d521 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Fri, 11 Jun 2021 11:50:49 +0200 +Subject: [PATCH] usermod.c: fix covscan RESOURCE_LEAK + +Error: RESOURCE_LEAK (CWE-772): [#def31] +shadow-4.8.1/src/usermod.c:813: alloc_fn: Storage is returned from allocation function "__gr_dup". +shadow-4.8.1/src/usermod.c:813: var_assign: Assigning: "ngrp" = storage returned from "__gr_dup(grp)". +shadow-4.8.1/src/usermod.c:892: leaked_storage: Variable "ngrp" going out of scope leaks the storage it points to. + 890| } + 891| } + 892|-> } + 893| + 894| #ifdef SHADOWGRP + +Error: RESOURCE_LEAK (CWE-772): [#def32] +shadow-4.8.1/src/usermod.c:933: alloc_fn: Storage is returned from allocation function "__sgr_dup". +shadow-4.8.1/src/usermod.c:933: var_assign: Assigning: "nsgrp" = storage returned from "__sgr_dup(sgrp)". +shadow-4.8.1/src/usermod.c:1031: leaked_storage: Variable "nsgrp" going out of scope leaks the storage it points to. + 1029| } + 1030| } + 1031|-> } + 1032| #endif /* SHADOWGRP */ + 1033| + +Error: RESOURCE_LEAK (CWE-772): [#def34] +shadow-4.8.1/src/usermod.c:1161: alloc_fn: Storage is returned from allocation function "getgr_nam_gid". +shadow-4.8.1/src/usermod.c:1161: var_assign: Assigning: "grp" = storage returned from "getgr_nam_gid(optarg)". +shadow-4.8.1/src/usermod.c:1495: leaked_storage: Variable "grp" going out of scope leaks the storage it points to. + 1493| } + 1494| #endif /* ENABLE_SUBIDS */ + 1495|-> } + 1496| + 1497| /* + +Error: RESOURCE_LEAK (CWE-772): [#def35] +shadow-4.8.1/src/usermod.c:1991: open_fn: Returning handle opened by "open". [Note: The source code implementation of the function has been overridden by a user model.] +shadow-4.8.1/src/usermod.c:1991: var_assign: Assigning: "fd" = handle returned from "open("/var/log/lastlog", 2)". +shadow-4.8.1/src/usermod.c:2000: noescape: Resource "fd" is not freed or pointed-to in "lseek". +shadow-4.8.1/src/usermod.c:2000: noescape: Resource "fd" is not freed or pointed-to in "read". [Note: The source code implementation of the function has been overridden by a builtin model.] +shadow-4.8.1/src/usermod.c:2003: noescape: Resource "fd" is not freed or pointed-to in "lseek". +shadow-4.8.1/src/usermod.c:2032: leaked_handle: Handle variable "fd" going out of scope leaks the handle. + 2030| } + 2031| } + 2032|-> } + 2033| + 2034| /* + +Error: RESOURCE_LEAK (CWE-772): [#def36] +shadow-4.8.1/src/usermod.c:2052: open_fn: Returning handle opened by "open". [Note: The source code implementation of the function has been overridden by a user model.] +shadow-4.8.1/src/usermod.c:2052: var_assign: Assigning: "fd" = handle returned from "open("/var/log/faillog", 2)". +shadow-4.8.1/src/usermod.c:2061: noescape: Resource "fd" is not freed or pointed-to in "lseek". +shadow-4.8.1/src/usermod.c:2061: noescape: Resource "fd" is not freed or pointed-to in "read". [Note: The source code implementation of the function has been overridden by a builtin model.] +shadow-4.8.1/src/usermod.c:2064: noescape: Resource "fd" is not freed or pointed-to in "lseek". +shadow-4.8.1/src/usermod.c:2092: leaked_handle: Handle variable "fd" going out of scope leaks the handle. + 2090| } + 2091| } + 2092|-> } + 2093| + 2094| #ifndef NO_MOVE_MAILBOX +--- + src/usermod.c | 25 +++++++++++++------------ + 1 file changed, 13 insertions(+), 12 deletions(-) + +diff --git a/src/usermod.c b/src/usermod.c +index 7870ba57..03bb9b9d 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -871,6 +871,8 @@ static void update_group (void) + SYSLOG ((LOG_WARN, "failed to prepare the new %s entry '%s'", gr_dbname (), ngrp->gr_name)); + fail_exit (E_GRP_UPDATE); + } ++ ++ gr_free(ngrp); + } + } + +@@ -1006,6 +1008,8 @@ static void update_gshadow (void) + sgr_dbname (), nsgrp->sg_name)); + fail_exit (E_GRP_UPDATE); + } ++ ++ free (nsgrp); + } + } + #endif /* SHADOWGRP */ +@@ -1152,6 +1156,7 @@ static void process_flags (int argc, char **argv) + } + user_newgid = grp->gr_gid; + gflg = true; ++ gr_free (grp); + break; + case 'G': + if (get_groups (optarg) != 0) { +@@ -1995,8 +2000,7 @@ static void update_lastlog (void) + /* Copy the old entry to its new location */ + if ( (lseek (fd, off_newuid, SEEK_SET) != off_newuid) + || (write (fd, &ll, sizeof ll) != (ssize_t) sizeof ll) +- || (fsync (fd) != 0) +- || (close (fd) != 0)) { ++ || (fsync (fd) != 0)) { + fprintf (stderr, + _("%s: failed to copy the lastlog entry of user %lu to user %lu: %s\n"), + Prog, (unsigned long) user_id, (unsigned long) user_newid, strerror (errno)); +@@ -2012,16 +2016,15 @@ static void update_lastlog (void) + memzero (&ll, sizeof (ll)); + if ( (lseek (fd, off_newuid, SEEK_SET) != off_newuid) + || (write (fd, &ll, sizeof ll) != (ssize_t) sizeof ll) +- || (fsync (fd) != 0) +- || (close (fd) != 0)) { ++ || (fsync (fd) != 0)) { + fprintf (stderr, + _("%s: failed to copy the lastlog entry of user %lu to user %lu: %s\n"), + Prog, (unsigned long) user_id, (unsigned long) user_newid, strerror (errno)); + } +- } else { +- (void) close (fd); + } + } ++ ++ (void) close (fd); + } + + /* +@@ -2056,8 +2059,7 @@ static void update_faillog (void) + /* Copy the old entry to its new location */ + if ( (lseek (fd, off_newuid, SEEK_SET) != off_newuid) + || (write (fd, &fl, sizeof fl) != (ssize_t) sizeof fl) +- || (fsync (fd) != 0) +- || (close (fd) != 0)) { ++ || (fsync (fd) != 0)) { + fprintf (stderr, + _("%s: failed to copy the faillog entry of user %lu to user %lu: %s\n"), + Prog, (unsigned long) user_id, (unsigned long) user_newid, strerror (errno)); +@@ -2072,16 +2074,15 @@ static void update_faillog (void) + /* Reset the new uid's faillog entry */ + memzero (&fl, sizeof (fl)); + if ( (lseek (fd, off_newuid, SEEK_SET) != off_newuid) +- || (write (fd, &fl, sizeof fl) != (ssize_t) sizeof fl) +- || (close (fd) != 0)) { ++ || (write (fd, &fl, sizeof fl) != (ssize_t) sizeof fl)) { + fprintf (stderr, + _("%s: failed to copy the faillog entry of user %lu to user %lu: %s\n"), + Prog, (unsigned long) user_id, (unsigned long) user_newid, strerror (errno)); + } +- } else { +- (void) close (fd); + } + } ++ ++ (void) close (fd); + } + + #ifndef NO_MOVE_MAILBOX +-- +2.31.1 + +From 5d0d7841971cc53d9a9d1aefe12f00204115bf6a Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Wed, 16 Jun 2021 09:50:53 +0200 +Subject: [PATCH] Fix covscan BUFFER_SIZE + +Error: BUFFER_SIZE (CWE-170): [#def6] +shadow-4.8.1/libmisc/failure.c:101: buffer_size_warning: Calling "strncpy" with a maximum size argument of 12 bytes on destination array "fl->fail_line" of size 12 bytes might leave the destination string unterminated. + 99| } + 100| + 101|-> strncpy (fl->fail_line, tty, sizeof fl->fail_line); + 102| (void) time (&fl->fail_time); + 103| + +Error: BUFFER_SIZE (CWE-170): [#def9] +shadow-4.8.1/libmisc/log.c:103: buffer_size_warning: Calling "strncpy" with a maximum size argument of 32 bytes on destination array "newlog.ll_line" of size 32 bytes might leave the destination string unterminated. + 101| (void) time (&ll_time); + 102| newlog.ll_time = ll_time; + 103|-> strncpy (newlog.ll_line, line, sizeof newlog.ll_line); + 104| #if HAVE_LL_HOST + 105| strncpy (newlog.ll_host, host, sizeof newlog.ll_host); + +Error: BUFFER_SIZE (CWE-170): [#def10] +shadow-4.8.1/libmisc/log.c:105: buffer_size_warning: Calling "strncpy" with a maximum size argument of 256 bytes on destination array "newlog.ll_host" of size 256 bytes might leave the destination string unterminated. + 103| strncpy (newlog.ll_line, line, sizeof newlog.ll_line); + 104| #if HAVE_LL_HOST + 105|-> strncpy (newlog.ll_host, host, sizeof newlog.ll_host); + 106| #endif + 107| if ( (lseek (fd, offset, SEEK_SET) != offset) + +Error: BUFFER_SIZE (CWE-170): [#def13] +shadow-4.8.1/libmisc/utmp.c:260: buffer_size_warning: Calling "strncpy" with a maximum size argument of 32 bytes on destination array "utent->ut_line" of size 32 bytes might leave the destination string unterminated. + 258| #endif /* HAVE_STRUCT_UTMP_UT_TYPE */ + 259| utent->ut_pid = getpid (); + 260|-> strncpy (utent->ut_line, line, sizeof (utent->ut_line)); + 261| #ifdef HAVE_STRUCT_UTMP_UT_ID + 262| if (NULL != ut) { + +Error: BUFFER_SIZE (CWE-170): [#def14] +shadow-4.8.1/libmisc/utmp.c:266: buffer_size_warning: Calling "strncpy" with a maximum size argument of 4 bytes on destination array "utent->ut_id" of size 4 bytes might leave the destination string unterminated. + 264| } else { + 265| /* XXX - assumes /dev/tty?? */ + 266|-> strncpy (utent->ut_id, line + 3, sizeof (utent->ut_id)); + 267| } + 268| #endif /* HAVE_STRUCT_UTMP_UT_ID */ + +Error: BUFFER_SIZE (CWE-170): [#def15] +shadow-4.8.1/libmisc/utmp.c:273: buffer_size_warning: Calling "strncpy" with a maximum size argument of 32 bytes on destination array "utent->ut_user" of size 32 bytes might leave the destination string unterminated. + 271| #endif /* HAVE_STRUCT_UTMP_UT_NAME */ + 272| #ifdef HAVE_STRUCT_UTMP_UT_USER + 273|-> strncpy (utent->ut_user, name, sizeof (utent->ut_user)); + 274| #endif /* HAVE_STRUCT_UTMP_UT_USER */ + 275| if (NULL != hostname) { + +Error: BUFFER_SIZE (CWE-170): [#def16] +shadow-4.8.1/libmisc/utmp.c:278: buffer_size_warning: Calling "strncpy" with a maximum size argument of 256 bytes on destination array "utent->ut_host" of size 256 bytes might leave the destination string unterminated. + 276| struct addrinfo *info = NULL; + 277| #ifdef HAVE_STRUCT_UTMP_UT_HOST + 278|-> strncpy (utent->ut_host, hostname, sizeof (utent->ut_host)); + 279| #endif /* HAVE_STRUCT_UTMP_UT_HOST */ + 280| #ifdef HAVE_STRUCT_UTMP_UT_SYSLEN + +Signed-off-by: Iker Pedrosa +--- + libmisc/failure.c | 2 +- + libmisc/log.c | 4 ++-- + libmisc/utmp.c | 8 ++++---- + 3 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/libmisc/failure.c b/libmisc/failure.c +index f6390a79..a1f3ec79 100644 +--- a/libmisc/failure.c ++++ b/libmisc/failure.c +@@ -98,7 +98,7 @@ void failure (uid_t uid, const char *tty, struct faillog *fl) + fl->fail_cnt++; + } + +- strncpy (fl->fail_line, tty, sizeof fl->fail_line); ++ strncpy (fl->fail_line, tty, sizeof (fl->fail_line) - 1); + (void) time (&fl->fail_time); + + /* +diff --git a/libmisc/log.c b/libmisc/log.c +index eb84859e..68a9d7e2 100644 +--- a/libmisc/log.c ++++ b/libmisc/log.c +@@ -100,9 +100,9 @@ void dolastlog ( + ll_time = newlog.ll_time; + (void) time (&ll_time); + newlog.ll_time = ll_time; +- strncpy (newlog.ll_line, line, sizeof newlog.ll_line); ++ strncpy (newlog.ll_line, line, sizeof (newlog.ll_line) - 1); + #if HAVE_LL_HOST +- strncpy (newlog.ll_host, host, sizeof newlog.ll_host); ++ strncpy (newlog.ll_host, host, sizeof (newlog.ll_host) - 1); + #endif + if ( (lseek (fd, offset, SEEK_SET) != offset) + || (write (fd, (const void *) &newlog, sizeof newlog) != (ssize_t) sizeof newlog) +diff --git a/libmisc/utmp.c b/libmisc/utmp.c +index ba69cf61..5dcd419f 100644 +--- a/libmisc/utmp.c ++++ b/libmisc/utmp.c +@@ -257,25 +257,25 @@ static void updwtmpx (const char *filename, const struct utmpx *utx) + utent->ut_type = USER_PROCESS; + #endif /* HAVE_STRUCT_UTMP_UT_TYPE */ + utent->ut_pid = getpid (); +- strncpy (utent->ut_line, line, sizeof (utent->ut_line)); ++ strncpy (utent->ut_line, line, sizeof (utent->ut_line) - 1); + #ifdef HAVE_STRUCT_UTMP_UT_ID + if (NULL != ut) { + strncpy (utent->ut_id, ut->ut_id, sizeof (utent->ut_id)); + } else { + /* XXX - assumes /dev/tty?? */ +- strncpy (utent->ut_id, line + 3, sizeof (utent->ut_id)); ++ strncpy (utent->ut_id, line + 3, sizeof (utent->ut_id) - 1); + } + #endif /* HAVE_STRUCT_UTMP_UT_ID */ + #ifdef HAVE_STRUCT_UTMP_UT_NAME + strncpy (utent->ut_name, name, sizeof (utent->ut_name)); + #endif /* HAVE_STRUCT_UTMP_UT_NAME */ + #ifdef HAVE_STRUCT_UTMP_UT_USER +- strncpy (utent->ut_user, name, sizeof (utent->ut_user)); ++ strncpy (utent->ut_user, name, sizeof (utent->ut_user) - 1); + #endif /* HAVE_STRUCT_UTMP_UT_USER */ + if (NULL != hostname) { + struct addrinfo *info = NULL; + #ifdef HAVE_STRUCT_UTMP_UT_HOST +- strncpy (utent->ut_host, hostname, sizeof (utent->ut_host)); ++ strncpy (utent->ut_host, hostname, sizeof (utent->ut_host) - 1); + #endif /* HAVE_STRUCT_UTMP_UT_HOST */ + #ifdef HAVE_STRUCT_UTMP_UT_SYSLEN + utent->ut_syslen = MIN (strlen (hostname), +-- +2.31.1 + +From e65cc6aebcb4132fa413f00a905216a5b35b3d57 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Mon, 14 Jun 2021 12:39:48 +0200 +Subject: [PATCH] Fix covscan RESOURCE_LEAK + +Error: RESOURCE_LEAK (CWE-772): [#def1] +shadow-4.8.1/lib/commonio.c:320: alloc_fn: Storage is returned from allocation function "fopen_set_perms". +shadow-4.8.1/lib/commonio.c:320: var_assign: Assigning: "bkfp" = storage returned from "fopen_set_perms(backup, "w", &sb)". +shadow-4.8.1/lib/commonio.c:329: noescape: Resource "bkfp" is not freed or pointed-to in "putc". +shadow-4.8.1/lib/commonio.c:334: noescape: Resource "bkfp" is not freed or pointed-to in "fflush". +shadow-4.8.1/lib/commonio.c:339: noescape: Resource "bkfp" is not freed or pointed-to in "fileno". +shadow-4.8.1/lib/commonio.c:342: leaked_storage: Variable "bkfp" going out of scope leaks the storage it points to. + 340| || (fclose (bkfp) != 0)) { + 341| /* FIXME: unlink the backup file? */ + 342|-> return -1; + 343| } + 344| + +Error: RESOURCE_LEAK (CWE-772): [#def2] +shadow-4.8.1/libmisc/addgrps.c:69: alloc_fn: Storage is returned from allocation function "malloc". +shadow-4.8.1/libmisc/addgrps.c:69: var_assign: Assigning: "grouplist" = storage returned from "malloc(i * 4UL)". +shadow-4.8.1/libmisc/addgrps.c:73: noescape: Resource "grouplist" is not freed or pointed-to in "getgroups". [Note: The source code implementation of the function has been overridden by a builtin model.] +shadow-4.8.1/libmisc/addgrps.c:126: leaked_storage: Variable "grouplist" going out of scope leaks the storage it points to. + 124| } + 125| + 126|-> return 0; + 127| } + 128| #else /* HAVE_SETGROUPS && !USE_PAM */ + +Error: RESOURCE_LEAK (CWE-772): [#def3] +shadow-4.8.1/libmisc/chowntty.c:62: alloc_fn: Storage is returned from allocation function "getgr_nam_gid". +shadow-4.8.1/libmisc/chowntty.c:62: var_assign: Assigning: "grent" = storage returned from "getgr_nam_gid(getdef_str("TTYGROUP"))". +shadow-4.8.1/libmisc/chowntty.c:98: leaked_storage: Variable "grent" going out of scope leaks the storage it points to. + 96| */ + 97| #endif + 98|-> } + 99| + +Error: RESOURCE_LEAK (CWE-772): [#def4] +shadow-4.8.1/libmisc/copydir.c:742: open_fn: Returning handle opened by "open". [Note: The source code implementation of the function has been overridden by a user model.] +shadow-4.8.1/libmisc/copydir.c:742: var_assign: Assigning: "ifd" = handle returned from "open(src, 0)". +shadow-4.8.1/libmisc/copydir.c:748: leaked_handle: Handle variable "ifd" going out of scope leaks the handle. + 746| #ifdef WITH_SELINUX + 747| if (set_selinux_file_context (dst, NULL) != 0) { + 748|-> return -1; + 749| } + 750| #endif /* WITH_SELINUX */ + +Error: RESOURCE_LEAK (CWE-772): [#def5] +shadow-4.8.1/libmisc/copydir.c:751: open_fn: Returning handle opened by "open". [Note: The source code implementation of the function has been overridden by a user model.] +shadow-4.8.1/libmisc/copydir.c:751: var_assign: Assigning: "ofd" = handle returned from "open(dst, 577, statp->st_mode & 0xfffU)". +shadow-4.8.1/libmisc/copydir.c:752: noescape: Resource "ofd" is not freed or pointed-to in "fchown_if_needed". +shadow-4.8.1/libmisc/copydir.c:775: leaked_handle: Handle variable "ofd" going out of scope leaks the handle. + 773| ) { + 774| (void) close (ifd); + 775|-> return -1; + 776| } + 777| + +Error: RESOURCE_LEAK (CWE-772): [#def7] +shadow-4.8.1/libmisc/idmapping.c:188: alloc_fn: Storage is returned from allocation function "xmalloc". +shadow-4.8.1/libmisc/idmapping.c:188: var_assign: Assigning: "buf" = storage returned from "xmalloc(bufsize)". +shadow-4.8.1/libmisc/idmapping.c:188: var_assign: Assigning: "pos" = "buf". +shadow-4.8.1/libmisc/idmapping.c:213: noescape: Resource "buf" is not freed or pointed-to in "write". +shadow-4.8.1/libmisc/idmapping.c:219: leaked_storage: Variable "pos" going out of scope leaks the storage it points to. +shadow-4.8.1/libmisc/idmapping.c:219: leaked_storage: Variable "buf" going out of scope leaks the storage it points to. + 217| } + 218| close(fd); + 219|-> } + +Error: RESOURCE_LEAK (CWE-772): [#def8] +shadow-4.8.1/libmisc/list.c:211: alloc_fn: Storage is returned from allocation function "xstrdup". +shadow-4.8.1/libmisc/list.c:211: var_assign: Assigning: "members" = storage returned from "xstrdup(comma)". +shadow-4.8.1/libmisc/list.c:217: var_assign: Assigning: "cp" = "members". +shadow-4.8.1/libmisc/list.c:218: noescape: Resource "cp" is not freed or pointed-to in "strchr". +shadow-4.8.1/libmisc/list.c:244: leaked_storage: Variable "cp" going out of scope leaks the storage it points to. +shadow-4.8.1/libmisc/list.c:244: leaked_storage: Variable "members" going out of scope leaks the storage it points to. + 242| if ('\0' == *members) { + 243| *array = (char *) 0; + 244|-> return array; + 245| } + 246| + +Error: RESOURCE_LEAK (CWE-772): [#def11] +shadow-4.8.1/libmisc/myname.c:61: alloc_fn: Storage is returned from allocation function "xgetpwnam". +shadow-4.8.1/libmisc/myname.c:61: var_assign: Assigning: "pw" = storage returned from "xgetpwnam(cp)". +shadow-4.8.1/libmisc/myname.c:67: leaked_storage: Variable "pw" going out of scope leaks the storage it points to. + 65| } + 66| + 67|-> return xgetpwuid (ruid); + 68| } + 69| + +Error: RESOURCE_LEAK (CWE-772): [#def12] +shadow-4.8.1/libmisc/user_busy.c:260: alloc_fn: Storage is returned from allocation function "opendir". +shadow-4.8.1/libmisc/user_busy.c:260: var_assign: Assigning: "task_dir" = storage returned from "opendir(task_path)". +shadow-4.8.1/libmisc/user_busy.c:262: noescape: Resource "task_dir" is not freed or pointed-to in "readdir". +shadow-4.8.1/libmisc/user_busy.c:278: leaked_storage: Variable "task_dir" going out of scope leaks the storage it points to. + 276| _("%s: user %s is currently used by process %d\n"), + 277| Prog, name, pid); + 278|-> return 1; + 279| } + 280| } + +Error: RESOURCE_LEAK (CWE-772): [#def20] +shadow-4.8.1/src/newgrp.c:162: alloc_fn: Storage is returned from allocation function "xgetspnam". +shadow-4.8.1/src/newgrp.c:162: var_assign: Assigning: "spwd" = storage returned from "xgetspnam(pwd->pw_name)". +shadow-4.8.1/src/newgrp.c:234: leaked_storage: Variable "spwd" going out of scope leaks the storage it points to. + 232| } + 233| + 234|-> return; + 235| + 236| failure: + +Error: RESOURCE_LEAK (CWE-772): [#def21] +shadow-4.8.1/src/passwd.c:530: alloc_fn: Storage is returned from allocation function "xstrdup". +shadow-4.8.1/src/passwd.c:530: var_assign: Assigning: "cp" = storage returned from "xstrdup(crypt_passwd)". +shadow-4.8.1/src/passwd.c:551: noescape: Resource "cp" is not freed or pointed-to in "strlen". +shadow-4.8.1/src/passwd.c:554: noescape: Resource "cp" is not freed or pointed-to in "strcat". [Note: The source code implementation of the function has been overridden by a builtin model.] +shadow-4.8.1/src/passwd.c:555: overwrite_var: Overwriting "cp" in "cp = newpw" leaks the storage that "cp" points to. + 553| strcpy (newpw, "!"); + 554| strcat (newpw, cp); + 555|-> cp = newpw; + 556| } + 557| return cp; +--- + lib/commonio.c | 8 ++++++-- + libmisc/addgrps.c | 6 +++++- + libmisc/chowntty.c | 1 + + libmisc/copydir.c | 6 ++++++ + libmisc/idmapping.c | 1 + + libmisc/list.c | 3 +++ + libmisc/myname.c | 3 +++ + libmisc/user_busy.c | 1 + + src/newgrp.c | 3 ++- + src/passwd.c | 5 +++++ + 10 files changed, 33 insertions(+), 4 deletions(-) + +diff --git a/lib/commonio.c b/lib/commonio.c +index 23ac91f9..cef404b9 100644 +--- a/lib/commonio.c ++++ b/lib/commonio.c +@@ -336,8 +336,12 @@ static int create_backup (const char *backup, FILE * fp) + /* FIXME: unlink the backup file? */ + return -1; + } +- if ( (fsync (fileno (bkfp)) != 0) +- || (fclose (bkfp) != 0)) { ++ if (fsync (fileno (bkfp)) != 0) { ++ (void) fclose (bkfp); ++ /* FIXME: unlink the backup file? */ ++ return -1; ++ } ++ if (fclose (bkfp) != 0) { + /* FIXME: unlink the backup file? */ + return -1; + } +diff --git a/libmisc/addgrps.c b/libmisc/addgrps.c +index 2e38e340..76c172a5 100644 +--- a/libmisc/addgrps.c ++++ b/libmisc/addgrps.c +@@ -57,6 +57,7 @@ int add_groups (const char *list) + bool added; + char *token; + char buf[1024]; ++ int ret; + + if (strlen (list) >= sizeof (buf)) { + errno = EINVAL; +@@ -120,9 +121,12 @@ int add_groups (const char *list) + } + + if (added) { +- return setgroups ((size_t)ngroups, grouplist); ++ ret = setgroups ((size_t)ngroups, grouplist); ++ free (grouplist); ++ return ret; + } + ++ free (grouplist); + return 0; + } + #else /* HAVE_SETGROUPS && !USE_PAM */ +diff --git a/libmisc/chowntty.c b/libmisc/chowntty.c +index ea706c4f..a42ab622 100644 +--- a/libmisc/chowntty.c ++++ b/libmisc/chowntty.c +@@ -62,6 +62,7 @@ void chown_tty (const struct passwd *info) + grent = getgr_nam_gid (getdef_str ("TTYGROUP")); + if (NULL != grent) { + gid = grent->gr_gid; ++ gr_free (grent); + } else { + gid = info->pw_gid; + } +diff --git a/libmisc/copydir.c b/libmisc/copydir.c +index 91d391f8..015e1b68 100644 +--- a/libmisc/copydir.c ++++ b/libmisc/copydir.c +@@ -745,6 +745,7 @@ static int copy_file (const char *src, const char *dst, + } + #ifdef WITH_SELINUX + if (set_selinux_file_context (dst, NULL) != 0) { ++ (void) close (ifd); + return -1; + } + #endif /* WITH_SELINUX */ +@@ -771,12 +772,16 @@ static int copy_file (const char *src, const char *dst, + && (errno != 0)) + #endif /* WITH_ATTR */ + ) { ++ if (ofd >= 0) { ++ (void) close (ofd); ++ } + (void) close (ifd); + return -1; + } + + while ((cnt = read (ifd, buf, sizeof buf)) > 0) { + if (write (ofd, buf, (size_t)cnt) != cnt) { ++ (void) close (ofd); + (void) close (ifd); + return -1; + } +@@ -786,6 +791,7 @@ static int copy_file (const char *src, const char *dst, + + #ifdef HAVE_FUTIMES + if (futimes (ofd, mt) != 0) { ++ (void) close (ofd); + return -1; + } + #endif /* HAVE_FUTIMES */ +diff --git a/libmisc/idmapping.c b/libmisc/idmapping.c +index b0ae488c..3324f671 100644 +--- a/libmisc/idmapping.c ++++ b/libmisc/idmapping.c +@@ -241,4 +241,5 @@ void write_mapping(int proc_dir_fd, int ranges, struct map_range *mappings, + exit(EXIT_FAILURE); + } + close(fd); ++ free(buf); + } +diff --git a/libmisc/list.c b/libmisc/list.c +index 2da734a7..d85d5f20 100644 +--- a/libmisc/list.c ++++ b/libmisc/list.c +@@ -241,6 +241,7 @@ bool is_on_list (char *const *list, const char *member) + + if ('\0' == *members) { + *array = (char *) 0; ++ free (members); + return array; + } + +@@ -262,6 +263,8 @@ bool is_on_list (char *const *list, const char *member) + } + } + ++ free (members); ++ + /* + * Return the new array of pointers + */ +diff --git a/libmisc/myname.c b/libmisc/myname.c +index 05efdad3..e1b7f702 100644 +--- a/libmisc/myname.c ++++ b/libmisc/myname.c +@@ -62,6 +62,9 @@ + if ((NULL != pw) && (pw->pw_uid == ruid)) { + return pw; + } ++ if (NULL != pw) { ++ pw_free (pw); ++ } + } + + return xgetpwuid (ruid); +diff --git a/libmisc/user_busy.c b/libmisc/user_busy.c +index 4b507fe2..3deebfc3 100644 +--- a/libmisc/user_busy.c ++++ b/libmisc/user_busy.c +@@ -269,6 +269,7 @@ static int user_busy_processes (const char *name, uid_t uid) + } + if (check_status (name, task_path+6, uid) != 0) { + (void) closedir (proc); ++ (void) closedir (task_dir); + #ifdef ENABLE_SUBIDS + sub_uid_close(); + #endif +diff --git a/src/newgrp.c b/src/newgrp.c +index 2aa28b87..2b9293b4 100644 +--- a/src/newgrp.c ++++ b/src/newgrp.c +@@ -162,8 +162,9 @@ static void check_perms (const struct group *grp, + */ + spwd = xgetspnam (pwd->pw_name); + if (NULL != spwd) { +- pwd->pw_passwd = spwd->sp_pwdp; ++ pwd->pw_passwd = xstrdup (spwd->sp_pwdp); + } ++ spw_free (spwd); + + if ((pwd->pw_passwd[0] == '\0') && (grp->gr_passwd[0] != '\0')) { + needspasswd = true; +diff --git a/src/passwd.c b/src/passwd.c +index 3d4206f4..9d7df331 100644 +--- a/src/passwd.c ++++ b/src/passwd.c +@@ -553,6 +553,11 @@ static char *update_crypt_pw (char *cp) + + strcpy (newpw, "!"); + strcat (newpw, cp); ++#ifndef USE_PAM ++ if (do_update_pwd) { ++ free (cp); ++ } ++#endif /* USE_PAM */ + cp = newpw; + } + return cp; +-- +2.31.1 + diff --git a/shadow-utils.spec b/shadow-utils.spec index 2817429..bde69bc 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.8.1 -Release: 12%{?dist} +Release: 13%{?dist} Epoch: 2 URL: https://github.com/shadow-maint/shadow Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -99,6 +99,13 @@ Patch57: shadow-4.8.1-libsubid_make_logfd_not_extern.patch Patch58: shadow-4.8.1-yescrypt-support.patch # https://github.com/shadow-maint/shadow/commit/7a3bb4d0ea8166acc539c788a8ce943acf4a6aa7 Patch59: shadow-4.8.1-fix_YESCRYPT_salt_cost_param_type.patch +# https://github.com/shadow-maint/shadow/commit/c44b71cec25d60efc51aec9de3abce1f6efbfcf5 +# https://github.com/shadow-maint/shadow/commit/fd9d79a1a3438ba7703939cfcd45fc266782c64e +# https://github.com/shadow-maint/shadow/commit/8281c82e324b57b3a4b520afad26b43ce128d521 +# https://github.com/shadow-maint/shadow/commit/1aed7ae945aafaeb253fc89a7ecedeaedf72654e +# https://github.com/shadow-maint/shadow/commit/5d0d7841971cc53d9a9d1aefe12f00204115bf6a +# https://github.com/shadow-maint/shadow/commit/e65cc6aebcb4132fa413f00a905216a5b35b3d57 +Patch60: shadow-4.8.1-covscan_fixes.patch License: BSD and GPLv2+ BuildRequires: make @@ -183,6 +190,7 @@ Development files for shadow-utils-subid. %patch57 -p1 -b .libsubid_make_logfd_not_extern %patch58 -p1 -b .yescrypt %patch59 -p1 -b .YESCRYPT_salt_cost_param_type +%patch60 -p1 -b .covscan_fixes iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -352,6 +360,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la %{_libdir}/libsubid.so %changelog +* Mon Jun 28 2021 Iker Pedrosa - 2:4.8.1-13 +- Covscan fixes + * Mon Jun 21 2021 Björn Esser - 2:4.8.1-12 - Backport support for yescrypt hash method - Add a patch to fix the parameter type of YESCRYPT_salt_cost() From c0e594d3c5c5162e622a66700fbfccced5777b16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= Date: Mon, 21 Jun 2021 14:57:16 +0200 Subject: [PATCH 035/134] Add a patch to fix the used prefix for the bcrypt hash method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Esser --- shadow-4.8.1-fix_bcrypt_prefix.patch | 35 ++++++++++++++++++++++++++++ shadow-utils.spec | 8 ++++++- 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 shadow-4.8.1-fix_bcrypt_prefix.patch diff --git a/shadow-4.8.1-fix_bcrypt_prefix.patch b/shadow-4.8.1-fix_bcrypt_prefix.patch new file mode 100644 index 0000000..e8ac3bc --- /dev/null +++ b/shadow-4.8.1-fix_bcrypt_prefix.patch @@ -0,0 +1,35 @@ +From 738d92a4bd99a2038aa5f97b2fc85daa7011e403 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= +Date: Sat, 12 Jun 2021 13:54:14 +0200 +Subject: [PATCH] libmisc/salt.c: bcrypt should use $2b$ as prefix for setting. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This prefix is the recommended one for new bcrypt hashes +for a long time. + +Signed-off-by: Björn Esser +--- + libmisc/salt.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +diff --git a/libmisc/salt.c b/libmisc/salt.c +index 1bfa015b..5dc521ef 100644 +--- a/libmisc/salt.c ++++ b/libmisc/salt.c +@@ -90,12 +90,8 @@ static void seedRNG (void) + */ + #define MAGNUM(array,ch) (array)[0]=(array)[2]='$',(array)[1]=(ch),(array)[3]='\0' + #ifdef USE_BCRYPT +-/* +- * Using the Prefix $2a$ to enable an anti-collision safety measure in musl libc. +- * Negatively affects a subset of passwords containing the '\xff' character, +- * which is not valid UTF-8 (so "unlikely to cause much annoyance"). +- */ +-#define BCRYPTMAGNUM(array) (array)[0]=(array)[3]='$',(array)[1]='2',(array)[2]='a',(array)[4]='\0' ++/* Use $2b$ as prefix for compatibility with OpenBSD's bcrypt. */ ++#define BCRYPTMAGNUM(array) (array)[0]=(array)[3]='$',(array)[1]='2',(array)[2]='b',(array)[4]='\0' + #endif /* USE_BCRYPT */ + + #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) diff --git a/shadow-utils.spec b/shadow-utils.spec index bde69bc..1e1366a 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.8.1 -Release: 13%{?dist} +Release: 14%{?dist} Epoch: 2 URL: https://github.com/shadow-maint/shadow Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -106,6 +106,8 @@ Patch59: shadow-4.8.1-fix_YESCRYPT_salt_cost_param_type.patch # https://github.com/shadow-maint/shadow/commit/5d0d7841971cc53d9a9d1aefe12f00204115bf6a # https://github.com/shadow-maint/shadow/commit/e65cc6aebcb4132fa413f00a905216a5b35b3d57 Patch60: shadow-4.8.1-covscan_fixes.patch +# https://github.com/shadow-maint/shadow/commit/738d92a4bd99a2038aa5f97b2fc85daa7011e403 +Patch61: shadow-4.8.1-fix_bcrypt_prefix.patch License: BSD and GPLv2+ BuildRequires: make @@ -191,6 +193,7 @@ Development files for shadow-utils-subid. %patch58 -p1 -b .yescrypt %patch59 -p1 -b .YESCRYPT_salt_cost_param_type %patch60 -p1 -b .covscan_fixes +%patch61 -p1 -b .bcrypt_prefix iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -360,6 +363,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la %{_libdir}/libsubid.so %changelog +* Mon Jun 28 2021 Björn Esser - 2:4.8.1-14 +- Add a patch to fix the used prefix for the bcrypt hash method + * Mon Jun 28 2021 Iker Pedrosa - 2:4.8.1-13 - Covscan fixes From 2615b08c3119e52e40081724aac621c0f99cbe03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= Date: Mon, 21 Jun 2021 15:01:46 +0200 Subject: [PATCH 036/134] Add a patch to cleanup the code in libmisc/salt.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Esser --- shadow-4.8.1-salt_c_sanitize_code.patch | 555 ++++++++++++++++++++++++ shadow-utils.spec | 4 + 2 files changed, 559 insertions(+) create mode 100644 shadow-4.8.1-salt_c_sanitize_code.patch diff --git a/shadow-4.8.1-salt_c_sanitize_code.patch b/shadow-4.8.1-salt_c_sanitize_code.patch new file mode 100644 index 0000000..1ca1d3b --- /dev/null +++ b/shadow-4.8.1-salt_c_sanitize_code.patch @@ -0,0 +1,555 @@ +From 14b108728a5d55c3d478a170c39f0e2ffd4de1b0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= +Date: Mon, 14 Jun 2021 23:28:28 +0200 +Subject: [PATCH] libmisc/salt.c: Sanitize code. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +* Move all pre-processor defines to the top of the file. +* Unify the gensalt() function to be useable for all supported + hash methods. +* Drop the gensalt_{b,yes}crypt() functions in favor of the + previous change. +* Refactor the functions converting the rounds number into + a string for use with the crypt() function, to not require + any static buffer anymore. +* Clarify the comment about how crypt_make_salt() chooses the used + hash method from the settings in the login.defs file. +* Use memset() to fill static buffers with zero before using them. +* Use a fixed amount of 16 random base64-chars for the + sha{256,512}crypt hash methods, which is effectively still less + than the recommendation from NIST (>= 128 bits), but the maximum + those methods can effectively use (approx. 90 bits). +* Rename ROUNDS_{MIN,MAX} to SHA_ROUNDS_{MIN,MAX}. +* Bugfixes in the logic of setting rounds in BCRYPT_salt_rounds(). +* Likewise for YESCRYPT_salt_cost(). +* Fix formatting and white-space errors. + +Signed-off-by: Björn Esser +--- + libmisc/salt.c | 332 ++++++++++++++++++++++--------------------------- + 1 file changed, 147 insertions(+), 185 deletions(-) + +diff --git a/libmisc/salt.c b/libmisc/salt.c +index 5dc521ef..98982ed1 100644 +--- a/libmisc/salt.c ++++ b/libmisc/salt.c +@@ -12,6 +12,7 @@ + #ident "$Id$" + + #include ++#include + #include + #include + #include +@@ -19,6 +20,59 @@ + #include "defines.h" + #include "getdef.h" + ++/* Add the salt prefix. */ ++#define MAGNUM(array,ch) (array)[0]=(array)[2]='$',(array)[1]=(ch),(array)[3]='\0' ++ ++#ifdef USE_BCRYPT ++/* Use $2b$ as prefix for compatibility with OpenBSD's bcrypt. */ ++#define BCRYPTMAGNUM(array) (array)[0]=(array)[3]='$',(array)[1]='2',(array)[2]='b',(array)[4]='\0' ++#define BCRYPT_SALT_SIZE 22 ++/* Default number of rounds if not explicitly specified. */ ++#define B_ROUNDS_DEFAULT 13 ++/* Minimum number of rounds. */ ++#define B_ROUNDS_MIN 4 ++/* Maximum number of rounds. */ ++#define B_ROUNDS_MAX 31 ++#endif /* USE_BCRYPT */ ++ ++#ifdef USE_SHA_CRYPT ++/* Fixed salt len for sha{256,512}crypt. */ ++#define SHA_CRYPT_SALT_SIZE 16 ++/* Default number of rounds if not explicitly specified. */ ++#define SHA_ROUNDS_DEFAULT 5000 ++/* Minimum number of rounds. */ ++#define SHA_ROUNDS_MIN 1000 ++/* Maximum number of rounds. */ ++#define SHA_ROUNDS_MAX 999999999 ++#endif ++ ++#ifdef USE_YESCRYPT ++/* ++ * Default number of base64 characters used for the salt. ++ * 24 characters gives a 144 bits (18 bytes) salt. Unlike the more ++ * traditional 128 bits (16 bytes) salt, this 144 bits salt is always ++ * represented by the same number of base64 characters without padding ++ * issue, even with a non-standard base64 encoding scheme. ++ */ ++#define YESCRYPT_SALT_SIZE 24 ++/* Default cost if not explicitly specified. */ ++#define Y_COST_DEFAULT 5 ++/* Minimum cost. */ ++#define Y_COST_MIN 1 ++/* Maximum cost. */ ++#define Y_COST_MAX 11 ++#endif ++ ++/* Fixed salt len for md5crypt. */ ++#define MD5_CRYPT_SALT_SIZE 8 ++ ++/* Generate salt of size salt_size. */ ++#define MAX_SALT_SIZE 44 ++#define MIN_SALT_SIZE 8 ++ ++/* Maximum size of the generated salt string. */ ++#define GENSALT_SETTING_SIZE 100 ++ + /* local function prototypes */ + static void seedRNG (void); + static /*@observer@*/const char *gensalt (size_t salt_size); +@@ -26,19 +80,17 @@ static /*@observer@*/const char *gensalt (size_t salt_size); + static long shadow_random (long min, long max); + #endif /* USE_SHA_CRYPT || USE_BCRYPT */ + #ifdef USE_SHA_CRYPT +-static /*@observer@*/const char *SHA_salt_rounds (/*@null@*/int *prefered_rounds); ++static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, /*@null@*/int *prefered_rounds); + #endif /* USE_SHA_CRYPT */ + #ifdef USE_BCRYPT +-static /*@observer@*/const char *gensalt_bcrypt (void); +-static /*@observer@*/const char *BCRYPT_salt_rounds (/*@null@*/int *prefered_rounds); ++static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, /*@null@*/int *prefered_rounds); + #endif /* USE_BCRYPT */ + #ifdef USE_YESCRYPT +-static /*@observer@*/const char *gensalt_yescrypt (void); +-static /*@observer@*/const char *YESCRYPT_salt_cost (/*@null@*/int *prefered_cost); ++static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, /*@null@*/int *prefered_cost); + #endif /* USE_YESCRYPT */ + + #ifndef HAVE_L64A +-static /*@observer@*/char *l64a(long value) ++static /*@observer@*/char *l64a (long value) + { + static char buf[8]; + char *s = buf; +@@ -69,7 +121,7 @@ static /*@observer@*/char *l64a(long value) + + *s = '\0'; + +- return(buf); ++ return buf; + } + #endif /* !HAVE_L64A */ + +@@ -85,15 +137,6 @@ static void seedRNG (void) + } + } + +-/* +- * Add the salt prefix. +- */ +-#define MAGNUM(array,ch) (array)[0]=(array)[2]='$',(array)[1]=(ch),(array)[3]='\0' +-#ifdef USE_BCRYPT +-/* Use $2b$ as prefix for compatibility with OpenBSD's bcrypt. */ +-#define BCRYPTMAGNUM(array) (array)[0]=(array)[3]='$',(array)[1]='2',(array)[2]='b',(array)[4]='\0' +-#endif /* USE_BCRYPT */ +- + #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) + /* It is not clear what is the maximum value of random(). + * We assume 2^31-1.*/ +@@ -122,26 +165,21 @@ static long shadow_random (long min, long max) + #endif /* USE_SHA_CRYPT || USE_BCRYPT */ + + #ifdef USE_SHA_CRYPT +-/* Default number of rounds if not explicitly specified. */ +-#define ROUNDS_DEFAULT 5000 +-/* Minimum number of rounds. */ +-#define ROUNDS_MIN 1000 +-/* Maximum number of rounds. */ +-#define ROUNDS_MAX 999999999 + /* +- * Return a salt prefix specifying the rounds number for the SHA crypt methods. ++ * Fill a salt prefix specifying the rounds number for the SHA crypt methods ++ * to a buffer. + */ +-static /*@observer@*/const char *SHA_salt_rounds (/*@null@*/int *prefered_rounds) ++static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, /*@null@*/int *prefered_rounds) + { +- static char rounds_prefix[18]; /* Max size: rounds=999999999$ */ +- long rounds; ++ unsigned long rounds; ++ const size_t buf_begin = strlen (buf); + + if (NULL == prefered_rounds) { + long min_rounds = getdef_long ("SHA_CRYPT_MIN_ROUNDS", -1); + long max_rounds = getdef_long ("SHA_CRYPT_MAX_ROUNDS", -1); + + if ((-1 == min_rounds) && (-1 == max_rounds)) { +- return ""; ++ rounds = SHA_ROUNDS_DEFAULT; + } + + if (-1 == min_rounds) { +@@ -156,196 +194,142 @@ static /*@observer@*/const char *SHA_salt_rounds (/*@null@*/int *prefered_rounds + max_rounds = min_rounds; + } + +- rounds = shadow_random (min_rounds, max_rounds); ++ rounds = (unsigned long) shadow_random (min_rounds, max_rounds); + } else if (0 == *prefered_rounds) { +- return ""; ++ rounds = SHA_ROUNDS_DEFAULT; + } else { +- rounds = *prefered_rounds; ++ rounds = (unsigned long) *prefered_rounds; + } + + /* Sanity checks. The libc should also check this, but this + * protects against a rounds_prefix overflow. */ +- if (rounds < ROUNDS_MIN) { +- rounds = ROUNDS_MIN; ++ if (rounds < SHA_ROUNDS_MIN) { ++ rounds = SHA_ROUNDS_MIN; ++ } ++ ++ if (rounds > SHA_ROUNDS_MAX) { ++ rounds = SHA_ROUNDS_MAX; + } + +- if (rounds > ROUNDS_MAX) { +- rounds = ROUNDS_MAX; ++ /* Nothing to do here if SHA_ROUNDS_DEFAULT is used. */ ++ if (rounds == SHA_ROUNDS_DEFAULT) { ++ return; + } + +- (void) snprintf (rounds_prefix, sizeof rounds_prefix, +- "rounds=%ld$", rounds); ++ /* Check if the result buffer is long enough. */ ++ assert (GENSALT_SETTING_SIZE > buf_begin + 17); + +- return rounds_prefix; ++ (void) snprintf (buf + buf_begin, 18, "rounds=%lu$", rounds); + } + #endif /* USE_SHA_CRYPT */ + + #ifdef USE_BCRYPT +-/* Default number of rounds if not explicitly specified. */ +-#define B_ROUNDS_DEFAULT 13 +-/* Minimum number of rounds. */ +-#define B_ROUNDS_MIN 4 +-/* Maximum number of rounds. */ +-#define B_ROUNDS_MAX 31 + /* +- * Return a salt prefix specifying the rounds number for the BCRYPT method. ++ * Fill a salt prefix specifying the rounds number for the BCRYPT method ++ * to a buffer. + */ +-static /*@observer@*/const char *BCRYPT_salt_rounds (/*@null@*/int *prefered_rounds) ++static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, /*@null@*/int *prefered_rounds) + { +- static char rounds_prefix[4]; /* Max size: 31$ */ +- long rounds; ++ unsigned long rounds; ++ const size_t buf_begin = strlen (buf); + + if (NULL == prefered_rounds) { + long min_rounds = getdef_long ("BCRYPT_MIN_ROUNDS", -1); + long max_rounds = getdef_long ("BCRYPT_MAX_ROUNDS", -1); + +- if (((-1 == min_rounds) && (-1 == max_rounds)) || (0 == *prefered_rounds)) { ++ if ((-1 == min_rounds) && (-1 == max_rounds)) { + rounds = B_ROUNDS_DEFAULT; +- } +- else { ++ } else { + if (-1 == min_rounds) { + min_rounds = max_rounds; + } +- ++ + if (-1 == max_rounds) { + max_rounds = min_rounds; + } +- ++ + if (min_rounds > max_rounds) { + max_rounds = min_rounds; + } +- +- rounds = shadow_random (min_rounds, max_rounds); ++ ++ rounds = (unsigned long) shadow_random (min_rounds, max_rounds); + } ++ } else if (0 == *prefered_rounds) { ++ rounds = B_ROUNDS_DEFAULT; + } else { +- rounds = *prefered_rounds; ++ rounds = (unsigned long) *prefered_rounds; + } + +- /* +- * Sanity checks. +- * Use 19 as an upper bound for now, +- * because musl doesn't allow rounds >= 20. +- */ ++ /* Sanity checks. */ + if (rounds < B_ROUNDS_MIN) { + rounds = B_ROUNDS_MIN; + } + ++ /* ++ * Use 19 as an upper bound for now, ++ * because musl doesn't allow rounds >= 20. ++ */ + if (rounds > 19) { + /* rounds = B_ROUNDS_MAX; */ + rounds = 19; + } + +- (void) snprintf (rounds_prefix, sizeof rounds_prefix, +- "%2.2ld$", rounds); +- +- return rounds_prefix; +-} +- +-#define BCRYPT_SALT_SIZE 22 +-/* +- * Generate a 22 character salt string for bcrypt. +- */ +-static /*@observer@*/const char *gensalt_bcrypt (void) +-{ +- static char salt[32]; +- +- salt[0] = '\0'; ++ /* Check if the result buffer is long enough. */ ++ assert (GENSALT_SETTING_SIZE > buf_begin + 3); + +- seedRNG (); +- strcat (salt, l64a (random())); +- do { +- strcat (salt, l64a (random())); +- } while (strlen (salt) < BCRYPT_SALT_SIZE); +- +- salt[BCRYPT_SALT_SIZE] = '\0'; +- +- return salt; ++ (void) snprintf (buf + buf_begin, 4, "%2.2lu$", rounds); + } + #endif /* USE_BCRYPT */ + + #ifdef USE_YESCRYPT +-/* Default cost if not explicitly specified. */ +-#define Y_COST_DEFAULT 5 +-/* Minimum cost. */ +-#define Y_COST_MIN 1 +-/* Maximum cost. */ +-#define Y_COST_MAX 11 + /* +- * Return a salt prefix specifying the cost for the YESCRYPT method. ++ * Fill a salt prefix specifying the cost for the YESCRYPT method ++ * to a buffer. + */ +-static /*@observer@*/const char *YESCRYPT_salt_cost (/*@null@*/int *prefered_cost) ++static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, /*@null@*/int *prefered_cost) + { +- static char cost_prefix[5]; +- long cost; ++ unsigned long cost; ++ const size_t buf_begin = strlen (buf); + + if (NULL == prefered_cost) { + cost = getdef_num ("YESCRYPT_COST_FACTOR", Y_COST_DEFAULT); ++ } else if (0 == *prefered_cost) { ++ cost = Y_COST_DEFAULT; + } else { +- cost = *prefered_cost; ++ cost = (unsigned long) *prefered_cost; + } + ++ /* Sanity checks. */ + if (cost < Y_COST_MIN) { + cost = Y_COST_MIN; + } ++ + if (cost > Y_COST_MAX) { + cost = Y_COST_MAX; + } + +- cost_prefix[0] = 'j'; ++ /* Check if the result buffer is long enough. */ ++ assert (GENSALT_SETTING_SIZE > buf_begin + 3); ++ ++ buf[buf_begin + 0] = 'j'; + if (cost < 3) { +- cost_prefix[1] = 0x36 + cost; ++ buf[buf_begin + 1] = 0x36 + cost; + } else if (cost < 6) { +- cost_prefix[1] = 0x34 + cost; ++ buf[buf_begin + 1] = 0x34 + cost; + } else { +- cost_prefix[1] = 0x3b + cost; ++ buf[buf_begin + 1] = 0x3b + cost; + } +- cost_prefix[2] = cost >= 3 ? 'T' : '5'; +- cost_prefix[3] = '$'; +- cost_prefix[4] = 0; +- +- return cost_prefix; +-} +- +-/* +- * Default number of base64 characters used for the salt. +- * 24 characters gives a 144 bits (18 bytes) salt. Unlike the more +- * traditional 128 bits (16 bytes) salt, this 144 bits salt is always +- * represented by the same number of base64 characters without padding +- * issue, even with a non-standard base64 encoding scheme. +- */ +-#define YESCRYPT_SALT_SIZE 24 +-/* +- * Generate a 22 character salt string for yescrypt. +- */ +-static /*@observer@*/const char *gensalt_yescrypt (void) +-{ +- static char salt[32]; +- +- salt[0] = '\0'; +- +- seedRNG (); +- strcat (salt, l64a (random())); +- do { +- strcat (salt, l64a (random())); +- } while (strlen (salt) < YESCRYPT_SALT_SIZE); +- +- salt[YESCRYPT_SALT_SIZE] = '\0'; +- +- return salt; ++ buf[buf_begin + 2] = cost >= 3 ? 'T' : '5'; ++ buf[buf_begin + 3] = '$'; ++ buf[buf_begin + 4] = '\0'; + } + #endif /* USE_YESCRYPT */ + +-/* +- * Generate salt of size salt_size. +- */ +-#define MAX_SALT_SIZE 16 +-#define MIN_SALT_SIZE 8 +- + static /*@observer@*/const char *gensalt (size_t salt_size) + { +- static char salt[32]; ++ static char salt[MAX_SALT_SIZE + 6]; + +- salt[0] = '\0'; ++ memset (salt, '\0', MAX_SALT_SIZE + 6); + + assert (salt_size >= MIN_SALT_SIZE && + salt_size <= MAX_SALT_SIZE); +@@ -368,8 +352,9 @@ static /*@observer@*/const char *gensalt (size_t salt_size) + * Other methods can be set with ENCRYPT_METHOD + * + * The method can be forced with the meth parameter. +- * If NULL, the method will be defined according to the MD5_CRYPT_ENAB and +- * ENCRYPT_METHOD login.defs variables. ++ * If NULL, the method will be defined according to the ENCRYPT_METHOD ++ * variable, and if not set according to the MD5_CRYPT_ENAB variable, ++ * which can both be set inside the login.defs file. + * + * If meth is specified, an additional parameter can be provided. + * * For the SHA256 and SHA512 method, this specifies the number of rounds +@@ -378,17 +363,11 @@ static /*@observer@*/const char *gensalt (size_t salt_size) + */ + /*@observer@*/const char *crypt_make_salt (/*@null@*//*@observer@*/const char *meth, /*@null@*/void *arg) + { +- /* Max result size for the SHA methods: +- * +3 $5$ +- * +17 rounds=999999999$ +- * +16 salt +- * +1 \0 +- */ +- static char result[40]; +- size_t salt_len = 8; ++ static char result[GENSALT_SETTING_SIZE]; ++ size_t salt_len = MAX_SALT_SIZE; + const char *method; + +- result[0] = '\0'; ++ memset (result, '\0', GENSALT_SETTING_SIZE); + + if (NULL != meth) + method = meth; +@@ -401,61 +380,44 @@ static /*@observer@*/const char *gensalt (size_t salt_size) + + if (0 == strcmp (method, "MD5")) { + MAGNUM(result, '1'); ++ salt_len = MD5_CRYPT_SALT_SIZE; + #ifdef USE_BCRYPT + } else if (0 == strcmp (method, "BCRYPT")) { + BCRYPTMAGNUM(result); +- strcat(result, BCRYPT_salt_rounds((int *)arg)); ++ salt_len = BCRYPT_SALT_SIZE; ++ BCRYPT_salt_rounds_to_buf (result, (int *) arg); + #endif /* USE_BCRYPT */ + #ifdef USE_YESCRYPT + } else if (0 == strcmp (method, "YESCRYPT")) { + MAGNUM(result, 'y'); +- strcat(result, YESCRYPT_salt_cost((int *)arg)); ++ salt_len = YESCRYPT_SALT_SIZE; ++ YESCRYPT_salt_cost_to_buf (result, (int *) arg); + #endif /* USE_YESCRYPT */ + #ifdef USE_SHA_CRYPT + } else if (0 == strcmp (method, "SHA256")) { + MAGNUM(result, '5'); +- strcat(result, SHA_salt_rounds((int *)arg)); +- salt_len = (size_t) shadow_random (8, 16); ++ salt_len = SHA_CRYPT_SALT_SIZE; ++ SHA_salt_rounds_to_buf (result, (int *) arg); + } else if (0 == strcmp (method, "SHA512")) { + MAGNUM(result, '6'); +- strcat(result, SHA_salt_rounds((int *)arg)); +- salt_len = (size_t) shadow_random (8, 16); ++ salt_len = SHA_CRYPT_SALT_SIZE; ++ SHA_salt_rounds_to_buf (result, (int *) arg); + #endif /* USE_SHA_CRYPT */ + } else if (0 != strcmp (method, "DES")) { + fprintf (shadow_logfd, + _("Invalid ENCRYPT_METHOD value: '%s'.\n" + "Defaulting to DES.\n"), + method); +- result[0] = '\0'; ++ salt_len = MAX_SALT_SIZE; ++ memset (result, '\0', GENSALT_SETTING_SIZE); + } + +- /* +- * Concatenate a pseudo random salt. +- */ +- assert (sizeof (result) > strlen (result) + salt_len); +-#ifdef USE_BCRYPT +- if (0 == strcmp (method, "BCRYPT")) { +- strncat (result, gensalt_bcrypt (), +- sizeof (result) - strlen (result) - 1); +- return result; +- } else { +-#endif /* USE_BCRYPT */ +-#ifdef USE_YESCRYPT +- if (0 == strcmp (method, "YESCRYPT")) { +- strncat (result, gensalt_yescrypt (), +- sizeof (result) - strlen (result) - 1); +- return result; +- } else { +-#endif /* USE_YESCRYPT */ +- strncat (result, gensalt (salt_len), +- sizeof (result) - strlen (result) - 1); +-#ifdef USE_YESCRYPT +- } +-#endif /* USE_YESCRYPT */ +-#ifdef USE_BCRYPT +- } +-#endif /* USE_BCRYPT */ ++ /* Check if the result buffer is long enough. */ ++ assert (GENSALT_SETTING_SIZE > strlen (result) + salt_len); ++ ++ /* Concatenate a pseudo random salt. */ ++ strncat (result, gensalt (salt_len), ++ GENSALT_SETTING_SIZE - strlen (result) - 1); + + return result; + } +- diff --git a/shadow-utils.spec b/shadow-utils.spec index 1e1366a..928798c 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -108,6 +108,8 @@ Patch59: shadow-4.8.1-fix_YESCRYPT_salt_cost_param_type.patch Patch60: shadow-4.8.1-covscan_fixes.patch # https://github.com/shadow-maint/shadow/commit/738d92a4bd99a2038aa5f97b2fc85daa7011e403 Patch61: shadow-4.8.1-fix_bcrypt_prefix.patch +# https://github.com/shadow-maint/shadow/commit/14b108728a5d55c3d478a170c39f0e2ffd4de1b0 +Patch62: shadow-4.8.1-salt_c_sanitize_code.patch License: BSD and GPLv2+ BuildRequires: make @@ -194,6 +196,7 @@ Development files for shadow-utils-subid. %patch59 -p1 -b .YESCRYPT_salt_cost_param_type %patch60 -p1 -b .covscan_fixes %patch61 -p1 -b .bcrypt_prefix +%patch62 -p1 -b .sanitize_code iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -365,6 +368,7 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la %changelog * Mon Jun 28 2021 Björn Esser - 2:4.8.1-14 - Add a patch to fix the used prefix for the bcrypt hash method +- Add a patch to cleanup the code in libmisc/salt.c * Mon Jun 28 2021 Iker Pedrosa - 2:4.8.1-13 - Covscan fixes From 1b6e097b0e73a509cb80585983b8ac600b1734a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= Date: Wed, 23 Jun 2021 22:19:36 +0200 Subject: [PATCH 037/134] Add a patch adding some clarifying comments in libmisc/salt.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Esser --- shadow-4.8.1-salt_c_comments.patch | 75 ++++++++++++++++++++++++++++++ shadow-utils.spec | 4 ++ 2 files changed, 79 insertions(+) create mode 100644 shadow-4.8.1-salt_c_comments.patch diff --git a/shadow-4.8.1-salt_c_comments.patch b/shadow-4.8.1-salt_c_comments.patch new file mode 100644 index 0000000..1ec77e4 --- /dev/null +++ b/shadow-4.8.1-salt_c_comments.patch @@ -0,0 +1,75 @@ +From dbf230e4cf823dd6b6a3bad6d29dfad4f0ffa8fc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= +Date: Mon, 14 Jun 2021 23:28:28 +0200 +Subject: [PATCH] libmisc/salt.c: Add comments how the minmum buffer length is + computed. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In the previous commit we refactored the functions converting the +rounds number into a string for use with the crypt() function, to +not require any static buffer anymore. + +Add some clarifying comments about how the minimum required buffer +length is computed inside of these functions. + +Signed-off-by: Björn Esser +--- + libmisc/salt.c | 29 +++++++++++++++++++++++++---- + 1 file changed, 25 insertions(+), 4 deletions(-) + +diff --git a/libmisc/salt.c b/libmisc/salt.c +index 98982ed1..e17093fc 100644 +--- a/libmisc/salt.c ++++ b/libmisc/salt.c +@@ -216,7 +216,14 @@ static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, /*@null@*/int *pref + return; + } + +- /* Check if the result buffer is long enough. */ ++ /* ++ * Check if the result buffer is long enough. ++ * We are going to write a maximum of 17 bytes, ++ * plus one byte for the terminator. ++ * rounds=XXXXXXXXX$ ++ * 00000000011111111 ++ * 12345678901234567 ++ */ + assert (GENSALT_SETTING_SIZE > buf_begin + 17); + + (void) snprintf (buf + buf_begin, 18, "rounds=%lu$", rounds); +@@ -274,7 +281,14 @@ static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, /*@null@*/int *p + rounds = 19; + } + +- /* Check if the result buffer is long enough. */ ++ /* ++ * Check if the result buffer is long enough. ++ * We are going to write three bytes, ++ * plus one byte for the terminator. ++ * XX$ ++ * 000 ++ * 123 ++ */ + assert (GENSALT_SETTING_SIZE > buf_begin + 3); + + (void) snprintf (buf + buf_begin, 4, "%2.2lu$", rounds); +@@ -308,8 +322,15 @@ static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, /*@null@*/int *p + cost = Y_COST_MAX; + } + +- /* Check if the result buffer is long enough. */ +- assert (GENSALT_SETTING_SIZE > buf_begin + 3); ++ /* ++ * Check if the result buffer is long enough. ++ * We are going to write four bytes, ++ * plus one byte for the terminator. ++ * jXX$ ++ * 0000 ++ * 1234 ++ */ ++ assert (GENSALT_SETTING_SIZE > buf_begin + 4); + + buf[buf_begin + 0] = 'j'; + if (cost < 3) { diff --git a/shadow-utils.spec b/shadow-utils.spec index 928798c..5145b38 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -110,6 +110,8 @@ Patch60: shadow-4.8.1-covscan_fixes.patch Patch61: shadow-4.8.1-fix_bcrypt_prefix.patch # https://github.com/shadow-maint/shadow/commit/14b108728a5d55c3d478a170c39f0e2ffd4de1b0 Patch62: shadow-4.8.1-salt_c_sanitize_code.patch +# https://github.com/shadow-maint/shadow/commit/dbf230e4cf823dd6b6a3bad6d29dfad4f0ffa8fc +Patch63: shadow-4.8.1-salt_c_comments.patch License: BSD and GPLv2+ BuildRequires: make @@ -197,6 +199,7 @@ Development files for shadow-utils-subid. %patch60 -p1 -b .covscan_fixes %patch61 -p1 -b .bcrypt_prefix %patch62 -p1 -b .sanitize_code +%patch63 -p1 -b .comments iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -369,6 +372,7 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la * Mon Jun 28 2021 Björn Esser - 2:4.8.1-14 - Add a patch to fix the used prefix for the bcrypt hash method - Add a patch to cleanup the code in libmisc/salt.c +- Add a patch adding some clarifying comments in libmisc/salt.c * Mon Jun 28 2021 Iker Pedrosa - 2:4.8.1-13 - Covscan fixes From bace2f8c6b021981f73395c46dac0989f4d494c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= Date: Wed, 23 Jun 2021 22:22:04 +0200 Subject: [PATCH 038/134] Add a patch to obtain random bytes from /dev/urandom MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Esser --- shadow-4.8.1-salt_c_use_dev_urandom.patch | 114 ++++++++++++++++++++++ shadow-utils.spec | 4 + 2 files changed, 118 insertions(+) create mode 100644 shadow-4.8.1-salt_c_use_dev_urandom.patch diff --git a/shadow-4.8.1-salt_c_use_dev_urandom.patch b/shadow-4.8.1-salt_c_use_dev_urandom.patch new file mode 100644 index 0000000..ba37b77 --- /dev/null +++ b/shadow-4.8.1-salt_c_use_dev_urandom.patch @@ -0,0 +1,114 @@ +From bc8257cf73328e450511b13cbd35e1994feccb30 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= +Date: Wed, 23 Jun 2021 16:06:47 +0200 +Subject: [PATCH] libmisc/salt.c: Obtain random bytes from /dev/urandom. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Using the random() function to obtain pseudo-random bytes +for generating salt strings is considered to be dangerous. +See CWE-327. + +We really should use a more reliable source for obtaining +pseudo-random bytes like /dev/urandom. + +Fixes #376. + +Signed-off-by: Björn Esser +--- + libmisc/salt.c | 45 ++++++++++++++++++++++++--------------------- + 1 file changed, 24 insertions(+), 21 deletions(-) + +diff --git a/libmisc/salt.c b/libmisc/salt.c +index e17093fc..af9f011f 100644 +--- a/libmisc/salt.c ++++ b/libmisc/salt.c +@@ -11,11 +11,10 @@ + + #ident "$Id$" + +-#include +-#include +-#include +-#include + #include ++#include ++#include ++#include + #include "prototypes.h" + #include "defines.h" + #include "getdef.h" +@@ -74,7 +73,7 @@ + #define GENSALT_SETTING_SIZE 100 + + /* local function prototypes */ +-static void seedRNG (void); ++static long read_random_bytes (void); + static /*@observer@*/const char *gensalt (size_t salt_size); + #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) + static long shadow_random (long min, long max); +@@ -125,23 +124,27 @@ static /*@observer@*/char *l64a (long value) + } + #endif /* !HAVE_L64A */ + +-static void seedRNG (void) ++/* Read sizeof (long) random bytes from /dev/urandom. */ ++static long read_random_bytes (void) + { +- struct timeval tv; +- static int seeded = 0; ++ long randval = 0; ++ FILE *f = fopen ("/dev/urandom", "r"); + +- if (0 == seeded) { +- (void) gettimeofday (&tv, NULL); +- srandom (tv.tv_sec ^ tv.tv_usec ^ getpid ()); +- seeded = 1; ++ if (fread (&randval, sizeof (randval), 1, f) != sizeof (randval)) ++ { ++ fprintf (shadow_logfd, ++ _("Unable to read from /dev/urandom.\n")); ++ ++ fclose(f); ++ exit (1); + } ++ ++ fclose(f); ++ ++ return randval; + } + + #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) +-/* It is not clear what is the maximum value of random(). +- * We assume 2^31-1.*/ +-#define RANDOM_MAX 0x7FFFFFFF +- + /* + * Return a random number between min and max (both included). + * +@@ -151,8 +154,9 @@ static long shadow_random (long min, long max) + { + double drand; + long ret; +- seedRNG (); +- drand = (double) (max - min + 1) * random () / RANDOM_MAX; ++ ++ drand = (double) (read_random_bytes () & RAND_MAX) / (double) RAND_MAX; ++ drand *= (double) (max - min + 1); + /* On systems were this is not random() range is lower, we favor + * higher numbers of salt. */ + ret = (long) (max + 1 - drand); +@@ -354,10 +358,9 @@ static /*@observer@*/const char *gensalt (size_t salt_size) + + assert (salt_size >= MIN_SALT_SIZE && + salt_size <= MAX_SALT_SIZE); +- seedRNG (); +- strcat (salt, l64a (random())); ++ strcat (salt, l64a (read_random_bytes ())); + do { +- strcat (salt, l64a (random())); ++ strcat (salt, l64a (read_random_bytes ())); + } while (strlen (salt) < salt_size); + + salt[salt_size] = '\0'; diff --git a/shadow-utils.spec b/shadow-utils.spec index 5145b38..a5badbb 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -112,6 +112,8 @@ Patch61: shadow-4.8.1-fix_bcrypt_prefix.patch Patch62: shadow-4.8.1-salt_c_sanitize_code.patch # https://github.com/shadow-maint/shadow/commit/dbf230e4cf823dd6b6a3bad6d29dfad4f0ffa8fc Patch63: shadow-4.8.1-salt_c_comments.patch +# https://github.com/shadow-maint/shadow/commit/bc8257cf73328e450511b13cbd35e1994feccb30 +Patch64: shadow-4.8.1-salt_c_use_dev_urandom.patch License: BSD and GPLv2+ BuildRequires: make @@ -200,6 +202,7 @@ Development files for shadow-utils-subid. %patch61 -p1 -b .bcrypt_prefix %patch62 -p1 -b .sanitize_code %patch63 -p1 -b .comments +%patch64 -p1 -b .use_dev_urandom iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -373,6 +376,7 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la - Add a patch to fix the used prefix for the bcrypt hash method - Add a patch to cleanup the code in libmisc/salt.c - Add a patch adding some clarifying comments in libmisc/salt.c +- Add a patch to obtain random bytes from /dev/urandom * Mon Jun 28 2021 Iker Pedrosa - 2:4.8.1-13 - Covscan fixes From 2b6f7135243105d4526c3e9b4eddb4b745081a90 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Tue, 29 Jun 2021 08:53:22 +0200 Subject: [PATCH 039/134] useradd: free correct pointer (#1976809) --- ..._create_relative_home_path_correctly.patch | 24 +++++++++++++++++++ shadow-utils.spec | 8 ++++++- 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 shadow-4.8.1-useradd_create_relative_home_path_correctly.patch diff --git a/shadow-4.8.1-useradd_create_relative_home_path_correctly.patch b/shadow-4.8.1-useradd_create_relative_home_path_correctly.patch new file mode 100644 index 0000000..a318f7a --- /dev/null +++ b/shadow-4.8.1-useradd_create_relative_home_path_correctly.patch @@ -0,0 +1,24 @@ +diff -up shadow-4.8.1/src/useradd.c.useradd_create_relative_home_path_correctly shadow-4.8.1/src/useradd.c +--- shadow-4.8.1/src/useradd.c.useradd_create_relative_home_path_correctly 2021-06-28 16:10:23.928435372 +0200 ++++ shadow-4.8.1/src/useradd.c 2021-06-28 16:11:30.784495046 +0200 +@@ -2140,7 +2140,6 @@ static void create_home (void) + Prog, user_home); + fail_exit (E_HOMEDIR); + } +- ++bhome; + + #ifdef WITH_SELINUX + if (set_selinux_file_context (prefix_user_home, NULL) != 0) { +@@ -2157,7 +2156,11 @@ static void create_home (void) + */ + cp = strtok (bhome, "/"); + while (cp) { +- strcat (path, "/"); ++ /* Avoid turning a relative path into an absolute path. ++ */ ++ if (bhome[0] == '/' || strlen (path) != 0) { ++ strcat (path, "/"); ++ } + strcat (path, cp); + if (access (path, F_OK) != 0) { + /* Check if parent directory is BTRFS, fail if requesting diff --git a/shadow-utils.spec b/shadow-utils.spec index a5badbb..20830e6 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.8.1 -Release: 14%{?dist} +Release: 15%{?dist} Epoch: 2 URL: https://github.com/shadow-maint/shadow Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -114,6 +114,8 @@ Patch62: shadow-4.8.1-salt_c_sanitize_code.patch Patch63: shadow-4.8.1-salt_c_comments.patch # https://github.com/shadow-maint/shadow/commit/bc8257cf73328e450511b13cbd35e1994feccb30 Patch64: shadow-4.8.1-salt_c_use_dev_urandom.patch +# https://github.com/shadow-maint/shadow/commit/2c542f6c65f858b3dba20f58db4da56572f67a54 +Patch65: shadow-4.8.1-useradd_create_relative_home_path_correctly.patch License: BSD and GPLv2+ BuildRequires: make @@ -203,6 +205,7 @@ Development files for shadow-utils-subid. %patch62 -p1 -b .sanitize_code %patch63 -p1 -b .comments %patch64 -p1 -b .use_dev_urandom +%patch65 -p1 -b .useradd_create_relative_home_path_correctly iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -372,6 +375,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la %{_libdir}/libsubid.so %changelog +* Tue Jun 29 2021 Iker Pedrosa - 2:4.8.1-15 +- useradd: free correct pointer (#1976809) + * Mon Jun 28 2021 Björn Esser - 2:4.8.1-14 - Add a patch to fix the used prefix for the bcrypt hash method - Add a patch to cleanup the code in libmisc/salt.c From a6d57fc8a3234d8e2321cdf0b81afbffc7f37987 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= Date: Sun, 4 Jul 2021 12:34:22 +0200 Subject: [PATCH 040/134] Add a patch to obtain random bytes using getentropy() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Esser --- shadow-4.8.1-getentropy_random_bytes.patch | 123 +++++++++++++++++++++ shadow-utils.spec | 8 +- 2 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 shadow-4.8.1-getentropy_random_bytes.patch diff --git a/shadow-4.8.1-getentropy_random_bytes.patch b/shadow-4.8.1-getentropy_random_bytes.patch new file mode 100644 index 0000000..c1affce --- /dev/null +++ b/shadow-4.8.1-getentropy_random_bytes.patch @@ -0,0 +1,123 @@ +From c82ed0c15e0e9e47df0b4c22672b72e35f061a9d +From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= +Date: Sun, 4 Jul 2021 12:10:11 +0200 +Subject: [PATCH] libmisc/salt.c: Use secure system ressources to obtain random + bytes. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In a previous commit we introduced /dev/urandom as a source to obtain +random bytes from. This may not be available on all systems, or when +operating inside of a chroot. + +Almost all systems provide functions to obtain random bytes from +secure system ressources. Thus we should prefer to use these, and +fall back to /dev/urandom, if there is no such function present, as +a last resort. + +Signed-off-by: Björn Esser +--- + configure.ac | 17 +++++++++-------- + libmisc/salt.c | 42 ++++++++++++++++++++++++++++++++++++------ + 2 files changed, 45 insertions(+), 14 deletions(-) + +Index: shadow-4.8.1/configure.ac +=================================================================== +--- shadow-4.8.1.orig/configure.ac ++++ shadow-4.8.1/configure.ac +@@ -44,18 +44,19 @@ AC_HEADER_STDBOOL + + AC_CHECK_HEADERS(crypt.h errno.h fcntl.h limits.h unistd.h sys/time.h utmp.h \ + utmpx.h termios.h termio.h sgtty.h sys/ioctl.h syslog.h paths.h \ +- utime.h ulimit.h sys/capability.h sys/resource.h gshadow.h lastlog.h \ +- locale.h rpc/key_prot.h netdb.h acl/libacl.h attr/libattr.h \ +- attr/error_context.h) ++ utime.h ulimit.h sys/capability.h sys/random.h sys/resource.h \ ++ gshadow.h lastlog.h locale.h rpc/key_prot.h netdb.h acl/libacl.h \ ++ attr/libattr.h attr/error_context.h) + + dnl shadow now uses the libc's shadow implementation + AC_CHECK_HEADER([shadow.h],,[AC_MSG_ERROR([You need a libc with shadow.h])]) + +-AC_CHECK_FUNCS(l64a fchmod fchown fsync futimes getgroups gethostname getspnam \ +- gettimeofday getusershell getutent initgroups lchown lckpwdf lstat \ +- lutimes memcpy memset setgroups sigaction strchr updwtmp updwtmpx innetgr \ +- getpwnam_r getpwuid_r getgrnam_r getgrgid_r getspnam_r getaddrinfo \ +- ruserok dlopen) ++AC_CHECK_FUNCS(arc4random_buf l64a fchmod fchown fsync futimes getgroups \ ++ gethostname getentropy getrandom getspnam gettimeofday getusershell \ ++ getutent initgroups lchown lckpwdf lstat lutimes memcpy memset \ ++ setgroups sigaction strchr updwtmp updwtmpx innetgr getpwnam_r \ ++ getpwuid_r getgrnam_r getgrgid_r getspnam_r getaddrinfo ruserok \ ++ dlopen) + AC_SYS_LARGEFILE + + dnl Checks for typedefs, structures, and compiler characteristics. +Index: shadow-4.8.1/libmisc/salt.c +=================================================================== +--- shadow-4.8.1.orig/libmisc/salt.c ++++ shadow-4.8.1/libmisc/salt.c +@@ -15,6 +15,9 @@ + #include + #include + #include ++#if HAVE_SYS_RANDOM_H ++#include ++#endif + #include "prototypes.h" + #include "defines.h" + #include "getdef.h" +@@ -128,19 +131,46 @@ static /*@observer@*/char *l64a (long va + static long read_random_bytes (void) + { + long randval = 0; +- FILE *f = fopen ("/dev/urandom", "r"); + +- if (fread (&randval, sizeof (randval), 1, f) != sizeof (randval)) +- { +- fprintf (shadow_logfd, +- _("Unable to read from /dev/urandom.\n")); ++#ifdef HAVE_ARC4RANDOM_BUF ++ /* arc4random_buf, if it exists, can never fail. */ ++ arc4random_buf (&randval, sizeof (randval)); ++ goto end; ++ ++#elif defined(HAVE_GETENTROPY) ++ /* getentropy may exist but lack kernel support. */ ++ if (getentropy (&randval, sizeof (randval))) { ++ goto fail; ++ } ++ ++ goto end; ++ ++#elif defined(HAVE_GETRANDOM) ++ /* Likewise getrandom. */ ++ if ((size_t) getrandom (&randval, sizeof (randval), 0) != sizeof (randval)) { ++ goto fail; ++ } + ++ goto end; ++ ++#else ++ FILE *f = fopen ("/dev/urandom", "r"); ++ ++ if (fread (&randval, sizeof (randval), 1, f) != sizeof (randval)) { + fclose(f); +- exit (1); ++ goto fail; + } + + fclose(f); ++ goto end; ++#endif ++ ++fail: ++ fprintf (shadow_logfd, ++ _("Unable to obtain random bytes.\n")); ++ exit (1); + ++end: + return randval; + } + diff --git a/shadow-utils.spec b/shadow-utils.spec index 20830e6..7923c7b 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.8.1 -Release: 15%{?dist} +Release: 16%{?dist} Epoch: 2 URL: https://github.com/shadow-maint/shadow Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -116,6 +116,8 @@ Patch63: shadow-4.8.1-salt_c_comments.patch Patch64: shadow-4.8.1-salt_c_use_dev_urandom.patch # https://github.com/shadow-maint/shadow/commit/2c542f6c65f858b3dba20f58db4da56572f67a54 Patch65: shadow-4.8.1-useradd_create_relative_home_path_correctly.patch +# https://github.com/shadow-maint/shadow/commit/c82ed0c15e0e9e47df0b4c22672b72e35f061a9d +Patch66: shadow-4.8.1-getentropy_random_bytes.patch License: BSD and GPLv2+ BuildRequires: make @@ -206,6 +208,7 @@ Development files for shadow-utils-subid. %patch63 -p1 -b .comments %patch64 -p1 -b .use_dev_urandom %patch65 -p1 -b .useradd_create_relative_home_path_correctly +%patch66 -p1 -b .getentropy_random_bytes iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -375,6 +378,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la %{_libdir}/libsubid.so %changelog +* Sun Jul 04 2021 Björn Esser - 2:4.8.1-16 +- Add a patch to obtain random bytes using getentropy() + * Tue Jun 29 2021 Iker Pedrosa - 2:4.8.1-15 - useradd: free correct pointer (#1976809) From a4f9def9dd72b299fd4a036f399bb8510c4ae252 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= Date: Thu, 24 Jun 2021 12:47:17 +0200 Subject: [PATCH 041/134] Update shadow-4.8-crypt_h.patch with the upstreamed version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Esser --- shadow-4.8-crypt_h.patch | 39 +++- shadow-4.8.1-crypt_gensalt.patch | 310 +++++++++++++++++++++++++++++++ shadow-utils.spec | 9 +- 3 files changed, 348 insertions(+), 10 deletions(-) create mode 100644 shadow-4.8.1-crypt_gensalt.patch diff --git a/shadow-4.8-crypt_h.patch b/shadow-4.8-crypt_h.patch index e2704e8..6d36376 100644 --- a/shadow-4.8-crypt_h.patch +++ b/shadow-4.8-crypt_h.patch @@ -1,6 +1,24 @@ -diff -up shadow-4.8/configure.ac.crypt_h shadow-4.8/configure.ac ---- shadow-4.8/configure.ac.crypt_h 2020-01-13 10:26:17.400481712 +0100 -+++ shadow-4.8/configure.ac 2020-01-13 10:29:11.563529093 +0100 +From c93897a8d71b9b1790caf3b2dee38dbe62518ae3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= +Date: Thu, 24 Jun 2021 12:39:27 +0200 +Subject: [PATCH] lib/defines.h: Include if present on the system. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The functions crypt(3), crypt_gensalt(3), and their +feature test macros may be defined in there. + +Signed-off-by: Björn Esser +--- + configure.ac | 2 +- + lib/defines.h | 10 ++++++++++ + 2 files changed, 11 insertions(+), 1 deletion(-) + +Index: shadow-4.8.1/configure.ac +=================================================================== +--- shadow-4.8.1.orig/configure.ac ++++ shadow-4.8.1/configure.ac @@ -32,7 +32,7 @@ AC_HEADER_STDC AC_HEADER_SYS_WAIT AC_HEADER_STDBOOL @@ -10,9 +28,10 @@ diff -up shadow-4.8/configure.ac.crypt_h shadow-4.8/configure.ac utmpx.h termios.h termio.h sgtty.h sys/ioctl.h syslog.h paths.h \ utime.h ulimit.h sys/capability.h sys/resource.h gshadow.h lastlog.h \ locale.h rpc/key_prot.h netdb.h acl/libacl.h attr/libattr.h \ -diff -up shadow-4.8/lib/defines.h.crypt_h shadow-4.8/lib/defines.h ---- shadow-4.8/lib/defines.h.crypt_h 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8/lib/defines.h 2020-01-13 10:26:17.400481712 +0100 +Index: shadow-4.8.1/lib/defines.h +=================================================================== +--- shadow-4.8.1.orig/lib/defines.h ++++ shadow-4.8.1/lib/defines.h @@ -4,6 +4,8 @@ #ifndef _DEFINES_H_ #define _DEFINES_H_ @@ -22,12 +41,16 @@ diff -up shadow-4.8/lib/defines.h.crypt_h shadow-4.8/lib/defines.h #if HAVE_STDBOOL_H # include #else -@@ -94,6 +96,10 @@ char *strchr (), *strrchr (), *strtok () +@@ -94,6 +96,14 @@ char *strchr (), *strrchr (), *strtok (); # include #endif ++/* ++ * crypt(3), crypt_gensalt(3), and their ++ * feature test macros may be defined in here. ++ */ +#if HAVE_CRYPT_H -+# include /* crypt(3) may be defined in here */ ++# include +#endif + #if TIME_WITH_SYS_TIME diff --git a/shadow-4.8.1-crypt_gensalt.patch b/shadow-4.8.1-crypt_gensalt.patch new file mode 100644 index 0000000..25198e6 --- /dev/null +++ b/shadow-4.8.1-crypt_gensalt.patch @@ -0,0 +1,310 @@ +From ea04eb301d08c0c58f1120f87d4ec184d3983ce5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= +Date: Tue, 15 Jun 2021 14:23:42 +0200 +Subject: [PATCH] libmisc/salt.c: Use crypt_gensalt(), if available in + libcrypt. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Most Linux distributions, including Fedora and RHEL 8, are shipping +with libxcrypt >= 4.0. + +Since that version of libxcrypt the provided family of crypt_gensalt() +functions are able to use automatic entropy drawn from secure system +ressources, like arc4random(), getentropy() or getrandom(). + +Anyways, the settings generated by crypt_gensalt() are always +guaranteed to works with the crypt() function. + +Using crypt_gensalt() is also needed to make proper use of newer +hashing methods, like yescrypt, provided by libxcrypt. + +Signed-off-by: Björn Esser +--- + libmisc/salt.c | 132 +++++++++++++++++++++++++++++++++++++++---------- + 1 file changed, 105 insertions(+), 27 deletions(-) + +diff --git a/libmisc/salt.c b/libmisc/salt.c +index 13408a53..9fd34332 100644 +--- a/libmisc/salt.c ++++ b/libmisc/salt.c +@@ -22,6 +22,13 @@ + #include "defines.h" + #include "getdef.h" + ++#if (defined CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY && \ ++ CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY) ++#define USE_XCRYPT_GENSALT 1 ++#else ++#define USE_XCRYPT_GENSALT 0 ++#endif ++ + /* Add the salt prefix. */ + #define MAGNUM(array,ch) (array)[0]=(array)[2]='$',(array)[1]=(ch),(array)[3]='\0' + +@@ -77,21 +84,26 @@ + + /* local function prototypes */ + static long read_random_bytes (void); ++#if !USE_XCRYPT_GENSALT + static /*@observer@*/const char *gensalt (size_t salt_size); ++#endif /* !USE_XCRYPT_GENSALT */ + #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) + static long shadow_random (long min, long max); + #endif /* USE_SHA_CRYPT || USE_BCRYPT */ + #ifdef USE_SHA_CRYPT +-static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, /*@null@*/int *prefered_rounds); ++static /*@observer@*/const unsigned long SHA_get_salt_rounds (/*@null@*/int *prefered_rounds); ++static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, unsigned long rounds); + #endif /* USE_SHA_CRYPT */ + #ifdef USE_BCRYPT +-static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, /*@null@*/int *prefered_rounds); ++static /*@observer@*/const unsigned long BCRYPT_get_salt_rounds (/*@null@*/int *prefered_rounds); ++static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, unsigned long rounds); + #endif /* USE_BCRYPT */ + #ifdef USE_YESCRYPT +-static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, /*@null@*/int *prefered_cost); ++static /*@observer@*/const unsigned long YESCRYPT_get_salt_cost (/*@null@*/int *prefered_cost); ++static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, unsigned long cost); + #endif /* USE_YESCRYPT */ + +-#ifndef HAVE_L64A ++#if !USE_XCRYPT_GENSALT && !defined(HAVE_L64A) + static /*@observer@*/char *l64a (long value) + { + static char buf[8]; +@@ -125,7 +137,7 @@ static /*@observer@*/char *l64a (long value) + + return buf; + } +-#endif /* !HAVE_L64A */ ++#endif /* !USE_XCRYPT_GENSALT && !defined(HAVE_L64A) */ + + /* Read sizeof (long) random bytes from /dev/urandom. */ + static long read_random_bytes (void) +@@ -199,14 +211,10 @@ static long shadow_random (long min, long max) + #endif /* USE_SHA_CRYPT || USE_BCRYPT */ + + #ifdef USE_SHA_CRYPT +-/* +- * Fill a salt prefix specifying the rounds number for the SHA crypt methods +- * to a buffer. +- */ +-static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, /*@null@*/int *prefered_rounds) ++/* Return the the rounds number for the SHA crypt methods. */ ++static /*@observer@*/const unsigned long SHA_get_salt_rounds (/*@null@*/int *prefered_rounds) + { + unsigned long rounds; +- const size_t buf_begin = strlen (buf); + + if (NULL == prefered_rounds) { + long min_rounds = getdef_long ("SHA_CRYPT_MIN_ROUNDS", -1); +@@ -245,6 +253,17 @@ static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, /*@null@*/int *pref + rounds = SHA_ROUNDS_MAX; + } + ++ return rounds; ++} ++ ++/* ++ * Fill a salt prefix specifying the rounds number for the SHA crypt methods ++ * to a buffer. ++ */ ++static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, unsigned long rounds) ++{ ++ const size_t buf_begin = strlen (buf); ++ + /* Nothing to do here if SHA_ROUNDS_DEFAULT is used. */ + if (rounds == SHA_ROUNDS_DEFAULT) { + return; +@@ -265,14 +284,10 @@ static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, /*@null@*/int *pref + #endif /* USE_SHA_CRYPT */ + + #ifdef USE_BCRYPT +-/* +- * Fill a salt prefix specifying the rounds number for the BCRYPT method +- * to a buffer. +- */ +-static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, /*@null@*/int *prefered_rounds) ++/* Return the the rounds number for the BCRYPT method. */ ++static /*@observer@*/const unsigned long BCRYPT_get_salt_rounds (/*@null@*/int *prefered_rounds) + { + unsigned long rounds; +- const size_t buf_begin = strlen (buf); + + if (NULL == prefered_rounds) { + long min_rounds = getdef_long ("BCRYPT_MIN_ROUNDS", -1); +@@ -306,6 +321,11 @@ static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, /*@null@*/int *p + rounds = B_ROUNDS_MIN; + } + ++#if USE_XCRYPT_GENSALT ++ if (rounds > B_ROUNDS_MAX) { ++ rounds = B_ROUNDS_MAX; ++ } ++#else /* USE_XCRYPT_GENSALT */ + /* + * Use 19 as an upper bound for now, + * because musl doesn't allow rounds >= 20. +@@ -314,6 +334,18 @@ static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, /*@null@*/int *p + /* rounds = B_ROUNDS_MAX; */ + rounds = 19; + } ++#endif /* USE_XCRYPT_GENSALT */ ++ ++ return rounds; ++} ++ ++/* ++ * Fill a salt prefix specifying the rounds number for the BCRYPT method ++ * to a buffer. ++ */ ++static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, unsigned long rounds) ++{ ++ const size_t buf_begin = strlen (buf); + + /* + * Check if the result buffer is long enough. +@@ -330,14 +362,10 @@ static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, /*@null@*/int *p + #endif /* USE_BCRYPT */ + + #ifdef USE_YESCRYPT +-/* +- * Fill a salt prefix specifying the cost for the YESCRYPT method +- * to a buffer. +- */ +-static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, /*@null@*/int *prefered_cost) ++/* Return the the cost number for the YESCRYPT method. */ ++static /*@observer@*/const unsigned long YESCRYPT_get_salt_cost (/*@null@*/int *prefered_cost) + { + unsigned long cost; +- const size_t buf_begin = strlen (buf); + + if (NULL == prefered_cost) { + cost = getdef_num ("YESCRYPT_COST_FACTOR", Y_COST_DEFAULT); +@@ -356,6 +384,17 @@ static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, /*@null@*/int *p + cost = Y_COST_MAX; + } + ++ return cost; ++} ++ ++/* ++ * Fill a salt prefix specifying the cost for the YESCRYPT method ++ * to a buffer. ++ */ ++static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, unsigned long cost) ++{ ++ const size_t buf_begin = strlen (buf); ++ + /* + * Check if the result buffer is long enough. + * We are going to write four bytes, +@@ -380,6 +419,7 @@ static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, /*@null@*/int *p + } + #endif /* USE_YESCRYPT */ + ++#if !USE_XCRYPT_GENSALT + static /*@observer@*/const char *gensalt (size_t salt_size) + { + static char salt[MAX_SALT_SIZE + 6]; +@@ -397,6 +437,7 @@ static /*@observer@*/const char *gensalt (size_t salt_size) + + return salt; + } ++#endif /* !USE_XCRYPT_GENSALT */ + + /* + * Generate 8 base64 ASCII characters of random salt. If MD5_CRYPT_ENAB +@@ -420,6 +461,7 @@ static /*@observer@*/const char *gensalt (size_t salt_size) + static char result[GENSALT_SETTING_SIZE]; + size_t salt_len = MAX_SALT_SIZE; + const char *method; ++ unsigned long rounds = 0; + + memset (result, '\0', GENSALT_SETTING_SIZE); + +@@ -435,27 +477,32 @@ static /*@observer@*/const char *gensalt (size_t salt_size) + if (0 == strcmp (method, "MD5")) { + MAGNUM(result, '1'); + salt_len = MD5_CRYPT_SALT_SIZE; ++ rounds = 0; + #ifdef USE_BCRYPT + } else if (0 == strcmp (method, "BCRYPT")) { + BCRYPTMAGNUM(result); + salt_len = BCRYPT_SALT_SIZE; +- BCRYPT_salt_rounds_to_buf (result, (int *) arg); ++ rounds = BCRYPT_get_salt_rounds ((int *) arg); ++ BCRYPT_salt_rounds_to_buf (result, rounds); + #endif /* USE_BCRYPT */ + #ifdef USE_YESCRYPT + } else if (0 == strcmp (method, "YESCRYPT")) { + MAGNUM(result, 'y'); + salt_len = YESCRYPT_SALT_SIZE; +- YESCRYPT_salt_cost_to_buf (result, (int *) arg); ++ rounds = YESCRYPT_get_salt_cost ((int *) arg); ++ YESCRYPT_salt_cost_to_buf (result, rounds); + #endif /* USE_YESCRYPT */ + #ifdef USE_SHA_CRYPT + } else if (0 == strcmp (method, "SHA256")) { + MAGNUM(result, '5'); + salt_len = SHA_CRYPT_SALT_SIZE; +- SHA_salt_rounds_to_buf (result, (int *) arg); ++ rounds = SHA_get_salt_rounds ((int *) arg); ++ SHA_salt_rounds_to_buf (result, rounds); + } else if (0 == strcmp (method, "SHA512")) { + MAGNUM(result, '6'); + salt_len = SHA_CRYPT_SALT_SIZE; +- SHA_salt_rounds_to_buf (result, (int *) arg); ++ rounds = SHA_get_salt_rounds ((int *) arg); ++ SHA_salt_rounds_to_buf (result, rounds); + #endif /* USE_SHA_CRYPT */ + } else if (0 != strcmp (method, "DES")) { + fprintf (shadow_logfd, +@@ -463,9 +510,39 @@ static /*@observer@*/const char *gensalt (size_t salt_size) + "Defaulting to DES.\n"), + method); + salt_len = MAX_SALT_SIZE; ++ rounds = 0; + memset (result, '\0', GENSALT_SETTING_SIZE); + } + ++#if USE_XCRYPT_GENSALT ++ /* ++ * Prepare DES setting for crypt_gensalt(), if result ++ * has not been filled with anything previously. ++ */ ++ if ('\0' == result[0]) { ++ /* Avoid -Wunused-but-set-variable. */ ++ salt_len = GENSALT_SETTING_SIZE - 1; ++ rounds = 0; ++ memset (result, '.', salt_len); ++ result[salt_len] = '\0'; ++ } ++ ++ char *retval = crypt_gensalt (result, rounds, NULL, 0); ++ ++ /* Should not happen, but... */ ++ if (NULL == retval) { ++ fprintf (shadow_logfd, ++ _("Unable to generate a salt from setting " ++ "\"%s\", check your settings in " ++ "ENCRYPT_METHOD and the corresponding " ++ "configuration for your selected hash " ++ "method.\n"), result); ++ ++ exit (1); ++ } ++ ++ return retval; ++#else /* USE_XCRYPT_GENSALT */ + /* Check if the result buffer is long enough. */ + assert (GENSALT_SETTING_SIZE > strlen (result) + salt_len); + +@@ -474,4 +551,5 @@ static /*@observer@*/const char *gensalt (size_t salt_size) + GENSALT_SETTING_SIZE - strlen (result) - 1); + + return result; ++#endif /* USE_XCRYPT_GENSALT */ + } diff --git a/shadow-utils.spec b/shadow-utils.spec index 7923c7b..7e5b216 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.8.1 -Release: 16%{?dist} +Release: 17%{?dist} Epoch: 2 URL: https://github.com/shadow-maint/shadow Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -48,7 +48,7 @@ Patch28: shadow-4.8-selinux-perms.patch Patch29: shadow-4.2.1-null-tm.patch # SElinux related - upstreamability unknown Patch31: shadow-4.6-getenforce.patch -# Handle include of crypt.h - could be upstreamed +# https://github.com/shadow-maint/shadow/commit/c93897a8d71b9b1790caf3b2dee38dbe62518ae3 Patch32: shadow-4.8-crypt_h.patch # Handle /etc/passwd corruption - could be upstreamed Patch33: shadow-4.8-long-entry.patch @@ -118,6 +118,8 @@ Patch64: shadow-4.8.1-salt_c_use_dev_urandom.patch Patch65: shadow-4.8.1-useradd_create_relative_home_path_correctly.patch # https://github.com/shadow-maint/shadow/commit/c82ed0c15e0e9e47df0b4c22672b72e35f061a9d Patch66: shadow-4.8.1-getentropy_random_bytes.patch +# https://github.com/shadow-maint/shadow/commit/ea04eb301d08c0c58f1120f87d4ec184d3983ce5 +Patch67: shadow-4.8.1-crypt_gensalt.patch License: BSD and GPLv2+ BuildRequires: make @@ -209,6 +211,7 @@ Development files for shadow-utils-subid. %patch64 -p1 -b .use_dev_urandom %patch65 -p1 -b .useradd_create_relative_home_path_correctly %patch66 -p1 -b .getentropy_random_bytes +%patch67 -p1 -b .crypt_gensalt iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -380,6 +383,8 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la %changelog * Sun Jul 04 2021 Björn Esser - 2:4.8.1-16 - Add a patch to obtain random bytes using getentropy() +- Update shadow-4.8-crypt_h.patch with the upstreamed version +- Add a patch to make use of crypt_gensalt() from libxcrypt * Tue Jun 29 2021 Iker Pedrosa - 2:4.8.1-15 - useradd: free correct pointer (#1976809) From 90349359e4198987255c007060106575cf6452a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= Date: Mon, 5 Jul 2021 12:08:36 +0200 Subject: [PATCH 042/134] Fix release tag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Esser --- shadow-utils.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index 7e5b216..a78e1a3 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.8.1 -Release: 17%{?dist} +Release: 16%{?dist} Epoch: 2 URL: https://github.com/shadow-maint/shadow Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz From 08a62b5fa3ab4570e3b6e810737b033133d94c75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= Date: Mon, 12 Jul 2021 09:59:19 +0200 Subject: [PATCH 043/134] Enable bcrypt support, as libxcrypt supports it well MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Esser --- shadow-utils.login.defs | 15 ++++++++++++++- shadow-utils.spec | 6 +++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/shadow-utils.login.defs b/shadow-utils.login.defs index 67845ce..486203b 100644 --- a/shadow-utils.login.defs +++ b/shadow-utils.login.defs @@ -219,7 +219,20 @@ ENCRYPT_METHOD YESCRYPT # Currently SHA_CRYPT_MIN_ROUNDS is not supported -# Currently BCRYPT_MIN_ROUNDS and BCRYPT_MAX_ROUNDS are not supported +# +# Only works if ENCRYPT_METHOD is set to BCRYPT. +# +# Define the number of BCRYPT rounds. +# With a lot of rounds, it is more difficult to brute-force the password. +# However, more CPU resources will be needed to authenticate users if +# this value is increased. +# +# If not specified, 13 rounds will be attempted. +# If only one of the MIN or MAX values is set, then this value will be used. +# If MIN > MAX, the highest value will be used. +# +#BCRYPT_MIN_ROUNDS 13 +#BCRYPT_MAX_ROUNDS 31 # # Only works if ENCRYPT_METHOD is set to YESCRYPT. diff --git a/shadow-utils.spec b/shadow-utils.spec index a78e1a3..75898fd 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.8.1 -Release: 16%{?dist} +Release: 17%{?dist} Epoch: 2 URL: https://github.com/shadow-maint/shadow Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -238,6 +238,7 @@ autoreconf --enable-man \ --with-audit \ --with-sha-crypt \ + --with-bcrypt \ --with-yescrypt \ --with-selinux \ --without-libcrack \ @@ -381,6 +382,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la %{_libdir}/libsubid.so %changelog +* Mon Jul 12 2021 Björn Esser - 2:4.8.1-17 +- Enable bcrypt support, as libxcrypt supports it well + * Sun Jul 04 2021 Björn Esser - 2:4.8.1-16 - Add a patch to obtain random bytes using getentropy() - Update shadow-4.8-crypt_h.patch with the upstreamed version From fbe143d1bd6f5cdd0c936d1fb61fd236550ddb49 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Wed, 14 Jul 2021 11:30:45 +0200 Subject: [PATCH 044/134] Fix regression issues detected in rhbz#667593 and rhbz#672510 Signed-off-by: Iker Pedrosa --- shadow-4.8.1-covscan_fixes.patch | 9 --------- shadow-utils.spec | 5 ++++- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/shadow-4.8.1-covscan_fixes.patch b/shadow-4.8.1-covscan_fixes.patch index ea78ced..daca69f 100644 --- a/shadow-4.8.1-covscan_fixes.patch +++ b/shadow-4.8.1-covscan_fixes.patch @@ -731,15 +731,6 @@ index 2da734a7..d85d5f20 100644 return array; } -@@ -262,6 +263,8 @@ bool is_on_list (char *const *list, const char *member) - } - } - -+ free (members); -+ - /* - * Return the new array of pointers - */ diff --git a/libmisc/myname.c b/libmisc/myname.c index 05efdad3..e1b7f702 100644 --- a/libmisc/myname.c diff --git a/shadow-utils.spec b/shadow-utils.spec index 75898fd..a8be8ee 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.8.1 -Release: 17%{?dist} +Release: 18%{?dist} Epoch: 2 URL: https://github.com/shadow-maint/shadow Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -382,6 +382,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la %{_libdir}/libsubid.so %changelog +* Wed Jul 14 2021 Iker Pedrosa - 2:4.8.1-18 +- Fix regression issues detected in rhbz#667593 and rhbz#672510 + * Mon Jul 12 2021 Björn Esser - 2:4.8.1-17 - Enable bcrypt support, as libxcrypt supports it well From 0d2b677f8f44352f8ce0fa62e9230e6f4b431842 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= Date: Wed, 14 Jul 2021 16:52:12 +0200 Subject: [PATCH 045/134] Add patch to fix 'fread returns element count, not element size' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Esser --- shadow-4.8.1-salt_c_fix_fread.patch | 29 +++++++++++++++++++++++++++++ shadow-utils.spec | 8 +++++++- 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 shadow-4.8.1-salt_c_fix_fread.patch diff --git a/shadow-4.8.1-salt_c_fix_fread.patch b/shadow-4.8.1-salt_c_fix_fread.patch new file mode 100644 index 0000000..754b292 --- /dev/null +++ b/shadow-4.8.1-salt_c_fix_fread.patch @@ -0,0 +1,29 @@ +From ffd35d89021a9b8375a9246082afc6fc270a93ee Mon Sep 17 00:00:00 2001 +From: steven Y Gui +Date: Wed, 14 Jul 2021 16:17:48 +0800 +Subject: [PATCH] fread returns element count, not element size +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Björn Esser +--- + libmisc/salt.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmisc/salt.c b/libmisc/salt.c +index 9fd34332..91d528fd 100644 +--- a/libmisc/salt.c ++++ b/libmisc/salt.c +@@ -168,7 +168,7 @@ static long read_random_bytes (void) + #else + FILE *f = fopen ("/dev/urandom", "r"); + +- if (fread (&randval, sizeof (randval), 1, f) != sizeof (randval)) { ++ if (fread (&randval, sizeof (randval), 1, f) != 1) { + fclose(f); + goto fail; + } +-- +2.31.1 + diff --git a/shadow-utils.spec b/shadow-utils.spec index a8be8ee..10efca9 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.8.1 -Release: 18%{?dist} +Release: 19%{?dist} Epoch: 2 URL: https://github.com/shadow-maint/shadow Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -120,6 +120,8 @@ Patch65: shadow-4.8.1-useradd_create_relative_home_path_correctly.patch Patch66: shadow-4.8.1-getentropy_random_bytes.patch # https://github.com/shadow-maint/shadow/commit/ea04eb301d08c0c58f1120f87d4ec184d3983ce5 Patch67: shadow-4.8.1-crypt_gensalt.patch +# https://github.com/shadow-maint/shadow/commit/ffd35d89021a9b8375a9246082afc6fc270a93ee +Patch68: shadow-4.8.1-salt_c_fix_fread.patch License: BSD and GPLv2+ BuildRequires: make @@ -212,6 +214,7 @@ Development files for shadow-utils-subid. %patch65 -p1 -b .useradd_create_relative_home_path_correctly %patch66 -p1 -b .getentropy_random_bytes %patch67 -p1 -b .crypt_gensalt +%patch68 -p1 -b .fix_fread iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -382,6 +385,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la %{_libdir}/libsubid.so %changelog +* Wed Jul 14 2021 Björn Esser - 2:4.8.1-19 +- Add patch to fix 'fread returns element count, not element size' + * Wed Jul 14 2021 Iker Pedrosa - 2:4.8.1-18 - Fix regression issues detected in rhbz#667593 and rhbz#672510 From 58090e11f17c64d21363adf09c72def050d2e303 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 23 Jul 2021 17:27:44 +0000 Subject: [PATCH 046/134] - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- shadow-utils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index 10efca9..c6caf48 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.8.1 -Release: 19%{?dist} +Release: 20%{?dist} Epoch: 2 URL: https://github.com/shadow-maint/shadow Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -385,6 +385,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la %{_libdir}/libsubid.so %changelog +* Fri Jul 23 2021 Fedora Release Engineering - 2:4.8.1-20 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + * Wed Jul 14 2021 Björn Esser - 2:4.8.1-19 - Add patch to fix 'fread returns element count, not element size' From 94f04f9e715426f7cd7df6959ac76ddc5a00e4a1 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Wed, 4 Aug 2021 10:14:14 +0200 Subject: [PATCH 047/134] Rebase to version 4.9 usermod: allow all group types with -G option (#1975327) Clean spec file Signed-off-by: Iker Pedrosa --- .gitignore | 2 + shadow-4.1.5.1-info-parent-dir.patch | 21 - shadow-4.1.5.1-logmsg.patch | 13 - shadow-4.1.5.1-userdel-helpfix.patch | 16 - shadow-4.6-getenforce.patch | 21 - shadow-4.8-crypt_h.patch | 58 - shadow-4.8-selinux.patch | 241 -- shadow-4.8-useradd-selinux-mail.patch | 61 - shadow-4.8.1-check-local-groups.patch | 642 ----- ...-4.8.1-commonio-force-lock-file-sync.patch | 39 - shadow-4.8.1-covscan_fixes.patch | 793 ------ shadow-4.8.1-crypt_gensalt.patch | 310 --- ....1-fix_YESCRYPT_salt_cost_param_type.patch | 39 - shadow-4.8.1-fix_bcrypt_prefix.patch | 35 - shadow-4.8.1-getentropy_random_bytes.patch | 123 - shadow-4.8.1-libsubid_creation.patch | 1522 ---------- ...bid_fix_newusers_nss_provides_subids.patch | 151 - ...bsubid_init_not_print_error_messages.patch | 40 - shadow-4.8.1-libsubid_init_return_false.patch | 37 - ...4.8.1-libsubid_make_logfd_not_extern.patch | 41 - ....1-libsubid_not_print_error_messages.patch | 2443 ----------------- shadow-4.8.1-libsubid_nsswitch_support.patch | 2107 -------------- ....1-libsubid_simplify_ranges_variable.patch | 264 -- ....8.1-man-include-lastlog-file-caveat.patch | 33 - ...w-4.8.1-man-mention-nss-in-newuidmap.patch | 44 - ...w-4.8.1-man_clarify_subid_delegation.patch | 246 -- shadow-4.8.1-manfix.patch | 341 --- shadow-4.8.1-salt_c_comments.patch | 75 - shadow-4.8.1-salt_c_fix_fread.patch | 29 - shadow-4.8.1-salt_c_sanitize_code.patch | 555 ---- shadow-4.8.1-salt_c_use_dev_urandom.patch | 114 - shadow-4.8.1-useradd-man-clarification.patch | 35 - shadow-4.8.1-useradd_SUB_UID_COUNT-0.patch | 44 - ..._create_relative_home_path_correctly.patch | 24 - shadow-4.8.1-yescrypt-support.patch | 960 ------- ...ate.patch => shadow-4.9-audit-update.patch | 24 +- ...ge.patch => shadow-4.9-default-range.patch | 11 +- shadow-4.9-manfix.patch | 180 ++ shadow-4.9-move-create-home.patch | 64 + ...ow-4.9-newuidmap-libeconf-dependency.patch | 15 + ...-null-tm.patch => shadow-4.9-null-tm.patch | 21 - ....6-redhat.patch => shadow-4.9-redhat.patch | 20 +- ...ow-4.9-usermod-allow-all-group-types.patch | 322 +++ shadow-utils.spec | 179 +- sources | 4 +- 45 files changed, 643 insertions(+), 11716 deletions(-) delete mode 100644 shadow-4.1.5.1-info-parent-dir.patch delete mode 100644 shadow-4.1.5.1-logmsg.patch delete mode 100644 shadow-4.1.5.1-userdel-helpfix.patch delete mode 100644 shadow-4.6-getenforce.patch delete mode 100644 shadow-4.8-crypt_h.patch delete mode 100644 shadow-4.8-selinux.patch delete mode 100644 shadow-4.8-useradd-selinux-mail.patch delete mode 100644 shadow-4.8.1-check-local-groups.patch delete mode 100644 shadow-4.8.1-commonio-force-lock-file-sync.patch delete mode 100644 shadow-4.8.1-covscan_fixes.patch delete mode 100644 shadow-4.8.1-crypt_gensalt.patch delete mode 100644 shadow-4.8.1-fix_YESCRYPT_salt_cost_param_type.patch delete mode 100644 shadow-4.8.1-fix_bcrypt_prefix.patch delete mode 100644 shadow-4.8.1-getentropy_random_bytes.patch delete mode 100644 shadow-4.8.1-libsubid_creation.patch delete mode 100644 shadow-4.8.1-libsubid_fix_newusers_nss_provides_subids.patch delete mode 100644 shadow-4.8.1-libsubid_init_not_print_error_messages.patch delete mode 100644 shadow-4.8.1-libsubid_init_return_false.patch delete mode 100644 shadow-4.8.1-libsubid_make_logfd_not_extern.patch delete mode 100644 shadow-4.8.1-libsubid_not_print_error_messages.patch delete mode 100644 shadow-4.8.1-libsubid_nsswitch_support.patch delete mode 100644 shadow-4.8.1-libsubid_simplify_ranges_variable.patch delete mode 100644 shadow-4.8.1-man-include-lastlog-file-caveat.patch delete mode 100644 shadow-4.8.1-man-mention-nss-in-newuidmap.patch delete mode 100644 shadow-4.8.1-man_clarify_subid_delegation.patch delete mode 100644 shadow-4.8.1-manfix.patch delete mode 100644 shadow-4.8.1-salt_c_comments.patch delete mode 100644 shadow-4.8.1-salt_c_fix_fread.patch delete mode 100644 shadow-4.8.1-salt_c_sanitize_code.patch delete mode 100644 shadow-4.8.1-salt_c_use_dev_urandom.patch delete mode 100644 shadow-4.8.1-useradd-man-clarification.patch delete mode 100644 shadow-4.8.1-useradd_SUB_UID_COUNT-0.patch delete mode 100644 shadow-4.8.1-useradd_create_relative_home_path_correctly.patch delete mode 100644 shadow-4.8.1-yescrypt-support.patch rename shadow-4.8.1-audit-update.patch => shadow-4.9-audit-update.patch (99%) rename shadow-4.1.5.1-default-range.patch => shadow-4.9-default-range.patch (72%) create mode 100644 shadow-4.9-manfix.patch create mode 100644 shadow-4.9-move-create-home.patch create mode 100644 shadow-4.9-newuidmap-libeconf-dependency.patch rename shadow-4.2.1-null-tm.patch => shadow-4.9-null-tm.patch (75%) rename shadow-4.6-redhat.patch => shadow-4.9-redhat.patch (65%) create mode 100644 shadow-4.9-usermod-allow-all-group-types.patch diff --git a/.gitignore b/.gitignore index de3b420..cc68ade 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,5 @@ shadow-4.1.4.2.tar.bz2 /shadow-4.8.tar.xz.asc /shadow-4.8.1.tar.xz /shadow-4.8.1.tar.xz.asc +/shadow-4.9.tar.xz +/shadow-4.9.tar.xz.asc diff --git a/shadow-4.1.5.1-info-parent-dir.patch b/shadow-4.1.5.1-info-parent-dir.patch deleted file mode 100644 index b3a525b..0000000 --- a/shadow-4.1.5.1-info-parent-dir.patch +++ /dev/null @@ -1,21 +0,0 @@ -Index: shadow-4.5/man/newusers.8.xml -=================================================================== ---- shadow-4.5.orig/man/newusers.8.xml -+++ shadow-4.5/man/newusers.8.xml -@@ -218,7 +218,15 @@ - - If this field does not specify an existing directory, the - specified directory is created, with ownership set to the -- user being created or updated and its primary group. -+ user being created or updated and its primary group. Note -+ that newusers does not create parent directories of the new -+ user's home directory. The newusers command will fail to -+ create the home directory if the parent directories do not -+ exist, and will send a message to stderr informing the user -+ of the failure. The newusers command will not halt or return -+ a failure to the calling shell if it fails to create the home -+ directory, it will continue to process the batch of new users -+ specified. - - - If the home directory of an existing user is changed, diff --git a/shadow-4.1.5.1-logmsg.patch b/shadow-4.1.5.1-logmsg.patch deleted file mode 100644 index ca7e57b..0000000 --- a/shadow-4.1.5.1-logmsg.patch +++ /dev/null @@ -1,13 +0,0 @@ -Index: shadow-4.5/src/useradd.c -=================================================================== ---- shadow-4.5.orig/src/useradd.c -+++ shadow-4.5/src/useradd.c -@@ -323,7 +323,7 @@ static void fail_exit (int code) - user_name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); - #endif -- SYSLOG ((LOG_INFO, "failed adding user '%s', data deleted", user_name)); -+ SYSLOG ((LOG_INFO, "failed adding user '%s', exit code: %d", user_name, code)); - exit (code); - } - diff --git a/shadow-4.1.5.1-userdel-helpfix.patch b/shadow-4.1.5.1-userdel-helpfix.patch deleted file mode 100644 index 075f482..0000000 --- a/shadow-4.1.5.1-userdel-helpfix.patch +++ /dev/null @@ -1,16 +0,0 @@ -Index: shadow-4.5/src/userdel.c -=================================================================== ---- shadow-4.5.orig/src/userdel.c -+++ shadow-4.5/src/userdel.c -@@ -143,8 +143,9 @@ static void usage (int status) - "\n" - "Options:\n"), - Prog); -- (void) fputs (_(" -f, --force force removal of files,\n" -- " even if not owned by user\n"), -+ (void) fputs (_(" -f, --force force some actions that would fail otherwise\n" -+ " e.g. removal of user still logged in\n" -+ " or files, even if not owned by the user\n"), - usageout); - (void) fputs (_(" -h, --help display this help message and exit\n"), usageout); - (void) fputs (_(" -r, --remove remove home directory and mail spool\n"), usageout); diff --git a/shadow-4.6-getenforce.patch b/shadow-4.6-getenforce.patch deleted file mode 100644 index 8a55bf5..0000000 --- a/shadow-4.6-getenforce.patch +++ /dev/null @@ -1,21 +0,0 @@ -diff -up shadow-4.6/lib/selinux.c.getenforce shadow-4.6/lib/selinux.c ---- shadow-4.6/lib/selinux.c.getenforce 2018-05-28 15:10:15.870315221 +0200 -+++ shadow-4.6/lib/selinux.c 2018-05-28 15:10:15.894315731 +0200 -@@ -75,7 +75,7 @@ int set_selinux_file_context (const char - } - return 0; - error: -- if (security_getenforce () != 0) { -+ if (security_getenforce () > 0) { - return 1; - } - return 0; -@@ -95,7 +95,7 @@ int reset_selinux_file_context (void) - selinux_checked = true; - } - if (selinux_enabled) { -- if (setfscreatecon (NULL) != 0) { -+ if (setfscreatecon (NULL) != 0 && security_getenforce () > 0) { - return 1; - } - } diff --git a/shadow-4.8-crypt_h.patch b/shadow-4.8-crypt_h.patch deleted file mode 100644 index 6d36376..0000000 --- a/shadow-4.8-crypt_h.patch +++ /dev/null @@ -1,58 +0,0 @@ -From c93897a8d71b9b1790caf3b2dee38dbe62518ae3 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= -Date: Thu, 24 Jun 2021 12:39:27 +0200 -Subject: [PATCH] lib/defines.h: Include if present on the system. -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The functions crypt(3), crypt_gensalt(3), and their -feature test macros may be defined in there. - -Signed-off-by: Björn Esser ---- - configure.ac | 2 +- - lib/defines.h | 10 ++++++++++ - 2 files changed, 11 insertions(+), 1 deletion(-) - -Index: shadow-4.8.1/configure.ac -=================================================================== ---- shadow-4.8.1.orig/configure.ac -+++ shadow-4.8.1/configure.ac -@@ -32,7 +32,7 @@ AC_HEADER_STDC - AC_HEADER_SYS_WAIT - AC_HEADER_STDBOOL - --AC_CHECK_HEADERS(errno.h fcntl.h limits.h unistd.h sys/time.h utmp.h \ -+AC_CHECK_HEADERS(crypt.h errno.h fcntl.h limits.h unistd.h sys/time.h utmp.h \ - utmpx.h termios.h termio.h sgtty.h sys/ioctl.h syslog.h paths.h \ - utime.h ulimit.h sys/capability.h sys/resource.h gshadow.h lastlog.h \ - locale.h rpc/key_prot.h netdb.h acl/libacl.h attr/libattr.h \ -Index: shadow-4.8.1/lib/defines.h -=================================================================== ---- shadow-4.8.1.orig/lib/defines.h -+++ shadow-4.8.1/lib/defines.h -@@ -4,6 +4,8 @@ - #ifndef _DEFINES_H_ - #define _DEFINES_H_ - -+#include "config.h" -+ - #if HAVE_STDBOOL_H - # include - #else -@@ -94,6 +96,14 @@ char *strchr (), *strrchr (), *strtok (); - # include - #endif - -+/* -+ * crypt(3), crypt_gensalt(3), and their -+ * feature test macros may be defined in here. -+ */ -+#if HAVE_CRYPT_H -+# include -+#endif -+ - #if TIME_WITH_SYS_TIME - # include - # include diff --git a/shadow-4.8-selinux.patch b/shadow-4.8-selinux.patch deleted file mode 100644 index 7b2177b..0000000 --- a/shadow-4.8-selinux.patch +++ /dev/null @@ -1,241 +0,0 @@ -diff -up shadow-4.8/lib/commonio.c.selinux shadow-4.8/lib/commonio.c ---- shadow-4.8/lib/commonio.c.selinux 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8/lib/commonio.c 2020-01-13 10:08:53.769101131 +0100 -@@ -964,7 +964,7 @@ int commonio_close (struct commonio_db * - snprintf (buf, sizeof buf, "%s-", db->filename); - - #ifdef WITH_SELINUX -- if (set_selinux_file_context (buf) != 0) { -+ if (set_selinux_file_context (buf, db->filename) != 0) { - errors++; - } - #endif -@@ -997,7 +997,7 @@ int commonio_close (struct commonio_db * - snprintf (buf, sizeof buf, "%s+", db->filename); - - #ifdef WITH_SELINUX -- if (set_selinux_file_context (buf) != 0) { -+ if (set_selinux_file_context (buf, db->filename) != 0) { - errors++; - } - #endif -diff -up shadow-4.8/libmisc/copydir.c.selinux shadow-4.8/libmisc/copydir.c ---- shadow-4.8/libmisc/copydir.c.selinux 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8/libmisc/copydir.c 2020-01-13 10:08:53.769101131 +0100 -@@ -484,7 +484,7 @@ static int copy_dir (const char *src, co - */ - - #ifdef WITH_SELINUX -- if (set_selinux_file_context (dst) != 0) { -+ if (set_selinux_file_context (dst, NULL) != 0) { - return -1; - } - #endif /* WITH_SELINUX */ -@@ -605,7 +605,7 @@ static int copy_symlink (const char *src - } - - #ifdef WITH_SELINUX -- if (set_selinux_file_context (dst) != 0) { -+ if (set_selinux_file_context (dst, NULL) != 0) { - free (oldlink); - return -1; - } -@@ -684,7 +684,7 @@ static int copy_special (const char *src - int err = 0; - - #ifdef WITH_SELINUX -- if (set_selinux_file_context (dst) != 0) { -+ if (set_selinux_file_context (dst, NULL) != 0) { - return -1; - } - #endif /* WITH_SELINUX */ -@@ -744,7 +744,7 @@ static int copy_file (const char *src, c - return -1; - } - #ifdef WITH_SELINUX -- if (set_selinux_file_context (dst) != 0) { -+ if (set_selinux_file_context (dst, NULL) != 0) { - return -1; - } - #endif /* WITH_SELINUX */ -diff -up shadow-4.8/lib/prototypes.h.selinux shadow-4.8/lib/prototypes.h ---- shadow-4.8/lib/prototypes.h.selinux 2020-01-13 10:08:53.769101131 +0100 -+++ shadow-4.8/lib/prototypes.h 2020-01-13 10:11:20.914627399 +0100 -@@ -334,7 +334,7 @@ extern /*@observer@*/const char *crypt_m - - /* selinux.c */ - #ifdef WITH_SELINUX --extern int set_selinux_file_context (const char *dst_name); -+extern int set_selinux_file_context (const char *dst_name, const char *orig_name); - extern int reset_selinux_file_context (void); - extern int check_selinux_permit (const char *perm_name); - #endif -diff -up shadow-4.8/lib/selinux.c.selinux shadow-4.8/lib/selinux.c ---- shadow-4.8/lib/selinux.c.selinux 2019-11-12 01:18:25.000000000 +0100 -+++ shadow-4.8/lib/selinux.c 2020-01-13 10:08:53.769101131 +0100 -@@ -51,7 +51,7 @@ static bool selinux_enabled; - * Callers may have to Reset SELinux to create files with default - * contexts with reset_selinux_file_context - */ --int set_selinux_file_context (const char *dst_name) -+int set_selinux_file_context (const char *dst_name, const char *orig_name) - { - /*@null@*/security_context_t scontext = NULL; - -@@ -63,19 +63,23 @@ int set_selinux_file_context (const char - if (selinux_enabled) { - /* Get the default security context for this file */ - if (matchpathcon (dst_name, 0, &scontext) < 0) { -- if (security_getenforce () != 0) { -- return 1; -- } -+ /* We could not get the default, copy the original */ -+ if (orig_name == NULL) -+ goto error; -+ if (getfilecon (orig_name, &scontext) < 0) -+ goto error; - } - /* Set the security context for the next created file */ -- if (setfscreatecon (scontext) < 0) { -- if (security_getenforce () != 0) { -- return 1; -- } -- } -+ if (setfscreatecon (scontext) < 0) -+ goto error; - freecon (scontext); - } - return 0; -+ error: -+ if (security_getenforce () != 0) { -+ return 1; -+ } -+ return 0; - } - - /* -diff -up shadow-4.8/lib/semanage.c.selinux shadow-4.8/lib/semanage.c ---- shadow-4.8/lib/semanage.c.selinux 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8/lib/semanage.c 2020-01-13 10:08:53.766101181 +0100 -@@ -294,6 +294,9 @@ int set_seuser (const char *login_name, - - ret = 0; - -+ /* drop obsolete matchpathcon cache */ -+ matchpathcon_fini(); -+ - done: - semanage_seuser_key_free (key); - semanage_handle_destroy (handle); -@@ -369,6 +372,10 @@ int del_seuser (const char *login_name) - } - - ret = 0; -+ -+ /* drop obsolete matchpathcon cache */ -+ matchpathcon_fini(); -+ - done: - semanage_handle_destroy (handle); - return ret; -diff -up shadow-4.8/src/useradd.c.selinux shadow-4.8/src/useradd.c ---- shadow-4.8/src/useradd.c.selinux 2020-01-13 10:08:53.762101248 +0100 -+++ shadow-4.8/src/useradd.c 2020-01-13 10:08:53.767101164 +0100 -@@ -2078,7 +2078,7 @@ static void create_home (void) - ++bhome; - - #ifdef WITH_SELINUX -- if (set_selinux_file_context (prefix_user_home) != 0) { -+ if (set_selinux_file_context (prefix_user_home, NULL) != 0) { - fprintf (stderr, - _("%s: cannot set SELinux context for home directory %s\n"), - Prog, user_home); -@@ -2232,6 +2232,7 @@ static void create_mail (void) - */ - int main (int argc, char **argv) - { -+ int rv = E_SUCCESS; - #ifdef ACCT_TOOLS_SETUID - #ifdef USE_PAM - pam_handle_t *pamh = NULL; -@@ -2454,27 +2455,12 @@ int main (int argc, char **argv) - - usr_update (); - -- if (mflg) { -- create_home (); -- if (home_added) { -- copy_tree (def_template, prefix_user_home, false, false, -- (uid_t)-1, user_id, (gid_t)-1, user_gid); -- } else { -- fprintf (stderr, -- _("%s: warning: the home directory %s already exists.\n" -- "%s: Not copying any file from skel directory into it.\n"), -- Prog, user_home, Prog); -- } -- -- } -- -- /* Do not create mail directory for system accounts */ -- if (!rflg) { -- create_mail (); -- } -- - close_files (); - -+ nscd_flush_cache ("passwd"); -+ nscd_flush_cache ("group"); -+ sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP); -+ - /* - * tallylog_reset needs to be able to lookup - * a valid existing user name, -@@ -2485,8 +2471,9 @@ int main (int argc, char **argv) - } - - #ifdef WITH_SELINUX -- if (Zflg) { -- if (set_seuser (user_name, user_selinux) != 0) { -+ if (Zflg && *user_selinux) { -+ if (is_selinux_enabled () > 0) { -+ if (set_seuser (user_name, user_selinux) != 0) { - fprintf (stderr, - _("%s: warning: the user name %s to %s SELinux user mapping failed.\n"), - Prog, user_name, user_selinux); -@@ -2495,15 +2482,31 @@ int main (int argc, char **argv) - "adding SELinux user mapping", - user_name, (unsigned int) user_id, 0); - #endif /* WITH_AUDIT */ -- fail_exit (E_SE_UPDATE); -+ rv = E_SE_UPDATE; -+ } - } - } - #endif /* WITH_SELINUX */ - -- nscd_flush_cache ("passwd"); -- nscd_flush_cache ("group"); -- sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP); -+ if (mflg) { -+ create_home (); -+ if (home_added) { -+ copy_tree (def_template, prefix_user_home, false, true, -+ (uid_t)-1, user_id, (gid_t)-1, user_gid); -+ } else { -+ fprintf (stderr, -+ _("%s: warning: the home directory %s already exists.\n" -+ "%s: Not copying any file from skel directory into it.\n"), -+ Prog, user_home, Prog); -+ } -+ -+ } -+ -+ /* Do not create mail directory for system accounts */ -+ if (!rflg) { -+ create_mail (); -+ } - -- return E_SUCCESS; -+ return rv; - } - diff --git a/shadow-4.8-useradd-selinux-mail.patch b/shadow-4.8-useradd-selinux-mail.patch deleted file mode 100644 index 1777f2d..0000000 --- a/shadow-4.8-useradd-selinux-mail.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 4dc62ebcf37d7568be1d4ca54367215eba8b8a28 Mon Sep 17 00:00:00 2001 -From: ikerexxe -Date: Wed, 5 Feb 2020 15:04:39 +0100 -Subject: [PATCH] useradd: doesn't generate /var/spool/mail/$USER with the - proper SELinux user identity - -Explanation: use set_selinux_file_context() and reset_selinux_file_context() for create_mail() just as is done for create_home() - -Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1690527 ---- - src/useradd.c | 20 ++++++++++++++++++++ - 1 file changed, 20 insertions(+) - -diff --git a/src/useradd.c b/src/useradd.c -index a679392d..645d4a40 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -190,6 +190,7 @@ static bool home_added = false; - #define E_NAME_IN_USE 9 /* username already in use */ - #define E_GRP_UPDATE 10 /* can't update group file */ - #define E_HOMEDIR 12 /* can't create home directory */ -+#define E_MAILBOXFILE 13 /* can't create mailbox file */ - #define E_SE_UPDATE 14 /* can't update SELinux user mapping */ - #ifdef ENABLE_SUBIDS - #define E_SUB_UID_UPDATE 16 /* can't update the subordinate uid file */ -@@ -2210,6 +2211,16 @@ static void create_mail (void) - sprintf (file, "%s/%s/%s", prefix, spool, user_name); - else - sprintf (file, "%s/%s", spool, user_name); -+ -+#ifdef WITH_SELINUX -+ if (set_selinux_file_context (file, NULL) != 0) { -+ fprintf (stderr, -+ _("%s: cannot set SELinux context for mailbox file %s\n"), -+ Prog, file); -+ fail_exit (E_MAILBOXFILE); -+ } -+#endif -+ - fd = open (file, O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, 0); - if (fd < 0) { - perror (_("Creating mailbox file")); -@@ -2234,6 +2245,15 @@ static void create_mail (void) - - fsync (fd); - close (fd); -+#ifdef WITH_SELINUX -+ /* Reset SELinux to create files with default contexts */ -+ if (reset_selinux_file_context () != 0) { -+ fprintf (stderr, -+ _("%s: cannot reset SELinux file creation context\n"), -+ Prog); -+ fail_exit (E_MAILBOXFILE); -+ } -+#endif - } - } - --- -2.24.1 - diff --git a/shadow-4.8.1-check-local-groups.patch b/shadow-4.8.1-check-local-groups.patch deleted file mode 100644 index 6e9d2bf..0000000 --- a/shadow-4.8.1-check-local-groups.patch +++ /dev/null @@ -1,642 +0,0 @@ -From 140510de9de4771feb3af1d859c09604043a4c9b Mon Sep 17 00:00:00 2001 -From: ikerexxe -Date: Fri, 27 Mar 2020 14:23:02 +0100 -Subject: [PATCH 1/2] usermod: check only local groups with -G option - -Check only local groups when adding new supplementary groups to a user - -Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1727236 ---- - src/usermod.c | 220 ++++++++++++++++++++++++++++++++------------------ - 1 file changed, 143 insertions(+), 77 deletions(-) - -diff --git a/src/usermod.c b/src/usermod.c -index 05b98715..ef430296 100644 ---- a/src/usermod.c -+++ b/src/usermod.c -@@ -183,6 +183,7 @@ static bool sub_gid_locked = false; - static void date_to_str (/*@unique@*//*@out@*/char *buf, size_t maxsize, - long int date); - static int get_groups (char *); -+static struct group * get_local_group (char * grp_name); - static /*@noreturn@*/void usage (int status); - static void new_pwent (struct passwd *); - static void new_spent (struct spwd *); -@@ -196,7 +197,9 @@ static void grp_update (void); - - static void process_flags (int, char **); - static void close_files (void); -+static void close_group_files (void); - static void open_files (void); -+static void open_group_files (void); - static void usr_update (void); - static void move_home (void); - static void update_lastlog (void); -@@ -253,6 +256,11 @@ static int get_groups (char *list) - return 0; - } - -+ /* -+ * Open the group files -+ */ -+ open_group_files (); -+ - /* - * So long as there is some data to be converted, strip off each - * name and look it up. A mix of numerical and string values for -@@ -272,7 +280,7 @@ static int get_groups (char *list) - * Names starting with digits are treated as numerical GID - * values, otherwise the string is looked up as is. - */ -- grp = prefix_getgr_nam_gid (list); -+ grp = get_local_group (list); - - /* - * There must be a match, either by GID value or by -@@ -322,6 +330,8 @@ static int get_groups (char *list) - gr_free ((struct group *)grp); - } while (NULL != list); - -+ close_group_files (); -+ - user_groups[ngroups] = (char *) 0; - - /* -@@ -334,6 +344,44 @@ static int get_groups (char *list) - return 0; - } - -+/* -+ * get_local_group - checks if a given group name exists locally -+ * -+ * get_local_group() checks if a given group name exists locally. -+ * If the name exists the group information is returned, otherwise NULL is -+ * returned. -+ */ -+static struct group * get_local_group(char * grp_name) -+{ -+ const struct group *grp; -+ struct group *result_grp = NULL; -+ long long int gid; -+ char *endptr; -+ -+ gid = strtoll (grp_name, &endptr, 10); -+ if ( ('\0' != *grp_name) -+ && ('\0' == *endptr) -+ && (ERANGE != errno) -+ && (gid == (gid_t)gid)) { -+ grp = gr_locate_gid ((gid_t) gid); -+ } -+ else { -+ grp = gr_locate(grp_name); -+ } -+ -+ if (grp != NULL) { -+ result_grp = __gr_dup (grp); -+ if (NULL == result_grp) { -+ fprintf (stderr, -+ _("%s: Out of memory. Cannot find group '%s'.\n"), -+ Prog, grp_name); -+ fail_exit (E_GRP_UPDATE); -+ } -+ } -+ -+ return result_grp; -+} -+ - #ifdef ENABLE_SUBIDS - struct ulong_range - { -@@ -1447,50 +1495,7 @@ static void close_files (void) - } - - if (Gflg || lflg) { -- if (gr_close () == 0) { -- fprintf (stderr, -- _("%s: failure while writing changes to %s\n"), -- Prog, gr_dbname ()); -- SYSLOG ((LOG_ERR, -- "failure while writing changes to %s", -- gr_dbname ())); -- fail_exit (E_GRP_UPDATE); -- } --#ifdef SHADOWGRP -- if (is_shadow_grp) { -- if (sgr_close () == 0) { -- fprintf (stderr, -- _("%s: failure while writing changes to %s\n"), -- Prog, sgr_dbname ()); -- SYSLOG ((LOG_ERR, -- "failure while writing changes to %s", -- sgr_dbname ())); -- fail_exit (E_GRP_UPDATE); -- } -- } --#endif --#ifdef SHADOWGRP -- if (is_shadow_grp) { -- if (sgr_unlock () == 0) { -- fprintf (stderr, -- _("%s: failed to unlock %s\n"), -- Prog, sgr_dbname ()); -- SYSLOG ((LOG_ERR, -- "failed to unlock %s", -- sgr_dbname ())); -- /* continue */ -- } -- } --#endif -- if (gr_unlock () == 0) { -- fprintf (stderr, -- _("%s: failed to unlock %s\n"), -- Prog, gr_dbname ()); -- SYSLOG ((LOG_ERR, -- "failed to unlock %s", -- gr_dbname ())); -- /* continue */ -- } -+ close_group_files (); - } - - if (is_shadow_pwd) { -@@ -1559,6 +1564,60 @@ static void close_files (void) - #endif - } - -+/* -+ * close_group_files - close all of the files that were opened -+ * -+ * close_group_files() closes all of the files that were opened related -+ * with groups. This causes any modified entries to be written out. -+ */ -+static void close_group_files (void) -+{ -+ if (gr_close () == 0) { -+ fprintf (stderr, -+ _("%s: failure while writing changes to %s\n"), -+ Prog, gr_dbname ()); -+ SYSLOG ((LOG_ERR, -+ "failure while writing changes to %s", -+ gr_dbname ())); -+ fail_exit (E_GRP_UPDATE); -+ } -+#ifdef SHADOWGRP -+ if (is_shadow_grp) { -+ if (sgr_close () == 0) { -+ fprintf (stderr, -+ _("%s: failure while writing changes to %s\n"), -+ Prog, sgr_dbname ()); -+ SYSLOG ((LOG_ERR, -+ "failure while writing changes to %s", -+ sgr_dbname ())); -+ fail_exit (E_GRP_UPDATE); -+ } -+ } -+#endif -+#ifdef SHADOWGRP -+ if (is_shadow_grp) { -+ if (sgr_unlock () == 0) { -+ fprintf (stderr, -+ _("%s: failed to unlock %s\n"), -+ Prog, sgr_dbname ()); -+ SYSLOG ((LOG_ERR, -+ "failed to unlock %s", -+ sgr_dbname ())); -+ /* continue */ -+ } -+ } -+#endif -+ if (gr_unlock () == 0) { -+ fprintf (stderr, -+ _("%s: failed to unlock %s\n"), -+ Prog, gr_dbname ()); -+ SYSLOG ((LOG_ERR, -+ "failed to unlock %s", -+ gr_dbname ())); -+ /* continue */ -+ } -+} -+ - /* - * open_files - lock and open the password files - * -@@ -1594,38 +1653,7 @@ static void open_files (void) - } - - if (Gflg || lflg) { -- /* -- * Lock and open the group file. This will load all of the -- * group entries. -- */ -- if (gr_lock () == 0) { -- fprintf (stderr, -- _("%s: cannot lock %s; try again later.\n"), -- Prog, gr_dbname ()); -- fail_exit (E_GRP_UPDATE); -- } -- gr_locked = true; -- if (gr_open (O_CREAT | O_RDWR) == 0) { -- fprintf (stderr, -- _("%s: cannot open %s\n"), -- Prog, gr_dbname ()); -- fail_exit (E_GRP_UPDATE); -- } --#ifdef SHADOWGRP -- if (is_shadow_grp && (sgr_lock () == 0)) { -- fprintf (stderr, -- _("%s: cannot lock %s; try again later.\n"), -- Prog, sgr_dbname ()); -- fail_exit (E_GRP_UPDATE); -- } -- sgr_locked = true; -- if (is_shadow_grp && (sgr_open (O_CREAT | O_RDWR) == 0)) { -- fprintf (stderr, -- _("%s: cannot open %s\n"), -- Prog, sgr_dbname ()); -- fail_exit (E_GRP_UPDATE); -- } --#endif -+ open_group_files (); - } - #ifdef ENABLE_SUBIDS - if (vflg || Vflg) { -@@ -1661,6 +1689,44 @@ static void open_files (void) - #endif /* ENABLE_SUBIDS */ - } - -+/* -+ * open_group_files - lock and open the group files -+ * -+ * open_group_files() loads all of the group entries. -+ */ -+static void open_group_files (void) -+{ -+ if (gr_lock () == 0) { -+ fprintf (stderr, -+ _("%s: cannot lock %s; try again later.\n"), -+ Prog, gr_dbname ()); -+ fail_exit (E_GRP_UPDATE); -+ } -+ gr_locked = true; -+ if (gr_open (O_CREAT | O_RDWR) == 0) { -+ fprintf (stderr, -+ _("%s: cannot open %s\n"), -+ Prog, gr_dbname ()); -+ fail_exit (E_GRP_UPDATE); -+ } -+ -+#ifdef SHADOWGRP -+ if (is_shadow_grp && (sgr_lock () == 0)) { -+ fprintf (stderr, -+ _("%s: cannot lock %s; try again later.\n"), -+ Prog, sgr_dbname ()); -+ fail_exit (E_GRP_UPDATE); -+ } -+ sgr_locked = true; -+ if (is_shadow_grp && (sgr_open (O_CREAT | O_RDWR) == 0)) { -+ fprintf (stderr, -+ _("%s: cannot open %s\n"), -+ Prog, sgr_dbname ()); -+ fail_exit (E_GRP_UPDATE); -+ } -+#endif -+} -+ - /* - * usr_update - create the user entries - * --- -2.25.4 - - -From 8762f465d487a52bf68f9c0b7c3c1eb3caea7bc9 Mon Sep 17 00:00:00 2001 -From: ikerexxe -Date: Mon, 30 Mar 2020 09:08:23 +0200 -Subject: [PATCH 2/2] useradd: check only local groups with -G option - -Check only local groups when adding new supplementary groups to a user - -Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1727236 ---- - src/useradd.c | 234 +++++++++++++++++++++++++++++++++----------------- - 1 file changed, 157 insertions(+), 77 deletions(-) - -diff --git a/src/useradd.c b/src/useradd.c -index 645d4a40..90210233 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -211,6 +211,7 @@ static void get_defaults (void); - static void show_defaults (void); - static int set_defaults (void); - static int get_groups (char *); -+static struct group * get_local_group (char * grp_name); - static void usage (int status); - static void new_pwent (struct passwd *); - -@@ -220,7 +221,10 @@ static void grp_update (void); - - static void process_flags (int argc, char **argv); - static void close_files (void); -+static void close_group_files (void); -+static void unlock_group_files (void); - static void open_files (void); -+static void open_group_files (void); - static void open_shadow (void); - static void faillog_reset (uid_t); - static void lastlog_reset (uid_t); -@@ -731,6 +735,11 @@ static int get_groups (char *list) - return 0; - } - -+ /* -+ * Open the group files -+ */ -+ open_group_files (); -+ - /* - * So long as there is some data to be converted, strip off - * each name and look it up. A mix of numerical and string -@@ -749,7 +758,7 @@ static int get_groups (char *list) - * Names starting with digits are treated as numerical - * GID values, otherwise the string is looked up as is. - */ -- grp = prefix_getgr_nam_gid (list); -+ grp = get_local_group (list); - - /* - * There must be a match, either by GID value or by -@@ -799,6 +808,9 @@ static int get_groups (char *list) - user_groups[ngroups++] = xstrdup (grp->gr_name); - } while (NULL != list); - -+ close_group_files (); -+ unlock_group_files (); -+ - user_groups[ngroups] = (char *) 0; - - /* -@@ -811,6 +823,44 @@ static int get_groups (char *list) - return 0; - } - -+/* -+ * get_local_group - checks if a given group name exists locally -+ * -+ * get_local_group() checks if a given group name exists locally. -+ * If the name exists the group information is returned, otherwise NULL is -+ * returned. -+ */ -+static struct group * get_local_group(char * grp_name) -+{ -+ const struct group *grp; -+ struct group *result_grp = NULL; -+ long long int gid; -+ char *endptr; -+ -+ gid = strtoll (grp_name, &endptr, 10); -+ if ( ('\0' != *grp_name) -+ && ('\0' == *endptr) -+ && (ERANGE != errno) -+ && (gid == (gid_t)gid)) { -+ grp = gr_locate_gid ((gid_t) gid); -+ } -+ else { -+ grp = gr_locate(grp_name); -+ } -+ -+ if (grp != NULL) { -+ result_grp = __gr_dup (grp); -+ if (NULL == result_grp) { -+ fprintf (stderr, -+ _("%s: Out of memory. Cannot find group '%s'.\n"), -+ Prog, grp_name); -+ fail_exit (E_GRP_UPDATE); -+ } -+ } -+ -+ return result_grp; -+} -+ - /* - * usage - display usage message and exit - */ -@@ -1530,23 +1580,9 @@ static void close_files (void) - SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); - fail_exit (E_PW_UPDATE); - } -- if (do_grp_update) { -- if (gr_close () == 0) { -- fprintf (stderr, -- _("%s: failure while writing changes to %s\n"), Prog, gr_dbname ()); -- SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ())); -- fail_exit (E_GRP_UPDATE); -- } --#ifdef SHADOWGRP -- if (is_shadow_grp && (sgr_close () == 0)) { -- fprintf (stderr, -- _("%s: failure while writing changes to %s\n"), -- Prog, sgr_dbname ()); -- SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ())); -- fail_exit (E_GRP_UPDATE); -- } --#endif -- } -+ -+ close_group_files (); -+ - #ifdef ENABLE_SUBIDS - if (is_sub_uid && (sub_uid_close () == 0)) { - fprintf (stderr, -@@ -1587,34 +1623,9 @@ static void close_files (void) - /* continue */ - } - pw_locked = false; -- if (gr_unlock () == 0) { -- fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); -- SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); --#ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_USER, Prog, -- "unlocking-group-file", -- user_name, AUDIT_NO_ID, -- SHADOW_AUDIT_FAILURE); --#endif -- /* continue */ -- } -- gr_locked = false; --#ifdef SHADOWGRP -- if (is_shadow_grp) { -- if (sgr_unlock () == 0) { -- fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); -- SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); --#ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_USER, Prog, -- "unlocking-gshadow-file", -- user_name, AUDIT_NO_ID, -- SHADOW_AUDIT_FAILURE); --#endif -- /* continue */ -- } -- sgr_locked = false; -- } --#endif -+ -+ unlock_group_files (); -+ - #ifdef ENABLE_SUBIDS - if (is_sub_uid) { - if (sub_uid_unlock () == 0) { -@@ -1647,6 +1658,71 @@ static void close_files (void) - #endif /* ENABLE_SUBIDS */ - } - -+/* -+ * close_group_files - close all of the files that were opened -+ * -+ * close_group_files() closes all of the files that were opened related -+ * with groups. This causes any modified entries to be written out. -+ */ -+static void close_group_files (void) -+{ -+ if (do_grp_update) { -+ if (gr_close () == 0) { -+ fprintf (stderr, -+ _("%s: failure while writing changes to %s\n"), Prog, gr_dbname ()); -+ SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ())); -+ fail_exit (E_GRP_UPDATE); -+ } -+#ifdef SHADOWGRP -+ if (is_shadow_grp && (sgr_close () == 0)) { -+ fprintf (stderr, -+ _("%s: failure while writing changes to %s\n"), -+ Prog, sgr_dbname ()); -+ SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ())); -+ fail_exit (E_GRP_UPDATE); -+ } -+#endif /* SHADOWGRP */ -+ } -+} -+ -+/* -+ * unlock_group_files - unlock all of the files that were locked -+ * -+ * unlock_group_files() unlocks all of the files that were locked related -+ * with groups. This causes any modified entries to be written out. -+ */ -+static void unlock_group_files (void) -+{ -+ if (gr_unlock () == 0) { -+ fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); -+ SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); -+#ifdef WITH_AUDIT -+ audit_logger (AUDIT_ADD_USER, Prog, -+ "unlocking-group-file", -+ user_name, AUDIT_NO_ID, -+ SHADOW_AUDIT_FAILURE); -+#endif /* WITH_AUDIT */ -+ /* continue */ -+ } -+ gr_locked = false; -+#ifdef SHADOWGRP -+ if (is_shadow_grp) { -+ if (sgr_unlock () == 0) { -+ fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); -+ SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); -+#ifdef WITH_AUDIT -+ audit_logger (AUDIT_ADD_USER, Prog, -+ "unlocking-gshadow-file", -+ user_name, AUDIT_NO_ID, -+ SHADOW_AUDIT_FAILURE); -+#endif /* WITH_AUDIT */ -+ /* continue */ -+ } -+ sgr_locked = false; -+ } -+#endif /* SHADOWGRP */ -+} -+ - /* - * open_files - lock and open the password files - * -@@ -1668,37 +1744,8 @@ static void open_files (void) - - /* shadow file will be opened by open_shadow(); */ - -- /* -- * Lock and open the group file. -- */ -- if (gr_lock () == 0) { -- fprintf (stderr, -- _("%s: cannot lock %s; try again later.\n"), -- Prog, gr_dbname ()); -- fail_exit (E_GRP_UPDATE); -- } -- gr_locked = true; -- if (gr_open (O_CREAT | O_RDWR) == 0) { -- fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ()); -- fail_exit (E_GRP_UPDATE); -- } --#ifdef SHADOWGRP -- if (is_shadow_grp) { -- if (sgr_lock () == 0) { -- fprintf (stderr, -- _("%s: cannot lock %s; try again later.\n"), -- Prog, sgr_dbname ()); -- fail_exit (E_GRP_UPDATE); -- } -- sgr_locked = true; -- if (sgr_open (O_CREAT | O_RDWR) == 0) { -- fprintf (stderr, -- _("%s: cannot open %s\n"), -- Prog, sgr_dbname ()); -- fail_exit (E_GRP_UPDATE); -- } -- } --#endif -+ open_group_files (); -+ - #ifdef ENABLE_SUBIDS - if (is_sub_uid) { - if (sub_uid_lock () == 0) { -@@ -1733,6 +1780,39 @@ static void open_files (void) - #endif /* ENABLE_SUBIDS */ - } - -+static void open_group_files (void) -+{ -+ if (gr_lock () == 0) { -+ fprintf (stderr, -+ _("%s: cannot lock %s; try again later.\n"), -+ Prog, gr_dbname ()); -+ fail_exit (E_GRP_UPDATE); -+ } -+ gr_locked = true; -+ if (gr_open (O_CREAT | O_RDWR) == 0) { -+ fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ()); -+ fail_exit (E_GRP_UPDATE); -+ } -+ -+#ifdef SHADOWGRP -+ if (is_shadow_grp) { -+ if (sgr_lock () == 0) { -+ fprintf (stderr, -+ _("%s: cannot lock %s; try again later.\n"), -+ Prog, sgr_dbname ()); -+ fail_exit (E_GRP_UPDATE); -+ } -+ sgr_locked = true; -+ if (sgr_open (O_CREAT | O_RDWR) == 0) { -+ fprintf (stderr, -+ _("%s: cannot open %s\n"), -+ Prog, sgr_dbname ()); -+ fail_exit (E_GRP_UPDATE); -+ } -+ } -+#endif /* SHADOWGRP */ -+} -+ - static void open_shadow (void) - { - if (!is_shadow_pwd) { --- -2.25.4 - diff --git a/shadow-4.8.1-commonio-force-lock-file-sync.patch b/shadow-4.8.1-commonio-force-lock-file-sync.patch deleted file mode 100644 index 5ca7b53..0000000 --- a/shadow-4.8.1-commonio-force-lock-file-sync.patch +++ /dev/null @@ -1,39 +0,0 @@ -From fb0f702cbf958a5ee9097c1611212c9880b347ce Mon Sep 17 00:00:00 2001 -From: ikerexxe -Date: Mon, 2 Nov 2020 17:08:55 +0100 -Subject: [PATCH] commonio: force lock file sync - -lib/commonio.c: after writing to the lock file, force a file sync to -the storage system. - -Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1862056 ---- - lib/commonio.c | 12 +++++++++++- - 1 file changed, 11 insertions(+), 1 deletion(-) - -diff --git a/lib/commonio.c b/lib/commonio.c -index 16fa7e75..c5b3d104 100644 ---- a/lib/commonio.c -+++ b/lib/commonio.c -@@ -157,7 +157,17 @@ static int do_lock_file (const char *file, const char *lock, bool log) - if (write (fd, buf, (size_t) len) != len) { - if (log) { - (void) fprintf (stderr, -- "%s: %s: %s\n", -+ "%s: %s file write error: %s\n", -+ Prog, file, strerror (errno)); -+ } -+ (void) close (fd); -+ unlink (file); -+ return 0; -+ } -+ if (fdatasync (fd) == -1) { -+ if (log) { -+ (void) fprintf (stderr, -+ "%s: %s file sync error: %s\n", - Prog, file, strerror (errno)); - } - (void) close (fd); --- -2.26.2 - diff --git a/shadow-4.8.1-covscan_fixes.patch b/shadow-4.8.1-covscan_fixes.patch deleted file mode 100644 index daca69f..0000000 --- a/shadow-4.8.1-covscan_fixes.patch +++ /dev/null @@ -1,793 +0,0 @@ -From fd9d79a1a3438ba7703939cfcd45fc266782c64e Mon Sep 17 00:00:00 2001 -From: whzhe -Date: Thu, 17 Dec 2020 03:27:15 -0500 -Subject: [PATCH] useradd.c:fix memleak in get_groups - -Signed-off-by: whzhe ---- - src/useradd.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/src/useradd.c b/src/useradd.c -index 107e65f8..822b67f5 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -793,6 +793,7 @@ static int get_groups (char *list) - fprintf (stderr, - _("%s: group '%s' is a NIS group.\n"), - Prog, grp->gr_name); -+ gr_free(grp); - continue; - } - #endif -@@ -801,6 +802,7 @@ static int get_groups (char *list) - fprintf (stderr, - _("%s: too many groups specified (max %d).\n"), - Prog, ngroups); -+ gr_free(grp); - break; - } - -@@ -808,6 +810,7 @@ static int get_groups (char *list) - * Add the group name to the user's list of groups. - */ - user_groups[ngroups++] = xstrdup (grp->gr_name); -+ gr_free (grp); - } while (NULL != list); - - close_group_files (); --- -2.31.1 - -From c44b71cec25d60efc51aec9de3abce1f6efbfcf5 Mon Sep 17 00:00:00 2001 -From: whzhe51 -Date: Sat, 19 Dec 2020 04:29:06 -0500 -Subject: [PATCH] useradd.c:fix memleaks of grp Signed-off-by: whzhe51 - - ---- - src/useradd.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/useradd.c b/src/useradd.c -index 107e65f8..29c54e44 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -411,6 +411,7 @@ static void get_defaults (void) - } else { - def_group = grp->gr_gid; - def_gname = xstrdup (grp->gr_name); -+ gr_free(grp); - } - } - --- -2.31.1 - -From 1aed7ae945aafaeb253fc89a7ecedeaedf72654e Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Thu, 10 Jun 2021 13:05:03 +0200 -Subject: [PATCH] useradd.c: fix covscan RESOURCE_LEAK - -Error: RESOURCE_LEAK (CWE-772): [#def28] -shadow-4.8.1/src/useradd.c:1905: open_fn: Returning handle opened by "open". [Note: The source code implementation of the function has been overridden by a user model.] -shadow-4.8.1/src/useradd.c:1905: var_assign: Assigning: "fd" = handle returned from "open("/var/log/faillog", 2)". -shadow-4.8.1/src/useradd.c:1906: noescape: Resource "fd" is not freed or pointed-to in "lseek". -shadow-4.8.1/src/useradd.c:1917: leaked_handle: Handle variable "fd" going out of scope leaks the handle. - 1915| /* continue */ - 1916| } - 1917|-> } - 1918| - 1919| static void lastlog_reset (uid_t uid) - -Error: RESOURCE_LEAK (CWE-772): [#def29] -shadow-4.8.1/src/useradd.c:1938: open_fn: Returning handle opened by "open". [Note: The source code implementation of the function has been overridden by a user model.] -shadow-4.8.1/src/useradd.c:1938: var_assign: Assigning: "fd" = handle returned from "open("/var/log/lastlog", 2)". -shadow-4.8.1/src/useradd.c:1939: noescape: Resource "fd" is not freed or pointed-to in "lseek". -shadow-4.8.1/src/useradd.c:1950: leaked_handle: Handle variable "fd" going out of scope leaks the handle. - 1948| /* continue */ - 1949| } - 1950|-> } - 1951| - 1952| static void tallylog_reset (const char *user_name) - -Error: RESOURCE_LEAK (CWE-772): [#def30] -shadow-4.8.1/src/useradd.c:2109: alloc_fn: Storage is returned from allocation function "strdup". -shadow-4.8.1/src/useradd.c:2109: var_assign: Assigning: "bhome" = storage returned from "strdup(prefix_user_home)". -shadow-4.8.1/src/useradd.c:2131: noescape: Resource "bhome" is not freed or pointed-to in "strtok". -shadow-4.8.1/src/useradd.c:2207: leaked_storage: Variable "bhome" going out of scope leaks the storage it points to. - 2205| } - 2206| #endif - 2207|-> } - 2208| } - 2209| ---- - src/useradd.c | 41 ++++++++++++++++++++++++++++++++--------- - 1 file changed, 32 insertions(+), 9 deletions(-) - -diff --git a/src/useradd.c b/src/useradd.c -index 4248b62c..127177e2 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -1964,16 +1964,26 @@ static void faillog_reset (uid_t uid) - memzero (&fl, sizeof (fl)); - - fd = open (FAILLOG_FILE, O_RDWR); -- if ( (-1 == fd) -- || (lseek (fd, offset_uid, SEEK_SET) != offset_uid) -+ if (-1 == fd) { -+ fprintf (stderr, -+ _("%s: failed to open the faillog file for UID %lu: %s\n"), -+ Prog, (unsigned long) uid, strerror (errno)); -+ SYSLOG ((LOG_WARN, "failed to open the faillog file for UID %lu", (unsigned long) uid)); -+ return; -+ } -+ if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid) - || (write (fd, &fl, sizeof (fl)) != (ssize_t) sizeof (fl)) -- || (fsync (fd) != 0) -- || (close (fd) != 0)) { -+ || (fsync (fd) != 0)) { - fprintf (stderr, - _("%s: failed to reset the faillog entry of UID %lu: %s\n"), - Prog, (unsigned long) uid, strerror (errno)); - SYSLOG ((LOG_WARN, "failed to reset the faillog entry of UID %lu", (unsigned long) uid)); -- /* continue */ -+ } -+ if (close (fd) != 0) { -+ fprintf (stderr, -+ _("%s: failed to close the faillog file for UID %lu: %s\n"), -+ Prog, (unsigned long) uid, strerror (errno)); -+ SYSLOG ((LOG_WARN, "failed to close the faillog file for UID %lu", (unsigned long) uid)); - } - } - -@@ -1997,17 +2007,29 @@ static void lastlog_reset (uid_t uid) - memzero (&ll, sizeof (ll)); - - fd = open (LASTLOG_FILE, O_RDWR); -- if ( (-1 == fd) -- || (lseek (fd, offset_uid, SEEK_SET) != offset_uid) -+ if (-1 == fd) { -+ fprintf (stderr, -+ _("%s: failed to open the lastlog file for UID %lu: %s\n"), -+ Prog, (unsigned long) uid, strerror (errno)); -+ SYSLOG ((LOG_WARN, "failed to open the lastlog file for UID %lu", (unsigned long) uid)); -+ return; -+ } -+ if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid) - || (write (fd, &ll, sizeof (ll)) != (ssize_t) sizeof (ll)) -- || (fsync (fd) != 0) -- || (close (fd) != 0)) { -+ || (fsync (fd) != 0)) { - fprintf (stderr, - _("%s: failed to reset the lastlog entry of UID %lu: %s\n"), - Prog, (unsigned long) uid, strerror (errno)); - SYSLOG ((LOG_WARN, "failed to reset the lastlog entry of UID %lu", (unsigned long) uid)); - /* continue */ - } -+ if (close (fd) != 0) { -+ fprintf (stderr, -+ _("%s: failed to close the lastlog file for UID %lu: %s\n"), -+ Prog, (unsigned long) uid, strerror (errno)); -+ SYSLOG ((LOG_WARN, "failed to close the lastlog file for UID %lu", (unsigned long) uid)); -+ /* continue */ -+ } - } - - static void tallylog_reset (const char *user_name) -@@ -2254,6 +2276,7 @@ static void create_home (void) - } - cp = strtok (NULL, "/"); - } -+ free (bhome); - - (void) chown (prefix_user_home, user_id, user_gid); - mode_t mode = getdef_num ("HOME_MODE", --- -2.31.1 - -From 8281c82e324b57b3a4b520afad26b43ce128d521 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Fri, 11 Jun 2021 11:50:49 +0200 -Subject: [PATCH] usermod.c: fix covscan RESOURCE_LEAK - -Error: RESOURCE_LEAK (CWE-772): [#def31] -shadow-4.8.1/src/usermod.c:813: alloc_fn: Storage is returned from allocation function "__gr_dup". -shadow-4.8.1/src/usermod.c:813: var_assign: Assigning: "ngrp" = storage returned from "__gr_dup(grp)". -shadow-4.8.1/src/usermod.c:892: leaked_storage: Variable "ngrp" going out of scope leaks the storage it points to. - 890| } - 891| } - 892|-> } - 893| - 894| #ifdef SHADOWGRP - -Error: RESOURCE_LEAK (CWE-772): [#def32] -shadow-4.8.1/src/usermod.c:933: alloc_fn: Storage is returned from allocation function "__sgr_dup". -shadow-4.8.1/src/usermod.c:933: var_assign: Assigning: "nsgrp" = storage returned from "__sgr_dup(sgrp)". -shadow-4.8.1/src/usermod.c:1031: leaked_storage: Variable "nsgrp" going out of scope leaks the storage it points to. - 1029| } - 1030| } - 1031|-> } - 1032| #endif /* SHADOWGRP */ - 1033| - -Error: RESOURCE_LEAK (CWE-772): [#def34] -shadow-4.8.1/src/usermod.c:1161: alloc_fn: Storage is returned from allocation function "getgr_nam_gid". -shadow-4.8.1/src/usermod.c:1161: var_assign: Assigning: "grp" = storage returned from "getgr_nam_gid(optarg)". -shadow-4.8.1/src/usermod.c:1495: leaked_storage: Variable "grp" going out of scope leaks the storage it points to. - 1493| } - 1494| #endif /* ENABLE_SUBIDS */ - 1495|-> } - 1496| - 1497| /* - -Error: RESOURCE_LEAK (CWE-772): [#def35] -shadow-4.8.1/src/usermod.c:1991: open_fn: Returning handle opened by "open". [Note: The source code implementation of the function has been overridden by a user model.] -shadow-4.8.1/src/usermod.c:1991: var_assign: Assigning: "fd" = handle returned from "open("/var/log/lastlog", 2)". -shadow-4.8.1/src/usermod.c:2000: noescape: Resource "fd" is not freed or pointed-to in "lseek". -shadow-4.8.1/src/usermod.c:2000: noescape: Resource "fd" is not freed or pointed-to in "read". [Note: The source code implementation of the function has been overridden by a builtin model.] -shadow-4.8.1/src/usermod.c:2003: noescape: Resource "fd" is not freed or pointed-to in "lseek". -shadow-4.8.1/src/usermod.c:2032: leaked_handle: Handle variable "fd" going out of scope leaks the handle. - 2030| } - 2031| } - 2032|-> } - 2033| - 2034| /* - -Error: RESOURCE_LEAK (CWE-772): [#def36] -shadow-4.8.1/src/usermod.c:2052: open_fn: Returning handle opened by "open". [Note: The source code implementation of the function has been overridden by a user model.] -shadow-4.8.1/src/usermod.c:2052: var_assign: Assigning: "fd" = handle returned from "open("/var/log/faillog", 2)". -shadow-4.8.1/src/usermod.c:2061: noescape: Resource "fd" is not freed or pointed-to in "lseek". -shadow-4.8.1/src/usermod.c:2061: noescape: Resource "fd" is not freed or pointed-to in "read". [Note: The source code implementation of the function has been overridden by a builtin model.] -shadow-4.8.1/src/usermod.c:2064: noescape: Resource "fd" is not freed or pointed-to in "lseek". -shadow-4.8.1/src/usermod.c:2092: leaked_handle: Handle variable "fd" going out of scope leaks the handle. - 2090| } - 2091| } - 2092|-> } - 2093| - 2094| #ifndef NO_MOVE_MAILBOX ---- - src/usermod.c | 25 +++++++++++++------------ - 1 file changed, 13 insertions(+), 12 deletions(-) - -diff --git a/src/usermod.c b/src/usermod.c -index 7870ba57..03bb9b9d 100644 ---- a/src/usermod.c -+++ b/src/usermod.c -@@ -871,6 +871,8 @@ static void update_group (void) - SYSLOG ((LOG_WARN, "failed to prepare the new %s entry '%s'", gr_dbname (), ngrp->gr_name)); - fail_exit (E_GRP_UPDATE); - } -+ -+ gr_free(ngrp); - } - } - -@@ -1006,6 +1008,8 @@ static void update_gshadow (void) - sgr_dbname (), nsgrp->sg_name)); - fail_exit (E_GRP_UPDATE); - } -+ -+ free (nsgrp); - } - } - #endif /* SHADOWGRP */ -@@ -1152,6 +1156,7 @@ static void process_flags (int argc, char **argv) - } - user_newgid = grp->gr_gid; - gflg = true; -+ gr_free (grp); - break; - case 'G': - if (get_groups (optarg) != 0) { -@@ -1995,8 +2000,7 @@ static void update_lastlog (void) - /* Copy the old entry to its new location */ - if ( (lseek (fd, off_newuid, SEEK_SET) != off_newuid) - || (write (fd, &ll, sizeof ll) != (ssize_t) sizeof ll) -- || (fsync (fd) != 0) -- || (close (fd) != 0)) { -+ || (fsync (fd) != 0)) { - fprintf (stderr, - _("%s: failed to copy the lastlog entry of user %lu to user %lu: %s\n"), - Prog, (unsigned long) user_id, (unsigned long) user_newid, strerror (errno)); -@@ -2012,16 +2016,15 @@ static void update_lastlog (void) - memzero (&ll, sizeof (ll)); - if ( (lseek (fd, off_newuid, SEEK_SET) != off_newuid) - || (write (fd, &ll, sizeof ll) != (ssize_t) sizeof ll) -- || (fsync (fd) != 0) -- || (close (fd) != 0)) { -+ || (fsync (fd) != 0)) { - fprintf (stderr, - _("%s: failed to copy the lastlog entry of user %lu to user %lu: %s\n"), - Prog, (unsigned long) user_id, (unsigned long) user_newid, strerror (errno)); - } -- } else { -- (void) close (fd); - } - } -+ -+ (void) close (fd); - } - - /* -@@ -2056,8 +2059,7 @@ static void update_faillog (void) - /* Copy the old entry to its new location */ - if ( (lseek (fd, off_newuid, SEEK_SET) != off_newuid) - || (write (fd, &fl, sizeof fl) != (ssize_t) sizeof fl) -- || (fsync (fd) != 0) -- || (close (fd) != 0)) { -+ || (fsync (fd) != 0)) { - fprintf (stderr, - _("%s: failed to copy the faillog entry of user %lu to user %lu: %s\n"), - Prog, (unsigned long) user_id, (unsigned long) user_newid, strerror (errno)); -@@ -2072,16 +2074,15 @@ static void update_faillog (void) - /* Reset the new uid's faillog entry */ - memzero (&fl, sizeof (fl)); - if ( (lseek (fd, off_newuid, SEEK_SET) != off_newuid) -- || (write (fd, &fl, sizeof fl) != (ssize_t) sizeof fl) -- || (close (fd) != 0)) { -+ || (write (fd, &fl, sizeof fl) != (ssize_t) sizeof fl)) { - fprintf (stderr, - _("%s: failed to copy the faillog entry of user %lu to user %lu: %s\n"), - Prog, (unsigned long) user_id, (unsigned long) user_newid, strerror (errno)); - } -- } else { -- (void) close (fd); - } - } -+ -+ (void) close (fd); - } - - #ifndef NO_MOVE_MAILBOX --- -2.31.1 - -From 5d0d7841971cc53d9a9d1aefe12f00204115bf6a Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Wed, 16 Jun 2021 09:50:53 +0200 -Subject: [PATCH] Fix covscan BUFFER_SIZE - -Error: BUFFER_SIZE (CWE-170): [#def6] -shadow-4.8.1/libmisc/failure.c:101: buffer_size_warning: Calling "strncpy" with a maximum size argument of 12 bytes on destination array "fl->fail_line" of size 12 bytes might leave the destination string unterminated. - 99| } - 100| - 101|-> strncpy (fl->fail_line, tty, sizeof fl->fail_line); - 102| (void) time (&fl->fail_time); - 103| - -Error: BUFFER_SIZE (CWE-170): [#def9] -shadow-4.8.1/libmisc/log.c:103: buffer_size_warning: Calling "strncpy" with a maximum size argument of 32 bytes on destination array "newlog.ll_line" of size 32 bytes might leave the destination string unterminated. - 101| (void) time (&ll_time); - 102| newlog.ll_time = ll_time; - 103|-> strncpy (newlog.ll_line, line, sizeof newlog.ll_line); - 104| #if HAVE_LL_HOST - 105| strncpy (newlog.ll_host, host, sizeof newlog.ll_host); - -Error: BUFFER_SIZE (CWE-170): [#def10] -shadow-4.8.1/libmisc/log.c:105: buffer_size_warning: Calling "strncpy" with a maximum size argument of 256 bytes on destination array "newlog.ll_host" of size 256 bytes might leave the destination string unterminated. - 103| strncpy (newlog.ll_line, line, sizeof newlog.ll_line); - 104| #if HAVE_LL_HOST - 105|-> strncpy (newlog.ll_host, host, sizeof newlog.ll_host); - 106| #endif - 107| if ( (lseek (fd, offset, SEEK_SET) != offset) - -Error: BUFFER_SIZE (CWE-170): [#def13] -shadow-4.8.1/libmisc/utmp.c:260: buffer_size_warning: Calling "strncpy" with a maximum size argument of 32 bytes on destination array "utent->ut_line" of size 32 bytes might leave the destination string unterminated. - 258| #endif /* HAVE_STRUCT_UTMP_UT_TYPE */ - 259| utent->ut_pid = getpid (); - 260|-> strncpy (utent->ut_line, line, sizeof (utent->ut_line)); - 261| #ifdef HAVE_STRUCT_UTMP_UT_ID - 262| if (NULL != ut) { - -Error: BUFFER_SIZE (CWE-170): [#def14] -shadow-4.8.1/libmisc/utmp.c:266: buffer_size_warning: Calling "strncpy" with a maximum size argument of 4 bytes on destination array "utent->ut_id" of size 4 bytes might leave the destination string unterminated. - 264| } else { - 265| /* XXX - assumes /dev/tty?? */ - 266|-> strncpy (utent->ut_id, line + 3, sizeof (utent->ut_id)); - 267| } - 268| #endif /* HAVE_STRUCT_UTMP_UT_ID */ - -Error: BUFFER_SIZE (CWE-170): [#def15] -shadow-4.8.1/libmisc/utmp.c:273: buffer_size_warning: Calling "strncpy" with a maximum size argument of 32 bytes on destination array "utent->ut_user" of size 32 bytes might leave the destination string unterminated. - 271| #endif /* HAVE_STRUCT_UTMP_UT_NAME */ - 272| #ifdef HAVE_STRUCT_UTMP_UT_USER - 273|-> strncpy (utent->ut_user, name, sizeof (utent->ut_user)); - 274| #endif /* HAVE_STRUCT_UTMP_UT_USER */ - 275| if (NULL != hostname) { - -Error: BUFFER_SIZE (CWE-170): [#def16] -shadow-4.8.1/libmisc/utmp.c:278: buffer_size_warning: Calling "strncpy" with a maximum size argument of 256 bytes on destination array "utent->ut_host" of size 256 bytes might leave the destination string unterminated. - 276| struct addrinfo *info = NULL; - 277| #ifdef HAVE_STRUCT_UTMP_UT_HOST - 278|-> strncpy (utent->ut_host, hostname, sizeof (utent->ut_host)); - 279| #endif /* HAVE_STRUCT_UTMP_UT_HOST */ - 280| #ifdef HAVE_STRUCT_UTMP_UT_SYSLEN - -Signed-off-by: Iker Pedrosa ---- - libmisc/failure.c | 2 +- - libmisc/log.c | 4 ++-- - libmisc/utmp.c | 8 ++++---- - 3 files changed, 7 insertions(+), 7 deletions(-) - -diff --git a/libmisc/failure.c b/libmisc/failure.c -index f6390a79..a1f3ec79 100644 ---- a/libmisc/failure.c -+++ b/libmisc/failure.c -@@ -98,7 +98,7 @@ void failure (uid_t uid, const char *tty, struct faillog *fl) - fl->fail_cnt++; - } - -- strncpy (fl->fail_line, tty, sizeof fl->fail_line); -+ strncpy (fl->fail_line, tty, sizeof (fl->fail_line) - 1); - (void) time (&fl->fail_time); - - /* -diff --git a/libmisc/log.c b/libmisc/log.c -index eb84859e..68a9d7e2 100644 ---- a/libmisc/log.c -+++ b/libmisc/log.c -@@ -100,9 +100,9 @@ void dolastlog ( - ll_time = newlog.ll_time; - (void) time (&ll_time); - newlog.ll_time = ll_time; -- strncpy (newlog.ll_line, line, sizeof newlog.ll_line); -+ strncpy (newlog.ll_line, line, sizeof (newlog.ll_line) - 1); - #if HAVE_LL_HOST -- strncpy (newlog.ll_host, host, sizeof newlog.ll_host); -+ strncpy (newlog.ll_host, host, sizeof (newlog.ll_host) - 1); - #endif - if ( (lseek (fd, offset, SEEK_SET) != offset) - || (write (fd, (const void *) &newlog, sizeof newlog) != (ssize_t) sizeof newlog) -diff --git a/libmisc/utmp.c b/libmisc/utmp.c -index ba69cf61..5dcd419f 100644 ---- a/libmisc/utmp.c -+++ b/libmisc/utmp.c -@@ -257,25 +257,25 @@ static void updwtmpx (const char *filename, const struct utmpx *utx) - utent->ut_type = USER_PROCESS; - #endif /* HAVE_STRUCT_UTMP_UT_TYPE */ - utent->ut_pid = getpid (); -- strncpy (utent->ut_line, line, sizeof (utent->ut_line)); -+ strncpy (utent->ut_line, line, sizeof (utent->ut_line) - 1); - #ifdef HAVE_STRUCT_UTMP_UT_ID - if (NULL != ut) { - strncpy (utent->ut_id, ut->ut_id, sizeof (utent->ut_id)); - } else { - /* XXX - assumes /dev/tty?? */ -- strncpy (utent->ut_id, line + 3, sizeof (utent->ut_id)); -+ strncpy (utent->ut_id, line + 3, sizeof (utent->ut_id) - 1); - } - #endif /* HAVE_STRUCT_UTMP_UT_ID */ - #ifdef HAVE_STRUCT_UTMP_UT_NAME - strncpy (utent->ut_name, name, sizeof (utent->ut_name)); - #endif /* HAVE_STRUCT_UTMP_UT_NAME */ - #ifdef HAVE_STRUCT_UTMP_UT_USER -- strncpy (utent->ut_user, name, sizeof (utent->ut_user)); -+ strncpy (utent->ut_user, name, sizeof (utent->ut_user) - 1); - #endif /* HAVE_STRUCT_UTMP_UT_USER */ - if (NULL != hostname) { - struct addrinfo *info = NULL; - #ifdef HAVE_STRUCT_UTMP_UT_HOST -- strncpy (utent->ut_host, hostname, sizeof (utent->ut_host)); -+ strncpy (utent->ut_host, hostname, sizeof (utent->ut_host) - 1); - #endif /* HAVE_STRUCT_UTMP_UT_HOST */ - #ifdef HAVE_STRUCT_UTMP_UT_SYSLEN - utent->ut_syslen = MIN (strlen (hostname), --- -2.31.1 - -From e65cc6aebcb4132fa413f00a905216a5b35b3d57 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Mon, 14 Jun 2021 12:39:48 +0200 -Subject: [PATCH] Fix covscan RESOURCE_LEAK - -Error: RESOURCE_LEAK (CWE-772): [#def1] -shadow-4.8.1/lib/commonio.c:320: alloc_fn: Storage is returned from allocation function "fopen_set_perms". -shadow-4.8.1/lib/commonio.c:320: var_assign: Assigning: "bkfp" = storage returned from "fopen_set_perms(backup, "w", &sb)". -shadow-4.8.1/lib/commonio.c:329: noescape: Resource "bkfp" is not freed or pointed-to in "putc". -shadow-4.8.1/lib/commonio.c:334: noescape: Resource "bkfp" is not freed or pointed-to in "fflush". -shadow-4.8.1/lib/commonio.c:339: noescape: Resource "bkfp" is not freed or pointed-to in "fileno". -shadow-4.8.1/lib/commonio.c:342: leaked_storage: Variable "bkfp" going out of scope leaks the storage it points to. - 340| || (fclose (bkfp) != 0)) { - 341| /* FIXME: unlink the backup file? */ - 342|-> return -1; - 343| } - 344| - -Error: RESOURCE_LEAK (CWE-772): [#def2] -shadow-4.8.1/libmisc/addgrps.c:69: alloc_fn: Storage is returned from allocation function "malloc". -shadow-4.8.1/libmisc/addgrps.c:69: var_assign: Assigning: "grouplist" = storage returned from "malloc(i * 4UL)". -shadow-4.8.1/libmisc/addgrps.c:73: noescape: Resource "grouplist" is not freed or pointed-to in "getgroups". [Note: The source code implementation of the function has been overridden by a builtin model.] -shadow-4.8.1/libmisc/addgrps.c:126: leaked_storage: Variable "grouplist" going out of scope leaks the storage it points to. - 124| } - 125| - 126|-> return 0; - 127| } - 128| #else /* HAVE_SETGROUPS && !USE_PAM */ - -Error: RESOURCE_LEAK (CWE-772): [#def3] -shadow-4.8.1/libmisc/chowntty.c:62: alloc_fn: Storage is returned from allocation function "getgr_nam_gid". -shadow-4.8.1/libmisc/chowntty.c:62: var_assign: Assigning: "grent" = storage returned from "getgr_nam_gid(getdef_str("TTYGROUP"))". -shadow-4.8.1/libmisc/chowntty.c:98: leaked_storage: Variable "grent" going out of scope leaks the storage it points to. - 96| */ - 97| #endif - 98|-> } - 99| - -Error: RESOURCE_LEAK (CWE-772): [#def4] -shadow-4.8.1/libmisc/copydir.c:742: open_fn: Returning handle opened by "open". [Note: The source code implementation of the function has been overridden by a user model.] -shadow-4.8.1/libmisc/copydir.c:742: var_assign: Assigning: "ifd" = handle returned from "open(src, 0)". -shadow-4.8.1/libmisc/copydir.c:748: leaked_handle: Handle variable "ifd" going out of scope leaks the handle. - 746| #ifdef WITH_SELINUX - 747| if (set_selinux_file_context (dst, NULL) != 0) { - 748|-> return -1; - 749| } - 750| #endif /* WITH_SELINUX */ - -Error: RESOURCE_LEAK (CWE-772): [#def5] -shadow-4.8.1/libmisc/copydir.c:751: open_fn: Returning handle opened by "open". [Note: The source code implementation of the function has been overridden by a user model.] -shadow-4.8.1/libmisc/copydir.c:751: var_assign: Assigning: "ofd" = handle returned from "open(dst, 577, statp->st_mode & 0xfffU)". -shadow-4.8.1/libmisc/copydir.c:752: noescape: Resource "ofd" is not freed or pointed-to in "fchown_if_needed". -shadow-4.8.1/libmisc/copydir.c:775: leaked_handle: Handle variable "ofd" going out of scope leaks the handle. - 773| ) { - 774| (void) close (ifd); - 775|-> return -1; - 776| } - 777| - -Error: RESOURCE_LEAK (CWE-772): [#def7] -shadow-4.8.1/libmisc/idmapping.c:188: alloc_fn: Storage is returned from allocation function "xmalloc". -shadow-4.8.1/libmisc/idmapping.c:188: var_assign: Assigning: "buf" = storage returned from "xmalloc(bufsize)". -shadow-4.8.1/libmisc/idmapping.c:188: var_assign: Assigning: "pos" = "buf". -shadow-4.8.1/libmisc/idmapping.c:213: noescape: Resource "buf" is not freed or pointed-to in "write". -shadow-4.8.1/libmisc/idmapping.c:219: leaked_storage: Variable "pos" going out of scope leaks the storage it points to. -shadow-4.8.1/libmisc/idmapping.c:219: leaked_storage: Variable "buf" going out of scope leaks the storage it points to. - 217| } - 218| close(fd); - 219|-> } - -Error: RESOURCE_LEAK (CWE-772): [#def8] -shadow-4.8.1/libmisc/list.c:211: alloc_fn: Storage is returned from allocation function "xstrdup". -shadow-4.8.1/libmisc/list.c:211: var_assign: Assigning: "members" = storage returned from "xstrdup(comma)". -shadow-4.8.1/libmisc/list.c:217: var_assign: Assigning: "cp" = "members". -shadow-4.8.1/libmisc/list.c:218: noescape: Resource "cp" is not freed or pointed-to in "strchr". -shadow-4.8.1/libmisc/list.c:244: leaked_storage: Variable "cp" going out of scope leaks the storage it points to. -shadow-4.8.1/libmisc/list.c:244: leaked_storage: Variable "members" going out of scope leaks the storage it points to. - 242| if ('\0' == *members) { - 243| *array = (char *) 0; - 244|-> return array; - 245| } - 246| - -Error: RESOURCE_LEAK (CWE-772): [#def11] -shadow-4.8.1/libmisc/myname.c:61: alloc_fn: Storage is returned from allocation function "xgetpwnam". -shadow-4.8.1/libmisc/myname.c:61: var_assign: Assigning: "pw" = storage returned from "xgetpwnam(cp)". -shadow-4.8.1/libmisc/myname.c:67: leaked_storage: Variable "pw" going out of scope leaks the storage it points to. - 65| } - 66| - 67|-> return xgetpwuid (ruid); - 68| } - 69| - -Error: RESOURCE_LEAK (CWE-772): [#def12] -shadow-4.8.1/libmisc/user_busy.c:260: alloc_fn: Storage is returned from allocation function "opendir". -shadow-4.8.1/libmisc/user_busy.c:260: var_assign: Assigning: "task_dir" = storage returned from "opendir(task_path)". -shadow-4.8.1/libmisc/user_busy.c:262: noescape: Resource "task_dir" is not freed or pointed-to in "readdir". -shadow-4.8.1/libmisc/user_busy.c:278: leaked_storage: Variable "task_dir" going out of scope leaks the storage it points to. - 276| _("%s: user %s is currently used by process %d\n"), - 277| Prog, name, pid); - 278|-> return 1; - 279| } - 280| } - -Error: RESOURCE_LEAK (CWE-772): [#def20] -shadow-4.8.1/src/newgrp.c:162: alloc_fn: Storage is returned from allocation function "xgetspnam". -shadow-4.8.1/src/newgrp.c:162: var_assign: Assigning: "spwd" = storage returned from "xgetspnam(pwd->pw_name)". -shadow-4.8.1/src/newgrp.c:234: leaked_storage: Variable "spwd" going out of scope leaks the storage it points to. - 232| } - 233| - 234|-> return; - 235| - 236| failure: - -Error: RESOURCE_LEAK (CWE-772): [#def21] -shadow-4.8.1/src/passwd.c:530: alloc_fn: Storage is returned from allocation function "xstrdup". -shadow-4.8.1/src/passwd.c:530: var_assign: Assigning: "cp" = storage returned from "xstrdup(crypt_passwd)". -shadow-4.8.1/src/passwd.c:551: noescape: Resource "cp" is not freed or pointed-to in "strlen". -shadow-4.8.1/src/passwd.c:554: noescape: Resource "cp" is not freed or pointed-to in "strcat". [Note: The source code implementation of the function has been overridden by a builtin model.] -shadow-4.8.1/src/passwd.c:555: overwrite_var: Overwriting "cp" in "cp = newpw" leaks the storage that "cp" points to. - 553| strcpy (newpw, "!"); - 554| strcat (newpw, cp); - 555|-> cp = newpw; - 556| } - 557| return cp; ---- - lib/commonio.c | 8 ++++++-- - libmisc/addgrps.c | 6 +++++- - libmisc/chowntty.c | 1 + - libmisc/copydir.c | 6 ++++++ - libmisc/idmapping.c | 1 + - libmisc/list.c | 3 +++ - libmisc/myname.c | 3 +++ - libmisc/user_busy.c | 1 + - src/newgrp.c | 3 ++- - src/passwd.c | 5 +++++ - 10 files changed, 33 insertions(+), 4 deletions(-) - -diff --git a/lib/commonio.c b/lib/commonio.c -index 23ac91f9..cef404b9 100644 ---- a/lib/commonio.c -+++ b/lib/commonio.c -@@ -336,8 +336,12 @@ static int create_backup (const char *backup, FILE * fp) - /* FIXME: unlink the backup file? */ - return -1; - } -- if ( (fsync (fileno (bkfp)) != 0) -- || (fclose (bkfp) != 0)) { -+ if (fsync (fileno (bkfp)) != 0) { -+ (void) fclose (bkfp); -+ /* FIXME: unlink the backup file? */ -+ return -1; -+ } -+ if (fclose (bkfp) != 0) { - /* FIXME: unlink the backup file? */ - return -1; - } -diff --git a/libmisc/addgrps.c b/libmisc/addgrps.c -index 2e38e340..76c172a5 100644 ---- a/libmisc/addgrps.c -+++ b/libmisc/addgrps.c -@@ -57,6 +57,7 @@ int add_groups (const char *list) - bool added; - char *token; - char buf[1024]; -+ int ret; - - if (strlen (list) >= sizeof (buf)) { - errno = EINVAL; -@@ -120,9 +121,12 @@ int add_groups (const char *list) - } - - if (added) { -- return setgroups ((size_t)ngroups, grouplist); -+ ret = setgroups ((size_t)ngroups, grouplist); -+ free (grouplist); -+ return ret; - } - -+ free (grouplist); - return 0; - } - #else /* HAVE_SETGROUPS && !USE_PAM */ -diff --git a/libmisc/chowntty.c b/libmisc/chowntty.c -index ea706c4f..a42ab622 100644 ---- a/libmisc/chowntty.c -+++ b/libmisc/chowntty.c -@@ -62,6 +62,7 @@ void chown_tty (const struct passwd *info) - grent = getgr_nam_gid (getdef_str ("TTYGROUP")); - if (NULL != grent) { - gid = grent->gr_gid; -+ gr_free (grent); - } else { - gid = info->pw_gid; - } -diff --git a/libmisc/copydir.c b/libmisc/copydir.c -index 91d391f8..015e1b68 100644 ---- a/libmisc/copydir.c -+++ b/libmisc/copydir.c -@@ -745,6 +745,7 @@ static int copy_file (const char *src, const char *dst, - } - #ifdef WITH_SELINUX - if (set_selinux_file_context (dst, NULL) != 0) { -+ (void) close (ifd); - return -1; - } - #endif /* WITH_SELINUX */ -@@ -771,12 +772,16 @@ static int copy_file (const char *src, const char *dst, - && (errno != 0)) - #endif /* WITH_ATTR */ - ) { -+ if (ofd >= 0) { -+ (void) close (ofd); -+ } - (void) close (ifd); - return -1; - } - - while ((cnt = read (ifd, buf, sizeof buf)) > 0) { - if (write (ofd, buf, (size_t)cnt) != cnt) { -+ (void) close (ofd); - (void) close (ifd); - return -1; - } -@@ -786,6 +791,7 @@ static int copy_file (const char *src, const char *dst, - - #ifdef HAVE_FUTIMES - if (futimes (ofd, mt) != 0) { -+ (void) close (ofd); - return -1; - } - #endif /* HAVE_FUTIMES */ -diff --git a/libmisc/idmapping.c b/libmisc/idmapping.c -index b0ae488c..3324f671 100644 ---- a/libmisc/idmapping.c -+++ b/libmisc/idmapping.c -@@ -241,4 +241,5 @@ void write_mapping(int proc_dir_fd, int ranges, struct map_range *mappings, - exit(EXIT_FAILURE); - } - close(fd); -+ free(buf); - } -diff --git a/libmisc/list.c b/libmisc/list.c -index 2da734a7..d85d5f20 100644 ---- a/libmisc/list.c -+++ b/libmisc/list.c -@@ -241,6 +241,7 @@ bool is_on_list (char *const *list, const char *member) - - if ('\0' == *members) { - *array = (char *) 0; -+ free (members); - return array; - } - -diff --git a/libmisc/myname.c b/libmisc/myname.c -index 05efdad3..e1b7f702 100644 ---- a/libmisc/myname.c -+++ b/libmisc/myname.c -@@ -62,6 +62,9 @@ - if ((NULL != pw) && (pw->pw_uid == ruid)) { - return pw; - } -+ if (NULL != pw) { -+ pw_free (pw); -+ } - } - - return xgetpwuid (ruid); -diff --git a/libmisc/user_busy.c b/libmisc/user_busy.c -index 4b507fe2..3deebfc3 100644 ---- a/libmisc/user_busy.c -+++ b/libmisc/user_busy.c -@@ -269,6 +269,7 @@ static int user_busy_processes (const char *name, uid_t uid) - } - if (check_status (name, task_path+6, uid) != 0) { - (void) closedir (proc); -+ (void) closedir (task_dir); - #ifdef ENABLE_SUBIDS - sub_uid_close(); - #endif -diff --git a/src/newgrp.c b/src/newgrp.c -index 2aa28b87..2b9293b4 100644 ---- a/src/newgrp.c -+++ b/src/newgrp.c -@@ -162,8 +162,9 @@ static void check_perms (const struct group *grp, - */ - spwd = xgetspnam (pwd->pw_name); - if (NULL != spwd) { -- pwd->pw_passwd = spwd->sp_pwdp; -+ pwd->pw_passwd = xstrdup (spwd->sp_pwdp); - } -+ spw_free (spwd); - - if ((pwd->pw_passwd[0] == '\0') && (grp->gr_passwd[0] != '\0')) { - needspasswd = true; -diff --git a/src/passwd.c b/src/passwd.c -index 3d4206f4..9d7df331 100644 ---- a/src/passwd.c -+++ b/src/passwd.c -@@ -553,6 +553,11 @@ static char *update_crypt_pw (char *cp) - - strcpy (newpw, "!"); - strcat (newpw, cp); -+#ifndef USE_PAM -+ if (do_update_pwd) { -+ free (cp); -+ } -+#endif /* USE_PAM */ - cp = newpw; - } - return cp; --- -2.31.1 - diff --git a/shadow-4.8.1-crypt_gensalt.patch b/shadow-4.8.1-crypt_gensalt.patch deleted file mode 100644 index 25198e6..0000000 --- a/shadow-4.8.1-crypt_gensalt.patch +++ /dev/null @@ -1,310 +0,0 @@ -From ea04eb301d08c0c58f1120f87d4ec184d3983ce5 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= -Date: Tue, 15 Jun 2021 14:23:42 +0200 -Subject: [PATCH] libmisc/salt.c: Use crypt_gensalt(), if available in - libcrypt. -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Most Linux distributions, including Fedora and RHEL 8, are shipping -with libxcrypt >= 4.0. - -Since that version of libxcrypt the provided family of crypt_gensalt() -functions are able to use automatic entropy drawn from secure system -ressources, like arc4random(), getentropy() or getrandom(). - -Anyways, the settings generated by crypt_gensalt() are always -guaranteed to works with the crypt() function. - -Using crypt_gensalt() is also needed to make proper use of newer -hashing methods, like yescrypt, provided by libxcrypt. - -Signed-off-by: Björn Esser ---- - libmisc/salt.c | 132 +++++++++++++++++++++++++++++++++++++++---------- - 1 file changed, 105 insertions(+), 27 deletions(-) - -diff --git a/libmisc/salt.c b/libmisc/salt.c -index 13408a53..9fd34332 100644 ---- a/libmisc/salt.c -+++ b/libmisc/salt.c -@@ -22,6 +22,13 @@ - #include "defines.h" - #include "getdef.h" - -+#if (defined CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY && \ -+ CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY) -+#define USE_XCRYPT_GENSALT 1 -+#else -+#define USE_XCRYPT_GENSALT 0 -+#endif -+ - /* Add the salt prefix. */ - #define MAGNUM(array,ch) (array)[0]=(array)[2]='$',(array)[1]=(ch),(array)[3]='\0' - -@@ -77,21 +84,26 @@ - - /* local function prototypes */ - static long read_random_bytes (void); -+#if !USE_XCRYPT_GENSALT - static /*@observer@*/const char *gensalt (size_t salt_size); -+#endif /* !USE_XCRYPT_GENSALT */ - #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) - static long shadow_random (long min, long max); - #endif /* USE_SHA_CRYPT || USE_BCRYPT */ - #ifdef USE_SHA_CRYPT --static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, /*@null@*/int *prefered_rounds); -+static /*@observer@*/const unsigned long SHA_get_salt_rounds (/*@null@*/int *prefered_rounds); -+static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, unsigned long rounds); - #endif /* USE_SHA_CRYPT */ - #ifdef USE_BCRYPT --static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, /*@null@*/int *prefered_rounds); -+static /*@observer@*/const unsigned long BCRYPT_get_salt_rounds (/*@null@*/int *prefered_rounds); -+static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, unsigned long rounds); - #endif /* USE_BCRYPT */ - #ifdef USE_YESCRYPT --static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, /*@null@*/int *prefered_cost); -+static /*@observer@*/const unsigned long YESCRYPT_get_salt_cost (/*@null@*/int *prefered_cost); -+static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, unsigned long cost); - #endif /* USE_YESCRYPT */ - --#ifndef HAVE_L64A -+#if !USE_XCRYPT_GENSALT && !defined(HAVE_L64A) - static /*@observer@*/char *l64a (long value) - { - static char buf[8]; -@@ -125,7 +137,7 @@ static /*@observer@*/char *l64a (long value) - - return buf; - } --#endif /* !HAVE_L64A */ -+#endif /* !USE_XCRYPT_GENSALT && !defined(HAVE_L64A) */ - - /* Read sizeof (long) random bytes from /dev/urandom. */ - static long read_random_bytes (void) -@@ -199,14 +211,10 @@ static long shadow_random (long min, long max) - #endif /* USE_SHA_CRYPT || USE_BCRYPT */ - - #ifdef USE_SHA_CRYPT --/* -- * Fill a salt prefix specifying the rounds number for the SHA crypt methods -- * to a buffer. -- */ --static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, /*@null@*/int *prefered_rounds) -+/* Return the the rounds number for the SHA crypt methods. */ -+static /*@observer@*/const unsigned long SHA_get_salt_rounds (/*@null@*/int *prefered_rounds) - { - unsigned long rounds; -- const size_t buf_begin = strlen (buf); - - if (NULL == prefered_rounds) { - long min_rounds = getdef_long ("SHA_CRYPT_MIN_ROUNDS", -1); -@@ -245,6 +253,17 @@ static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, /*@null@*/int *pref - rounds = SHA_ROUNDS_MAX; - } - -+ return rounds; -+} -+ -+/* -+ * Fill a salt prefix specifying the rounds number for the SHA crypt methods -+ * to a buffer. -+ */ -+static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, unsigned long rounds) -+{ -+ const size_t buf_begin = strlen (buf); -+ - /* Nothing to do here if SHA_ROUNDS_DEFAULT is used. */ - if (rounds == SHA_ROUNDS_DEFAULT) { - return; -@@ -265,14 +284,10 @@ static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, /*@null@*/int *pref - #endif /* USE_SHA_CRYPT */ - - #ifdef USE_BCRYPT --/* -- * Fill a salt prefix specifying the rounds number for the BCRYPT method -- * to a buffer. -- */ --static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, /*@null@*/int *prefered_rounds) -+/* Return the the rounds number for the BCRYPT method. */ -+static /*@observer@*/const unsigned long BCRYPT_get_salt_rounds (/*@null@*/int *prefered_rounds) - { - unsigned long rounds; -- const size_t buf_begin = strlen (buf); - - if (NULL == prefered_rounds) { - long min_rounds = getdef_long ("BCRYPT_MIN_ROUNDS", -1); -@@ -306,6 +321,11 @@ static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, /*@null@*/int *p - rounds = B_ROUNDS_MIN; - } - -+#if USE_XCRYPT_GENSALT -+ if (rounds > B_ROUNDS_MAX) { -+ rounds = B_ROUNDS_MAX; -+ } -+#else /* USE_XCRYPT_GENSALT */ - /* - * Use 19 as an upper bound for now, - * because musl doesn't allow rounds >= 20. -@@ -314,6 +334,18 @@ static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, /*@null@*/int *p - /* rounds = B_ROUNDS_MAX; */ - rounds = 19; - } -+#endif /* USE_XCRYPT_GENSALT */ -+ -+ return rounds; -+} -+ -+/* -+ * Fill a salt prefix specifying the rounds number for the BCRYPT method -+ * to a buffer. -+ */ -+static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, unsigned long rounds) -+{ -+ const size_t buf_begin = strlen (buf); - - /* - * Check if the result buffer is long enough. -@@ -330,14 +362,10 @@ static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, /*@null@*/int *p - #endif /* USE_BCRYPT */ - - #ifdef USE_YESCRYPT --/* -- * Fill a salt prefix specifying the cost for the YESCRYPT method -- * to a buffer. -- */ --static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, /*@null@*/int *prefered_cost) -+/* Return the the cost number for the YESCRYPT method. */ -+static /*@observer@*/const unsigned long YESCRYPT_get_salt_cost (/*@null@*/int *prefered_cost) - { - unsigned long cost; -- const size_t buf_begin = strlen (buf); - - if (NULL == prefered_cost) { - cost = getdef_num ("YESCRYPT_COST_FACTOR", Y_COST_DEFAULT); -@@ -356,6 +384,17 @@ static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, /*@null@*/int *p - cost = Y_COST_MAX; - } - -+ return cost; -+} -+ -+/* -+ * Fill a salt prefix specifying the cost for the YESCRYPT method -+ * to a buffer. -+ */ -+static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, unsigned long cost) -+{ -+ const size_t buf_begin = strlen (buf); -+ - /* - * Check if the result buffer is long enough. - * We are going to write four bytes, -@@ -380,6 +419,7 @@ static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, /*@null@*/int *p - } - #endif /* USE_YESCRYPT */ - -+#if !USE_XCRYPT_GENSALT - static /*@observer@*/const char *gensalt (size_t salt_size) - { - static char salt[MAX_SALT_SIZE + 6]; -@@ -397,6 +437,7 @@ static /*@observer@*/const char *gensalt (size_t salt_size) - - return salt; - } -+#endif /* !USE_XCRYPT_GENSALT */ - - /* - * Generate 8 base64 ASCII characters of random salt. If MD5_CRYPT_ENAB -@@ -420,6 +461,7 @@ static /*@observer@*/const char *gensalt (size_t salt_size) - static char result[GENSALT_SETTING_SIZE]; - size_t salt_len = MAX_SALT_SIZE; - const char *method; -+ unsigned long rounds = 0; - - memset (result, '\0', GENSALT_SETTING_SIZE); - -@@ -435,27 +477,32 @@ static /*@observer@*/const char *gensalt (size_t salt_size) - if (0 == strcmp (method, "MD5")) { - MAGNUM(result, '1'); - salt_len = MD5_CRYPT_SALT_SIZE; -+ rounds = 0; - #ifdef USE_BCRYPT - } else if (0 == strcmp (method, "BCRYPT")) { - BCRYPTMAGNUM(result); - salt_len = BCRYPT_SALT_SIZE; -- BCRYPT_salt_rounds_to_buf (result, (int *) arg); -+ rounds = BCRYPT_get_salt_rounds ((int *) arg); -+ BCRYPT_salt_rounds_to_buf (result, rounds); - #endif /* USE_BCRYPT */ - #ifdef USE_YESCRYPT - } else if (0 == strcmp (method, "YESCRYPT")) { - MAGNUM(result, 'y'); - salt_len = YESCRYPT_SALT_SIZE; -- YESCRYPT_salt_cost_to_buf (result, (int *) arg); -+ rounds = YESCRYPT_get_salt_cost ((int *) arg); -+ YESCRYPT_salt_cost_to_buf (result, rounds); - #endif /* USE_YESCRYPT */ - #ifdef USE_SHA_CRYPT - } else if (0 == strcmp (method, "SHA256")) { - MAGNUM(result, '5'); - salt_len = SHA_CRYPT_SALT_SIZE; -- SHA_salt_rounds_to_buf (result, (int *) arg); -+ rounds = SHA_get_salt_rounds ((int *) arg); -+ SHA_salt_rounds_to_buf (result, rounds); - } else if (0 == strcmp (method, "SHA512")) { - MAGNUM(result, '6'); - salt_len = SHA_CRYPT_SALT_SIZE; -- SHA_salt_rounds_to_buf (result, (int *) arg); -+ rounds = SHA_get_salt_rounds ((int *) arg); -+ SHA_salt_rounds_to_buf (result, rounds); - #endif /* USE_SHA_CRYPT */ - } else if (0 != strcmp (method, "DES")) { - fprintf (shadow_logfd, -@@ -463,9 +510,39 @@ static /*@observer@*/const char *gensalt (size_t salt_size) - "Defaulting to DES.\n"), - method); - salt_len = MAX_SALT_SIZE; -+ rounds = 0; - memset (result, '\0', GENSALT_SETTING_SIZE); - } - -+#if USE_XCRYPT_GENSALT -+ /* -+ * Prepare DES setting for crypt_gensalt(), if result -+ * has not been filled with anything previously. -+ */ -+ if ('\0' == result[0]) { -+ /* Avoid -Wunused-but-set-variable. */ -+ salt_len = GENSALT_SETTING_SIZE - 1; -+ rounds = 0; -+ memset (result, '.', salt_len); -+ result[salt_len] = '\0'; -+ } -+ -+ char *retval = crypt_gensalt (result, rounds, NULL, 0); -+ -+ /* Should not happen, but... */ -+ if (NULL == retval) { -+ fprintf (shadow_logfd, -+ _("Unable to generate a salt from setting " -+ "\"%s\", check your settings in " -+ "ENCRYPT_METHOD and the corresponding " -+ "configuration for your selected hash " -+ "method.\n"), result); -+ -+ exit (1); -+ } -+ -+ return retval; -+#else /* USE_XCRYPT_GENSALT */ - /* Check if the result buffer is long enough. */ - assert (GENSALT_SETTING_SIZE > strlen (result) + salt_len); - -@@ -474,4 +551,5 @@ static /*@observer@*/const char *gensalt (size_t salt_size) - GENSALT_SETTING_SIZE - strlen (result) - 1); - - return result; -+#endif /* USE_XCRYPT_GENSALT */ - } diff --git a/shadow-4.8.1-fix_YESCRYPT_salt_cost_param_type.patch b/shadow-4.8.1-fix_YESCRYPT_salt_cost_param_type.patch deleted file mode 100644 index a3aadd2..0000000 --- a/shadow-4.8.1-fix_YESCRYPT_salt_cost_param_type.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 8d987bc55ccb65a3ef3a541cc5e351cfcbef0c90 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= -Date: Sat, 12 Jun 2021 19:05:07 +0200 -Subject: [PATCH] libmisc/salt.c: Use int pointer for YESCRYPT_salt_cost(). -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The corresponding functions for the other hash methods all take -a pointer to an integer value as the only paramater, so this -particular function should do so as well. - -Signed-off-by: Björn Esser ---- - libmisc/salt.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/libmisc/salt.c b/libmisc/salt.c -index c35c6797..1bfa015b 100644 ---- a/libmisc/salt.c -+++ b/libmisc/salt.c -@@ -34,7 +34,7 @@ static /*@observer@*/const char *BCRYPT_salt_rounds (/*@null@*/int *prefered_rou - #endif /* USE_BCRYPT */ - #ifdef USE_YESCRYPT - static /*@observer@*/const char *gensalt_yescrypt (void); --static /*@observer@*/const char *YESCRYPT_salt_cost (/*@null@*/long *prefered_rounds); -+static /*@observer@*/const char *YESCRYPT_salt_cost (/*@null@*/int *prefered_cost); - #endif /* USE_YESCRYPT */ - - #ifndef HAVE_L64A -@@ -277,7 +277,7 @@ static /*@observer@*/const char *gensalt_bcrypt (void) - /* - * Return a salt prefix specifying the cost for the YESCRYPT method. - */ --static /*@observer@*/const char *YESCRYPT_salt_cost (/*@null@*/long *prefered_cost) -+static /*@observer@*/const char *YESCRYPT_salt_cost (/*@null@*/int *prefered_cost) - { - static char cost_prefix[5]; - long cost; diff --git a/shadow-4.8.1-fix_bcrypt_prefix.patch b/shadow-4.8.1-fix_bcrypt_prefix.patch deleted file mode 100644 index e8ac3bc..0000000 --- a/shadow-4.8.1-fix_bcrypt_prefix.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 738d92a4bd99a2038aa5f97b2fc85daa7011e403 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= -Date: Sat, 12 Jun 2021 13:54:14 +0200 -Subject: [PATCH] libmisc/salt.c: bcrypt should use $2b$ as prefix for setting. -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This prefix is the recommended one for new bcrypt hashes -for a long time. - -Signed-off-by: Björn Esser ---- - libmisc/salt.c | 8 ++------ - 1 file changed, 2 insertions(+), 6 deletions(-) - -diff --git a/libmisc/salt.c b/libmisc/salt.c -index 1bfa015b..5dc521ef 100644 ---- a/libmisc/salt.c -+++ b/libmisc/salt.c -@@ -90,12 +90,8 @@ static void seedRNG (void) - */ - #define MAGNUM(array,ch) (array)[0]=(array)[2]='$',(array)[1]=(ch),(array)[3]='\0' - #ifdef USE_BCRYPT --/* -- * Using the Prefix $2a$ to enable an anti-collision safety measure in musl libc. -- * Negatively affects a subset of passwords containing the '\xff' character, -- * which is not valid UTF-8 (so "unlikely to cause much annoyance"). -- */ --#define BCRYPTMAGNUM(array) (array)[0]=(array)[3]='$',(array)[1]='2',(array)[2]='a',(array)[4]='\0' -+/* Use $2b$ as prefix for compatibility with OpenBSD's bcrypt. */ -+#define BCRYPTMAGNUM(array) (array)[0]=(array)[3]='$',(array)[1]='2',(array)[2]='b',(array)[4]='\0' - #endif /* USE_BCRYPT */ - - #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) diff --git a/shadow-4.8.1-getentropy_random_bytes.patch b/shadow-4.8.1-getentropy_random_bytes.patch deleted file mode 100644 index c1affce..0000000 --- a/shadow-4.8.1-getentropy_random_bytes.patch +++ /dev/null @@ -1,123 +0,0 @@ -From c82ed0c15e0e9e47df0b4c22672b72e35f061a9d -From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= -Date: Sun, 4 Jul 2021 12:10:11 +0200 -Subject: [PATCH] libmisc/salt.c: Use secure system ressources to obtain random - bytes. -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -In a previous commit we introduced /dev/urandom as a source to obtain -random bytes from. This may not be available on all systems, or when -operating inside of a chroot. - -Almost all systems provide functions to obtain random bytes from -secure system ressources. Thus we should prefer to use these, and -fall back to /dev/urandom, if there is no such function present, as -a last resort. - -Signed-off-by: Björn Esser ---- - configure.ac | 17 +++++++++-------- - libmisc/salt.c | 42 ++++++++++++++++++++++++++++++++++++------ - 2 files changed, 45 insertions(+), 14 deletions(-) - -Index: shadow-4.8.1/configure.ac -=================================================================== ---- shadow-4.8.1.orig/configure.ac -+++ shadow-4.8.1/configure.ac -@@ -44,18 +44,19 @@ AC_HEADER_STDBOOL - - AC_CHECK_HEADERS(crypt.h errno.h fcntl.h limits.h unistd.h sys/time.h utmp.h \ - utmpx.h termios.h termio.h sgtty.h sys/ioctl.h syslog.h paths.h \ -- utime.h ulimit.h sys/capability.h sys/resource.h gshadow.h lastlog.h \ -- locale.h rpc/key_prot.h netdb.h acl/libacl.h attr/libattr.h \ -- attr/error_context.h) -+ utime.h ulimit.h sys/capability.h sys/random.h sys/resource.h \ -+ gshadow.h lastlog.h locale.h rpc/key_prot.h netdb.h acl/libacl.h \ -+ attr/libattr.h attr/error_context.h) - - dnl shadow now uses the libc's shadow implementation - AC_CHECK_HEADER([shadow.h],,[AC_MSG_ERROR([You need a libc with shadow.h])]) - --AC_CHECK_FUNCS(l64a fchmod fchown fsync futimes getgroups gethostname getspnam \ -- gettimeofday getusershell getutent initgroups lchown lckpwdf lstat \ -- lutimes memcpy memset setgroups sigaction strchr updwtmp updwtmpx innetgr \ -- getpwnam_r getpwuid_r getgrnam_r getgrgid_r getspnam_r getaddrinfo \ -- ruserok dlopen) -+AC_CHECK_FUNCS(arc4random_buf l64a fchmod fchown fsync futimes getgroups \ -+ gethostname getentropy getrandom getspnam gettimeofday getusershell \ -+ getutent initgroups lchown lckpwdf lstat lutimes memcpy memset \ -+ setgroups sigaction strchr updwtmp updwtmpx innetgr getpwnam_r \ -+ getpwuid_r getgrnam_r getgrgid_r getspnam_r getaddrinfo ruserok \ -+ dlopen) - AC_SYS_LARGEFILE - - dnl Checks for typedefs, structures, and compiler characteristics. -Index: shadow-4.8.1/libmisc/salt.c -=================================================================== ---- shadow-4.8.1.orig/libmisc/salt.c -+++ shadow-4.8.1/libmisc/salt.c -@@ -15,6 +15,9 @@ - #include - #include - #include -+#if HAVE_SYS_RANDOM_H -+#include -+#endif - #include "prototypes.h" - #include "defines.h" - #include "getdef.h" -@@ -128,19 +131,46 @@ static /*@observer@*/char *l64a (long va - static long read_random_bytes (void) - { - long randval = 0; -- FILE *f = fopen ("/dev/urandom", "r"); - -- if (fread (&randval, sizeof (randval), 1, f) != sizeof (randval)) -- { -- fprintf (shadow_logfd, -- _("Unable to read from /dev/urandom.\n")); -+#ifdef HAVE_ARC4RANDOM_BUF -+ /* arc4random_buf, if it exists, can never fail. */ -+ arc4random_buf (&randval, sizeof (randval)); -+ goto end; -+ -+#elif defined(HAVE_GETENTROPY) -+ /* getentropy may exist but lack kernel support. */ -+ if (getentropy (&randval, sizeof (randval))) { -+ goto fail; -+ } -+ -+ goto end; -+ -+#elif defined(HAVE_GETRANDOM) -+ /* Likewise getrandom. */ -+ if ((size_t) getrandom (&randval, sizeof (randval), 0) != sizeof (randval)) { -+ goto fail; -+ } - -+ goto end; -+ -+#else -+ FILE *f = fopen ("/dev/urandom", "r"); -+ -+ if (fread (&randval, sizeof (randval), 1, f) != sizeof (randval)) { - fclose(f); -- exit (1); -+ goto fail; - } - - fclose(f); -+ goto end; -+#endif -+ -+fail: -+ fprintf (shadow_logfd, -+ _("Unable to obtain random bytes.\n")); -+ exit (1); - -+end: - return randval; - } - diff --git a/shadow-4.8.1-libsubid_creation.patch b/shadow-4.8.1-libsubid_creation.patch deleted file mode 100644 index 072ed2e..0000000 --- a/shadow-4.8.1-libsubid_creation.patch +++ /dev/null @@ -1,1522 +0,0 @@ -From 0a7888b1fad613a052b988b01a71933b67296e68 Mon Sep 17 00:00:00 2001 -From: Serge Hallyn -Date: Sat, 18 Apr 2020 18:03:54 -0500 -Subject: [PATCH] Create a new libsubid - -Closes #154 - -Currently this has three functions: one which returns the -list of subuid ranges for a user, one returning the subgids, -and one which frees the ranges lists. - -I might be mistaken about what -disable-man means; some of -the code suggests it means just don't re-generate them, but -not totally ignore them. But that doesn't seem to really work, -so let's just ignore man/ when -disable-man. - -Remove --disable-shared. I'm not sure why it was there, but it stems -from long, long ago, and I suspect it comes from some ancient -toolchain bug. - -Create a tests/run_some, a shorter version of run_all. I'll -slowly add tests to this as I verify they work, then I can -work on fixing the once which don't. - -Also, don't touch man/ if not -enable-man. - -Changelog: - Apr 22: change the subid list api as recomended by Dan Walsh. - Apr 23: implement get_subid_owner - Apr 24: implement range add/release - Apr 25: finish tests and rebase - May 10: make @owner const - -Signed-off-by: Serge Hallyn ---- - Makefile.am | 13 +- - configure.ac | 3 +- - lib/subordinateio.c | 204 +++++++++++++++- - lib/subordinateio.h | 7 + - libsubid/Makefile.am | 25 ++ - libsubid/api.c | 231 ++++++++++++++++++ - libsubid/api.h | 17 ++ - libsubid/subid.h | 17 ++ - src/Makefile.am | 60 +++++ - src/free_subid_range.c | 50 ++++ - src/get_subid_owners.c | 40 +++ - src/list_subid_ranges.c | 41 ++++ - src/new_subid_range.c | 57 +++++ - tests/libsubid/01_list_ranges/config.txt | 0 - .../libsubid/01_list_ranges/config/etc/subgid | 2 + - .../libsubid/01_list_ranges/config/etc/subuid | 3 + - .../libsubid/01_list_ranges/list_ranges.test | 38 +++ - tests/libsubid/02_get_subid_owners/config.txt | 0 - .../02_get_subid_owners/config/etc/passwd | 20 ++ - .../02_get_subid_owners/config/etc/subgid | 2 + - .../02_get_subid_owners/config/etc/subuid | 4 + - .../02_get_subid_owners/get_subid_owners.test | 52 ++++ - .../03_add_remove/add_remove_subids.test | 59 +++++ - tests/libsubid/03_add_remove/config.txt | 0 - .../libsubid/03_add_remove/config/etc/passwd | 20 ++ - .../libsubid/03_add_remove/config/etc/subgid | 2 + - .../libsubid/03_add_remove/config/etc/subuid | 1 + - tests/run_some | 136 +++++++++++ - 31 files changed, 1105 insertions(+), 17 deletions(-) - create mode 100644 libsubid/Makefile.am - create mode 100644 libsubid/api.c - create mode 100644 libsubid/api.h - create mode 100644 libsubid/subid.h - create mode 100644 src/free_subid_range.c - create mode 100644 src/get_subid_owners.c - create mode 100644 src/list_subid_ranges.c - create mode 100644 src/new_subid_range.c - create mode 100644 tests/libsubid/01_list_ranges/config.txt - create mode 100644 tests/libsubid/01_list_ranges/config/etc/subgid - create mode 100644 tests/libsubid/01_list_ranges/config/etc/subuid - create mode 100755 tests/libsubid/01_list_ranges/list_ranges.test - create mode 100644 tests/libsubid/02_get_subid_owners/config.txt - create mode 100644 tests/libsubid/02_get_subid_owners/config/etc/passwd - create mode 100644 tests/libsubid/02_get_subid_owners/config/etc/subgid - create mode 100644 tests/libsubid/02_get_subid_owners/config/etc/subuid - create mode 100755 tests/libsubid/02_get_subid_owners/get_subid_owners.test - create mode 100755 tests/libsubid/03_add_remove/add_remove_subids.test - create mode 100644 tests/libsubid/03_add_remove/config.txt - create mode 100644 tests/libsubid/03_add_remove/config/etc/passwd - create mode 100644 tests/libsubid/03_add_remove/config/etc/subgid - create mode 100644 tests/libsubid/03_add_remove/config/etc/subuid - create mode 100755 tests/run_some - -diff --git a/Makefile.am b/Makefile.am -index 8851f5d6..b6456cf9 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -2,5 +2,14 @@ - - EXTRA_DIST = NEWS README TODO shadow.spec.in - --SUBDIRS = po man libmisc lib src \ -- contrib doc etc -+SUBDIRS = libmisc lib -+ -+if ENABLE_SUBIDS -+SUBDIRS += libsubid -+endif -+ -+SUBDIRS += src po contrib doc etc -+ -+if ENABLE_REGENERATE_MAN -+SUBDIRS += man -+endif -diff --git a/configure.ac b/configure.ac -index b8bc2b7a..b766eff0 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -22,8 +22,8 @@ test "$prefix" = "/usr" && exec_prefix="" - - AC_GNU_SOURCE - --AM_DISABLE_SHARED - AM_ENABLE_STATIC -+AM_ENABLE_SHARED - - AM_MAINTAINER_MODE - -@@ -725,6 +725,7 @@ AC_CONFIG_FILES([ - man/zh_TW/Makefile - libmisc/Makefile - lib/Makefile -+ libsubid/Makefile - src/Makefile - contrib/Makefile - etc/Makefile -diff --git a/lib/subordinateio.c b/lib/subordinateio.c -index 0d89a64e..67202c98 100644 ---- a/lib/subordinateio.c -+++ b/lib/subordinateio.c -@@ -13,14 +13,7 @@ - #include "subordinateio.h" - #include - #include -- --struct subordinate_range { -- const char *owner; -- unsigned long start; -- unsigned long count; --}; -- --#define NFIELDS 3 -+#include - - /* - * subordinate_dup: create a duplicate range -@@ -78,7 +71,7 @@ static void *subordinate_parse (const char *line) - static char rangebuf[1024]; - int i; - char *cp; -- char *fields[NFIELDS]; -+ char *fields[SUBID_NFIELDS]; - - /* - * Copy the string to a temporary buffer so the substrings can -@@ -93,7 +86,7 @@ static void *subordinate_parse (const char *line) - * field. The fields are converted into NUL terminated strings. - */ - -- for (cp = rangebuf, i = 0; (i < NFIELDS) && (NULL != cp); i++) { -+ for (cp = rangebuf, i = 0; (i < SUBID_NFIELDS) && (NULL != cp); i++) { - fields[i] = cp; - while (('\0' != *cp) && (':' != *cp)) { - cp++; -@@ -108,10 +101,10 @@ static void *subordinate_parse (const char *line) - } - - /* -- * There must be exactly NFIELDS colon separated fields or -+ * There must be exactly SUBID_NFIELDS colon separated fields or - * the entry is invalid. Also, fields must be non-blank. - */ -- if (i != NFIELDS || *fields[0] == '\0' || *fields[1] == '\0' || *fields[2] == '\0') -+ if (i != SUBID_NFIELDS || *fields[0] == '\0' || *fields[1] == '\0' || *fields[2] == '\0') - return NULL; - range.owner = fields[0]; - if (getulong (fields[1], &range.start) == 0) -@@ -314,6 +307,39 @@ static bool have_range(struct commonio_db *db, - return false; - } - -+static bool append_range(struct subordinate_range ***ranges, const struct subordinate_range *new, int n) -+{ -+ struct subordinate_range *tmp; -+ if (!*ranges) { -+ *ranges = malloc(2 * sizeof(struct subordinate_range **)); -+ if (!*ranges) -+ return false; -+ } else { -+ struct subordinate_range **new; -+ new = realloc(*ranges, (n + 2) * (sizeof(struct subordinate_range **))); -+ if (!new) -+ return false; -+ *ranges = new; -+ } -+ (*ranges)[n] = (*ranges)[n+1] = NULL; -+ tmp = subordinate_dup(new); -+ if (!tmp) -+ return false; -+ (*ranges)[n] = tmp; -+ return true; -+} -+ -+void free_subordinate_ranges(struct subordinate_range **ranges) -+{ -+ int i; -+ -+ if (!ranges) -+ return; -+ for (i = 0; ranges[i]; i++) -+ subordinate_free(ranges[i]); -+ free(ranges); -+} -+ - /* - * subordinate_range_cmp: compare uid ranges - * -@@ -692,6 +718,160 @@ gid_t sub_gid_find_free_range(gid_t min, gid_t max, unsigned long count) - start = find_free_range (&subordinate_gid_db, min, max, count); - return start == ULONG_MAX ? (gid_t) -1 : start; - } -+ -+/* -+ struct subordinate_range **list_owner_ranges(const char *owner, enum subid_type id_type) -+ * -+ * @owner: username -+ * @id_type: UID or GUID -+ * -+ * Returns the subuid or subgid ranges which are owned by the specified -+ * user. Username may be a username or a string representation of a -+ * UID number. If id_type is UID, then subuids are returned, else -+ * subgids are returned. If there is an error, < 0 is returned. -+ * -+ * The caller must free the subordinate range list. -+ */ -+struct subordinate_range **list_owner_ranges(const char *owner, enum subid_type id_type) -+{ -+ // TODO - need to handle owner being either uid or username -+ const struct subordinate_range *range; -+ struct subordinate_range **ranges = NULL; -+ struct commonio_db *db; -+ int size = 0; -+ -+ if (id_type == ID_TYPE_UID) -+ db = &subordinate_uid_db; -+ else -+ db = &subordinate_gid_db; -+ -+ commonio_rewind(db); -+ while ((range = commonio_next(db)) != NULL) { -+ if (0 == strcmp(range->owner, owner)) { -+ if (!append_range(&ranges, range, size++)) { -+ free_subordinate_ranges(ranges); -+ return NULL; -+ } -+ } -+ } -+ -+ return ranges; -+} -+ -+static bool all_digits(const char *str) -+{ -+ int i; -+ -+ for (i = 0; str[i] != '\0'; i++) -+ if (!isdigit(str[i])) -+ return false; -+ return true; -+} -+ -+static int append_uids(uid_t **uids, const char *owner, int n) -+{ -+ uid_t owner_uid; -+ uid_t *ret; -+ int i; -+ -+ if (all_digits(owner)) { -+ i = sscanf(owner, "%d", &owner_uid); -+ if (i != 1) { -+ // should not happen -+ free(*uids); -+ *uids = NULL; -+ return -1; -+ } -+ } else { -+ struct passwd *pwd = getpwnam(owner); -+ if (NULL == pwd) { -+ /* Username not defined in /etc/passwd, or error occured during lookup */ -+ free(*uids); -+ *uids = NULL; -+ return -1; -+ } -+ owner_uid = pwd->pw_uid; -+ } -+ -+ for (i = 0; i < n; i++) { -+ if (owner_uid == (*uids)[i]) -+ return n; -+ } -+ -+ ret = realloc(*uids, (n + 1) * sizeof(uid_t)); -+ if (!ret) { -+ free(*uids); -+ return -1; -+ } -+ ret[n] = owner_uid; -+ *uids = ret; -+ return n+1; -+} -+ -+int find_subid_owners(unsigned long id, uid_t **uids, enum subid_type id_type) -+{ -+ const struct subordinate_range *range; -+ struct commonio_db *db; -+ int n = 0; -+ -+ *uids = NULL; -+ if (id_type == ID_TYPE_UID) -+ db = &subordinate_uid_db; -+ else -+ db = &subordinate_gid_db; -+ -+ commonio_rewind(db); -+ while ((range = commonio_next(db)) != NULL) { -+ if (id >= range->start && id < range->start + range-> count) { -+ n = append_uids(uids, range->owner, n); -+ if (n < 0) -+ break; -+ } -+ } -+ -+ return n; -+} -+ -+bool new_subid_range(struct subordinate_range *range, enum subid_type id_type, bool reuse) -+{ -+ struct commonio_db *db; -+ const struct subordinate_range *r; -+ -+ if (id_type == ID_TYPE_UID) -+ db = &subordinate_uid_db; -+ else -+ db = &subordinate_gid_db; -+ commonio_rewind(db); -+ if (reuse) { -+ while ((r = commonio_next(db)) != NULL) { -+ // TODO account for username vs uid_t -+ if (0 != strcmp(r->owner, range->owner)) -+ continue; -+ if (r->count >= range->count) { -+ range->count = r->count; -+ range->start = r->start; -+ return true; -+ } -+ } -+ } -+ -+ range->start = find_free_range(db, range->start, ULONG_MAX, range->count); -+ if (range->start == ULONG_MAX) -+ return false; -+ -+ return add_range(db, range->owner, range->start, range->count) == 1; -+} -+ -+bool release_subid_range(struct subordinate_range *range, enum subid_type id_type) -+{ -+ struct commonio_db *db; -+ if (id_type == ID_TYPE_UID) -+ db = &subordinate_uid_db; -+ else -+ db = &subordinate_gid_db; -+ return remove_range(db, range->owner, range->start, range->count) == 1; -+} -+ - #else /* !ENABLE_SUBIDS */ - extern int errno; /* warning: ANSI C forbids an empty source file */ - #endif /* !ENABLE_SUBIDS */ -diff --git a/lib/subordinateio.h b/lib/subordinateio.h -index a21d72b8..13a21341 100644 ---- a/lib/subordinateio.h -+++ b/lib/subordinateio.h -@@ -11,6 +11,8 @@ - - #include - -+#include "../libsubid/subid.h" -+ - extern int sub_uid_close(void); - extern bool have_sub_uids(const char *owner, uid_t start, unsigned long count); - extern bool sub_uid_file_present (void); -@@ -23,6 +25,11 @@ extern int sub_uid_unlock (void); - extern int sub_uid_add (const char *owner, uid_t start, unsigned long count); - extern int sub_uid_remove (const char *owner, uid_t start, unsigned long count); - extern uid_t sub_uid_find_free_range(uid_t min, uid_t max, unsigned long count); -+extern struct subordinate_range **list_owner_ranges(const char *owner, enum subid_type id_type); -+extern bool new_subid_range(struct subordinate_range *range, enum subid_type id_type, bool reuse); -+extern bool release_subid_range(struct subordinate_range *range, enum subid_type id_type); -+extern int find_subid_owners(unsigned long id, uid_t **uids, enum subid_type id_type); -+extern void free_subordinate_ranges(struct subordinate_range **ranges); - - extern int sub_gid_close(void); - extern bool have_sub_gids(const char *owner, gid_t start, unsigned long count); -diff --git a/libsubid/Makefile.am b/libsubid/Makefile.am -new file mode 100644 -index 00000000..bdbc52c3 ---- /dev/null -+++ b/libsubid/Makefile.am -@@ -0,0 +1,25 @@ -+lib_LTLIBRARIES = libsubid.la -+libsubid_la_LDFLAGS = -Wl,-soname,libsubid.so.@LIBSUBID_ABI@ \ -+ -shared -version-info @LIBSUBID_ABI_MAJOR@ -+libsubid_la_SOURCES = api.c -+ -+MISCLIBS = \ -+ $(LIBAUDIT) \ -+ $(LIBSELINUX) \ -+ $(LIBSEMANAGE) \ -+ $(LIBCRYPT_NOPAM) \ -+ $(LIBSKEY) \ -+ $(LIBMD) \ -+ $(LIBECONF) \ -+ $(LIBCRYPT) \ -+ $(LIBTCB) -+ -+libsubid_la_LIBADD = \ -+ $(top_srcdir)/lib/libshadow.la \ -+ $(top_srcdir)/libmisc/libmisc.a \ -+ $(MISCLIBS) -+ -+AM_CPPFLAGS = \ -+ -I${top_srcdir}/lib \ -+ -I${top_srcdir}/libmisc \ -+ -DLOCALEDIR=\"$(datadir)/locale\" -diff --git a/libsubid/api.c b/libsubid/api.c -new file mode 100644 -index 00000000..91d73bed ---- /dev/null -+++ b/libsubid/api.c -@@ -0,0 +1,231 @@ -+/* -+ * Copyright (c) 2020 Serge Hallyn -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. The name of the copyright holders or contributors may not be used to -+ * endorse or promote products derived from this software without -+ * specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "subordinateio.h" -+#include "idmapping.h" -+#include "api.h" -+ -+static struct subordinate_range **get_subid_ranges(const char *owner, enum subid_type id_type) -+{ -+ struct subordinate_range **ranges = NULL; -+ -+ switch (id_type) { -+ case ID_TYPE_UID: -+ if (!sub_uid_open(O_RDONLY)) { -+ return NULL; -+ } -+ break; -+ case ID_TYPE_GID: -+ if (!sub_gid_open(O_RDONLY)) { -+ return NULL; -+ } -+ break; -+ default: -+ return NULL; -+ } -+ -+ ranges = list_owner_ranges(owner, id_type); -+ -+ if (id_type == ID_TYPE_UID) -+ sub_uid_close(); -+ else -+ sub_gid_close(); -+ -+ return ranges; -+} -+ -+struct subordinate_range **get_subuid_ranges(const char *owner) -+{ -+ return get_subid_ranges(owner, ID_TYPE_UID); -+} -+ -+struct subordinate_range **get_subgid_ranges(const char *owner) -+{ -+ return get_subid_ranges(owner, ID_TYPE_GID); -+} -+ -+void subid_free_ranges(struct subordinate_range **ranges) -+{ -+ return free_subordinate_ranges(ranges); -+} -+ -+int get_subid_owner(unsigned long id, uid_t **owner, enum subid_type id_type) -+{ -+ int ret = -1; -+ -+ switch (id_type) { -+ case ID_TYPE_UID: -+ if (!sub_uid_open(O_RDONLY)) { -+ return -1; -+ } -+ break; -+ case ID_TYPE_GID: -+ if (!sub_gid_open(O_RDONLY)) { -+ return -1; -+ } -+ break; -+ default: -+ return -1; -+ } -+ -+ ret = find_subid_owners(id, owner, id_type); -+ -+ if (id_type == ID_TYPE_UID) -+ sub_uid_close(); -+ else -+ sub_gid_close(); -+ -+ return ret; -+} -+ -+int get_subuid_owners(uid_t uid, uid_t **owner) -+{ -+ return get_subid_owner((unsigned long)uid, owner, ID_TYPE_UID); -+} -+ -+int get_subgid_owners(gid_t gid, uid_t **owner) -+{ -+ return get_subid_owner((unsigned long)gid, owner, ID_TYPE_GID); -+} -+ -+bool grant_subid_range(struct subordinate_range *range, bool reuse, -+ enum subid_type id_type) -+{ -+ bool ret; -+ -+ switch (id_type) { -+ case ID_TYPE_UID: -+ if (!sub_uid_lock()) { -+ printf("Failed loging subuids (errno %d)\n", errno); -+ return false; -+ } -+ if (!sub_uid_open(O_CREAT | O_RDWR)) { -+ printf("Failed opening subuids (errno %d)\n", errno); -+ sub_uid_unlock(); -+ return false; -+ } -+ break; -+ case ID_TYPE_GID: -+ if (!sub_gid_lock()) { -+ printf("Failed loging subgids (errno %d)\n", errno); -+ return false; -+ } -+ if (!sub_gid_open(O_CREAT | O_RDWR)) { -+ printf("Failed opening subgids (errno %d)\n", errno); -+ sub_gid_unlock(); -+ return false; -+ } -+ break; -+ default: -+ return false; -+ } -+ -+ ret = new_subid_range(range, id_type, reuse); -+ -+ if (id_type == ID_TYPE_UID) { -+ sub_uid_close(); -+ sub_uid_unlock(); -+ } else { -+ sub_gid_close(); -+ sub_gid_unlock(); -+ } -+ -+ return ret; -+} -+ -+bool grant_subuid_range(struct subordinate_range *range, bool reuse) -+{ -+ return grant_subid_range(range, reuse, ID_TYPE_UID); -+} -+ -+bool grant_subgid_range(struct subordinate_range *range, bool reuse) -+{ -+ return grant_subid_range(range, reuse, ID_TYPE_GID); -+} -+ -+bool free_subid_range(struct subordinate_range *range, enum subid_type id_type) -+{ -+ bool ret; -+ -+ switch (id_type) { -+ case ID_TYPE_UID: -+ if (!sub_uid_lock()) { -+ printf("Failed loging subuids (errno %d)\n", errno); -+ return false; -+ } -+ if (!sub_uid_open(O_CREAT | O_RDWR)) { -+ printf("Failed opening subuids (errno %d)\n", errno); -+ sub_uid_unlock(); -+ return false; -+ } -+ break; -+ case ID_TYPE_GID: -+ if (!sub_gid_lock()) { -+ printf("Failed loging subgids (errno %d)\n", errno); -+ return false; -+ } -+ if (!sub_gid_open(O_CREAT | O_RDWR)) { -+ printf("Failed opening subgids (errno %d)\n", errno); -+ sub_gid_unlock(); -+ return false; -+ } -+ break; -+ default: -+ return false; -+ } -+ -+ ret = release_subid_range(range, id_type); -+ -+ if (id_type == ID_TYPE_UID) { -+ sub_uid_close(); -+ sub_uid_unlock(); -+ } else { -+ sub_gid_close(); -+ sub_gid_unlock(); -+ } -+ -+ return ret; -+} -+ -+bool free_subuid_range(struct subordinate_range *range) -+{ -+ return free_subid_range(range, ID_TYPE_UID); -+} -+ -+bool free_subgid_range(struct subordinate_range *range) -+{ -+ return free_subid_range(range, ID_TYPE_GID); -+} -diff --git a/libsubid/api.h b/libsubid/api.h -new file mode 100644 -index 00000000..f65e3ec9 ---- /dev/null -+++ b/libsubid/api.h -@@ -0,0 +1,17 @@ -+#include "subid.h" -+#include -+ -+struct subordinate_range **get_subuid_ranges(const char *owner); -+struct subordinate_range **get_subgid_ranges(const char *owner); -+void subid_free_ranges(struct subordinate_range **ranges); -+ -+int get_subuid_owners(uid_t uid, uid_t **owner); -+int get_subgid_owners(uid_t uid, uid_t **owner); -+ -+/* range should be pre-allocated with owner and count filled in, start is -+ * ignored, can be 0 */ -+bool grant_subuid_range(struct subordinate_range *range, bool reuse); -+bool grant_subgid_range(struct subordinate_range *range, bool reuse); -+ -+bool free_subuid_range(struct subordinate_range *range); -+bool free_subgid_range(struct subordinate_range *range); -diff --git a/libsubid/subid.h b/libsubid/subid.h -new file mode 100644 -index 00000000..ba9a2f6f ---- /dev/null -+++ b/libsubid/subid.h -@@ -0,0 +1,17 @@ -+#include -+ -+#ifndef SUBID_RANGE_DEFINED -+#define SUBID_RANGE_DEFINED 1 -+struct subordinate_range { -+ const char *owner; -+ unsigned long start; -+ unsigned long count; -+}; -+ -+enum subid_type { -+ ID_TYPE_UID = 1, -+ ID_TYPE_GID = 2 -+}; -+ -+#define SUBID_NFIELDS 3 -+#endif -diff --git a/src/Makefile.am b/src/Makefile.am -index f175928a..8499ce08 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -156,4 +156,64 @@ if FCAPS - setcap cap_setuid+ep $(DESTDIR)$(ubindir)/newuidmap - setcap cap_setgid+ep $(DESTDIR)$(ubindir)/newgidmap - endif -+ -+noinst_PROGRAMS += list_subid_ranges \ -+ get_subid_owners \ -+ new_subid_range \ -+ free_subid_range -+ -+MISCLIBS = \ -+ $(LIBAUDIT) \ -+ $(LIBSELINUX) \ -+ $(LIBSEMANAGE) \ -+ $(LIBCRYPT_NOPAM) \ -+ $(LIBSKEY) \ -+ $(LIBMD) \ -+ $(LIBECONF) \ -+ $(LIBCRYPT) \ -+ $(LIBTCB) -+ -+list_subid_ranges_LDADD = \ -+ $(top_builddir)/lib/libshadow.la \ -+ $(top_builddir)/libmisc/libmisc.a \ -+ $(top_builddir)/libsubid/libsubid.la \ -+ $(MISCLIBS) -+ -+list_subid_ranges_CPPFLAGS = \ -+ -I$(top_srcdir)/lib \ -+ -I$(top_srcdir)/libmisc \ -+ -I$(top_srcdir)/libsubid -+ -+get_subid_owners_LDADD = \ -+ $(top_builddir)/lib/libshadow.la \ -+ $(top_builddir)/libmisc/libmisc.a \ -+ $(top_builddir)/libsubid/libsubid.la \ -+ $(MISCLIBS) -+ -+get_subid_owners_CPPFLAGS = \ -+ -I$(top_srcdir)/lib \ -+ -I$(top_srcdir)/libmisc \ -+ -I$(top_srcdir)/libsubid -+ -+new_subid_range_CPPFLAGS = \ -+ -I$(top_srcdir)/lib \ -+ -I$(top_srcdir)/libmisc \ -+ -I$(top_srcdir)/libsubid -+ -+new_subid_range_LDADD = \ -+ $(top_builddir)/lib/libshadow.la \ -+ $(top_builddir)/libmisc/libmisc.a \ -+ $(top_builddir)/libsubid/libsubid.la \ -+ $(MISCLIBS) -+ -+free_subid_range_CPPFLAGS = \ -+ -I$(top_srcdir)/lib \ -+ -I$(top_srcdir)/libmisc \ -+ -I$(top_srcdir)/libsubid -+ -+free_subid_range_LDADD = \ -+ $(top_builddir)/lib/libshadow.la \ -+ $(top_builddir)/libmisc/libmisc.a \ -+ $(top_builddir)/libsubid/libsubid.la \ -+ $(MISCLIBS) - endif -diff --git a/src/free_subid_range.c b/src/free_subid_range.c -new file mode 100644 -index 00000000..36858875 ---- /dev/null -+++ b/src/free_subid_range.c -@@ -0,0 +1,50 @@ -+#include -+#include -+#include "api.h" -+#include "stdlib.h" -+#include "prototypes.h" -+ -+/* Test program for the subid freeing routine */ -+ -+const char *Prog; -+ -+void usage(void) -+{ -+ fprintf(stderr, "Usage: %s [-g] user start count\n", Prog); -+ fprintf(stderr, " Release a user's subuid (or with -g, subgid) range\n"); -+ exit(EXIT_FAILURE); -+} -+ -+int main(int argc, char *argv[]) -+{ -+ int c; -+ bool ok; -+ struct subordinate_range range; -+ bool group = false; // get subuids by default -+ -+ Prog = Basename (argv[0]); -+ while ((c = getopt(argc, argv, "g")) != EOF) { -+ switch(c) { -+ case 'g': group = true; break; -+ default: usage(); -+ } -+ } -+ argv = &argv[optind]; -+ argc = argc - optind; -+ if (argc < 3) -+ usage(); -+ range.owner = argv[0]; -+ range.start = atoi(argv[1]); -+ range.count = atoi(argv[2]); -+ if (group) -+ ok = free_subgid_range(&range); -+ else -+ ok = free_subuid_range(&range); -+ -+ if (!ok) { -+ fprintf(stderr, "Failed freeing id range\n"); -+ exit(EXIT_FAILURE); -+ } -+ -+ return 0; -+} -diff --git a/src/get_subid_owners.c b/src/get_subid_owners.c -new file mode 100644 -index 00000000..a4385540 ---- /dev/null -+++ b/src/get_subid_owners.c -@@ -0,0 +1,40 @@ -+#include -+#include "api.h" -+#include "stdlib.h" -+#include "prototypes.h" -+ -+const char *Prog; -+ -+void usage(void) -+{ -+ fprintf(stderr, "Usage: [-g] %s subuid\n", Prog); -+ fprintf(stderr, " list uids who own the given subuid\n"); -+ fprintf(stderr, " pass -g to query a subgid\n"); -+ exit(EXIT_FAILURE); -+} -+ -+int main(int argc, char *argv[]) -+{ -+ int i, n; -+ uid_t *uids; -+ -+ Prog = Basename (argv[0]); -+ if (argc < 2) { -+ usage(); -+ } -+ if (argc == 3 && strcmp(argv[1], "-g") == 0) -+ n = get_subgid_owners(atoi(argv[2]), &uids); -+ else if (argc == 2 && strcmp(argv[1], "-h") == 0) -+ usage(); -+ else -+ n = get_subuid_owners(atoi(argv[1]), &uids); -+ if (n < 0) { -+ fprintf(stderr, "No owners found\n"); -+ exit(1); -+ } -+ for (i = 0; i < n; i++) { -+ printf("%d\n", uids[i]); -+ } -+ free(uids); -+ return 0; -+} -diff --git a/src/list_subid_ranges.c b/src/list_subid_ranges.c -new file mode 100644 -index 00000000..cdba610e ---- /dev/null -+++ b/src/list_subid_ranges.c -@@ -0,0 +1,41 @@ -+#include -+#include "api.h" -+#include "stdlib.h" -+#include "prototypes.h" -+ -+const char *Prog; -+ -+void usage(void) -+{ -+ fprintf(stderr, "Usage: %s [-g] user\n", Prog); -+ fprintf(stderr, " list subuid ranges for user\n"); -+ fprintf(stderr, " pass -g to list subgid ranges\n"); -+ exit(EXIT_FAILURE); -+} -+ -+int main(int argc, char *argv[]) -+{ -+ int i; -+ struct subordinate_range **ranges; -+ -+ Prog = Basename (argv[0]); -+ if (argc < 2) { -+ usage(); -+ } -+ if (argc == 3 && strcmp(argv[1], "-g") == 0) -+ ranges = get_subgid_ranges(argv[2]); -+ else if (argc == 2 && strcmp(argv[1], "-h") == 0) -+ usage(); -+ else -+ ranges = get_subuid_ranges(argv[1]); -+ if (!ranges) { -+ fprintf(stderr, "Error fetching ranges\n"); -+ exit(1); -+ } -+ for (i = 0; ranges[i]; i++) { -+ printf("%d: %s %lu %lu\n", i, ranges[i]->owner, -+ ranges[i]->start, ranges[i]->count); -+ } -+ subid_free_ranges(ranges); -+ return 0; -+} -diff --git a/src/new_subid_range.c b/src/new_subid_range.c -new file mode 100644 -index 00000000..6d7b033b ---- /dev/null -+++ b/src/new_subid_range.c -@@ -0,0 +1,57 @@ -+#include -+#include -+#include "api.h" -+#include "stdlib.h" -+#include "prototypes.h" -+ -+/* Test program for the subid creation routine */ -+ -+const char *Prog; -+ -+void usage(void) -+{ -+ fprintf(stderr, "Usage: %s [-g] [-n] user count\n", Prog); -+ fprintf(stderr, " Find a subuid (or with -g, subgid) range for user\n"); -+ fprintf(stderr, " If -n is given, a new range will be created even if one exists\n"); -+ fprintf(stderr, " count defaults to 65536\n"); -+ exit(EXIT_FAILURE); -+} -+ -+int main(int argc, char *argv[]) -+{ -+ int c; -+ struct subordinate_range range; -+ bool makenew = false; // reuse existing by default -+ bool group = false; // get subuids by default -+ bool ok; -+ -+ Prog = Basename (argv[0]); -+ while ((c = getopt(argc, argv, "gn")) != EOF) { -+ switch(c) { -+ case 'n': makenew = true; break; -+ case 'g': group = true; break; -+ default: usage(); -+ } -+ } -+ argv = &argv[optind]; -+ argc = argc - optind; -+ if (argc == 0) -+ usage(); -+ range.owner = argv[0]; -+ range.start = 0; -+ range.count = 65536; -+ if (argc > 1) -+ range.count = atoi(argv[1]); -+ if (group) -+ ok = grant_subgid_range(&range, !makenew); -+ else -+ ok = grant_subuid_range(&range, !makenew); -+ -+ if (!ok) { -+ fprintf(stderr, "Failed creating new id range\n"); -+ exit(EXIT_FAILURE); -+ } -+ printf("Subuid range %lu:%lu\n", range.start, range.count); -+ -+ return 0; -+} -diff --git a/tests/libsubid/01_list_ranges/config.txt b/tests/libsubid/01_list_ranges/config.txt -new file mode 100644 -index 00000000..e69de29b -diff --git a/tests/libsubid/01_list_ranges/config/etc/subgid b/tests/libsubid/01_list_ranges/config/etc/subgid -new file mode 100644 -index 00000000..b9495cfc ---- /dev/null -+++ b/tests/libsubid/01_list_ranges/config/etc/subgid -@@ -0,0 +1,2 @@ -+foo:200000:10000 -+root:500000:1000 -diff --git a/tests/libsubid/01_list_ranges/config/etc/subuid b/tests/libsubid/01_list_ranges/config/etc/subuid -new file mode 100644 -index 00000000..e5c537be ---- /dev/null -+++ b/tests/libsubid/01_list_ranges/config/etc/subuid -@@ -0,0 +1,3 @@ -+foo:300000:10000 -+foo:400000:10000 -+root:500000:1000 -diff --git a/tests/libsubid/01_list_ranges/list_ranges.test b/tests/libsubid/01_list_ranges/list_ranges.test -new file mode 100755 -index 00000000..b131303b ---- /dev/null -+++ b/tests/libsubid/01_list_ranges/list_ranges.test -@@ -0,0 +1,38 @@ -+#!/bin/sh -+ -+set -e -+ -+cd $(dirname $0) -+ -+. ../../common/config.sh -+. ../../common/log.sh -+ -+log_start "$0" "list_ranges shows subid ranges" -+ -+save_config -+ -+# restore the files on exit -+trap 'log_status "$0" "FAILURE"; restore_config' 0 -+ -+change_config -+ -+echo -n "list foo's ranges..." -+${build_path}/src/list_subid_ranges foo > /tmp/subuidlistout -+${build_path}/src/list_subid_ranges -g foo > /tmp/subgidlistout -+echo "OK" -+ -+echo -n "Check the subuid ranges..." -+[ $(wc -l /tmp/subuidlistout | awk '{ print $1 }') -eq 2 ] -+grep "0: foo 300000 10000" /tmp/subuidlistout -+grep "1: foo 400000 10000" /tmp/subuidlistout -+echo "OK" -+ -+echo -n "Check the subgid ranges..." -+[ $(wc -l /tmp/subgidlistout | awk '{ print $1 }') -eq 1 ] -+grep "0: foo 200000 10000" /tmp/subgidlistout -+echo "OK" -+ -+log_status "$0" "SUCCESS" -+restore_config -+trap '' 0 -+ -diff --git a/tests/libsubid/02_get_subid_owners/config.txt b/tests/libsubid/02_get_subid_owners/config.txt -new file mode 100644 -index 00000000..e69de29b -diff --git a/tests/libsubid/02_get_subid_owners/config/etc/passwd b/tests/libsubid/02_get_subid_owners/config/etc/passwd -new file mode 100644 -index 00000000..bf52df00 ---- /dev/null -+++ b/tests/libsubid/02_get_subid_owners/config/etc/passwd -@@ -0,0 +1,20 @@ -+root:x:0:0:root:/root:/bin/bash -+daemon:x:1:1:daemon:/usr/sbin:/bin/sh -+bin:x:2:2:bin:/bin:/bin/sh -+sys:x:3:3:sys:/dev:/bin/sh -+sync:x:4:65534:sync:/bin:/bin/sync -+games:x:5:60:games:/usr/games:/bin/sh -+man:x:6:12:man:/var/cache/man:/bin/sh -+lp:x:7:7:lp:/var/spool/lpd:/bin/sh -+mail:x:8:8:mail:/var/mail:/bin/sh -+news:x:9:9:news:/var/spool/news:/bin/sh -+uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh -+proxy:x:13:13:proxy:/bin:/bin/sh -+www-data:x:33:33:www-data:/var/www:/bin/sh -+backup:x:34:34:backup:/var/backups:/bin/sh -+list:x:38:38:Mailing List Manager:/var/list:/bin/sh -+irc:x:39:39:ircd:/var/run/ircd:/bin/sh -+gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh -+nobody:x:65534:65534:nobody:/nonexistent:/bin/sh -+Debian-exim:x:102:102::/var/spool/exim4:/bin/false -+foo:x:1000:1000::/home/foo:/bin/false -diff --git a/tests/libsubid/02_get_subid_owners/config/etc/subgid b/tests/libsubid/02_get_subid_owners/config/etc/subgid -new file mode 100644 -index 00000000..b9495cfc ---- /dev/null -+++ b/tests/libsubid/02_get_subid_owners/config/etc/subgid -@@ -0,0 +1,2 @@ -+foo:200000:10000 -+root:500000:1000 -diff --git a/tests/libsubid/02_get_subid_owners/config/etc/subuid b/tests/libsubid/02_get_subid_owners/config/etc/subuid -new file mode 100644 -index 00000000..dd11875a ---- /dev/null -+++ b/tests/libsubid/02_get_subid_owners/config/etc/subuid -@@ -0,0 +1,4 @@ -+foo:300000:10000 -+foo:400000:10000 -+foo:500000:10000 -+root:500000:1000 -diff --git a/tests/libsubid/02_get_subid_owners/get_subid_owners.test b/tests/libsubid/02_get_subid_owners/get_subid_owners.test -new file mode 100755 -index 00000000..145477cb ---- /dev/null -+++ b/tests/libsubid/02_get_subid_owners/get_subid_owners.test -@@ -0,0 +1,52 @@ -+#!/bin/sh -+ -+set -e -+ -+cd $(dirname $0) -+ -+. ../../common/config.sh -+. ../../common/log.sh -+ -+log_start "$0" "get subid owners" -+ -+save_config -+ -+# restore the files on exit -+trap 'log_status "$0" "FAILURE"; restore_config' 0 -+ -+change_config -+ -+echo -n "Noone owns 0 as a subid..." -+[ -z "$(${build_path}/src/get_subid_owners 0)" ] -+echo "OK" -+ -+echo -n "foo owns subuid 300000..." -+[ "$(${build_path}/src/get_subid_owners 300000)" = "1000" ] -+echo "OK" -+ -+echo -n "foo owns subgid 200000..." -+[ "$(${build_path}/src/get_subid_owners -g 200000)" = "1000" ] -+echo "OK" -+ -+echo -n "Noone owns subuid 200000..." -+[ -z "$(${build_path}/src/get_subid_owners -g 300000)" ] -+echo "OK" -+ -+echo -n "Noone owns subgid 300000..." -+[ -z "$(${build_path}/src/get_subid_owners -g 300000)" ] -+echo "OK" -+ -+echo -n "Both foo and root own subuid 500000..." -+cat > /tmp/expected << EOF -+1000 -+0 -+EOF -+${build_path}/src/get_subid_owners 500000 > /tmp/actual -+diff /tmp/expected /tmp/actual -+ -+echo "OK" -+ -+log_status "$0" "SUCCESS" -+restore_config -+trap '' 0 -+ -diff --git a/tests/libsubid/03_add_remove/add_remove_subids.test b/tests/libsubid/03_add_remove/add_remove_subids.test -new file mode 100755 -index 00000000..a24a9752 ---- /dev/null -+++ b/tests/libsubid/03_add_remove/add_remove_subids.test -@@ -0,0 +1,59 @@ -+#!/bin/sh -+ -+set -e -+ -+cd $(dirname $0) -+ -+. ../../common/config.sh -+. ../../common/log.sh -+ -+log_start "$0" "add and remove subid ranges" -+ -+save_config -+ -+# restore the files on exit -+trap 'log_status "$0" "FAILURE"; restore_config' 0 -+ -+change_config -+ -+echo -n "Existing ranges returned when possible..." -+res=$(${build_path}/src/new_subid_range foo 500) -+echo "debug" -+echo "res is $res" -+echo "wanted Subuid range 300000:10000" -+echo "end debug" -+[ "$res" = "Subuid range 300000:10000" ] -+[ $(grep -c foo /etc/subuid) -eq 1 ] -+echo "OK" -+ -+echo -n "New range returned if requested..." -+res=$(${build_path}/src/new_subid_range foo 500 -n) -+[ "$res" = "Subuid range 310000:500" ] -+[ $(grep -c foo /etc/subuid) -eq 2 ] -+echo "OK" -+ -+echo -n "Free works..." -+res=$(${build_path}/src/free_subid_range foo 310000 500) -+[ $(grep -c foo /etc/subuid) -eq 1 ] -+echo "OK" -+ -+echo -n "Subgids work too..." -+res=$(${build_path}/src/new_subid_range -g foo 100000) -+echo "DEBUG: res is ${res}" -+[ "$res" = "Subuid range 501000:100000" ] -+echo "DEBUG: subgid is:" -+cat /etc/subgid -+[ $(grep -c foo /etc/subgid) -eq 2 ] -+ -+echo -n "Subgid free works..." -+res=$(${build_path}/src/free_subid_range -g foo 501000 100000) -+echo "DEBUG: res is ${res}" -+echo "DEBUG: subgid is:" -+cat /etc/subgid -+[ $(grep -c foo /etc/subgid) -eq 1 ] -+echo "OK" -+ -+log_status "$0" "SUCCESS" -+restore_config -+trap '' 0 -+ -diff --git a/tests/libsubid/03_add_remove/config.txt b/tests/libsubid/03_add_remove/config.txt -new file mode 100644 -index 00000000..e69de29b -diff --git a/tests/libsubid/03_add_remove/config/etc/passwd b/tests/libsubid/03_add_remove/config/etc/passwd -new file mode 100644 -index 00000000..bf52df00 ---- /dev/null -+++ b/tests/libsubid/03_add_remove/config/etc/passwd -@@ -0,0 +1,20 @@ -+root:x:0:0:root:/root:/bin/bash -+daemon:x:1:1:daemon:/usr/sbin:/bin/sh -+bin:x:2:2:bin:/bin:/bin/sh -+sys:x:3:3:sys:/dev:/bin/sh -+sync:x:4:65534:sync:/bin:/bin/sync -+games:x:5:60:games:/usr/games:/bin/sh -+man:x:6:12:man:/var/cache/man:/bin/sh -+lp:x:7:7:lp:/var/spool/lpd:/bin/sh -+mail:x:8:8:mail:/var/mail:/bin/sh -+news:x:9:9:news:/var/spool/news:/bin/sh -+uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh -+proxy:x:13:13:proxy:/bin:/bin/sh -+www-data:x:33:33:www-data:/var/www:/bin/sh -+backup:x:34:34:backup:/var/backups:/bin/sh -+list:x:38:38:Mailing List Manager:/var/list:/bin/sh -+irc:x:39:39:ircd:/var/run/ircd:/bin/sh -+gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh -+nobody:x:65534:65534:nobody:/nonexistent:/bin/sh -+Debian-exim:x:102:102::/var/spool/exim4:/bin/false -+foo:x:1000:1000::/home/foo:/bin/false -diff --git a/tests/libsubid/03_add_remove/config/etc/subgid b/tests/libsubid/03_add_remove/config/etc/subgid -new file mode 100644 -index 00000000..b9495cfc ---- /dev/null -+++ b/tests/libsubid/03_add_remove/config/etc/subgid -@@ -0,0 +1,2 @@ -+foo:200000:10000 -+root:500000:1000 -diff --git a/tests/libsubid/03_add_remove/config/etc/subuid b/tests/libsubid/03_add_remove/config/etc/subuid -new file mode 100644 -index 00000000..cf80c2f7 ---- /dev/null -+++ b/tests/libsubid/03_add_remove/config/etc/subuid -@@ -0,0 +1 @@ -+foo:300000:10000 -diff --git a/tests/run_some b/tests/run_some -new file mode 100755 -index 00000000..2d085d59 ---- /dev/null -+++ b/tests/run_some -@@ -0,0 +1,136 @@ -+#!/bin/sh -+ -+set -e -+ -+export LC_ALL=C -+unset LANG -+unset LANGUAGE -+. common/config.sh -+ -+USE_PAM="yes" -+FAILURE_TESTS="yes" -+ -+succeeded=0 -+failed=0 -+failed_tests="" -+ -+run_test() -+{ -+ [ -f RUN_TEST.STOP ] && exit 1 -+ -+ if $1 > $1.log -+ then -+ succeeded=$((succeeded+1)) -+ echo -n "+" -+ else -+ failed=$((failed+1)) -+ failed_tests="$failed_tests $1" -+ echo -n "-" -+ fi -+ cat $1.log >> testsuite.log -+ [ -f /etc/passwd.lock ] && echo $1 /etc/passwd.lock || true -+ [ -f /etc/group.lock ] && echo $1 /etc/group.lock || true -+ [ -f /etc/shadow.lock ] && echo $1 /etc/shadow.lock || true -+ [ -f /etc/gshadow.lock ] && echo $1 /etc/gshadow.lock || true -+ if [ "$(stat -c"%G" /etc/shadow)" != "shadow" ] -+ then -+ echo $1 -+ ls -l /etc/shadow -+ chgrp shadow /etc/shadow -+ fi -+ if [ -d /nonexistent ] -+ then -+ echo $1 /nonexistent -+ rmdir /nonexistent -+ fi -+} -+ -+echo "+: test passed" -+echo "-: test failed" -+ -+# Empty the complete log. -+> testsuite.log -+ -+find ${build_path} -name "*.gcda" -delete -+run_test ./su/01/su_root.test -+run_test ./su/01/su_user.test -+find ${build_path} -name "*.gcda" -exec chmod a+rw {} \; -+run_test ./su/02/env_FOO-options_--login -+run_test ./su/02/env_FOO-options_--login_bash -+run_test ./su/02/env_FOO-options_--preserve-environment -+run_test ./su/02/env_FOO-options_--preserve-environment_bash -+run_test ./su/02/env_FOO-options_- -+run_test ./su/02/env_FOO-options_-_bash -+run_test ./su/02/env_FOO-options_-l-m -+run_test ./su/02/env_FOO-options_-l-m_bash -+run_test ./su/02/env_FOO-options_-l -+run_test ./su/02/env_FOO-options_-l_bash -+run_test ./su/02/env_FOO-options_-m_bash -+run_test ./su/02/env_FOO-options_-m -+run_test ./su/02/env_FOO-options_-p -+run_test ./su/02/env_FOO-options_-p_bash -+run_test ./su/02/env_FOO-options__bash -+run_test ./su/02/env_FOO-options_ -+run_test ./su/02/env_FOO-options_-p- -+run_test ./su/02/env_FOO-options_-p-_bash -+run_test ./su/02/env_special-options_-l-p -+run_test ./su/02/env_special-options_-l -+run_test ./su/02/env_special-options_-l-p_bash -+run_test ./su/02/env_special-options_-l_bash -+run_test ./su/02/env_special-options_-p -+run_test ./su/02/env_special-options_-p_bash -+run_test ./su/02/env_special-options_ -+run_test ./su/02/env_special-options__bash -+run_test ./su/02/env_special_root-options_-l-p -+run_test ./su/02/env_special_root-options_-l-p_bash -+run_test ./su/02/env_special_root-options_-l -+run_test ./su/02/env_special_root-options_-l_bash -+run_test ./su/02/env_special_root-options_-p -+run_test ./su/02/env_special_root-options_-p_bash -+run_test ./su/02/env_special_root-options_ -+run_test ./su/02/env_special_root-options__bash -+run_test ./su/03/su_run_command01.test -+run_test ./su/03/su_run_command02.test -+run_test ./su/03/su_run_command03.test -+run_test ./su/03/su_run_command04.test -+run_test ./su/03/su_run_command05.test -+run_test ./su/03/su_run_command06.test -+run_test ./su/03/su_run_command07.test -+run_test ./su/03/su_run_command08.test -+run_test ./su/03/su_run_command09.test -+run_test ./su/03/su_run_command10.test -+run_test ./su/03/su_run_command11.test -+run_test ./su/03/su_run_command12.test -+run_test ./su/03/su_run_command13.test -+run_test ./su/03/su_run_command14.test -+run_test ./su/03/su_run_command15.test -+run_test ./su/03/su_run_command16.test -+run_test ./su/03/su_run_command17.test -+run_test ./su/04/su_wrong_user.test -+run_test ./su/04/su_user_wrong_passwd.test -+run_test ./su/04/su_user_wrong_passwd_syslog.test -+run_test ./su/05/su_user_wrong_passwd_syslog.test -+run_test ./su/06/su_user_syslog.test -+run_test ./su/07/su_user_syslog.test -+run_test ./su/08/env_special-options_ -+run_test ./su/08/env_special_root-options_ -+run_test ./su/09/env_special-options_ -+run_test ./su/09/env_special_root-options_ -+run_test ./su/10_su_sulog_success/su.test -+run_test ./su/11_su_sulog_failure/su.test -+run_test ./su/12_su_child_failure/su.test -+run_test ./su/13_su_child_success/su.test -+run_test ./libsubid/01_list_ranges/list_ranges.test -+run_test ./libsubid/02_get_subid_owners/get_subid_owners.test -+run_test ./libsubid/03_add_remove/add_remove_subids.test -+ -+echo -+echo "$succeeded test(s) passed" -+echo "$failed test(s) failed" -+echo "log written in 'testsuite.log'" -+if [ "$failed" != "0" ] -+then -+ echo "the following tests failed:" -+ echo $failed_tests -+fi -+ --- -2.30.2 - -From 607f1dd549cf9abc87af1cf29275f0d2d11eea29 Mon Sep 17 00:00:00 2001 -From: Serge Hallyn -Date: Fri, 19 Jun 2020 22:09:20 -0500 -Subject: [PATCH] libsubid: fix a prototype in api.h - -Signed-off-by: Serge Hallyn ---- - libsubid/api.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libsubid/api.h b/libsubid/api.h -index f65e3ec9..fbdf0f9e 100644 ---- a/libsubid/api.h -+++ b/libsubid/api.h -@@ -6,7 +6,7 @@ struct subordinate_range **get_subgid_ranges(const char *owner); - void subid_free_ranges(struct subordinate_range **ranges); - - int get_subuid_owners(uid_t uid, uid_t **owner); --int get_subgid_owners(uid_t uid, uid_t **owner); -+int get_subgid_owners(gid_t gid, uid_t **owner); - - /* range should be pre-allocated with owner and count filled in, start is - * ignored, can be 0 */ --- -2.30.2 - -From b5fb1b38eea2fb0489ed088c82daf6700e72363e Mon Sep 17 00:00:00 2001 -From: Serge Hallyn -Date: Fri, 1 Jan 2021 13:01:54 -0600 -Subject: [PATCH] libsubid: move libmisc.a to last LIBADD entry - -Closes #297 - -Signed-off-by: Serge Hallyn ---- - libsubid/Makefile.am | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/libsubid/Makefile.am b/libsubid/Makefile.am -index bdbc52c3..8bef1ecc 100644 ---- a/libsubid/Makefile.am -+++ b/libsubid/Makefile.am -@@ -16,8 +16,8 @@ MISCLIBS = \ - - libsubid_la_LIBADD = \ - $(top_srcdir)/lib/libshadow.la \ -- $(top_srcdir)/libmisc/libmisc.a \ -- $(MISCLIBS) -+ $(MISCLIBS) \ -+ $(top_srcdir)/libmisc/libmisc.a - - AM_CPPFLAGS = \ - -I${top_srcdir}/lib \ --- -2.30.2 - -From 43a917cce54019799a8de037fd63780a2b640afc Mon Sep 17 00:00:00 2001 -From: Serge Hallyn -Date: Sat, 18 Apr 2020 14:57:56 -0500 -Subject: [PATCH] configure: define abi versions - -Signed-off-by: Serge Hallyn ---- - configure.ac | 12 +++++++++++- - 1 file changed, 11 insertions(+), 1 deletion(-) - -diff --git a/configure.ac b/configure.ac -index e4c6aaec..b8bc2b7a 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1,11 +1,21 @@ - dnl Process this file with autoconf to produce a configure script. --AC_PREREQ([2.64]) -+AC_PREREQ([2.69]) -+m4_define([libsubid_abi_major], 1) -+m4_define([libsubid_abi_minor], 0) -+m4_define([libsubid_abi_micro], 0) -+m4_define([libsubid_abi], [libsubid_abi_major.libsubid_abi_minor.libsubid_abi_micro]) - AC_INIT([shadow], [4.8.1], [pkg-shadow-devel@lists.alioth.debian.org], [], - [https://github.com/shadow-maint/shadow]) - AM_INIT_AUTOMAKE([1.11 foreign dist-xz]) -+AC_CONFIG_MACRO_DIRS([m4]) - AM_SILENT_RULES([yes]) - AC_CONFIG_HEADERS([config.h]) - -+AC_SUBST([LIBSUBID_ABI_MAJOR], [libsubid_abi_major]) -+AC_SUBST([LIBSUBID_ABI_MINOR], [libsubid_abi_minor]) -+AC_SUBST([LIBSUBID_ABI_MICRO], [libsubid_abi_micro]) -+AC_SUBST([LIBSUBID_ABI], [libsubid_abi]) -+ - dnl Some hacks... - test "$prefix" = "NONE" && prefix="/usr" - test "$prefix" = "/usr" && exec_prefix="" --- -2.30.2 - diff --git a/shadow-4.8.1-libsubid_fix_newusers_nss_provides_subids.patch b/shadow-4.8.1-libsubid_fix_newusers_nss_provides_subids.patch deleted file mode 100644 index c0ca905..0000000 --- a/shadow-4.8.1-libsubid_fix_newusers_nss_provides_subids.patch +++ /dev/null @@ -1,151 +0,0 @@ -diff -up shadow-4.8.1/lib/nss.c.libsubid_fix_newusers_nss_provides_subids shadow-4.8.1/lib/nss.c ---- shadow-4.8.1/lib/nss.c.libsubid_fix_newusers_nss_provides_subids 2021-05-25 09:37:14.772741048 +0200 -+++ shadow-4.8.1/lib/nss.c 2021-05-25 09:37:14.782741188 +0200 -@@ -116,14 +116,6 @@ void nss_init(char *nsswitch_path) { - subid_nss = NULL; - goto done; - } -- subid_nss->has_any_range = dlsym(h, "shadow_subid_has_any_range"); -- if (!subid_nss->has_any_range) { -- fprintf(shadow_logfd, "%s did not provide @has_any_range@\n", libname); -- dlclose(h); -- free(subid_nss); -- subid_nss = NULL; -- goto done; -- } - subid_nss->find_subid_owners = dlsym(h, "shadow_subid_find_subid_owners"); - if (!subid_nss->find_subid_owners) { - fprintf(shadow_logfd, "%s did not provide @find_subid_owners@\n", libname); -diff -up shadow-4.8.1/lib/prototypes.h.libsubid_fix_newusers_nss_provides_subids shadow-4.8.1/lib/prototypes.h ---- shadow-4.8.1/lib/prototypes.h.libsubid_fix_newusers_nss_provides_subids 2021-05-25 09:37:14.780741160 +0200 -+++ shadow-4.8.1/lib/prototypes.h 2021-05-25 09:37:14.782741188 +0200 -@@ -279,18 +279,6 @@ extern bool nss_is_initialized(); - - struct subid_nss_ops { - /* -- * nss_has_any_range: does a user own any subid range -- * -- * @owner: username -- * @idtype: subuid or subgid -- * @result: true if a subid allocation was found for @owner -- * -- * returns success if the module was able to determine an answer (true or false), -- * else an error status. -- */ -- enum subid_status (*has_any_range)(const char *owner, enum subid_type idtype, bool *result); -- -- /* - * nss_has_range: does a user own a given subid range - * - * @owner: username -diff -up shadow-4.8.1/lib/subordinateio.c.libsubid_fix_newusers_nss_provides_subids shadow-4.8.1/lib/subordinateio.c ---- shadow-4.8.1/lib/subordinateio.c.libsubid_fix_newusers_nss_provides_subids 2021-05-25 09:37:14.780741160 +0200 -+++ shadow-4.8.1/lib/subordinateio.c 2021-05-25 09:37:14.782741188 +0200 -@@ -598,19 +598,8 @@ int sub_uid_open (int mode) - return commonio_open (&subordinate_uid_db, mode); - } - --bool sub_uid_assigned(const char *owner) -+bool local_sub_uid_assigned(const char *owner) - { -- struct subid_nss_ops *h; -- bool found; -- enum subid_status status; -- h = get_subid_nss_handle(); -- if (h) { -- status = h->has_any_range(owner, ID_TYPE_UID, &found); -- if (status == SUBID_STATUS_SUCCESS && found) -- return true; -- return false; -- } -- - return range_exists (&subordinate_uid_db, owner); - } - -@@ -720,18 +709,8 @@ bool have_sub_gids(const char *owner, gi - return have_range(&subordinate_gid_db, owner, start, count); - } - --bool sub_gid_assigned(const char *owner) -+bool local_sub_gid_assigned(const char *owner) - { -- struct subid_nss_ops *h; -- bool found; -- enum subid_status status; -- h = get_subid_nss_handle(); -- if (h) { -- status = h->has_any_range(owner, ID_TYPE_GID, &found); -- if (status == SUBID_STATUS_SUCCESS && found) -- return true; -- return false; -- } - return range_exists (&subordinate_gid_db, owner); - } - -diff -up shadow-4.8.1/lib/subordinateio.h.libsubid_fix_newusers_nss_provides_subids shadow-4.8.1/lib/subordinateio.h ---- shadow-4.8.1/lib/subordinateio.h.libsubid_fix_newusers_nss_provides_subids 2021-05-25 09:37:14.780741160 +0200 -+++ shadow-4.8.1/lib/subordinateio.h 2021-05-25 09:37:14.782741188 +0200 -@@ -16,7 +16,7 @@ - extern int sub_uid_close(void); - extern bool have_sub_uids(const char *owner, uid_t start, unsigned long count); - extern bool sub_uid_file_present (void); --extern bool sub_uid_assigned(const char *owner); -+extern bool local_sub_uid_assigned(const char *owner); - extern int sub_uid_lock (void); - extern int sub_uid_setdbname (const char *filename); - extern /*@observer@*/const char *sub_uid_dbname (void); -@@ -34,7 +34,7 @@ extern void free_subordinate_ranges(stru - extern int sub_gid_close(void); - extern bool have_sub_gids(const char *owner, gid_t start, unsigned long count); - extern bool sub_gid_file_present (void); --extern bool sub_gid_assigned(const char *owner); -+extern bool local_sub_gid_assigned(const char *owner); - extern int sub_gid_lock (void); - extern int sub_gid_setdbname (const char *filename); - extern /*@observer@*/const char *sub_gid_dbname (void); -diff -up shadow-4.8.1/src/newusers.c.libsubid_fix_newusers_nss_provides_subids shadow-4.8.1/src/newusers.c ---- shadow-4.8.1/src/newusers.c.libsubid_fix_newusers_nss_provides_subids 2021-05-25 09:37:14.776741104 +0200 -+++ shadow-4.8.1/src/newusers.c 2021-05-25 09:37:25.955897160 +0200 -@@ -1021,6 +1021,24 @@ static void close_files (void) - #endif /* ENABLE_SUBIDS */ - } - -+static bool want_subuids(void) -+{ -+ if (get_subid_nss_handle() != NULL) -+ return false; -+ if (getdef_ulong ("SUB_UID_COUNT", 65536) == 0) -+ return false; -+ return true; -+} -+ -+static bool want_subgids(void) -+{ -+ if (get_subid_nss_handle() != NULL) -+ return false; -+ if (getdef_ulong ("SUB_GID_COUNT", 65536) == 0) -+ return false; -+ return true; -+} -+ - int main (int argc, char **argv) - { - char buf[BUFSIZ]; -@@ -1250,7 +1268,7 @@ int main (int argc, char **argv) - /* - * Add subordinate uids if the user does not have them. - */ -- if (is_sub_uid && !sub_uid_assigned(fields[0])) { -+ if (is_sub_uid && want_subuids() && !local_sub_uid_assigned(fields[0])) { - uid_t sub_uid_start = 0; - unsigned long sub_uid_count = 0; - if (find_new_sub_uids(fields[0], &sub_uid_start, &sub_uid_count) == 0) { -@@ -1270,7 +1288,7 @@ int main (int argc, char **argv) - /* - * Add subordinate gids if the user does not have them. - */ -- if (is_sub_gid && !sub_gid_assigned(fields[0])) { -+ if (is_sub_gid && want_subgids() && !local_sub_gid_assigned(fields[0])) { - gid_t sub_gid_start = 0; - unsigned long sub_gid_count = 0; - if (find_new_sub_gids(fields[0], &sub_gid_start, &sub_gid_count) == 0) { diff --git a/shadow-4.8.1-libsubid_init_not_print_error_messages.patch b/shadow-4.8.1-libsubid_init_not_print_error_messages.patch deleted file mode 100644 index 820a043..0000000 --- a/shadow-4.8.1-libsubid_init_not_print_error_messages.patch +++ /dev/null @@ -1,40 +0,0 @@ -From b0e86b959fe5c086ffb5e7eaf3c1b1e9219411e9 Mon Sep 17 00:00:00 2001 -From: Serge Hallyn -Date: Sun, 23 May 2021 08:03:10 -0500 -Subject: [PATCH] libsubid_init: don't print messages on error - -Signed-off-by: Serge Hallyn ---- - libsubid/api.c | 7 ++----- - 1 file changed, 2 insertions(+), 5 deletions(-) - -diff --git a/libsubid/api.c b/libsubid/api.c -index c4848142..b477b271 100644 ---- a/libsubid/api.c -+++ b/libsubid/api.c -@@ -46,12 +46,10 @@ bool libsubid_init(const char *progname, FILE * logfd) - { - if (progname) { - progname = strdup(progname); -- if (progname) { -+ if (progname) - Prog = progname; -- } else { -- fprintf(stderr, "Out of memory"); -+ else - return false; -- } - } - - if (logfd) { -@@ -60,7 +58,6 @@ bool libsubid_init(const char *progname, FILE * logfd) - } - shadow_logfd = fopen("/dev/null", "w"); - if (!shadow_logfd) { -- fprintf(stderr, "ERROR opening /dev/null for error messages. Using stderr."); - shadow_logfd = stderr; - return false; - } --- -2.30.2 - diff --git a/shadow-4.8.1-libsubid_init_return_false.patch b/shadow-4.8.1-libsubid_init_return_false.patch deleted file mode 100644 index 4d02d0d..0000000 --- a/shadow-4.8.1-libsubid_init_return_false.patch +++ /dev/null @@ -1,37 +0,0 @@ -From e34f49c1966fcaa9390a544a0136ec189a3c870e Mon Sep 17 00:00:00 2001 -From: Serge Hallyn -Date: Mon, 17 May 2021 08:48:03 -0500 -Subject: [PATCH] libsubid_init: return false if out of memory - -The rest of the run isn't likely to get much better, is it? - -Thanks to Alexey for pointing this out. - -Signed-off-by: Serge Hallyn -Cc: Alexey Tikhonov ---- - libsubid/api.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/libsubid/api.c b/libsubid/api.c -index 8ca09859..8618e500 100644 ---- a/libsubid/api.c -+++ b/libsubid/api.c -@@ -46,10 +46,12 @@ bool libsubid_init(const char *progname, FILE * logfd) - { - if (progname) { - progname = strdup(progname); -- if (progname) -+ if (progname) { - Prog = progname; -- else -+ } else { - fprintf(stderr, "Out of memory"); -+ return false; -+ } - } - - if (logfd) { --- -2.30.2 - diff --git a/shadow-4.8.1-libsubid_make_logfd_not_extern.patch b/shadow-4.8.1-libsubid_make_logfd_not_extern.patch deleted file mode 100644 index 2994442..0000000 --- a/shadow-4.8.1-libsubid_make_logfd_not_extern.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 1d767fb779d7b203ad609540d1dc605cf62d1050 Mon Sep 17 00:00:00 2001 -From: Serge Hallyn -Date: Fri, 28 May 2021 22:02:16 -0500 -Subject: [PATCH] libsubid/api.c: make shadow_logfd not extern - -Closes #346 - -Also #include stdio.h - -Signed-off-by: Serge Hallyn ---- - libsubid/api.c | 2 +- - libsubid/subid.h | 1 + - 2 files changed, 2 insertions(+), 1 deletion(-) - -diff --git a/libsubid/api.c b/libsubid/api.c -index b477b271..a7b904d0 100644 ---- a/libsubid/api.c -+++ b/libsubid/api.c -@@ -40,7 +40,7 @@ - #include "subid.h" - - const char *Prog = "(libsubid)"; --extern FILE * shadow_logfd; -+FILE *shadow_logfd; - - bool libsubid_init(const char *progname, FILE * logfd) - { -diff --git a/libsubid/subid.h b/libsubid/subid.h -index 5fef2572..eabafe4d 100644 ---- a/libsubid/subid.h -+++ b/libsubid/subid.h -@@ -1,4 +1,5 @@ - #include -+#include - #include - - #ifndef SUBID_RANGE_DEFINED --- -2.31.1 - diff --git a/shadow-4.8.1-libsubid_not_print_error_messages.patch b/shadow-4.8.1-libsubid_not_print_error_messages.patch deleted file mode 100644 index 3cef98c..0000000 --- a/shadow-4.8.1-libsubid_not_print_error_messages.patch +++ /dev/null @@ -1,2443 +0,0 @@ -diff -up shadow-4.8.1/lib/commonio.c.libsubid_not_print_error_messages shadow-4.8.1/lib/commonio.c ---- shadow-4.8.1/lib/commonio.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.919268967 +0200 -+++ shadow-4.8.1/lib/commonio.c 2021-05-24 13:04:19.928269091 +0200 -@@ -144,7 +144,7 @@ static int do_lock_file (const char *fil - fd = open (file, O_CREAT | O_TRUNC | O_WRONLY, 0600); - if (-1 == fd) { - if (log) { -- (void) fprintf (stderr, -+ (void) fprintf (shadow_logfd, - "%s: %s: %s\n", - Prog, file, strerror (errno)); - } -@@ -156,7 +156,7 @@ static int do_lock_file (const char *fil - len = (ssize_t) strlen (buf) + 1; - if (write (fd, buf, (size_t) len) != len) { - if (log) { -- (void) fprintf (stderr, -+ (void) fprintf (shadow_logfd, - "%s: %s file write error: %s\n", - Prog, file, strerror (errno)); - } -@@ -166,7 +166,7 @@ static int do_lock_file (const char *fil - } - if (fdatasync (fd) == -1) { - if (log) { -- (void) fprintf (stderr, -+ (void) fprintf (shadow_logfd, - "%s: %s file sync error: %s\n", - Prog, file, strerror (errno)); - } -@@ -179,7 +179,7 @@ static int do_lock_file (const char *fil - if (link (file, lock) == 0) { - retval = check_link_count (file); - if ((0==retval) && log) { -- (void) fprintf (stderr, -+ (void) fprintf (shadow_logfd, - "%s: %s: lock file already used\n", - Prog, file); - } -@@ -190,7 +190,7 @@ static int do_lock_file (const char *fil - fd = open (lock, O_RDWR); - if (-1 == fd) { - if (log) { -- (void) fprintf (stderr, -+ (void) fprintf (shadow_logfd, - "%s: %s: %s\n", - Prog, lock, strerror (errno)); - } -@@ -202,7 +202,7 @@ static int do_lock_file (const char *fil - close (fd); - if (len <= 0) { - if (log) { -- (void) fprintf (stderr, -+ (void) fprintf (shadow_logfd, - "%s: existing lock file %s without a PID\n", - Prog, lock); - } -@@ -213,7 +213,7 @@ static int do_lock_file (const char *fil - buf[len] = '\0'; - if (get_pid (buf, &pid) == 0) { - if (log) { -- (void) fprintf (stderr, -+ (void) fprintf (shadow_logfd, - "%s: existing lock file %s with an invalid PID '%s'\n", - Prog, lock, buf); - } -@@ -223,7 +223,7 @@ static int do_lock_file (const char *fil - } - if (kill (pid, 0) == 0) { - if (log) { -- (void) fprintf (stderr, -+ (void) fprintf (shadow_logfd, - "%s: lock %s already used by PID %lu\n", - Prog, lock, (unsigned long) pid); - } -@@ -233,7 +233,7 @@ static int do_lock_file (const char *fil - } - if (unlink (lock) != 0) { - if (log) { -- (void) fprintf (stderr, -+ (void) fprintf (shadow_logfd, - "%s: cannot get lock %s: %s\n", - Prog, lock, strerror (errno)); - } -@@ -245,13 +245,13 @@ static int do_lock_file (const char *fil - if (link (file, lock) == 0) { - retval = check_link_count (file); - if ((0==retval) && log) { -- (void) fprintf (stderr, -+ (void) fprintf (shadow_logfd, - "%s: %s: lock file already used\n", - Prog, file); - } - } else { - if (log) { -- (void) fprintf (stderr, -+ (void) fprintf (shadow_logfd, - "%s: cannot get lock %s: %s\n", - Prog, lock, strerror (errno)); - } -@@ -442,7 +442,7 @@ int commonio_lock (struct commonio_db *d - if (0 == lock_count) { - if (lckpwdf () == -1) { - if (geteuid () != 0) { -- (void) fprintf (stderr, -+ (void) fprintf (shadow_logfd, - "%s: Permission denied.\n", - Prog); - } -@@ -478,7 +478,7 @@ int commonio_lock (struct commonio_db *d - } - /* no unnecessary retries on "permission denied" errors */ - if (geteuid () != 0) { -- (void) fprintf (stderr, "%s: Permission denied.\n", -+ (void) fprintf (shadow_logfd, "%s: Permission denied.\n", - Prog); - return 0; - } -@@ -1109,7 +1109,7 @@ int commonio_update (struct commonio_db - p = find_entry_by_name (db, db->ops->getname (eptr)); - if (NULL != p) { - if (next_entry_by_name (db, p->next, db->ops->getname (eptr)) != NULL) { -- fprintf (stderr, _("Multiple entries named '%s' in %s. Please fix this with pwck or grpck.\n"), db->ops->getname (eptr), db->filename); -+ fprintf (shadow_logfd, _("Multiple entries named '%s' in %s. Please fix this with pwck or grpck.\n"), db->ops->getname (eptr), db->filename); - db->ops->free (nentry); - return 0; - } -@@ -1214,7 +1214,7 @@ int commonio_remove (struct commonio_db - return 0; - } - if (next_entry_by_name (db, p->next, name) != NULL) { -- fprintf (stderr, _("Multiple entries named '%s' in %s. Please fix this with pwck or grpck.\n"), name, db->filename); -+ fprintf (shadow_logfd, _("Multiple entries named '%s' in %s. Please fix this with pwck or grpck.\n"), name, db->filename); - return 0; - } - -diff -up shadow-4.8.1/lib/encrypt.c.libsubid_not_print_error_messages shadow-4.8.1/lib/encrypt.c ---- shadow-4.8.1/lib/encrypt.c.libsubid_not_print_error_messages 2019-12-01 18:02:43.000000000 +0100 -+++ shadow-4.8.1/lib/encrypt.c 2021-05-24 13:04:19.928269091 +0200 -@@ -81,7 +81,7 @@ - method = &nummethod[0]; - } - } -- (void) fprintf (stderr, -+ (void) fprintf (shadow_logfd, - _("crypt method not supported by libcrypt? (%s)\n"), - method); - exit (EXIT_FAILURE); -diff -up shadow-4.8.1/lib/getdef.c.libsubid_not_print_error_messages shadow-4.8.1/lib/getdef.c ---- shadow-4.8.1/lib/getdef.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.915268912 +0200 -+++ shadow-4.8.1/lib/getdef.c 2021-05-24 13:04:19.928269091 +0200 -@@ -250,7 +250,7 @@ int getdef_num (const char *item, int df - if ( (getlong (d->value, &val) == 0) - || (val > INT_MAX) - || (val < INT_MIN)) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("configuration error - cannot parse %s value: '%s'"), - item, d->value); - return dflt; -@@ -285,7 +285,7 @@ unsigned int getdef_unum (const char *it - if ( (getlong (d->value, &val) == 0) - || (val < 0) - || (val > INT_MAX)) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("configuration error - cannot parse %s value: '%s'"), - item, d->value); - return dflt; -@@ -318,7 +318,7 @@ long getdef_long (const char *item, long - } - - if (getlong (d->value, &val) == 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("configuration error - cannot parse %s value: '%s'"), - item, d->value); - return dflt; -@@ -351,7 +351,7 @@ unsigned long getdef_ulong (const char * - - if (getulong (d->value, &val) == 0) { - /* FIXME: we should have a getulong */ -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("configuration error - cannot parse %s value: '%s'"), - item, d->value); - return dflt; -@@ -389,7 +389,7 @@ int putdef_str (const char *name, const - cp = strdup (value); - if (NULL == cp) { - (void) fputs (_("Could not allocate space for config info.\n"), -- stderr); -+ shadow_logfd); - SYSLOG ((LOG_ERR, "could not allocate space for config info")); - return -1; - } -@@ -434,7 +434,7 @@ static /*@observer@*/ /*@null@*/struct i - goto out; - } - } -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("configuration error - unknown item '%s' (notify administrator)\n"), - name); - SYSLOG ((LOG_CRIT, "unknown configuration item `%s'", name)); -diff -up shadow-4.8.1/libmisc/addgrps.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/addgrps.c ---- shadow-4.8.1/libmisc/addgrps.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/libmisc/addgrps.c 2021-05-24 13:04:19.929269104 +0200 -@@ -93,7 +93,7 @@ int add_groups (const char *list) - - grp = getgrnam (token); /* local, no need for xgetgrnam */ - if (NULL == grp) { -- fprintf (stderr, _("Warning: unknown group %s\n"), -+ fprintf (shadow_logfd, _("Warning: unknown group %s\n"), - token); - continue; - } -@@ -105,7 +105,7 @@ int add_groups (const char *list) - } - - if (ngroups >= sysconf (_SC_NGROUPS_MAX)) { -- fputs (_("Warning: too many groups\n"), stderr); -+ fputs (_("Warning: too many groups\n"), shadow_logfd); - break; - } - tmp = (gid_t *) realloc (grouplist, (size_t)(ngroups + 1) * sizeof (GETGROUPS_T)); -diff -up shadow-4.8.1/libmisc/audit_help.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/audit_help.c ---- shadow-4.8.1/libmisc/audit_help.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.905268774 +0200 -+++ shadow-4.8.1/libmisc/audit_help.c 2021-05-24 13:04:19.929269104 +0200 -@@ -59,7 +59,7 @@ void audit_help_open (void) - return; - } - (void) fputs (_("Cannot open audit interface - aborting.\n"), -- stderr); -+ shadow_logfd); - exit (EXIT_FAILURE); - } - } -diff -up shadow-4.8.1/libmisc/chowntty.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/chowntty.c ---- shadow-4.8.1/libmisc/chowntty.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/libmisc/chowntty.c 2021-05-24 13:04:19.929269104 +0200 -@@ -75,7 +75,7 @@ void chown_tty (const struct passwd *inf - || (fchmod (STDIN_FILENO, (mode_t)getdef_num ("TTYPERM", 0600)) != 0)) { - int err = errno; - -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("Unable to change owner or mode of tty stdin: %s"), - strerror (err)); - SYSLOG ((LOG_WARN, -diff -up shadow-4.8.1/libmisc/cleanup_group.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/cleanup_group.c ---- shadow-4.8.1/libmisc/cleanup_group.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.905268774 +0200 -+++ shadow-4.8.1/libmisc/cleanup_group.c 2021-05-24 13:04:19.929269104 +0200 -@@ -203,7 +203,7 @@ void cleanup_report_del_group_gshadow (v - void cleanup_unlock_group (unused void *arg) - { - if (gr_unlock () == 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: failed to unlock %s\n"), - Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); -@@ -223,7 +223,7 @@ void cleanup_unlock_group (unused void * - void cleanup_unlock_gshadow (unused void *arg) - { - if (sgr_unlock () == 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: failed to unlock %s\n"), - Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); -diff -up shadow-4.8.1/libmisc/cleanup_user.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/cleanup_user.c ---- shadow-4.8.1/libmisc/cleanup_user.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.905268774 +0200 -+++ shadow-4.8.1/libmisc/cleanup_user.c 2021-05-24 13:04:19.929269104 +0200 -@@ -120,7 +120,7 @@ void cleanup_report_add_user_shadow (voi - void cleanup_unlock_passwd (unused void *arg) - { - if (pw_unlock () == 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: failed to unlock %s\n"), - Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); -@@ -139,7 +139,7 @@ void cleanup_unlock_passwd (unused void - void cleanup_unlock_shadow (unused void *arg) - { - if (spw_unlock () == 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: failed to unlock %s\n"), - Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); -diff -up shadow-4.8.1/libmisc/copydir.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/copydir.c ---- shadow-4.8.1/libmisc/copydir.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.898268677 +0200 -+++ shadow-4.8.1/libmisc/copydir.c 2021-05-24 13:04:19.929269104 +0200 -@@ -125,11 +125,11 @@ static void error_acl (struct error_cont - } - - va_start (ap, fmt); -- (void) fprintf (stderr, _("%s: "), Prog); -- if (vfprintf (stderr, fmt, ap) != 0) { -- (void) fputs (_(": "), stderr); -+ (void) fprintf (shadow_logfd, _("%s: "), Prog); -+ if (vfprintf (shadow_logfd, fmt, ap) != 0) { -+ (void) fputs (_(": "), shadow_logfd); - } -- (void) fprintf (stderr, "%s\n", strerror (errno)); -+ (void) fprintf (shadow_logfd, "%s\n", strerror (errno)); - va_end (ap); - } - -@@ -248,7 +248,7 @@ int copy_tree (const char *src_root, con - } - - if (!S_ISDIR (sb.st_mode)) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - "%s: %s is not a directory", - Prog, src_root); - return -1; -diff -up shadow-4.8.1/libmisc/env.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/env.c ---- shadow-4.8.1/libmisc/env.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/libmisc/env.c 2021-05-24 13:04:19.929269104 +0200 -@@ -171,7 +171,7 @@ void addenv (const char *string, /*@null - } - newenvp = __newenvp; - } else { -- (void) fputs (_("Environment overflow\n"), stderr); -+ (void) fputs (_("Environment overflow\n"), shadow_logfd); - newenvc--; - free (newenvp[newenvc]); - } -diff -up shadow-4.8.1/libmisc/find_new_gid.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/find_new_gid.c ---- shadow-4.8.1/libmisc/find_new_gid.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.914268898 +0200 -+++ shadow-4.8.1/libmisc/find_new_gid.c 2021-05-24 13:04:19.929269104 +0200 -@@ -74,7 +74,7 @@ static int get_ranges (bool sys_group, g - - /* Check that the ranges make sense */ - if (*max_id < *min_id) { -- (void) fprintf (stderr, -+ (void) fprintf (shadow_logfd, - _("%s: Invalid configuration: SYS_GID_MIN (%lu), " - "GID_MIN (%lu), SYS_GID_MAX (%lu)\n"), - Prog, (unsigned long) *min_id, -@@ -104,7 +104,7 @@ static int get_ranges (bool sys_group, g - - /* Check that the ranges make sense */ - if (*max_id < *min_id) { -- (void) fprintf (stderr, -+ (void) fprintf (shadow_logfd, - _("%s: Invalid configuration: GID_MIN (%lu), " - "GID_MAX (%lu)\n"), - Prog, (unsigned long) *min_id, -@@ -220,7 +220,7 @@ int find_new_gid (bool sys_group, - * more likely to want to stop and address the - * issue. - */ -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Encountered error attempting to use " - "preferred GID: %s\n"), - Prog, strerror (result)); -@@ -250,7 +250,7 @@ int find_new_gid (bool sys_group, - /* Create an array to hold all of the discovered GIDs */ - used_gids = malloc (sizeof (bool) * (gid_max +1)); - if (NULL == used_gids) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: failed to allocate memory: %s\n"), - Prog, strerror (errno)); - return -1; -@@ -330,7 +330,7 @@ int find_new_gid (bool sys_group, - * - */ - if (!nospam) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Can't get unique system GID (%s). " - "Suppressing additional messages.\n"), - Prog, strerror (result)); -@@ -373,7 +373,7 @@ int find_new_gid (bool sys_group, - * - */ - if (!nospam) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Can't get unique system GID (%s). " - "Suppressing additional messages.\n"), - Prog, strerror (result)); -@@ -433,7 +433,7 @@ int find_new_gid (bool sys_group, - * - */ - if (!nospam) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Can't get unique GID (%s). " - "Suppressing additional messages.\n"), - Prog, strerror (result)); -@@ -476,7 +476,7 @@ int find_new_gid (bool sys_group, - * - */ - if (!nospam) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Can't get unique GID (%s). " - "Suppressing additional messages.\n"), - Prog, strerror (result)); -@@ -495,7 +495,7 @@ int find_new_gid (bool sys_group, - } - - /* The code reached here and found no available IDs in the range */ -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Can't get unique GID (no more available GIDs)\n"), - Prog); - SYSLOG ((LOG_WARN, "no more available GIDs on the system")); -diff -up shadow-4.8.1/libmisc/find_new_sub_gids.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/find_new_sub_gids.c ---- shadow-4.8.1/libmisc/find_new_sub_gids.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/libmisc/find_new_sub_gids.c 2021-05-24 13:04:19.930269118 +0200 -@@ -61,7 +61,7 @@ int find_new_sub_gids (const char *owner - count = getdef_ulong ("SUB_GID_COUNT", 65536); - - if (min > max || count >= max || (min + count - 1) > max) { -- (void) fprintf (stderr, -+ (void) fprintf (shadow_logfd, - _("%s: Invalid configuration: SUB_GID_MIN (%lu)," - " SUB_GID_MAX (%lu), SUB_GID_COUNT (%lu)\n"), - Prog, min, max, count); -@@ -70,7 +70,7 @@ int find_new_sub_gids (const char *owner - - start = sub_gid_find_free_range(min, max, count); - if (start == (gid_t)-1) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Can't get unique subordinate GID range\n"), - Prog); - SYSLOG ((LOG_WARN, "no more available subordinate GIDs on the system")); -diff -up shadow-4.8.1/libmisc/find_new_sub_uids.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/find_new_sub_uids.c ---- shadow-4.8.1/libmisc/find_new_sub_uids.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/libmisc/find_new_sub_uids.c 2021-05-24 13:04:19.930269118 +0200 -@@ -61,7 +61,7 @@ int find_new_sub_uids (const char *owner - count = getdef_ulong ("SUB_UID_COUNT", 65536); - - if (min > max || count >= max || (min + count - 1) > max) { -- (void) fprintf (stderr, -+ (void) fprintf (shadow_logfd, - _("%s: Invalid configuration: SUB_UID_MIN (%lu)," - " SUB_UID_MAX (%lu), SUB_UID_COUNT (%lu)\n"), - Prog, min, max, count); -@@ -70,7 +70,7 @@ int find_new_sub_uids (const char *owner - - start = sub_uid_find_free_range(min, max, count); - if (start == (uid_t)-1) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Can't get unique subordinate UID range\n"), - Prog); - SYSLOG ((LOG_WARN, "no more available subordinate UIDs on the system")); -diff -up shadow-4.8.1/libmisc/find_new_uid.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/find_new_uid.c ---- shadow-4.8.1/libmisc/find_new_uid.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.914268898 +0200 -+++ shadow-4.8.1/libmisc/find_new_uid.c 2021-05-24 13:04:19.930269118 +0200 -@@ -74,7 +74,7 @@ static int get_ranges (bool sys_user, ui - - /* Check that the ranges make sense */ - if (*max_id < *min_id) { -- (void) fprintf (stderr, -+ (void) fprintf (shadow_logfd, - _("%s: Invalid configuration: SYS_UID_MIN (%lu), " - "UID_MIN (%lu), SYS_UID_MAX (%lu)\n"), - Prog, (unsigned long) *min_id, -@@ -104,7 +104,7 @@ static int get_ranges (bool sys_user, ui - - /* Check that the ranges make sense */ - if (*max_id < *min_id) { -- (void) fprintf (stderr, -+ (void) fprintf (shadow_logfd, - _("%s: Invalid configuration: UID_MIN (%lu), " - "UID_MAX (%lu)\n"), - Prog, (unsigned long) *min_id, -@@ -220,7 +220,7 @@ int find_new_uid(bool sys_user, - * more likely to want to stop and address the - * issue. - */ -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Encountered error attempting to use " - "preferred UID: %s\n"), - Prog, strerror (result)); -@@ -250,7 +250,7 @@ int find_new_uid(bool sys_user, - /* Create an array to hold all of the discovered UIDs */ - used_uids = malloc (sizeof (bool) * (uid_max +1)); - if (NULL == used_uids) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: failed to allocate memory: %s\n"), - Prog, strerror (errno)); - return -1; -@@ -330,7 +330,7 @@ int find_new_uid(bool sys_user, - * - */ - if (!nospam) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Can't get unique system UID (%s). " - "Suppressing additional messages.\n"), - Prog, strerror (result)); -@@ -373,7 +373,7 @@ int find_new_uid(bool sys_user, - * - */ - if (!nospam) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Can't get unique system UID (%s). " - "Suppressing additional messages.\n"), - Prog, strerror (result)); -@@ -433,7 +433,7 @@ int find_new_uid(bool sys_user, - * - */ - if (!nospam) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Can't get unique UID (%s). " - "Suppressing additional messages.\n"), - Prog, strerror (result)); -@@ -476,7 +476,7 @@ int find_new_uid(bool sys_user, - * - */ - if (!nospam) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Can't get unique UID (%s). " - "Suppressing additional messages.\n"), - Prog, strerror (result)); -@@ -495,7 +495,7 @@ int find_new_uid(bool sys_user, - } - - /* The code reached here and found no available IDs in the range */ -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Can't get unique UID (no more available UIDs)\n"), - Prog); - SYSLOG ((LOG_WARN, "no more available UIDs on the system")); -diff -up shadow-4.8.1/libmisc/gettime.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/gettime.c ---- shadow-4.8.1/libmisc/gettime.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/libmisc/gettime.c 2021-05-24 13:04:19.930269118 +0200 -@@ -61,23 +61,23 @@ - epoch = strtoull (source_date_epoch, &endptr, 10); - if ((errno == ERANGE && (epoch == ULLONG_MAX || epoch == 0)) - || (errno != 0 && epoch == 0)) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("Environment variable $SOURCE_DATE_EPOCH: strtoull: %s\n"), - strerror(errno)); - } else if (endptr == source_date_epoch) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("Environment variable $SOURCE_DATE_EPOCH: No digits were found: %s\n"), - endptr); - } else if (*endptr != '\0') { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("Environment variable $SOURCE_DATE_EPOCH: Trailing garbage: %s\n"), - endptr); - } else if (epoch > ULONG_MAX) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("Environment variable $SOURCE_DATE_EPOCH: value must be smaller than or equal to %lu but was found to be: %llu\n"), - ULONG_MAX, epoch); - } else if (epoch > fallback) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("Environment variable $SOURCE_DATE_EPOCH: value must be smaller than or equal to the current time (%lu) but was found to be: %llu\n"), - fallback, epoch); - } else { -diff -up shadow-4.8.1/libmisc/idmapping.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/idmapping.c ---- shadow-4.8.1/libmisc/idmapping.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/libmisc/idmapping.c 2021-05-24 13:20:06.679312187 +0200 -@@ -47,19 +47,19 @@ struct map_range *get_map_ranges(int ran - int idx, argidx; - - if (ranges < 0 || argc < 0) { -- fprintf(stderr, "%s: error calculating number of arguments\n", Prog); -+ fprintf(shadow_logfd, "%s: error calculating number of arguments\n", Prog); - return NULL; - } - - if (ranges != ((argc + 2) / 3)) { -- fprintf(stderr, "%s: ranges: %u is wrong for argc: %d\n", Prog, ranges, argc); -+ fprintf(shadow_logfd, "%s: ranges: %u is wrong for argc: %d\n", Prog, ranges, argc); - return NULL; - } - - if ((ranges * 3) > argc) { -- fprintf(stderr, "ranges: %u argc: %d\n", -+ fprintf(shadow_logfd, "ranges: %u argc: %d\n", - ranges, argc); -- fprintf(stderr, -+ fprintf(shadow_logfd, - _( "%s: Not enough arguments to form %u mappings\n"), - Prog, ranges); - return NULL; -@@ -67,7 +67,7 @@ struct map_range *get_map_ranges(int ran - - mappings = calloc(ranges, sizeof(*mappings)); - if (!mappings) { -- fprintf(stderr, _( "%s: Memory allocation failure\n"), -+ fprintf(shadow_logfd, _( "%s: Memory allocation failure\n"), - Prog); - exit(EXIT_FAILURE); - } -@@ -88,24 +88,24 @@ struct map_range *get_map_ranges(int ran - return NULL; - } - if (ULONG_MAX - mapping->upper <= mapping->count || ULONG_MAX - mapping->lower <= mapping->count) { -- fprintf(stderr, _( "%s: subuid overflow detected.\n"), Prog); -+ fprintf(shadow_logfd, _( "%s: subuid overflow detected.\n"), Prog); - exit(EXIT_FAILURE); - } - if (mapping->upper > UINT_MAX || - mapping->lower > UINT_MAX || - mapping->count > UINT_MAX) { -- fprintf(stderr, _( "%s: subuid overflow detected.\n"), Prog); -+ fprintf(shadow_logfd, _( "%s: subuid overflow detected.\n"), Prog); - exit(EXIT_FAILURE); - } - if (mapping->lower + mapping->count > UINT_MAX || - mapping->upper + mapping->count > UINT_MAX) { -- fprintf(stderr, _( "%s: subuid overflow detected.\n"), Prog); -+ fprintf(shadow_logfd, _( "%s: subuid overflow detected.\n"), Prog); - exit(EXIT_FAILURE); - } - if (mapping->lower + mapping->count < mapping->lower || - mapping->upper + mapping->count < mapping->upper) { - /* this one really shouldn't be possible given previous checks */ -- fprintf(stderr, _( "%s: subuid overflow detected.\n"), Prog); -+ fprintf(shadow_logfd, _( "%s: subuid overflow detected.\n"), Prog); - exit(EXIT_FAILURE); - } - } -@@ -157,19 +157,19 @@ void write_mapping(int proc_dir_fd, int - } else if (strcmp(map_file, "gid_map") == 0) { - cap = CAP_SETGID; - } else { -- fprintf(stderr, _("%s: Invalid map file %s specified\n"), Prog, map_file); -+ fprintf(shadow_logfd, _("%s: Invalid map file %s specified\n"), Prog, map_file); - exit(EXIT_FAILURE); - } - - /* Align setuid- and fscaps-based new{g,u}idmap behavior. */ - if (geteuid() == 0 && geteuid() != ruid) { - if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) { -- fprintf(stderr, _("%s: Could not prctl(PR_SET_KEEPCAPS)\n"), Prog); -+ fprintf(shadow_logfd, _("%s: Could not prctl(PR_SET_KEEPCAPS)\n"), Prog); - exit(EXIT_FAILURE); - } - - if (seteuid(ruid) < 0) { -- fprintf(stderr, _("%s: Could not seteuid to %d\n"), Prog, ruid); -+ fprintf(shadow_logfd, _("%s: Could not seteuid to %d\n"), Prog, ruid); - exit(EXIT_FAILURE); - } - } -@@ -179,7 +179,7 @@ void write_mapping(int proc_dir_fd, int - data[0].effective = CAP_TO_MASK(cap); - data[0].permitted = data[0].effective; - if (capset(&hdr, data) < 0) { -- fprintf(stderr, _("%s: Could not set caps\n"), Prog); -+ fprintf(shadow_logfd, _("%s: Could not set caps\n"), Prog); - exit(EXIT_FAILURE); - } - #endif -@@ -197,7 +197,7 @@ void write_mapping(int proc_dir_fd, int - mapping->lower, - mapping->count); - if ((written <= 0) || (written >= (bufsize - (pos - buf)))) { -- fprintf(stderr, _("%s: snprintf failed!\n"), Prog); -+ fprintf(shadow_logfd, _("%s: snprintf failed!\n"), Prog); - exit(EXIT_FAILURE); - } - pos += written; -@@ -206,12 +206,12 @@ void write_mapping(int proc_dir_fd, int - /* Write the mapping to the mapping file */ - fd = openat(proc_dir_fd, map_file, O_WRONLY); - if (fd < 0) { -- fprintf(stderr, _("%s: open of %s failed: %s\n"), -+ fprintf(shadow_logfd, _("%s: open of %s failed: %s\n"), - Prog, map_file, strerror(errno)); - exit(EXIT_FAILURE); - } - if (write(fd, buf, pos - buf) != (pos - buf)) { -- fprintf(stderr, _("%s: write to %s failed: %s\n"), -+ fprintf(shadow_logfd, _("%s: write to %s failed: %s\n"), - Prog, map_file, strerror(errno)); - exit(EXIT_FAILURE); - } -diff -up shadow-4.8.1/libmisc/limits.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/limits.c ---- shadow-4.8.1/libmisc/limits.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/libmisc/limits.c 2021-05-24 13:04:19.930269118 +0200 -@@ -548,7 +548,7 @@ void setup_limits (const struct passwd * - #ifdef LIMITS - if (info->pw_uid != 0) { - if ((setup_user_limits (info->pw_name) & LOGIN_ERROR_LOGIN) != 0) { -- (void) fputs (_("Too many logins.\n"), stderr); -+ (void) fputs (_("Too many logins.\n"), shadow_logfd); - (void) sleep (2); /* XXX: Should be FAIL_DELAY */ - exit (EXIT_FAILURE); - } -diff -up shadow-4.8.1/libmisc/pam_pass.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/pam_pass.c ---- shadow-4.8.1/libmisc/pam_pass.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/libmisc/pam_pass.c 2021-05-24 13:04:19.930269118 +0200 -@@ -59,20 +59,20 @@ void do_pam_passwd (const char *user, bo - - ret = pam_start ("passwd", user, &conv, &pamh); - if (ret != PAM_SUCCESS) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("passwd: pam_start() failed, error %d\n"), ret); - exit (10); /* XXX */ - } - - ret = pam_chauthtok (pamh, flags); - if (ret != PAM_SUCCESS) { -- fprintf (stderr, _("passwd: %s\n"), pam_strerror (pamh, ret)); -- fputs (_("passwd: password unchanged\n"), stderr); -+ fprintf (shadow_logfd, _("passwd: %s\n"), pam_strerror (pamh, ret)); -+ fputs (_("passwd: password unchanged\n"), shadow_logfd); - pam_end (pamh, ret); - exit (10); /* XXX */ - } - -- fputs (_("passwd: password updated successfully\n"), stderr); -+ fputs (_("passwd: password updated successfully\n"), shadow_logfd); - (void) pam_end (pamh, PAM_SUCCESS); - } - #else /* !USE_PAM */ -diff -up shadow-4.8.1/libmisc/pam_pass_non_interactive.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/pam_pass_non_interactive.c ---- shadow-4.8.1/libmisc/pam_pass_non_interactive.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/libmisc/pam_pass_non_interactive.c 2021-05-24 13:04:19.930269118 +0200 -@@ -76,7 +76,7 @@ static int ni_conv (int num_msg, - - switch (msg[count]->msg_style) { - case PAM_PROMPT_ECHO_ON: -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: PAM modules requesting echoing are not supported.\n"), - Prog); - goto failed_conversation; -@@ -88,7 +88,7 @@ static int ni_conv (int num_msg, - break; - case PAM_ERROR_MSG: - if ( (NULL == msg[count]->msg) -- || (fprintf (stderr, "%s\n", msg[count]->msg) <0)) { -+ || (fprintf (shadow_logfd, "%s\n", msg[count]->msg) <0)) { - goto failed_conversation; - } - responses[count].resp = NULL; -@@ -101,7 +101,7 @@ static int ni_conv (int num_msg, - responses[count].resp = NULL; - break; - default: -- (void) fprintf (stderr, -+ (void) fprintf (shadow_logfd, - _("%s: conversation type %d not supported.\n"), - Prog, msg[count]->msg_style); - goto failed_conversation; -@@ -143,7 +143,7 @@ int do_pam_passwd_non_interactive (const - - ret = pam_start (pam_service, username, &non_interactive_pam_conv, &pamh); - if (ret != PAM_SUCCESS) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: (user %s) pam_start failure %d\n"), - Prog, username, ret); - return 1; -@@ -152,7 +152,7 @@ int do_pam_passwd_non_interactive (const - non_interactive_password = password; - ret = pam_chauthtok (pamh, 0); - if (ret != PAM_SUCCESS) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: (user %s) pam_chauthtok() failed, error:\n" - "%s\n"), - Prog, username, pam_strerror (pamh, ret)); -diff -up shadow-4.8.1/libmisc/prefix_flag.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/prefix_flag.c ---- shadow-4.8.1/libmisc/prefix_flag.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.930269118 +0200 -+++ shadow-4.8.1/libmisc/prefix_flag.c 2021-05-24 13:21:11.538205727 +0200 -@@ -80,14 +80,14 @@ extern const char* process_prefix_flag ( - if ( (strcmp (argv[i], "--prefix") == 0) - || (strcmp (argv[i], short_opt) == 0)) { - if (NULL != prefix) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: multiple --prefix options\n"), - Prog); - exit (E_BAD_ARG); - } - - if (i + 1 == argc) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: option '%s' requires an argument\n"), - Prog, argv[i]); - exit (E_BAD_ARG); -diff -up shadow-4.8.1/libmisc/pwdcheck.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/pwdcheck.c ---- shadow-4.8.1/libmisc/pwdcheck.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/libmisc/pwdcheck.c 2021-05-24 13:04:19.930269118 +0200 -@@ -51,7 +51,7 @@ void passwd_check (const char *user, con - if (pw_auth (passwd, user, PW_LOGIN, (char *) 0) != 0) { - SYSLOG ((LOG_WARN, "incorrect password for `%s'", user)); - (void) sleep (1); -- fprintf (stderr, _("Incorrect password for %s.\n"), user); -+ fprintf (shadow_logfd, _("Incorrect password for %s.\n"), user); - exit (EXIT_FAILURE); - } - } -diff -up shadow-4.8.1/libmisc/root_flag.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/root_flag.c ---- shadow-4.8.1/libmisc/root_flag.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/libmisc/root_flag.c 2021-05-24 14:39:04.286481468 +0200 -@@ -62,14 +62,14 @@ extern void process_root_flag (const cha - if ( (strcmp (argv[i], "--root") == 0) - || (strcmp (argv[i], short_opt) == 0)) { - if (NULL != newroot) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: multiple --root options\n"), - Prog); - exit (E_BAD_ARG); - } - - if (i + 1 == argc) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: option '%s' requires an argument\n"), - Prog, argv[i]); - exit (E_BAD_ARG); -@@ -88,34 +88,34 @@ static void change_root (const char* new - /* Drop privileges */ - if ( (setregid (getgid (), getgid ()) != 0) - || (setreuid (getuid (), getuid ()) != 0)) { -- fprintf (stderr, _("%s: failed to drop privileges (%s)\n"), -+ fprintf (shadow_logfd, _("%s: failed to drop privileges (%s)\n"), - Prog, strerror (errno)); - exit (EXIT_FAILURE); - } - - if ('/' != newroot[0]) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: invalid chroot path '%s'\n"), - Prog, newroot); - exit (E_BAD_ARG); - } - - if (access (newroot, F_OK) != 0) { -- fprintf(stderr, -+ fprintf(shadow_logfd, - _("%s: cannot access chroot directory %s: %s\n"), - Prog, newroot, strerror (errno)); - exit (E_BAD_ARG); - } - - if (chdir (newroot) != 0) { -- fprintf(stderr, -+ fprintf(shadow_logfd, - _("%s: cannot chdir to chroot directory %s: %s\n"), - Prog, newroot, strerror (errno)); - exit (E_BAD_ARG); - } - - if (chroot (newroot) != 0) { -- fprintf(stderr, -+ fprintf(shadow_logfd, - _("%s: unable to chroot to directory %s: %s\n"), - Prog, newroot, strerror (errno)); - exit (E_BAD_ARG); -diff -up shadow-4.8.1/libmisc/salt.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/salt.c ---- shadow-4.8.1/libmisc/salt.c.libsubid_not_print_error_messages 2019-12-01 18:02:43.000000000 +0100 -+++ shadow-4.8.1/libmisc/salt.c 2021-05-24 13:04:19.930269118 +0200 -@@ -344,7 +344,7 @@ static /*@observer@*/const char *gensalt - salt_len = (size_t) shadow_random (8, 16); - #endif /* USE_SHA_CRYPT */ - } else if (0 != strcmp (method, "DES")) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("Invalid ENCRYPT_METHOD value: '%s'.\n" - "Defaulting to DES.\n"), - method); -diff -up shadow-4.8.1/libmisc/setupenv.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/setupenv.c ---- shadow-4.8.1/libmisc/setupenv.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/libmisc/setupenv.c 2021-05-24 13:04:19.930269118 +0200 -@@ -219,7 +219,7 @@ void setup_env (struct passwd *info) - static char temp_pw_dir[] = "/"; - - if (!getdef_bool ("DEFAULT_HOME") || chdir ("/") == -1) { -- fprintf (stderr, _("Unable to cd to '%s'\n"), -+ fprintf (shadow_logfd, _("Unable to cd to '%s'\n"), - info->pw_dir); - SYSLOG ((LOG_WARN, - "unable to cd to `%s' for user `%s'\n", -diff -up shadow-4.8.1/libmisc/user_busy.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/user_busy.c ---- shadow-4.8.1/libmisc/user_busy.c.libsubid_not_print_error_messages 2020-01-23 19:04:44.000000000 +0100 -+++ shadow-4.8.1/libmisc/user_busy.c 2021-05-24 13:04:19.931269132 +0200 -@@ -96,7 +96,7 @@ static int user_busy_utmp (const char *n - continue; - } - -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: user %s is currently logged in\n"), - Prog, name); - return 1; -@@ -249,7 +249,7 @@ static int user_busy_processes (const ch - #ifdef ENABLE_SUBIDS - sub_uid_close(); - #endif -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: user %s is currently used by process %d\n"), - Prog, name, pid); - return 1; -@@ -272,7 +272,7 @@ static int user_busy_processes (const ch - #ifdef ENABLE_SUBIDS - sub_uid_close(); - #endif -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: user %s is currently used by process %d\n"), - Prog, name, pid); - return 1; -diff -up shadow-4.8.1/libmisc/xgetXXbyYY.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/xgetXXbyYY.c ---- shadow-4.8.1/libmisc/xgetXXbyYY.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/libmisc/xgetXXbyYY.c 2021-05-24 13:04:19.931269132 +0200 -@@ -74,7 +74,7 @@ - - result = malloc(sizeof(LOOKUP_TYPE)); - if (NULL == result) { -- fprintf (stderr, _("%s: out of memory\n"), -+ fprintf (shadow_logfd, _("%s: out of memory\n"), - "x" STRINGIZE(FUNCTION_NAME)); - exit (13); - } -@@ -84,7 +84,7 @@ - LOOKUP_TYPE *resbuf = NULL; - buffer = (char *)realloc (buffer, length); - if (NULL == buffer) { -- fprintf (stderr, _("%s: out of memory\n"), -+ fprintf (shadow_logfd, _("%s: out of memory\n"), - "x" STRINGIZE(FUNCTION_NAME)); - exit (13); - } -@@ -132,7 +132,7 @@ - if (result) { - result = DUP_FUNCTION(result); - if (NULL == result) { -- fprintf (stderr, _("%s: out of memory\n"), -+ fprintf (shadow_logfd, _("%s: out of memory\n"), - "x" STRINGIZE(FUNCTION_NAME)); - exit (13); - } -diff -up shadow-4.8.1/libmisc/xmalloc.c.libsubid_not_print_error_messages shadow-4.8.1/libmisc/xmalloc.c ---- shadow-4.8.1/libmisc/xmalloc.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/libmisc/xmalloc.c 2021-05-24 13:04:19.931269132 +0200 -@@ -54,7 +54,7 @@ - - ptr = (char *) malloc (size); - if (NULL == ptr) { -- (void) fprintf (stderr, -+ (void) fprintf (shadow_logfd, - _("%s: failed to allocate memory: %s\n"), - Prog, strerror (errno)); - exit (13); -diff -up shadow-4.8.1/lib/nscd.c.libsubid_not_print_error_messages shadow-4.8.1/lib/nscd.c ---- shadow-4.8.1/lib/nscd.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/lib/nscd.c 2021-05-24 13:04:19.928269091 +0200 -@@ -25,13 +25,13 @@ int nscd_flush_cache (const char *servic - - if (run_command (cmd, spawnedArgs, spawnedEnv, &status) != 0) { - /* run_command writes its own more detailed message. */ -- (void) fprintf (stderr, _(MSG_NSCD_FLUSH_CACHE_FAILED), Prog); -+ (void) fprintf (shadow_logfd, _(MSG_NSCD_FLUSH_CACHE_FAILED), Prog); - return -1; - } - - code = WEXITSTATUS (status); - if (!WIFEXITED (status)) { -- (void) fprintf (stderr, -+ (void) fprintf (shadow_logfd, - _("%s: nscd did not terminate normally (signal %d)\n"), - Prog, WTERMSIG (status)); - return -1; -@@ -43,9 +43,9 @@ int nscd_flush_cache (const char *servic - /* nscd is installed, but it isn't active. */ - return 0; - } else if (code != 0) { -- (void) fprintf (stderr, _("%s: nscd exited with status %d\n"), -+ (void) fprintf (shadow_logfd, _("%s: nscd exited with status %d\n"), - Prog, code); -- (void) fprintf (stderr, _(MSG_NSCD_FLUSH_CACHE_FAILED), Prog); -+ (void) fprintf (shadow_logfd, _(MSG_NSCD_FLUSH_CACHE_FAILED), Prog); - return -1; - } - -diff -up shadow-4.8.1/lib/nss.c.libsubid_not_print_error_messages shadow-4.8.1/lib/nss.c ---- shadow-4.8.1/lib/nss.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.924269036 +0200 -+++ shadow-4.8.1/lib/nss.c 2021-05-24 13:04:19.928269091 +0200 -@@ -56,7 +56,7 @@ void nss_init(char *nsswitch_path) { - // subid: files - nssfp = fopen(nsswitch_path, "r"); - if (!nssfp) { -- fprintf(stderr, "Failed opening %s: %m", nsswitch_path); -+ fprintf(shadow_logfd, "Failed opening %s: %m", nsswitch_path); - atomic_store(&nss_init_completed, true); - return; - } -@@ -82,16 +82,16 @@ void nss_init(char *nsswitch_path) { - goto done; - } - if (strlen(token) > 50) { -- fprintf(stderr, "Subid NSS module name too long (longer than 50 characters): %s\n", token); -- fprintf(stderr, "Using files\n"); -+ fprintf(shadow_logfd, "Subid NSS module name too long (longer than 50 characters): %s\n", token); -+ fprintf(shadow_logfd, "Using files\n"); - subid_nss = NULL; - goto done; - } - snprintf(libname, 64, "libsubid_%s.so", token); - h = dlopen(libname, RTLD_LAZY); - if (!h) { -- fprintf(stderr, "Error opening %s: %s\n", libname, dlerror()); -- fprintf(stderr, "Using files\n"); -+ fprintf(shadow_logfd, "Error opening %s: %s\n", libname, dlerror()); -+ fprintf(shadow_logfd, "Using files\n"); - subid_nss = NULL; - goto done; - } -@@ -102,7 +102,7 @@ void nss_init(char *nsswitch_path) { - } - subid_nss->has_range = dlsym(h, "shadow_subid_has_range"); - if (!subid_nss->has_range) { -- fprintf(stderr, "%s did not provide @has_range@\n", libname); -+ fprintf(shadow_logfd, "%s did not provide @has_range@\n", libname); - dlclose(h); - free(subid_nss); - subid_nss = NULL; -@@ -110,7 +110,7 @@ void nss_init(char *nsswitch_path) { - } - subid_nss->list_owner_ranges = dlsym(h, "shadow_subid_list_owner_ranges"); - if (!subid_nss->list_owner_ranges) { -- fprintf(stderr, "%s did not provide @list_owner_ranges@\n", libname); -+ fprintf(shadow_logfd, "%s did not provide @list_owner_ranges@\n", libname); - dlclose(h); - free(subid_nss); - subid_nss = NULL; -@@ -118,7 +118,7 @@ void nss_init(char *nsswitch_path) { - } - subid_nss->has_any_range = dlsym(h, "shadow_subid_has_any_range"); - if (!subid_nss->has_any_range) { -- fprintf(stderr, "%s did not provide @has_any_range@\n", libname); -+ fprintf(shadow_logfd, "%s did not provide @has_any_range@\n", libname); - dlclose(h); - free(subid_nss); - subid_nss = NULL; -@@ -126,7 +126,7 @@ void nss_init(char *nsswitch_path) { - } - subid_nss->find_subid_owners = dlsym(h, "shadow_subid_find_subid_owners"); - if (!subid_nss->find_subid_owners) { -- fprintf(stderr, "%s did not provide @find_subid_owners@\n", libname); -+ fprintf(shadow_logfd, "%s did not provide @find_subid_owners@\n", libname); - dlclose(h); - free(subid_nss); - subid_nss = NULL; -@@ -135,7 +135,7 @@ void nss_init(char *nsswitch_path) { - subid_nss->handle = h; - goto done; - } -- fprintf(stderr, "No usable subid NSS module found, using files\n"); -+ fprintf(shadow_logfd, "No usable subid NSS module found, using files\n"); - // subid_nss has to be null here, but to ease reviews: - free(subid_nss); - subid_nss = NULL; -diff -up shadow-4.8.1/lib/prototypes.h.libsubid_not_print_error_messages shadow-4.8.1/lib/prototypes.h ---- shadow-4.8.1/lib/prototypes.h.libsubid_not_print_error_messages 2021-05-24 13:04:19.924269036 +0200 -+++ shadow-4.8.1/lib/prototypes.h 2021-05-24 13:04:19.928269091 +0200 -@@ -59,7 +59,8 @@ - #include "defines.h" - #include "commonio.h" - --extern /*@observer@*/ const char *Prog; -+extern /*@observer@*/ const char *Prog; /* Program name showed in error messages */ -+extern FILE *shadow_logfd; /* file descripter to which error messages are printed */ - - /* addgrps.c */ - #if defined (HAVE_SETGROUPS) && ! defined (USE_PAM) -diff -up shadow-4.8.1/lib/selinux.c.libsubid_not_print_error_messages shadow-4.8.1/lib/selinux.c ---- shadow-4.8.1/lib/selinux.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.911268857 +0200 -+++ shadow-4.8.1/lib/selinux.c 2021-05-24 13:04:32.746445679 +0200 -@@ -135,7 +135,7 @@ static int selinux_log_cb (int type, con - && (errno != EAFNOSUPPORT)) { - - (void) fputs (_("Cannot open audit interface.\n"), -- stderr); -+ shadow_logfd); - SYSLOG ((LOG_WARN, "Cannot open audit interface.")); - } - } -@@ -188,7 +188,7 @@ int check_selinux_permit (const char *pe - selinux_set_callback (SELINUX_CB_LOG, (union selinux_callback) selinux_log_cb); - - if (getprevcon (&user_context_str) != 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: can not get previous SELinux process context: %s\n"), - Prog, strerror (errno)); - SYSLOG ((LOG_WARN, -diff -up shadow-4.8.1/lib/semanage.c.libsubid_not_print_error_messages shadow-4.8.1/lib/semanage.c ---- shadow-4.8.1/lib/semanage.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.900268705 +0200 -+++ shadow-4.8.1/lib/semanage.c 2021-05-24 13:05:24.747162090 +0200 -@@ -69,7 +69,7 @@ static void semanage_error_callback (unu - switch (semanage_msg_get_level (handle)) { - case SEMANAGE_MSG_ERR: - case SEMANAGE_MSG_WARN: -- fprintf (stderr, _("[libsemanage]: %s\n"), message); -+ fprintf (shadow_logfd, _("[libsemanage]: %s\n"), message); - break; - case SEMANAGE_MSG_INFO: - /* nop */ -@@ -87,7 +87,7 @@ static semanage_handle_t *semanage_init - - handle = semanage_handle_create (); - if (NULL == handle) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("Cannot create SELinux management handle\n")); - return NULL; - } -@@ -96,26 +96,26 @@ static semanage_handle_t *semanage_init - - ret = semanage_is_managed (handle); - if (ret != 1) { -- fprintf (stderr, _("SELinux policy not managed\n")); -+ fprintf (shadow_logfd, _("SELinux policy not managed\n")); - goto fail; - } - - ret = semanage_access_check (handle); - if (ret < SEMANAGE_CAN_READ) { -- fprintf (stderr, _("Cannot read SELinux policy store\n")); -+ fprintf (shadow_logfd, _("Cannot read SELinux policy store\n")); - goto fail; - } - - ret = semanage_connect (handle); - if (ret != 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("Cannot establish SELinux management connection\n")); - goto fail; - } - - ret = semanage_begin_transaction (handle); - if (ret != 0) { -- fprintf (stderr, _("Cannot begin SELinux transaction\n")); -+ fprintf (shadow_logfd, _("Cannot begin SELinux transaction\n")); - goto fail; - } - -@@ -137,7 +137,7 @@ static int semanage_user_mod (semanage_h - - semanage_seuser_query (handle, key, &seuser); - if (NULL == seuser) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("Could not query seuser for %s\n"), login_name); - ret = 1; - goto done; -@@ -146,7 +146,7 @@ static int semanage_user_mod (semanage_h - #if 0 - ret = semanage_seuser_set_mlsrange (handle, seuser, DEFAULT_SERANGE); - if (ret != 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("Could not set serange for %s\n"), login_name); - ret = 1; - goto done; -@@ -155,7 +155,7 @@ static int semanage_user_mod (semanage_h - - ret = semanage_seuser_set_sename (handle, seuser, seuser_name); - if (ret != 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("Could not set sename for %s\n"), - login_name); - ret = 1; -@@ -164,7 +164,7 @@ static int semanage_user_mod (semanage_h - - ret = semanage_seuser_modify_local (handle, key, seuser); - if (ret != 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("Could not modify login mapping for %s\n"), - login_name); - ret = 1; -@@ -188,7 +188,7 @@ static int semanage_user_add (semanage_h - - ret = semanage_seuser_create (handle, &seuser); - if (ret != 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("Cannot create SELinux login mapping for %s\n"), - login_name); - ret = 1; -@@ -197,7 +197,7 @@ static int semanage_user_add (semanage_h - - ret = semanage_seuser_set_name (handle, seuser, login_name); - if (ret != 0) { -- fprintf (stderr, _("Could not set name for %s\n"), login_name); -+ fprintf (shadow_logfd, _("Could not set name for %s\n"), login_name); - ret = 1; - goto done; - } -@@ -205,7 +205,7 @@ static int semanage_user_add (semanage_h - #if 0 - ret = semanage_seuser_set_mlsrange (handle, seuser, DEFAULT_SERANGE); - if (ret != 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("Could not set serange for %s\n"), - login_name); - ret = 1; -@@ -215,7 +215,7 @@ static int semanage_user_add (semanage_h - - ret = semanage_seuser_set_sename (handle, seuser, seuser_name); - if (ret != 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("Could not set SELinux user for %s\n"), - login_name); - ret = 1; -@@ -224,7 +224,7 @@ static int semanage_user_add (semanage_h - - ret = semanage_seuser_modify_local (handle, key, seuser); - if (ret != 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("Could not add login mapping for %s\n"), - login_name); - ret = 1; -@@ -252,21 +252,21 @@ int set_seuser (const char *login_name, - - handle = semanage_init (); - if (NULL == handle) { -- fprintf (stderr, _("Cannot init SELinux management\n")); -+ fprintf (shadow_logfd, _("Cannot init SELinux management\n")); - ret = 1; - goto done; - } - - ret = semanage_seuser_key_create (handle, login_name, &key); - if (ret != 0) { -- fprintf (stderr, _("Cannot create SELinux user key\n")); -+ fprintf (shadow_logfd, _("Cannot create SELinux user key\n")); - ret = 1; - goto done; - } - - ret = semanage_seuser_exists (handle, key, &seuser_exists); - if (ret < 0) { -- fprintf (stderr, _("Cannot verify the SELinux user\n")); -+ fprintf (shadow_logfd, _("Cannot verify the SELinux user\n")); - ret = 1; - goto done; - } -@@ -274,7 +274,7 @@ int set_seuser (const char *login_name, - if (0 != seuser_exists) { - ret = semanage_user_mod (handle, key, login_name, seuser_name); - if (ret != 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("Cannot modify SELinux user mapping\n")); - ret = 1; - goto done; -@@ -282,7 +282,7 @@ int set_seuser (const char *login_name, - } else { - ret = semanage_user_add (handle, key, login_name, seuser_name); - if (ret != 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("Cannot add SELinux user mapping\n")); - ret = 1; - goto done; -@@ -291,7 +291,7 @@ int set_seuser (const char *login_name, - - ret = semanage_commit (handle); - if (ret < 0) { -- fprintf (stderr, _("Cannot commit SELinux transaction\n")); -+ fprintf (shadow_logfd, _("Cannot commit SELinux transaction\n")); - ret = 1; - goto done; - } -@@ -317,27 +317,27 @@ int del_seuser (const char *login_name) - - handle = semanage_init (); - if (NULL == handle) { -- fprintf (stderr, _("Cannot init SELinux management\n")); -+ fprintf (shadow_logfd, _("Cannot init SELinux management\n")); - ret = 1; - goto done; - } - - ret = semanage_seuser_key_create (handle, login_name, &key); - if (ret != 0) { -- fprintf (stderr, _("Cannot create SELinux user key\n")); -+ fprintf (shadow_logfd, _("Cannot create SELinux user key\n")); - ret = 1; - goto done; - } - - ret = semanage_seuser_exists (handle, key, &exists); - if (ret < 0) { -- fprintf (stderr, _("Cannot verify the SELinux user\n")); -+ fprintf (shadow_logfd, _("Cannot verify the SELinux user\n")); - ret = 1; - goto done; - } - - if (0 == exists) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("Login mapping for %s is not defined, OK if default mapping was used\n"), - login_name); - ret = 0; /* probably default mapping */ -@@ -346,13 +346,13 @@ int del_seuser (const char *login_name) - - ret = semanage_seuser_exists_local (handle, key, &exists); - if (ret < 0) { -- fprintf (stderr, _("Cannot verify the SELinux user\n")); -+ fprintf (shadow_logfd, _("Cannot verify the SELinux user\n")); - ret = 1; - goto done; - } - - if (0 == exists) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("Login mapping for %s is defined in policy, cannot be deleted\n"), - login_name); - ret = 0; /* Login mapping defined in policy can't be deleted */ -@@ -361,7 +361,7 @@ int del_seuser (const char *login_name) - - ret = semanage_seuser_del_local (handle, key); - if (ret != 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("Could not delete login mapping for %s"), - login_name); - ret = 1; -@@ -370,7 +370,7 @@ int del_seuser (const char *login_name) - - ret = semanage_commit (handle); - if (ret < 0) { -- fprintf (stderr, _("Cannot commit SELinux transaction\n")); -+ fprintf (shadow_logfd, _("Cannot commit SELinux transaction\n")); - ret = 1; - goto done; - } -diff -up shadow-4.8.1/lib/spawn.c.libsubid_not_print_error_messages shadow-4.8.1/lib/spawn.c ---- shadow-4.8.1/lib/spawn.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/lib/spawn.c 2021-05-24 13:04:19.929269104 +0200 -@@ -48,7 +48,7 @@ int run_command (const char *cmd, const - } - - (void) fflush (stdout); -- (void) fflush (stderr); -+ (void) fflush (shadow_logfd); - - pid = fork (); - if (0 == pid) { -@@ -57,11 +57,11 @@ int run_command (const char *cmd, const - if (ENOENT == errno) { - exit (E_CMD_NOTFOUND); - } -- fprintf (stderr, "%s: cannot execute %s: %s\n", -+ fprintf (shadow_logfd, "%s: cannot execute %s: %s\n", - Prog, cmd, strerror (errno)); - exit (E_CMD_NOEXEC); - } else if ((pid_t)-1 == pid) { -- fprintf (stderr, "%s: cannot execute %s: %s\n", -+ fprintf (shadow_logfd, "%s: cannot execute %s: %s\n", - Prog, cmd, strerror (errno)); - return -1; - } -@@ -74,7 +74,7 @@ int run_command (const char *cmd, const - || ((pid_t)-1 != wpid && wpid != pid)); - - if ((pid_t)-1 == wpid) { -- fprintf (stderr, "%s: waitpid (status: %d): %s\n", -+ fprintf (shadow_logfd, "%s: waitpid (status: %d): %s\n", - Prog, *status, strerror (errno)); - return -1; - } -diff -up shadow-4.8.1/libsubid/api.c.libsubid_not_print_error_messages shadow-4.8.1/libsubid/api.c ---- shadow-4.8.1/libsubid/api.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.926269063 +0200 -+++ shadow-4.8.1/libsubid/api.c 2021-05-24 13:04:19.931269132 +0200 -@@ -32,12 +32,39 @@ - #include - #include - #include -+#include - #include - #include - #include "subordinateio.h" - #include "idmapping.h" - #include "subid.h" - -+const char *Prog = "(libsubid)"; -+extern FILE * shadow_logfd; -+ -+bool libsubid_init(const char *progname, FILE * logfd) -+{ -+ if (progname) { -+ progname = strdup(progname); -+ if (progname) -+ Prog = progname; -+ else -+ fprintf(stderr, "Out of memory"); -+ } -+ -+ if (logfd) { -+ shadow_logfd = logfd; -+ return true; -+ } -+ shadow_logfd = fopen("/dev/null", "w"); -+ if (!shadow_logfd) { -+ fprintf(stderr, "ERROR opening /dev/null for error messages. Using stderr."); -+ shadow_logfd = stderr; -+ return false; -+ } -+ return true; -+} -+ - static - int get_subid_ranges(const char *owner, enum subid_type id_type, struct subordinate_range ***ranges) - { -diff -up shadow-4.8.1/libsubid/subid.h.libsubid_not_print_error_messages shadow-4.8.1/libsubid/subid.h ---- shadow-4.8.1/libsubid/subid.h.libsubid_not_print_error_messages 2021-05-24 13:04:19.926269063 +0200 -+++ shadow-4.8.1/libsubid/subid.h 2021-05-24 13:04:19.931269132 +0200 -@@ -22,6 +22,22 @@ enum subid_status { - }; - - /* -+ * libsubid_init: initialize libsubid -+ * -+ * @progname: Name to display as program. If NULL, then "(libsubid)" will be -+ * shown in error messages. -+ * @logfd: Open file pointer to pass error messages to. If NULL, then -+ * /dev/null will be opened and messages will be sent there. The -+ * default if libsubid_init() is not called is stderr (2). -+ * -+ * This function does not need to be called. If not called, then the defaults -+ * will be used. -+ * -+ * Returns false if an error occurred. -+ */ -+bool libsubid_init(const char *progname, FILE *logfd); -+ -+/* - * get_subuid_ranges: return a list of UID ranges for a user - * - * @owner: username being queried -diff -up shadow-4.8.1/lib/tcbfuncs.c.libsubid_not_print_error_messages shadow-4.8.1/lib/tcbfuncs.c ---- shadow-4.8.1/lib/tcbfuncs.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/lib/tcbfuncs.c 2021-05-24 13:04:19.929269104 +0200 -@@ -72,8 +72,8 @@ shadowtcb_status shadowtcb_gain_priv (vo - * to exit soon. - */ - #define OUT_OF_MEMORY do { \ -- fprintf (stderr, _("%s: out of memory\n"), Prog); \ -- (void) fflush (stderr); \ -+ fprintf (shadow_logfd, _("%s: out of memory\n"), Prog); \ -+ (void) fflush (shadow_logfd); \ - } while (false) - - /* Returns user's tcb directory path relative to TCB_DIR. */ -@@ -116,7 +116,7 @@ static /*@null@*/ char *shadowtcb_path_r - return NULL; - } - if (lstat (path, &st) != 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Cannot stat %s: %s\n"), - Prog, path, strerror (errno)); - free (path); -@@ -132,7 +132,7 @@ static /*@null@*/ char *shadowtcb_path_r - return rval; - } - if (!S_ISLNK (st.st_mode)) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: %s is neither a directory, nor a symlink.\n"), - Prog, path); - free (path); -@@ -140,7 +140,7 @@ static /*@null@*/ char *shadowtcb_path_r - } - ret = readlink (path, link, sizeof (link) - 1); - if (-1 == ret) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Cannot read symbolic link %s: %s\n"), - Prog, path, strerror (errno)); - free (path); -@@ -149,7 +149,7 @@ static /*@null@*/ char *shadowtcb_path_r - free (path); - if ((size_t)ret >= sizeof(link) - 1) { - link[sizeof(link) - 1] = '\0'; -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Suspiciously long symlink: %s\n"), - Prog, link); - return NULL; -@@ -207,7 +207,7 @@ static shadowtcb_status mkdir_leading (c - } - ptr = path; - if (stat (TCB_DIR, &st) != 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Cannot stat %s: %s\n"), - Prog, TCB_DIR, strerror (errno)); - goto out_free_path; -@@ -219,19 +219,19 @@ static shadowtcb_status mkdir_leading (c - return SHADOWTCB_FAILURE; - } - if ((mkdir (dir, 0700) != 0) && (errno != EEXIST)) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Cannot create directory %s: %s\n"), - Prog, dir, strerror (errno)); - goto out_free_dir; - } - if (chown (dir, 0, st.st_gid) != 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Cannot change owner of %s: %s\n"), - Prog, dir, strerror (errno)); - goto out_free_dir; - } - if (chmod (dir, 0711) != 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Cannot change mode of %s: %s\n"), - Prog, dir, strerror (errno)); - goto out_free_dir; -@@ -261,7 +261,7 @@ static shadowtcb_status unlink_suffs (co - return SHADOWTCB_FAILURE; - } - if ((unlink (tmp) != 0) && (errno != ENOENT)) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: unlink: %s: %s\n"), - Prog, tmp, strerror (errno)); - free (tmp); -@@ -286,7 +286,7 @@ static shadowtcb_status rmdir_leading (c - } - if (rmdir (dir) != 0) { - if (errno != ENOTEMPTY) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Cannot remove directory %s: %s\n"), - Prog, dir, strerror (errno)); - ret = SHADOWTCB_FAILURE; -@@ -315,7 +315,7 @@ static shadowtcb_status move_dir (const - goto out_free_nomem; - } - if (stat (olddir, &oldmode) != 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Cannot stat %s: %s\n"), - Prog, olddir, strerror (errno)); - goto out_free; -@@ -342,7 +342,7 @@ static shadowtcb_status move_dir (const - goto out_free; - } - if (rename (real_old_dir, real_new_dir) != 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Cannot rename %s to %s: %s\n"), - Prog, real_old_dir, real_new_dir, strerror (errno)); - goto out_free; -@@ -351,7 +351,7 @@ static shadowtcb_status move_dir (const - goto out_free; - } - if ((unlink (olddir) != 0) && (errno != ENOENT)) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Cannot remove %s: %s\n"), - Prog, olddir, strerror (errno)); - goto out_free; -@@ -365,7 +365,7 @@ static shadowtcb_status move_dir (const - } - if ( (strcmp (real_new_dir, newdir) != 0) - && (symlink (real_new_dir_rel, newdir) != 0)) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Cannot create symbolic link %s: %s\n"), - Prog, real_new_dir_rel, strerror (errno)); - goto out_free; -@@ -464,37 +464,37 @@ shadowtcb_status shadowtcb_move (/*@NULL - return SHADOWTCB_FAILURE; - } - if (stat (tcbdir, &dirmode) != 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Cannot stat %s: %s\n"), - Prog, tcbdir, strerror (errno)); - goto out_free; - } - if (chown (tcbdir, 0, 0) != 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Cannot change owners of %s: %s\n"), - Prog, tcbdir, strerror (errno)); - goto out_free; - } - if (chmod (tcbdir, 0700) != 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Cannot change mode of %s: %s\n"), - Prog, tcbdir, strerror (errno)); - goto out_free; - } - if (lstat (shadow, &filemode) != 0) { - if (errno != ENOENT) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Cannot lstat %s: %s\n"), - Prog, shadow, strerror (errno)); - goto out_free; - } -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Warning, user %s has no tcb shadow file.\n"), - Prog, user_newname); - } else { - if (!S_ISREG (filemode.st_mode) || - filemode.st_nlink != 1) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Emergency: %s's tcb shadow is not a " - "regular file with st_nlink=1.\n" - "The account is left locked.\n"), -@@ -502,13 +502,13 @@ shadowtcb_status shadowtcb_move (/*@NULL - goto out_free; - } - if (chown (shadow, user_newid, filemode.st_gid) != 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Cannot change owner of %s: %s\n"), - Prog, shadow, strerror (errno)); - goto out_free; - } - if (chmod (shadow, filemode.st_mode & 07777) != 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Cannot change mode of %s: %s\n"), - Prog, shadow, strerror (errno)); - goto out_free; -@@ -518,7 +518,7 @@ shadowtcb_status shadowtcb_move (/*@NULL - goto out_free; - } - if (chown (tcbdir, user_newid, dirmode.st_gid) != 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Cannot change owner of %s: %s\n"), - Prog, tcbdir, strerror (errno)); - goto out_free; -@@ -543,7 +543,7 @@ shadowtcb_status shadowtcb_create (const - return SHADOWTCB_SUCCESS; - } - if (stat (TCB_DIR, &tcbdir_stat) != 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Cannot stat %s: %s\n"), - Prog, TCB_DIR, strerror (errno)); - return SHADOWTCB_FAILURE; -@@ -563,39 +563,39 @@ shadowtcb_status shadowtcb_create (const - return SHADOWTCB_FAILURE; - } - if (mkdir (dir, 0700) != 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: mkdir: %s: %s\n"), - Prog, dir, strerror (errno)); - goto out_free; - } - fd = open (shadow, O_RDWR | O_CREAT | O_TRUNC, 0600); - if (fd < 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Cannot open %s: %s\n"), - Prog, shadow, strerror (errno)); - goto out_free; - } - close (fd); - if (chown (shadow, 0, authgid) != 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Cannot change owner of %s: %s\n"), - Prog, shadow, strerror (errno)); - goto out_free; - } - if (chmod (shadow, (mode_t) ((authgid == shadowgid) ? 0600 : 0640)) != 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Cannot change mode of %s: %s\n"), - Prog, shadow, strerror (errno)); - goto out_free; - } - if (chown (dir, 0, authgid) != 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Cannot change owner of %s: %s\n"), - Prog, dir, strerror (errno)); - goto out_free; - } - if (chmod (dir, (mode_t) ((authgid == shadowgid) ? 02700 : 02710)) != 0) { -- fprintf (stderr, -+ fprintf (shadow_logfd, - _("%s: Cannot change mode of %s: %s\n"), - Prog, dir, strerror (errno)); - goto out_free; -diff -up shadow-4.8.1/src/chage.c.libsubid_not_print_error_messages shadow-4.8.1/src/chage.c ---- shadow-4.8.1/src/chage.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.910268843 +0200 -+++ shadow-4.8.1/src/chage.c 2021-05-24 13:04:19.931269132 +0200 -@@ -62,6 +62,7 @@ - * Global variables - */ - const char *Prog; -+FILE *shadow_logfd = NULL; - - static bool - dflg = false, /* set last password change date */ -@@ -816,6 +817,7 @@ int main (int argc, char **argv) - * Get the program name so that error messages can use it. - */ - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - - sanitize_env (); - (void) setlocale (LC_ALL, ""); -diff -up shadow-4.8.1/src/check_subid_range.c.libsubid_not_print_error_messages shadow-4.8.1/src/check_subid_range.c ---- shadow-4.8.1/src/check_subid_range.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.925269050 +0200 -+++ shadow-4.8.1/src/check_subid_range.c 2021-05-24 13:04:19.931269132 +0200 -@@ -18,6 +18,7 @@ - #include "idmapping.h" - - const char *Prog; -+FILE *shadow_logfd = NULL; - - int main(int argc, char **argv) - { -@@ -25,6 +26,7 @@ int main(int argc, char **argv) - unsigned long start, count; - bool check_uids; - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - - if (argc != 5) - exit(1); -diff -up shadow-4.8.1/src/chfn.c.libsubid_not_print_error_messages shadow-4.8.1/src/chfn.c ---- shadow-4.8.1/src/chfn.c.libsubid_not_print_error_messages 2019-11-12 01:18:25.000000000 +0100 -+++ shadow-4.8.1/src/chfn.c 2021-05-24 13:04:19.931269132 +0200 -@@ -57,6 +57,7 @@ - * Global variables. - */ - const char *Prog; -+FILE *shadow_logfd = NULL; - static char fullnm[BUFSIZ]; - static char roomno[BUFSIZ]; - static char workph[BUFSIZ]; -@@ -634,6 +635,7 @@ int main (int argc, char **argv) - * prefix to most error messages. - */ - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - - sanitize_env (); - (void) setlocale (LC_ALL, ""); -diff -up shadow-4.8.1/src/chgpasswd.c.libsubid_not_print_error_messages shadow-4.8.1/src/chgpasswd.c ---- shadow-4.8.1/src/chgpasswd.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.909268829 +0200 -+++ shadow-4.8.1/src/chgpasswd.c 2021-05-24 14:40:13.975427046 +0200 -@@ -66,6 +66,7 @@ - * Global variables - */ - const char *Prog; -+FILE *shadow_logfd = NULL; - static bool eflg = false; - static bool md5flg = false; - #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) -@@ -499,6 +500,7 @@ int main (int argc, char **argv) - int line = 0; - - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.8.1/src/chpasswd.c.libsubid_not_print_error_messages shadow-4.8.1/src/chpasswd.c ---- shadow-4.8.1/src/chpasswd.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.909268829 +0200 -+++ shadow-4.8.1/src/chpasswd.c 2021-05-24 14:43:57.102454551 +0200 -@@ -63,6 +63,7 @@ - * Global variables - */ - const char *Prog; -+FILE *shadow_logfd = NULL; - static bool eflg = false; - static bool md5flg = false; - #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) -@@ -487,6 +488,7 @@ int main (int argc, char **argv) - int line = 0; - - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.8.1/src/chsh.c.libsubid_not_print_error_messages shadow-4.8.1/src/chsh.c ---- shadow-4.8.1/src/chsh.c.libsubid_not_print_error_messages 2019-11-12 01:18:25.000000000 +0100 -+++ shadow-4.8.1/src/chsh.c 2021-05-24 13:04:19.931269132 +0200 -@@ -59,6 +59,7 @@ - * Global variables - */ - const char *Prog; /* Program name */ -+FILE *shadow_logfd = NULL; - static bool amroot; /* Real UID is root */ - static char loginsh[BUFSIZ]; /* Name of new login shell */ - /* command line options */ -@@ -441,6 +442,7 @@ int main (int argc, char **argv) - * most error messages. - */ - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.8.1/src/expiry.c.libsubid_not_print_error_messages shadow-4.8.1/src/expiry.c ---- shadow-4.8.1/src/expiry.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/src/expiry.c 2021-05-24 13:04:19.931269132 +0200 -@@ -46,6 +46,7 @@ - - /* Global variables */ - const char *Prog; -+FILE *shadow_logfd = NULL; - static bool cflg = false; - - /* local function prototypes */ -@@ -144,6 +145,7 @@ int main (int argc, char **argv) - struct spwd *spwd; - - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - - sanitize_env (); - -diff -up shadow-4.8.1/src/faillog.c.libsubid_not_print_error_messages shadow-4.8.1/src/faillog.c ---- shadow-4.8.1/src/faillog.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.910268843 +0200 -+++ shadow-4.8.1/src/faillog.c 2021-05-24 13:04:19.932269146 +0200 -@@ -62,6 +62,7 @@ static void reset (void); - * Global variables - */ - const char *Prog; /* Program name */ -+FILE *shadow_logfd = NULL; - static FILE *fail; /* failure file stream */ - static time_t seconds; /* that number of days in seconds */ - static unsigned long umin; /* if uflg and has_umin, only display users with uid >= umin */ -@@ -573,6 +574,7 @@ int main (int argc, char **argv) - * most error messages. - */ - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.8.1/src/free_subid_range.c.libsubid_not_print_error_messages shadow-4.8.1/src/free_subid_range.c ---- shadow-4.8.1/src/free_subid_range.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.926269063 +0200 -+++ shadow-4.8.1/src/free_subid_range.c 2021-05-24 13:04:19.932269146 +0200 -@@ -7,6 +7,7 @@ - /* Test program for the subid freeing routine */ - - const char *Prog; -+FILE *shadow_logfd = NULL; - - void usage(void) - { -@@ -23,6 +24,7 @@ int main(int argc, char *argv[]) - bool group = false; // get subuids by default - - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - while ((c = getopt(argc, argv, "g")) != EOF) { - switch(c) { - case 'g': group = true; break; -diff -up shadow-4.8.1/src/get_subid_owners.c.libsubid_not_print_error_messages shadow-4.8.1/src/get_subid_owners.c ---- shadow-4.8.1/src/get_subid_owners.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.926269063 +0200 -+++ shadow-4.8.1/src/get_subid_owners.c 2021-05-24 13:04:19.932269146 +0200 -@@ -4,6 +4,7 @@ - #include "prototypes.h" - - const char *Prog; -+FILE *shadow_logfd = NULL; - - void usage(void) - { -@@ -19,6 +20,7 @@ int main(int argc, char *argv[]) - uid_t *uids; - - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - if (argc < 2) { - usage(); - } -diff -up shadow-4.8.1/src/gpasswd.c.libsubid_not_print_error_messages shadow-4.8.1/src/gpasswd.c ---- shadow-4.8.1/src/gpasswd.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.906268788 +0200 -+++ shadow-4.8.1/src/gpasswd.c 2021-05-24 13:04:19.932269146 +0200 -@@ -58,6 +58,7 @@ - */ - /* The name of this command, as it is invoked */ - const char *Prog; -+FILE *shadow_logfd = NULL; - - #ifdef SHADOWGRP - /* Indicate if shadow groups are enabled on the system -@@ -926,6 +927,7 @@ int main (int argc, char **argv) - */ - bywho = getuid (); - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - - OPENLOG ("gpasswd"); - setbuf (stdout, NULL); -diff -up shadow-4.8.1/src/groupadd.c.libsubid_not_print_error_messages shadow-4.8.1/src/groupadd.c ---- shadow-4.8.1/src/groupadd.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.906268788 +0200 -+++ shadow-4.8.1/src/groupadd.c 2021-05-24 13:04:19.932269146 +0200 -@@ -72,6 +72,7 @@ - * Global variables - */ - const char *Prog; -+FILE *shadow_logfd = NULL; - - static /*@null@*/char *group_name; - static gid_t group_id; -@@ -582,6 +583,7 @@ int main (int argc, char **argv) - * Get my name so that I can use it to report errors. - */ - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.8.1/src/groupdel.c.libsubid_not_print_error_messages shadow-4.8.1/src/groupdel.c ---- shadow-4.8.1/src/groupdel.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.906268788 +0200 -+++ shadow-4.8.1/src/groupdel.c 2021-05-24 13:04:19.932269146 +0200 -@@ -58,6 +58,7 @@ - * Global variables - */ - const char *Prog; -+FILE *shadow_logfd = NULL; - - static char *group_name; - static gid_t group_id = -1; -@@ -377,6 +378,7 @@ int main (int argc, char **argv) - * Get my name so that I can use it to report errors. - */ - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.8.1/src/groupmems.c.libsubid_not_print_error_messages shadow-4.8.1/src/groupmems.c ---- shadow-4.8.1/src/groupmems.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/src/groupmems.c 2021-05-24 13:04:19.932269146 +0200 -@@ -65,6 +65,7 @@ - * Global variables - */ - const char *Prog; -+FILE *shadow_logfd = NULL; - - static char *adduser = NULL; - static char *deluser = NULL; -@@ -595,6 +596,7 @@ int main (int argc, char **argv) - * Get my name so that I can use it to report errors. - */ - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.8.1/src/groupmod.c.libsubid_not_print_error_messages shadow-4.8.1/src/groupmod.c ---- shadow-4.8.1/src/groupmod.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.906268788 +0200 -+++ shadow-4.8.1/src/groupmod.c 2021-05-24 13:04:19.932269146 +0200 -@@ -76,6 +76,7 @@ - * Global variables - */ - const char *Prog; -+FILE *shadow_logfd = NULL; - - #ifdef SHADOWGRP - static bool is_shadow_grp; -@@ -799,6 +800,7 @@ int main (int argc, char **argv) - * Get my name so that I can use it to report errors. - */ - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.8.1/src/groups.c.libsubid_not_print_error_messages shadow-4.8.1/src/groups.c ---- shadow-4.8.1/src/groups.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/src/groups.c 2021-05-24 13:04:19.932269146 +0200 -@@ -43,6 +43,7 @@ - * Global variables - */ - const char *Prog; -+FILE *shadow_logfd = NULL; - - /* local function prototypes */ - static void print_groups (const char *member); -@@ -126,6 +127,7 @@ int main (int argc, char **argv) - * Get the program name so that error messages can use it. - */ - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - - if (argc == 1) { - -diff -up shadow-4.8.1/src/grpck.c.libsubid_not_print_error_messages shadow-4.8.1/src/grpck.c ---- shadow-4.8.1/src/grpck.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/src/grpck.c 2021-05-24 13:04:19.932269146 +0200 -@@ -68,6 +68,7 @@ - * Global variables - */ - const char *Prog; -+FILE *shadow_logfd = NULL; - - static const char *grp_file = GROUP_FILE; - static bool use_system_grp_file = true; -@@ -836,6 +837,7 @@ int main (int argc, char **argv) - * Get my name so that I can use it to report errors. - */ - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.8.1/src/grpconv.c.libsubid_not_print_error_messages shadow-4.8.1/src/grpconv.c ---- shadow-4.8.1/src/grpconv.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/src/grpconv.c 2021-05-24 13:04:19.932269146 +0200 -@@ -59,6 +59,7 @@ - * Global variables - */ - const char *Prog; -+FILE *shadow_logfd = NULL; - - static bool gr_locked = false; - static bool sgr_locked = false; -@@ -146,6 +147,7 @@ int main (int argc, char **argv) - struct sgrp sgent; - - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.8.1/src/grpunconv.c.libsubid_not_print_error_messages shadow-4.8.1/src/grpunconv.c ---- shadow-4.8.1/src/grpunconv.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/src/grpunconv.c 2021-05-24 13:04:19.932269146 +0200 -@@ -59,6 +59,7 @@ - * Global variables - */ - const char *Prog; -+FILE *shadow_logfd = NULL; - - static bool gr_locked = false; - static bool sgr_locked = false; -@@ -145,6 +146,7 @@ int main (int argc, char **argv) - const struct sgrp *sg; - - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.8.1/src/lastlog.c.libsubid_not_print_error_messages shadow-4.8.1/src/lastlog.c ---- shadow-4.8.1/src/lastlog.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.910268843 +0200 -+++ shadow-4.8.1/src/lastlog.c 2021-05-24 13:04:19.932269146 +0200 -@@ -59,6 +59,7 @@ - * Global variables - */ - const char *Prog; /* Program name */ -+FILE *shadow_logfd = NULL; - static FILE *lastlogfile; /* lastlog file stream */ - static unsigned long umin; /* if uflg and has_umin, only display users with uid >= umin */ - static bool has_umin = false; -@@ -304,6 +305,7 @@ int main (int argc, char **argv) - * most error messages. - */ - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.8.1/src/list_subid_ranges.c.libsubid_not_print_error_messages shadow-4.8.1/src/list_subid_ranges.c ---- shadow-4.8.1/src/list_subid_ranges.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.926269063 +0200 -+++ shadow-4.8.1/src/list_subid_ranges.c 2021-05-24 13:04:19.932269146 +0200 -@@ -4,6 +4,7 @@ - #include "prototypes.h" - - const char *Prog; -+FILE *shadow_logfd = NULL; - - void usage(void) - { -@@ -19,6 +20,7 @@ int main(int argc, char *argv[]) - struct subordinate_range **ranges; - - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - if (argc < 2) { - usage(); - } -diff -up shadow-4.8.1/src/login.c.libsubid_not_print_error_messages shadow-4.8.1/src/login.c ---- shadow-4.8.1/src/login.c.libsubid_not_print_error_messages 2020-01-12 14:58:49.000000000 +0100 -+++ shadow-4.8.1/src/login.c 2021-05-24 13:04:19.933269160 +0200 -@@ -83,6 +83,7 @@ static pam_handle_t *pamh = NULL; - * Global variables - */ - const char *Prog; -+FILE *shadow_logfd = NULL; - - static const char *hostname = ""; - static /*@null@*/ /*@only@*/char *username = NULL; -@@ -577,6 +578,7 @@ int main (int argc, char **argv) - - amroot = (getuid () == 0); - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - - if (geteuid() != 0) { - fprintf (stderr, _("%s: Cannot possibly work without effective root\n"), Prog); -diff -up shadow-4.8.1/src/logoutd.c.libsubid_not_print_error_messages shadow-4.8.1/src/logoutd.c ---- shadow-4.8.1/src/logoutd.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/src/logoutd.c 2021-05-24 13:04:19.933269160 +0200 -@@ -44,6 +44,7 @@ - * Global variables - */ - const char *Prog; -+FILE *shadow_logfd = NULL; - - #ifndef DEFAULT_HUP_MESG - #define DEFAULT_HUP_MESG _("login time exceeded\n\n") -@@ -187,6 +188,7 @@ int main (int argc, char **argv) - * Start syslogging everything - */ - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - - OPENLOG ("logoutd"); - -diff -up shadow-4.8.1/src/newgidmap.c.libsubid_not_print_error_messages shadow-4.8.1/src/newgidmap.c ---- shadow-4.8.1/src/newgidmap.c.libsubid_not_print_error_messages 2019-10-13 04:52:08.000000000 +0200 -+++ shadow-4.8.1/src/newgidmap.c 2021-05-24 13:04:19.933269160 +0200 -@@ -45,6 +45,7 @@ - * Global variables - */ - const char *Prog; -+FILE *shadow_logfd = NULL; - - - static bool verify_range(struct passwd *pw, struct map_range *range, bool *allow_setgroups) -@@ -175,6 +176,7 @@ int main(int argc, char **argv) - bool allow_setgroups = false; - - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - - /* - * The valid syntax are -diff -up shadow-4.8.1/src/newgrp.c.libsubid_not_print_error_messages shadow-4.8.1/src/newgrp.c ---- shadow-4.8.1/src/newgrp.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.906268788 +0200 -+++ shadow-4.8.1/src/newgrp.c 2021-05-24 14:45:30.372720097 +0200 -@@ -49,6 +49,7 @@ - * Global variables - */ - const char *Prog; -+FILE *shadow_logfd = NULL; - - extern char **newenvp; - extern char **environ; -@@ -444,6 +445,7 @@ int main (int argc, char **argv) - * don't need to re-exec anything. -- JWP - */ - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - is_newgrp = (strcmp (Prog, "newgrp") == 0); - OPENLOG (is_newgrp ? "newgrp" : "sg"); - gid = getgid (); -diff -up shadow-4.8.1/src/new_subid_range.c.libsubid_not_print_error_messages shadow-4.8.1/src/new_subid_range.c ---- shadow-4.8.1/src/new_subid_range.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.926269063 +0200 -+++ shadow-4.8.1/src/new_subid_range.c 2021-05-24 13:04:19.933269160 +0200 -@@ -7,6 +7,7 @@ - /* Test program for the subid creation routine */ - - const char *Prog; -+FILE *shadow_logfd = NULL; - - void usage(void) - { -@@ -26,6 +27,7 @@ int main(int argc, char *argv[]) - bool ok; - - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - while ((c = getopt(argc, argv, "gn")) != EOF) { - switch(c) { - case 'n': makenew = true; break; -diff -up shadow-4.8.1/src/newuidmap.c.libsubid_not_print_error_messages shadow-4.8.1/src/newuidmap.c ---- shadow-4.8.1/src/newuidmap.c.libsubid_not_print_error_messages 2019-10-13 04:52:08.000000000 +0200 -+++ shadow-4.8.1/src/newuidmap.c 2021-05-24 13:04:19.933269160 +0200 -@@ -45,6 +45,7 @@ - * Global variables - */ - const char *Prog; -+FILE *shadow_logfd = NULL; - - static bool verify_range(struct passwd *pw, struct map_range *range) - { -@@ -105,6 +106,7 @@ int main(int argc, char **argv) - int written; - - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - - /* - * The valid syntax are -diff -up shadow-4.8.1/src/newusers.c.libsubid_not_print_error_messages shadow-4.8.1/src/newusers.c ---- shadow-4.8.1/src/newusers.c.libsubid_not_print_error_messages 2020-01-17 16:47:56.000000000 +0100 -+++ shadow-4.8.1/src/newusers.c 2021-05-24 13:04:19.933269160 +0200 -@@ -75,6 +75,7 @@ - * Global variables - */ - const char *Prog; -+FILE *shadow_logfd = NULL; - - static bool rflg = false; /* create a system account */ - #ifndef USE_PAM -@@ -1040,6 +1041,7 @@ int main (int argc, char **argv) - #endif /* USE_PAM */ - - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.8.1/src/passwd.c.libsubid_not_print_error_messages shadow-4.8.1/src/passwd.c ---- shadow-4.8.1/src/passwd.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.910268843 +0200 -+++ shadow-4.8.1/src/passwd.c 2021-05-24 13:04:19.933269160 +0200 -@@ -66,6 +66,7 @@ - * Global variables - */ - const char *Prog; /* Program name */ -+FILE *shadow_logfd = NULL; - - static char *name; /* The name of user whose password is being changed */ - static char *myname; /* The current user's name */ -@@ -752,6 +753,7 @@ int main (int argc, char **argv) - * most error messages. - */ - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.8.1/src/pwck.c.libsubid_not_print_error_messages shadow-4.8.1/src/pwck.c ---- shadow-4.8.1/src/pwck.c.libsubid_not_print_error_messages 2019-10-13 02:56:08.000000000 +0200 -+++ shadow-4.8.1/src/pwck.c 2021-05-24 13:04:19.933269160 +0200 -@@ -70,6 +70,7 @@ - * Global variables - */ - const char *Prog; -+FILE *shadow_logfd = NULL; - - static bool use_system_pw_file = true; - static bool use_system_spw_file = true; -diff -up shadow-4.8.1/src/pwconv.c.libsubid_not_print_error_messages shadow-4.8.1/src/pwconv.c ---- shadow-4.8.1/src/pwconv.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/src/pwconv.c 2021-05-24 13:04:19.933269160 +0200 -@@ -89,6 +89,7 @@ - * Global variables - */ - const char *Prog; -+FILE *shadow_logfd = NULL; - - static bool spw_locked = false; - static bool pw_locked = false; -@@ -176,6 +177,7 @@ int main (int argc, char **argv) - struct spwd spent; - - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.8.1/src/pwunconv.c.libsubid_not_print_error_messages shadow-4.8.1/src/pwunconv.c ---- shadow-4.8.1/src/pwunconv.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/src/pwunconv.c 2021-05-24 13:04:19.933269160 +0200 -@@ -53,6 +53,7 @@ - * Global variables - */ - const char *Prog; -+FILE *shadow_logfd = NULL; - - static bool spw_locked = false; - static bool pw_locked = false; -@@ -137,6 +138,7 @@ int main (int argc, char **argv) - const struct spwd *spwd; - - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.8.1/src/su.c.libsubid_not_print_error_messages shadow-4.8.1/src/su.c ---- shadow-4.8.1/src/su.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/src/su.c 2021-05-24 13:04:19.934269173 +0200 -@@ -82,6 +82,7 @@ - * Global variables - */ - const char *Prog; -+FILE *shadow_logfd = NULL; - static /*@observer@*/const char *caller_tty = NULL; /* Name of tty SU is run from */ - static bool caller_is_root = false; - static uid_t caller_uid; -@@ -699,6 +700,7 @@ static void save_caller_context (char ** - * most error messages. - */ - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - - caller_uid = getuid (); - caller_is_root = (caller_uid == 0); -diff -up shadow-4.8.1/src/sulogin.c.libsubid_not_print_error_messages shadow-4.8.1/src/sulogin.c ---- shadow-4.8.1/src/sulogin.c.libsubid_not_print_error_messages 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/src/sulogin.c 2021-05-24 13:04:19.934269173 +0200 -@@ -50,6 +50,7 @@ - * Global variables - */ - const char *Prog; -+FILE *shadow_logfd = NULL; - - static char name[BUFSIZ]; - static char pass[BUFSIZ]; -@@ -106,6 +107,7 @@ static RETSIGTYPE catch_signals (unused - #endif - - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); - (void) textdomain (PACKAGE); -diff -up shadow-4.8.1/src/useradd.c.libsubid_not_print_error_messages shadow-4.8.1/src/useradd.c ---- shadow-4.8.1/src/useradd.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.918268953 +0200 -+++ shadow-4.8.1/src/useradd.c 2021-05-24 13:04:19.934269173 +0200 -@@ -92,6 +92,7 @@ - * Global variables - */ - const char *Prog; -+FILE *shadow_logfd = NULL; - - /* - * These defaults are used if there is no defaults file. -@@ -2301,6 +2302,7 @@ int main (int argc, char **argv) - * Get my name so that I can use it to report errors. - */ - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.8.1/src/userdel.c.libsubid_not_print_error_messages shadow-4.8.1/src/userdel.c ---- shadow-4.8.1/src/userdel.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.907268801 +0200 -+++ shadow-4.8.1/src/userdel.c 2021-05-24 13:04:19.934269173 +0200 -@@ -89,6 +89,7 @@ - * Global variables - */ - const char *Prog; -+FILE *shadow_logfd = NULL; - - static char *user_name; - static uid_t user_id; -@@ -941,6 +942,7 @@ int main (int argc, char **argv) - * Get my name so that I can use it to report errors. - */ - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); - (void) textdomain (PACKAGE); -diff -up shadow-4.8.1/src/usermod.c.libsubid_not_print_error_messages shadow-4.8.1/src/usermod.c ---- shadow-4.8.1/src/usermod.c.libsubid_not_print_error_messages 2021-05-24 13:04:19.917268939 +0200 -+++ shadow-4.8.1/src/usermod.c 2021-05-24 13:04:19.934269173 +0200 -@@ -102,6 +102,7 @@ - * Global variables - */ - const char *Prog; -+FILE *shadow_logfd = NULL; - - static char *user_name; - static char *user_newname; -@@ -2214,6 +2215,7 @@ int main (int argc, char **argv) - * Get my name so that I can use it to report errors. - */ - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.8.1/src/vipw.c.libsubid_not_print_error_messages shadow-4.8.1/src/vipw.c ---- shadow-4.8.1/src/vipw.c.libsubid_not_print_error_messages 2019-12-01 17:52:32.000000000 +0100 -+++ shadow-4.8.1/src/vipw.c 2021-05-24 13:04:19.934269173 +0200 -@@ -63,6 +63,7 @@ - * Global variables - */ - const char *Prog; -+FILE *shadow_logfd = NULL; - - static const char *filename, *fileeditname; - static bool filelocked = false; -@@ -481,6 +482,7 @@ int main (int argc, char **argv) - bool do_vipw; - - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); diff --git a/shadow-4.8.1-libsubid_nsswitch_support.patch b/shadow-4.8.1-libsubid_nsswitch_support.patch deleted file mode 100644 index eafa7c1..0000000 --- a/shadow-4.8.1-libsubid_nsswitch_support.patch +++ /dev/null @@ -1,2107 +0,0 @@ -From 514c1328b6c90d817ae0a9f7addfb3c9a11a275a Mon Sep 17 00:00:00 2001 -From: Serge Hallyn -Date: Sun, 31 Jan 2021 22:44:09 -0600 -Subject: [PATCH 1/6] try again to fix libmisc sharing problem - -Issue #297 reported seeing - -*** Warning: Linking the shared library libsubid.la against the -*** static library ../libmisc/libmisc.a is not portable! - -which commit b5fb1b38eea2fb0489ed088c82daf6700e72363e was supposed -to fix. But a few commits later it's back. So try to fix it -in the way the bug reporter suggested. This broke builds some -other ways, namely a few missing library specifications, so add -those. - -Signed-off-by: Serge Hallyn ---- - configure.ac | 2 +- - libmisc/Makefile.am | 6 +++--- - libsubid/Makefile.am | 6 ++++-- - src/Makefile.am | 37 +++++++++++++++++++++++-------------- - 4 files changed, 31 insertions(+), 20 deletions(-) - -diff --git a/configure.ac b/configure.ac -index 6aaae6b7..7884bfb6 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -55,7 +55,7 @@ AC_CHECK_FUNCS(l64a fchmod fchown fsync futimes getgroups gethostname getspnam \ - gettimeofday getusershell getutent initgroups lchown lckpwdf lstat \ - lutimes memcpy memset setgroups sigaction strchr updwtmp updwtmpx innetgr \ - getpwnam_r getpwuid_r getgrnam_r getgrgid_r getspnam_r getaddrinfo \ -- ruserok) -+ ruserok dlopen) - AC_SYS_LARGEFILE - - dnl Checks for typedefs, structures, and compiler characteristics. -diff --git a/libmisc/Makefile.am b/libmisc/Makefile.am -index 7f43161f..9766a7ec 100644 ---- a/libmisc/Makefile.am -+++ b/libmisc/Makefile.am -@@ -3,9 +3,9 @@ EXTRA_DIST = .indent.pro xgetXXbyYY.c - - AM_CPPFLAGS = -I$(top_srcdir)/lib $(ECONF_CPPFLAGS) - --noinst_LIBRARIES = libmisc.a -+noinst_LTLIBRARIES = libmisc.la - --libmisc_a_SOURCES = \ -+libmisc_la_SOURCES = \ - addgrps.c \ - age.c \ - audit_help.c \ -@@ -74,6 +74,6 @@ libmisc_a_SOURCES = \ - yesno.c - - if WITH_BTRFS --libmisc_a_SOURCES += btrfs.c -+libmisc_la_SOURCES += btrfs.c - endif - -diff --git a/libsubid/Makefile.am b/libsubid/Makefile.am -index 8bef1ecc..f24dbb94 100644 ---- a/libsubid/Makefile.am -+++ b/libsubid/Makefile.am -@@ -12,12 +12,14 @@ MISCLIBS = \ - $(LIBMD) \ - $(LIBECONF) \ - $(LIBCRYPT) \ -+ $(LIBACL) \ -+ $(LIBATTR) \ - $(LIBTCB) - - libsubid_la_LIBADD = \ - $(top_srcdir)/lib/libshadow.la \ -- $(MISCLIBS) \ -- $(top_srcdir)/libmisc/libmisc.a -+ $(top_srcdir)/libmisc/libmisc.la \ -+ $(MISCLIBS) - - AM_CPPFLAGS = \ - -I${top_srcdir}/lib \ -diff --git a/src/Makefile.am b/src/Makefile.am -index 8499ce08..e9d354fd 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -78,7 +78,7 @@ shadowsgidubins = passwd - endif - - LDADD = $(INTLLIBS) \ -- $(top_builddir)/libmisc/libmisc.a \ -+ $(top_builddir)/libmisc/libmisc.la \ - $(top_builddir)/lib/libshadow.la \ - $(LIBTCB) - -@@ -95,28 +95,37 @@ LIBCRYPT_NOPAM = $(LIBCRYPT) - endif - - chage_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) --newuidmap_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP) --newgidmap_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP) -+newuidmap_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP) -ldl -+newgidmap_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP) -ldl - chfn_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF) - chgpasswd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF) - chsh_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF) - chpasswd_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF) - expiry_LDADD = $(LDADD) $(LIBECONF) - gpasswd_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF) --groupadd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) --groupdel_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) -+groupadd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) -ldl -+groupdel_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) -ldl - groupmems_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) --groupmod_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) -+groupmod_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) -ldl - grpck_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) - grpconv_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) - grpunconv_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) - lastlog_LDADD = $(LDADD) $(LIBAUDIT) $(LIBECONF) -+newuidmap_SOURCES = newuidmap.c ../libmisc/nss.c -+newgidmap_SOURCES = newgidmap.c ../libmisc/nss.c -+groupadd_SOURCES = groupadd.c ../libmisc/nss.c -+groupmod_SOURCES = groupmod.c ../libmisc/nss.c -+groupdel_SOURCES = groupdel.c ../libmisc/nss.c -+newusers_SOURCES = newusers.c ../libmisc/nss.c -+useradd_SOURCES = useradd.c ../libmisc/nss.c -+usermod_SOURCES = usermod.c ../libmisc/nss.c -+userdel_SOURCES = userdel.c ../libmisc/nss.c - login_SOURCES = \ - login.c \ - login_nopam.c - login_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF) - newgrp_LDADD = $(LDADD) $(LIBAUDIT) $(LIBCRYPT) $(LIBECONF) --newusers_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF) -+newusers_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF) -ldl - nologin_LDADD = - passwd_LDADD = $(LDADD) $(LIBPAM) $(LIBCRACK) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBECONF) - pwck_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) -@@ -127,9 +136,9 @@ su_SOURCES = \ - suauth.c - su_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF) - sulogin_LDADD = $(LDADD) $(LIBCRYPT) $(LIBECONF) --useradd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBACL) $(LIBATTR) $(LIBECONF) --userdel_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBECONF) --usermod_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBACL) $(LIBATTR) $(LIBECONF) -+useradd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBACL) $(LIBATTR) $(LIBECONF) -ldl -+userdel_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBECONF) -ldl -+usermod_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBACL) $(LIBATTR) $(LIBECONF) -ldl - vipw_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) - - install-am: all-am -@@ -175,7 +184,7 @@ MISCLIBS = \ - - list_subid_ranges_LDADD = \ - $(top_builddir)/lib/libshadow.la \ -- $(top_builddir)/libmisc/libmisc.a \ -+ $(top_builddir)/libmisc/libmisc.la \ - $(top_builddir)/libsubid/libsubid.la \ - $(MISCLIBS) - -@@ -186,7 +195,7 @@ list_subid_ranges_CPPFLAGS = \ - - get_subid_owners_LDADD = \ - $(top_builddir)/lib/libshadow.la \ -- $(top_builddir)/libmisc/libmisc.a \ -+ $(top_builddir)/libmisc/libmisc.la \ - $(top_builddir)/libsubid/libsubid.la \ - $(MISCLIBS) - -@@ -202,7 +211,7 @@ new_subid_range_CPPFLAGS = \ - - new_subid_range_LDADD = \ - $(top_builddir)/lib/libshadow.la \ -- $(top_builddir)/libmisc/libmisc.a \ -+ $(top_builddir)/libmisc/libmisc.la \ - $(top_builddir)/libsubid/libsubid.la \ - $(MISCLIBS) - -@@ -213,7 +222,7 @@ free_subid_range_CPPFLAGS = \ - - free_subid_range_LDADD = \ - $(top_builddir)/lib/libshadow.la \ -- $(top_builddir)/libmisc/libmisc.a \ -+ $(top_builddir)/libmisc/libmisc.la \ - $(top_builddir)/libsubid/libsubid.la \ - $(MISCLIBS) - endif --- -2.30.2 - - -From 8492dee6632e340dee76eee895c3e30877bebf45 Mon Sep 17 00:00:00 2001 -From: Serge Hallyn -Date: Sun, 31 Jan 2021 17:38:20 -0600 -Subject: [PATCH 2/6] subids: support nsswitch - -Closes #154 - -When starting any operation to do with subuid delegation, check -nsswitch for a module to use. If none is specified, then use -the traditional /etc/subuid and /etc/subgid files. - -Currently only one module is supported, and there is no fallback -to the files on errors. Several possibilities could be considered: - -1. in case of connection error, fall back to files -2. in case of unknown user, also fall back to files - -etc... - -When non-files nss module is used, functions to edit the range -are not supported. It may make sense to support it, but it also -may make sense to require another tool to be used. - -libsubordinateio also uses the nss_ helpers. This is how for instance -lxc could easily be converted to supporting nsswitch. - -Add a set of test cases, including a dummy libsubid_zzz module. This -hardcodes values such that: - -'ubuntu' gets 200000 - 300000 -'user1' gets 100000 - 165536 -'error' emulates an nss module error -'unknown' emulates a user unknown to the nss module -'conn' emulates a connection error ot the nss module - -Changes to libsubid: - -Change the list_owner_ranges api: return a count instead of making the array -null terminated. - -This is a breaking change, so bump the libsubid abi major number. - -Rename free_subuid_range and free_subgid_range to ungrant_subuid_range, -because otherwise it's confusing with free_subid_ranges which frees - memory. - -Run libsubid tests in jenkins - -Switch argument order in find_subid_owners - -Move the db locking into subordinateio.c - -Signed-off-by: Serge Hallyn ---- - configure.ac | 2 +- - lib/Makefile.am | 1 + - lib/nss.c | 157 ++++++++++++++++ - lib/prototypes.h | 69 ++++++++ - lib/subordinateio.c | 256 ++++++++++++++++++++++++--- - lib/subordinateio.h | 6 +- - libmisc/idmapping.h | 2 + - libsubid/Makefile.am | 2 +- - libsubid/api.c | 168 +++--------------- - libsubid/api.h | 10 +- - libsubid/subid.h | 8 + - src/Makefile.am | 29 +-- - src/check_subid_range.c | 48 +++++ - src/free_subid_range.c | 4 +- - src/list_subid_ranges.c | 10 +- - tests/libsubid/04_nss/Makefile | 12 ++ - tests/libsubid/04_nss/empty | 0 - tests/libsubid/04_nss/libsubid_zzz.c | 146 +++++++++++++++ - tests/libsubid/04_nss/nsswitch1.conf | 20 +++ - tests/libsubid/04_nss/nsswitch2.conf | 22 +++ - tests/libsubid/04_nss/nsswitch3.conf | 22 +++ - tests/libsubid/04_nss/subidnss.test | 22 +++ - tests/libsubid/04_nss/test_nss.c | 72 ++++++++ - tests/libsubid/04_nss/test_range | 50 ++++++ - tests/run_some | 1 + - 26 files changed, 935 insertions(+), 205 deletions(-) - create mode 100644 lib/nss.c - create mode 100644 src/check_subid_range.c - create mode 100644 tests/libsubid/04_nss/Makefile - create mode 100644 tests/libsubid/04_nss/empty - create mode 100644 tests/libsubid/04_nss/libsubid_zzz.c - create mode 100644 tests/libsubid/04_nss/nsswitch1.conf - create mode 100644 tests/libsubid/04_nss/nsswitch2.conf - create mode 100644 tests/libsubid/04_nss/nsswitch3.conf - create mode 100755 tests/libsubid/04_nss/subidnss.test - create mode 100644 tests/libsubid/04_nss/test_nss.c - create mode 100755 tests/libsubid/04_nss/test_range - -diff --git a/configure.ac b/configure.ac -index 7884bfb6..7f7e8784 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1,6 +1,6 @@ - dnl Process this file with autoconf to produce a configure script. - AC_PREREQ([2.69]) --m4_define([libsubid_abi_major], 1) -+m4_define([libsubid_abi_major], 2) - m4_define([libsubid_abi_minor], 0) - m4_define([libsubid_abi_micro], 0) - m4_define([libsubid_abi], [libsubid_abi_major.libsubid_abi_minor.libsubid_abi_micro]) -diff --git a/lib/Makefile.am b/lib/Makefile.am -index bd9d6bfb..ecf3ee25 100644 ---- a/lib/Makefile.am -+++ b/lib/Makefile.am -@@ -31,6 +31,7 @@ libshadow_la_SOURCES = \ - groupio.h \ - gshadow.c \ - lockpw.c \ -+ nss.c \ - nscd.c \ - nscd.h \ - sssd.c \ -diff --git a/lib/nss.c b/lib/nss.c -new file mode 100644 -index 00000000..2f924740 ---- /dev/null -+++ b/lib/nss.c -@@ -0,0 +1,157 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "prototypes.h" -+#include "../libsubid/subid.h" -+ -+#define NSSWITCH "/etc/nsswitch.conf" -+ -+// NSS plugin handling for subids -+// If nsswitch has a line like -+// subid: sssd -+// then sssd will be consulted for subids. Unlike normal NSS dbs, -+// only one db is supported at a time. That's open to debate, but -+// the subids are a pretty limited resource, and local files seem -+// bound to step on any other allocations leading to insecure -+// conditions. -+static atomic_flag nss_init_started; -+static atomic_bool nss_init_completed; -+ -+static struct subid_nss_ops *subid_nss; -+ -+bool nss_is_initialized() { -+ return atomic_load(&nss_init_completed); -+} -+ -+void nss_exit() { -+ if (nss_is_initialized() && subid_nss) { -+ dlclose(subid_nss->handle); -+ free(subid_nss); -+ subid_nss = NULL; -+ } -+} -+ -+// nsswitch_path is an argument only to support testing. -+void nss_init(char *nsswitch_path) { -+ FILE *nssfp = NULL; -+ char *line = NULL, *p, *token, *saveptr; -+ size_t len = 0; -+ -+ if (atomic_flag_test_and_set(&nss_init_started)) { -+ // Another thread has started nss_init, wait for it to complete -+ while (!atomic_load(&nss_init_completed)) -+ usleep(100); -+ return; -+ } -+ -+ if (!nsswitch_path) -+ nsswitch_path = NSSWITCH; -+ -+ // read nsswitch.conf to check for a line like: -+ // subid: files -+ nssfp = fopen(nsswitch_path, "r"); -+ if (!nssfp) { -+ fprintf(stderr, "Failed opening %s: %m", nsswitch_path); -+ atomic_store(&nss_init_completed, true); -+ return; -+ } -+ while ((getline(&line, &len, nssfp)) != -1) { -+ if (line[0] == '\0' || line[0] == '#') -+ continue; -+ if (strlen(line) < 8) -+ continue; -+ if (strncasecmp(line, "subid:", 6) != 0) -+ continue; -+ p = &line[6]; -+ while ((*p) && isspace(*p)) -+ p++; -+ if (!*p) -+ continue; -+ for (token = strtok_r(p, " \n\t", &saveptr); -+ token; -+ token = strtok_r(NULL, " \n\t", &saveptr)) { -+ char libname[65]; -+ void *h; -+ if (strcmp(token, "files") == 0) { -+ subid_nss = NULL; -+ goto done; -+ } -+ if (strlen(token) > 50) { -+ fprintf(stderr, "Subid NSS module name too long (longer than 50 characters): %s\n", token); -+ fprintf(stderr, "Using files\n"); -+ subid_nss = NULL; -+ goto done; -+ } -+ snprintf(libname, 64, "libsubid_%s.so", token); -+ h = dlopen(libname, RTLD_LAZY); -+ if (!h) { -+ fprintf(stderr, "Error opening %s: %s\n", libname, dlerror()); -+ fprintf(stderr, "Using files\n"); -+ subid_nss = NULL; -+ goto done; -+ } -+ subid_nss = malloc(sizeof(*subid_nss)); -+ if (!subid_nss) { -+ dlclose(h); -+ goto done; -+ } -+ subid_nss->has_range = dlsym(h, "shadow_subid_has_range"); -+ if (!subid_nss->has_range) { -+ fprintf(stderr, "%s did not provide @has_range@\n", libname); -+ dlclose(h); -+ free(subid_nss); -+ subid_nss = NULL; -+ goto done; -+ } -+ subid_nss->list_owner_ranges = dlsym(h, "shadow_subid_list_owner_ranges"); -+ if (!subid_nss->list_owner_ranges) { -+ fprintf(stderr, "%s did not provide @list_owner_ranges@\n", libname); -+ dlclose(h); -+ free(subid_nss); -+ subid_nss = NULL; -+ goto done; -+ } -+ subid_nss->has_any_range = dlsym(h, "shadow_subid_has_any_range"); -+ if (!subid_nss->has_any_range) { -+ fprintf(stderr, "%s did not provide @has_any_range@\n", libname); -+ dlclose(h); -+ free(subid_nss); -+ subid_nss = NULL; -+ goto done; -+ } -+ subid_nss->find_subid_owners = dlsym(h, "shadow_subid_find_subid_owners"); -+ if (!subid_nss->find_subid_owners) { -+ fprintf(stderr, "%s did not provide @find_subid_owners@\n", libname); -+ dlclose(h); -+ free(subid_nss); -+ subid_nss = NULL; -+ goto done; -+ } -+ subid_nss->handle = h; -+ goto done; -+ } -+ fprintf(stderr, "No usable subid NSS module found, using files\n"); -+ // subid_nss has to be null here, but to ease reviews: -+ free(subid_nss); -+ subid_nss = NULL; -+ goto done; -+ } -+ -+done: -+ atomic_store(&nss_init_completed, true); -+ free(line); -+ if (nssfp) { -+ atexit(nss_exit); -+ fclose(nssfp); -+ } -+} -+ -+struct subid_nss_ops *get_subid_nss_handle() { -+ nss_init(NULL); -+ return subid_nss; -+} -diff --git a/lib/prototypes.h b/lib/prototypes.h -index ac9ad274..0c42bcc2 100644 ---- a/lib/prototypes.h -+++ b/lib/prototypes.h -@@ -262,6 +262,75 @@ extern void motd (void); - /* myname.c */ - extern /*@null@*//*@only@*/struct passwd *get_my_pwent (void); - -+/* nss.c */ -+#include -+extern void nss_init(char *nsswitch_path); -+extern bool nss_is_initialized(); -+ -+struct subid_nss_ops { -+ /* -+ * nss_has_any_range: does a user own any subid range -+ * -+ * @owner: username -+ * @idtype: subuid or subgid -+ * @result: true if a subid allocation was found for @owner -+ * -+ * returns success if the module was able to determine an answer (true or false), -+ * else an error status. -+ */ -+ enum subid_status (*has_any_range)(const char *owner, enum subid_type idtype, bool *result); -+ -+ /* -+ * nss_has_range: does a user own a given subid range -+ * -+ * @owner: username -+ * @start: first subid in queried range -+ * @count: number of subids in queried range -+ * @idtype: subuid or subgid -+ * @result: true if @owner has been allocated the subid range. -+ * -+ * returns success if the module was able to determine an answer (true or false), -+ * else an error status. -+ */ -+ enum subid_status (*has_range)(const char *owner, unsigned long start, unsigned long count, enum subid_type idtype, bool *result); -+ -+ /* -+ * nss_list_owner_ranges: list the subid ranges delegated to a user. -+ * -+ * @owner - string representing username being queried -+ * @id_type - subuid or subgid -+ * @ranges - pointer to an array of struct subordinate_range pointers, or -+ * NULL. The returned array of struct subordinate_range and its -+ * members must be freed by the caller. -+ * @count - pointer to an integer into which the number of returned ranges -+ * is written. -+ -+ * returns success if the module was able to determine an answer, -+ * else an error status. -+ */ -+ enum subid_status (*list_owner_ranges)(const char *owner, enum subid_type id_type, struct subordinate_range ***ranges, int *count); -+ -+ /* -+ * nss_find_subid_owners: find uids who own a given subuid or subgid. -+ * -+ * @id - the delegated id (subuid or subgid) being queried -+ * @id_type - subuid or subgid -+ * @uids - pointer to an array of uids which will be allocated by -+ * nss_find_subid_owners() -+ * @count - number of uids found -+ * -+ * returns success if the module was able to determine an answer, -+ * else an error status. -+ */ -+ enum subid_status (*find_subid_owners)(unsigned long id, enum subid_type id_type, uid_t **uids, int *count); -+ -+ /* The dlsym handle to close */ -+ void *handle; -+}; -+ -+extern struct subid_nss_ops *get_subid_nss_handle(); -+ -+ - /* pam_pass_non_interactive.c */ - #ifdef USE_PAM - extern int do_pam_passwd_non_interactive (const char *pam_service, -diff --git a/lib/subordinateio.c b/lib/subordinateio.c -index 67202c98..0bb29958 100644 ---- a/lib/subordinateio.c -+++ b/lib/subordinateio.c -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - - /* - * subordinate_dup: create a duplicate range -@@ -311,17 +312,17 @@ static bool append_range(struct subordinate_range ***ranges, const struct subord - { - struct subordinate_range *tmp; - if (!*ranges) { -- *ranges = malloc(2 * sizeof(struct subordinate_range **)); -+ *ranges = malloc(sizeof(struct subordinate_range *)); - if (!*ranges) - return false; - } else { - struct subordinate_range **new; -- new = realloc(*ranges, (n + 2) * (sizeof(struct subordinate_range **))); -+ new = realloc(*ranges, (n + 1) * (sizeof(struct subordinate_range *))); - if (!new) - return false; - *ranges = new; - } -- (*ranges)[n] = (*ranges)[n+1] = NULL; -+ (*ranges)[n] = NULL; - tmp = subordinate_dup(new); - if (!tmp) - return false; -@@ -329,13 +330,13 @@ static bool append_range(struct subordinate_range ***ranges, const struct subord - return true; - } - --void free_subordinate_ranges(struct subordinate_range **ranges) -+void free_subordinate_ranges(struct subordinate_range **ranges, int count) - { - int i; - - if (!ranges) - return; -- for (i = 0; ranges[i]; i++) -+ for (i = 0; i < count; i++) - subordinate_free(ranges[i]); - free(ranges); - } -@@ -602,21 +603,46 @@ int sub_uid_open (int mode) - - bool sub_uid_assigned(const char *owner) - { -+ struct subid_nss_ops *h; -+ bool found; -+ enum subid_status status; -+ h = get_subid_nss_handle(); -+ if (h) { -+ status = h->has_any_range(owner, ID_TYPE_UID, &found); -+ if (status == SUBID_STATUS_SUCCESS && found) -+ return true; -+ return false; -+ } -+ - return range_exists (&subordinate_uid_db, owner); - } - - bool have_sub_uids(const char *owner, uid_t start, unsigned long count) - { -+ struct subid_nss_ops *h; -+ bool found; -+ enum subid_status status; -+ h = get_subid_nss_handle(); -+ if (h) { -+ status = h->has_range(owner, start, count, ID_TYPE_UID, &found); -+ if (status == SUBID_STATUS_SUCCESS && found) -+ return true; -+ return false; -+ } - return have_range (&subordinate_uid_db, owner, start, count); - } - - int sub_uid_add (const char *owner, uid_t start, unsigned long count) - { -+ if (get_subid_nss_handle()) -+ return -EOPNOTSUPP; - return add_range (&subordinate_uid_db, owner, start, count); - } - - int sub_uid_remove (const char *owner, uid_t start, unsigned long count) - { -+ if (get_subid_nss_handle()) -+ return -EOPNOTSUPP; - return remove_range (&subordinate_uid_db, owner, start, count); - } - -@@ -684,21 +710,45 @@ int sub_gid_open (int mode) - - bool have_sub_gids(const char *owner, gid_t start, unsigned long count) - { -+ struct subid_nss_ops *h; -+ bool found; -+ enum subid_status status; -+ h = get_subid_nss_handle(); -+ if (h) { -+ status = h->has_range(owner, start, count, ID_TYPE_GID, &found); -+ if (status == SUBID_STATUS_SUCCESS && found) -+ return true; -+ return false; -+ } - return have_range(&subordinate_gid_db, owner, start, count); - } - - bool sub_gid_assigned(const char *owner) - { -+ struct subid_nss_ops *h; -+ bool found; -+ enum subid_status status; -+ h = get_subid_nss_handle(); -+ if (h) { -+ status = h->has_any_range(owner, ID_TYPE_GID, &found); -+ if (status == SUBID_STATUS_SUCCESS && found) -+ return true; -+ return false; -+ } - return range_exists (&subordinate_gid_db, owner); - } - - int sub_gid_add (const char *owner, gid_t start, unsigned long count) - { -+ if (get_subid_nss_handle()) -+ return -EOPNOTSUPP; - return add_range (&subordinate_gid_db, owner, start, count); - } - - int sub_gid_remove (const char *owner, gid_t start, unsigned long count) - { -+ if (get_subid_nss_handle()) -+ return -EOPNOTSUPP; - return remove_range (&subordinate_gid_db, owner, start, count); - } - -@@ -720,42 +770,78 @@ gid_t sub_gid_find_free_range(gid_t min, gid_t max, unsigned long count) - } - - /* -- struct subordinate_range **list_owner_ranges(const char *owner, enum subid_type id_type) -+ * int list_owner_ranges(const char *owner, enum subid_type id_type, struct subordinate_range ***ranges) - * - * @owner: username - * @id_type: UID or GUID -+ * @ranges: pointer to array of ranges into which results will be placed. - * -- * Returns the subuid or subgid ranges which are owned by the specified -+ * Fills in the subuid or subgid ranges which are owned by the specified - * user. Username may be a username or a string representation of a - * UID number. If id_type is UID, then subuids are returned, else -- * subgids are returned. If there is an error, < 0 is returned. -+ * subgids are given. -+ -+ * Returns the number of ranges found, or < 0 on error. - * - * The caller must free the subordinate range list. - */ --struct subordinate_range **list_owner_ranges(const char *owner, enum subid_type id_type) -+int list_owner_ranges(const char *owner, enum subid_type id_type, struct subordinate_range ***in_ranges) - { - // TODO - need to handle owner being either uid or username -- const struct subordinate_range *range; - struct subordinate_range **ranges = NULL; -+ const struct subordinate_range *range; - struct commonio_db *db; -- int size = 0; -+ enum subid_status status; -+ int count = 0; -+ struct subid_nss_ops *h; - -- if (id_type == ID_TYPE_UID) -+ *in_ranges = NULL; -+ -+ h = get_subid_nss_handle(); -+ if (h) { -+ status = h->list_owner_ranges(owner, id_type, in_ranges, &count); -+ if (status == SUBID_STATUS_SUCCESS) -+ return count; -+ return -1; -+ } -+ -+ switch (id_type) { -+ case ID_TYPE_UID: -+ if (!sub_uid_open(O_RDONLY)) { -+ return -1; -+ } - db = &subordinate_uid_db; -- else -+ break; -+ case ID_TYPE_GID: -+ if (!sub_gid_open(O_RDONLY)) { -+ return -1; -+ } - db = &subordinate_gid_db; -+ break; -+ default: -+ return -1; -+ } - - commonio_rewind(db); - while ((range = commonio_next(db)) != NULL) { - if (0 == strcmp(range->owner, owner)) { -- if (!append_range(&ranges, range, size++)) { -- free_subordinate_ranges(ranges); -- return NULL; -+ if (!append_range(&ranges, range, count++)) { -+ free_subordinate_ranges(ranges, count-1); -+ ranges = NULL; -+ count = -1; -+ goto out; - } - } - } - -- return ranges; -+out: -+ if (id_type == ID_TYPE_UID) -+ sub_uid_close(); -+ else -+ sub_gid_close(); -+ -+ *in_ranges = ranges; -+ return count; - } - - static bool all_digits(const char *str) -@@ -808,17 +894,41 @@ static int append_uids(uid_t **uids, const char *owner, int n) - return n+1; - } - --int find_subid_owners(unsigned long id, uid_t **uids, enum subid_type id_type) -+int find_subid_owners(unsigned long id, enum subid_type id_type, uid_t **uids) - { - const struct subordinate_range *range; -+ struct subid_nss_ops *h; -+ enum subid_status status; - struct commonio_db *db; - int n = 0; - -- *uids = NULL; -- if (id_type == ID_TYPE_UID) -+ h = get_subid_nss_handle(); -+ if (h) { -+ status = h->find_subid_owners(id, id_type, uids, &n); -+ // Several ways we could handle the error cases here. -+ if (status != SUBID_STATUS_SUCCESS) -+ return -1; -+ return n; -+ } -+ -+ switch (id_type) { -+ case ID_TYPE_UID: -+ if (!sub_uid_open(O_RDONLY)) { -+ return -1; -+ } - db = &subordinate_uid_db; -- else -+ break; -+ case ID_TYPE_GID: -+ if (!sub_gid_open(O_RDONLY)) { -+ return -1; -+ } - db = &subordinate_gid_db; -+ break; -+ default: -+ return -1; -+ } -+ -+ *uids = NULL; - - commonio_rewind(db); - while ((range = commonio_next(db)) != NULL) { -@@ -829,6 +939,11 @@ int find_subid_owners(unsigned long id, uid_t **uids, enum subid_type id_type) - } - } - -+ if (id_type == ID_TYPE_UID) -+ sub_uid_close(); -+ else -+ sub_gid_close(); -+ - return n; - } - -@@ -836,11 +951,40 @@ bool new_subid_range(struct subordinate_range *range, enum subid_type id_type, b - { - struct commonio_db *db; - const struct subordinate_range *r; -+ bool ret; - -- if (id_type == ID_TYPE_UID) -+ if (get_subid_nss_handle()) -+ return false; -+ -+ switch (id_type) { -+ case ID_TYPE_UID: -+ if (!sub_uid_lock()) { -+ printf("Failed loging subuids (errno %d)\n", errno); -+ return false; -+ } -+ if (!sub_uid_open(O_CREAT | O_RDWR)) { -+ printf("Failed opening subuids (errno %d)\n", errno); -+ sub_uid_unlock(); -+ return false; -+ } - db = &subordinate_uid_db; -- else -+ break; -+ case ID_TYPE_GID: -+ if (!sub_gid_lock()) { -+ printf("Failed loging subgids (errno %d)\n", errno); -+ return false; -+ } -+ if (!sub_gid_open(O_CREAT | O_RDWR)) { -+ printf("Failed opening subgids (errno %d)\n", errno); -+ sub_gid_unlock(); -+ return false; -+ } - db = &subordinate_gid_db; -+ break; -+ default: -+ return false; -+ } -+ - commonio_rewind(db); - if (reuse) { - while ((r = commonio_next(db)) != NULL) { -@@ -856,20 +1000,74 @@ bool new_subid_range(struct subordinate_range *range, enum subid_type id_type, b - } - - range->start = find_free_range(db, range->start, ULONG_MAX, range->count); -- if (range->start == ULONG_MAX) -- return false; - -- return add_range(db, range->owner, range->start, range->count) == 1; -+ if (range->start == ULONG_MAX) { -+ ret = false; -+ goto out; -+ } -+ -+ ret = add_range(db, range->owner, range->start, range->count) == 1; -+ -+out: -+ if (id_type == ID_TYPE_UID) { -+ sub_uid_close(); -+ sub_uid_unlock(); -+ } else { -+ sub_gid_close(); -+ sub_gid_unlock(); -+ } -+ -+ return ret; - } - - bool release_subid_range(struct subordinate_range *range, enum subid_type id_type) - { - struct commonio_db *db; -- if (id_type == ID_TYPE_UID) -+ bool ret; -+ -+ if (get_subid_nss_handle()) -+ return false; -+ -+ switch (id_type) { -+ case ID_TYPE_UID: -+ if (!sub_uid_lock()) { -+ printf("Failed loging subuids (errno %d)\n", errno); -+ return false; -+ } -+ if (!sub_uid_open(O_CREAT | O_RDWR)) { -+ printf("Failed opening subuids (errno %d)\n", errno); -+ sub_uid_unlock(); -+ return false; -+ } - db = &subordinate_uid_db; -- else -+ break; -+ case ID_TYPE_GID: -+ if (!sub_gid_lock()) { -+ printf("Failed loging subgids (errno %d)\n", errno); -+ return false; -+ } -+ if (!sub_gid_open(O_CREAT | O_RDWR)) { -+ printf("Failed opening subgids (errno %d)\n", errno); -+ sub_gid_unlock(); -+ return false; -+ } - db = &subordinate_gid_db; -- return remove_range(db, range->owner, range->start, range->count) == 1; -+ break; -+ default: -+ return false; -+ } -+ -+ ret = remove_range(db, range->owner, range->start, range->count) == 1; -+ -+ if (id_type == ID_TYPE_UID) { -+ sub_uid_close(); -+ sub_uid_unlock(); -+ } else { -+ sub_gid_close(); -+ sub_gid_unlock(); -+ } -+ -+ return ret; - } - - #else /* !ENABLE_SUBIDS */ -diff --git a/lib/subordinateio.h b/lib/subordinateio.h -index 13a21341..e4be482c 100644 ---- a/lib/subordinateio.h -+++ b/lib/subordinateio.h -@@ -25,11 +25,11 @@ extern int sub_uid_unlock (void); - extern int sub_uid_add (const char *owner, uid_t start, unsigned long count); - extern int sub_uid_remove (const char *owner, uid_t start, unsigned long count); - extern uid_t sub_uid_find_free_range(uid_t min, uid_t max, unsigned long count); --extern struct subordinate_range **list_owner_ranges(const char *owner, enum subid_type id_type); -+extern int list_owner_ranges(const char *owner, enum subid_type id_type, struct subordinate_range ***ranges); - extern bool new_subid_range(struct subordinate_range *range, enum subid_type id_type, bool reuse); - extern bool release_subid_range(struct subordinate_range *range, enum subid_type id_type); --extern int find_subid_owners(unsigned long id, uid_t **uids, enum subid_type id_type); --extern void free_subordinate_ranges(struct subordinate_range **ranges); -+extern int find_subid_owners(unsigned long id, enum subid_type id_type, uid_t **uids); -+extern void free_subordinate_ranges(struct subordinate_range **ranges, int count); - - extern int sub_gid_close(void); - extern bool have_sub_gids(const char *owner, gid_t start, unsigned long count); -diff --git a/libmisc/idmapping.h b/libmisc/idmapping.h -index 3f32db68..1a8efe68 100644 ---- a/libmisc/idmapping.h -+++ b/libmisc/idmapping.h -@@ -40,5 +40,7 @@ extern struct map_range *get_map_ranges(int ranges, int argc, char **argv); - extern void write_mapping(int proc_dir_fd, int ranges, - struct map_range *mappings, const char *map_file, uid_t ruid); - -+extern void nss_init(char *nsswitch_path); -+ - #endif /* _ID_MAPPING_H_ */ - -diff --git a/libsubid/Makefile.am b/libsubid/Makefile.am -index f24dbb94..f543b5eb 100644 ---- a/libsubid/Makefile.am -+++ b/libsubid/Makefile.am -@@ -19,7 +19,7 @@ MISCLIBS = \ - libsubid_la_LIBADD = \ - $(top_srcdir)/lib/libshadow.la \ - $(top_srcdir)/libmisc/libmisc.la \ -- $(MISCLIBS) -+ $(MISCLIBS) -ldl - - AM_CPPFLAGS = \ - -I${top_srcdir}/lib \ -diff --git a/libsubid/api.c b/libsubid/api.c -index 91d73bed..737e1c8b 100644 ---- a/libsubid/api.c -+++ b/libsubid/api.c -@@ -38,132 +38,48 @@ - #include "idmapping.h" - #include "api.h" - --static struct subordinate_range **get_subid_ranges(const char *owner, enum subid_type id_type) -+static -+int get_subid_ranges(const char *owner, enum subid_type id_type, struct subordinate_range ***ranges) - { -- struct subordinate_range **ranges = NULL; -- -- switch (id_type) { -- case ID_TYPE_UID: -- if (!sub_uid_open(O_RDONLY)) { -- return NULL; -- } -- break; -- case ID_TYPE_GID: -- if (!sub_gid_open(O_RDONLY)) { -- return NULL; -- } -- break; -- default: -- return NULL; -- } -- -- ranges = list_owner_ranges(owner, id_type); -- -- if (id_type == ID_TYPE_UID) -- sub_uid_close(); -- else -- sub_gid_close(); -- -- return ranges; -+ return list_owner_ranges(owner, id_type, ranges); - } - --struct subordinate_range **get_subuid_ranges(const char *owner) -+int get_subuid_ranges(const char *owner, struct subordinate_range ***ranges) - { -- return get_subid_ranges(owner, ID_TYPE_UID); -+ return get_subid_ranges(owner, ID_TYPE_UID, ranges); - } - --struct subordinate_range **get_subgid_ranges(const char *owner) -+int get_subgid_ranges(const char *owner, struct subordinate_range ***ranges) - { -- return get_subid_ranges(owner, ID_TYPE_GID); -+ return get_subid_ranges(owner, ID_TYPE_GID, ranges); - } - --void subid_free_ranges(struct subordinate_range **ranges) -+void subid_free_ranges(struct subordinate_range **ranges, int count) - { -- return free_subordinate_ranges(ranges); -+ return free_subordinate_ranges(ranges, count); - } - --int get_subid_owner(unsigned long id, uid_t **owner, enum subid_type id_type) -+static -+int get_subid_owner(unsigned long id, enum subid_type id_type, uid_t **owner) - { -- int ret = -1; -- -- switch (id_type) { -- case ID_TYPE_UID: -- if (!sub_uid_open(O_RDONLY)) { -- return -1; -- } -- break; -- case ID_TYPE_GID: -- if (!sub_gid_open(O_RDONLY)) { -- return -1; -- } -- break; -- default: -- return -1; -- } -- -- ret = find_subid_owners(id, owner, id_type); -- -- if (id_type == ID_TYPE_UID) -- sub_uid_close(); -- else -- sub_gid_close(); -- -- return ret; -+ return find_subid_owners(id, id_type, owner); - } - - int get_subuid_owners(uid_t uid, uid_t **owner) - { -- return get_subid_owner((unsigned long)uid, owner, ID_TYPE_UID); -+ return get_subid_owner((unsigned long)uid, ID_TYPE_UID, owner); - } - - int get_subgid_owners(gid_t gid, uid_t **owner) - { -- return get_subid_owner((unsigned long)gid, owner, ID_TYPE_GID); -+ return get_subid_owner((unsigned long)gid, ID_TYPE_GID, owner); - } - -+static - bool grant_subid_range(struct subordinate_range *range, bool reuse, - enum subid_type id_type) - { -- bool ret; -- -- switch (id_type) { -- case ID_TYPE_UID: -- if (!sub_uid_lock()) { -- printf("Failed loging subuids (errno %d)\n", errno); -- return false; -- } -- if (!sub_uid_open(O_CREAT | O_RDWR)) { -- printf("Failed opening subuids (errno %d)\n", errno); -- sub_uid_unlock(); -- return false; -- } -- break; -- case ID_TYPE_GID: -- if (!sub_gid_lock()) { -- printf("Failed loging subgids (errno %d)\n", errno); -- return false; -- } -- if (!sub_gid_open(O_CREAT | O_RDWR)) { -- printf("Failed opening subgids (errno %d)\n", errno); -- sub_gid_unlock(); -- return false; -- } -- break; -- default: -- return false; -- } -- -- ret = new_subid_range(range, id_type, reuse); -- -- if (id_type == ID_TYPE_UID) { -- sub_uid_close(); -- sub_uid_unlock(); -- } else { -- sub_gid_close(); -- sub_gid_unlock(); -- } -- -- return ret; -+ return new_subid_range(range, id_type, reuse); - } - - bool grant_subuid_range(struct subordinate_range *range, bool reuse) -@@ -176,56 +92,18 @@ bool grant_subgid_range(struct subordinate_range *range, bool reuse) - return grant_subid_range(range, reuse, ID_TYPE_GID); - } - --bool free_subid_range(struct subordinate_range *range, enum subid_type id_type) -+static -+bool ungrant_subid_range(struct subordinate_range *range, enum subid_type id_type) - { -- bool ret; -- -- switch (id_type) { -- case ID_TYPE_UID: -- if (!sub_uid_lock()) { -- printf("Failed loging subuids (errno %d)\n", errno); -- return false; -- } -- if (!sub_uid_open(O_CREAT | O_RDWR)) { -- printf("Failed opening subuids (errno %d)\n", errno); -- sub_uid_unlock(); -- return false; -- } -- break; -- case ID_TYPE_GID: -- if (!sub_gid_lock()) { -- printf("Failed loging subgids (errno %d)\n", errno); -- return false; -- } -- if (!sub_gid_open(O_CREAT | O_RDWR)) { -- printf("Failed opening subgids (errno %d)\n", errno); -- sub_gid_unlock(); -- return false; -- } -- break; -- default: -- return false; -- } -- -- ret = release_subid_range(range, id_type); -- -- if (id_type == ID_TYPE_UID) { -- sub_uid_close(); -- sub_uid_unlock(); -- } else { -- sub_gid_close(); -- sub_gid_unlock(); -- } -- -- return ret; -+ return release_subid_range(range, id_type); - } - --bool free_subuid_range(struct subordinate_range *range) -+bool ungrant_subuid_range(struct subordinate_range *range) - { -- return free_subid_range(range, ID_TYPE_UID); -+ return ungrant_subid_range(range, ID_TYPE_UID); - } - --bool free_subgid_range(struct subordinate_range *range) -+bool ungrant_subgid_range(struct subordinate_range *range) - { -- return free_subid_range(range, ID_TYPE_GID); -+ return ungrant_subid_range(range, ID_TYPE_GID); - } -diff --git a/libsubid/api.h b/libsubid/api.h -index fbdf0f9e..97b04e25 100644 ---- a/libsubid/api.h -+++ b/libsubid/api.h -@@ -1,9 +1,9 @@ - #include "subid.h" - #include - --struct subordinate_range **get_subuid_ranges(const char *owner); --struct subordinate_range **get_subgid_ranges(const char *owner); --void subid_free_ranges(struct subordinate_range **ranges); -+int get_subuid_ranges(const char *owner, struct subordinate_range ***ranges); -+int get_subgid_ranges(const char *owner, struct subordinate_range ***ranges); -+void subid_free_ranges(struct subordinate_range **ranges, int count); - - int get_subuid_owners(uid_t uid, uid_t **owner); - int get_subgid_owners(gid_t gid, uid_t **owner); -@@ -13,5 +13,5 @@ int get_subgid_owners(gid_t gid, uid_t **owner); - bool grant_subuid_range(struct subordinate_range *range, bool reuse); - bool grant_subgid_range(struct subordinate_range *range, bool reuse); - --bool free_subuid_range(struct subordinate_range *range); --bool free_subgid_range(struct subordinate_range *range); -+bool ungrant_subuid_range(struct subordinate_range *range); -+bool ungrant_subgid_range(struct subordinate_range *range); -diff --git a/libsubid/subid.h b/libsubid/subid.h -index ba9a2f6f..2f27ad8a 100644 ---- a/libsubid/subid.h -+++ b/libsubid/subid.h -@@ -1,4 +1,5 @@ - #include -+#include - - #ifndef SUBID_RANGE_DEFINED - #define SUBID_RANGE_DEFINED 1 -@@ -13,5 +14,12 @@ enum subid_type { - ID_TYPE_GID = 2 - }; - -+enum subid_status { -+ SUBID_STATUS_SUCCESS = 0, -+ SUBID_STATUS_UNKNOWN_USER = 1, -+ SUBID_STATUS_ERROR_CONN = 2, -+ SUBID_STATUS_ERROR = 3, -+}; -+ - #define SUBID_NFIELDS 3 - #endif -diff --git a/src/Makefile.am b/src/Makefile.am -index e9d354fd..35027013 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -111,15 +111,6 @@ grpck_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) - grpconv_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) - grpunconv_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) - lastlog_LDADD = $(LDADD) $(LIBAUDIT) $(LIBECONF) --newuidmap_SOURCES = newuidmap.c ../libmisc/nss.c --newgidmap_SOURCES = newgidmap.c ../libmisc/nss.c --groupadd_SOURCES = groupadd.c ../libmisc/nss.c --groupmod_SOURCES = groupmod.c ../libmisc/nss.c --groupdel_SOURCES = groupdel.c ../libmisc/nss.c --newusers_SOURCES = newusers.c ../libmisc/nss.c --useradd_SOURCES = useradd.c ../libmisc/nss.c --usermod_SOURCES = usermod.c ../libmisc/nss.c --userdel_SOURCES = userdel.c ../libmisc/nss.c - login_SOURCES = \ - login.c \ - login_nopam.c -@@ -169,7 +160,8 @@ endif - noinst_PROGRAMS += list_subid_ranges \ - get_subid_owners \ - new_subid_range \ -- free_subid_range -+ free_subid_range \ -+ check_subid_range - - MISCLIBS = \ - $(LIBAUDIT) \ -@@ -186,7 +178,7 @@ list_subid_ranges_LDADD = \ - $(top_builddir)/lib/libshadow.la \ - $(top_builddir)/libmisc/libmisc.la \ - $(top_builddir)/libsubid/libsubid.la \ -- $(MISCLIBS) -+ $(MISCLIBS) -ldl - - list_subid_ranges_CPPFLAGS = \ - -I$(top_srcdir)/lib \ -@@ -197,7 +189,7 @@ get_subid_owners_LDADD = \ - $(top_builddir)/lib/libshadow.la \ - $(top_builddir)/libmisc/libmisc.la \ - $(top_builddir)/libsubid/libsubid.la \ -- $(MISCLIBS) -+ $(MISCLIBS) -ldl - - get_subid_owners_CPPFLAGS = \ - -I$(top_srcdir)/lib \ -@@ -213,7 +205,7 @@ new_subid_range_LDADD = \ - $(top_builddir)/lib/libshadow.la \ - $(top_builddir)/libmisc/libmisc.la \ - $(top_builddir)/libsubid/libsubid.la \ -- $(MISCLIBS) -+ $(MISCLIBS) -ldl - - free_subid_range_CPPFLAGS = \ - -I$(top_srcdir)/lib \ -@@ -224,5 +216,14 @@ free_subid_range_LDADD = \ - $(top_builddir)/lib/libshadow.la \ - $(top_builddir)/libmisc/libmisc.la \ - $(top_builddir)/libsubid/libsubid.la \ -- $(MISCLIBS) -+ $(MISCLIBS) -ldl -+ -+check_subid_range_CPPFLAGS = \ -+ -I$(top_srcdir)/lib \ -+ -I$(top_srcdir)/libmisc -+ -+check_subid_range_LDADD = \ -+ $(top_builddir)/lib/libshadow.la \ -+ $(top_builddir)/libmisc/libmisc.la \ -+ $(MISCLIBS) -ldl - endif -diff --git a/src/check_subid_range.c b/src/check_subid_range.c -new file mode 100644 -index 00000000..fb1c2cfc ---- /dev/null -+++ b/src/check_subid_range.c -@@ -0,0 +1,48 @@ -+// This program is for testing purposes only. -+// usage is "[program] owner [u|g] start count -+// Exits 0 if owner has subid range starting start, of size count -+// Exits 1 otherwise. -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "defines.h" -+#include "prototypes.h" -+#include "subordinateio.h" -+#include "idmapping.h" -+ -+const char *Prog; -+ -+int main(int argc, char **argv) -+{ -+ char *owner; -+ unsigned long start, count; -+ bool check_uids; -+ Prog = Basename (argv[0]); -+ -+ if (argc != 5) -+ exit(1); -+ -+ owner = argv[1]; -+ check_uids = argv[2][0] == 'u'; -+ start = strtoul(argv[3], NULL, 10); -+ if (start == ULONG_MAX && errno == ERANGE) -+ exit(1); -+ count = strtoul(argv[4], NULL, 10); -+ if (count == ULONG_MAX && errno == ERANGE) -+ exit(1); -+ if (check_uids) { -+ if (have_sub_uids(owner, start, count)) -+ exit(0); -+ exit(1); -+ } -+ if (have_sub_gids(owner, start, count)) -+ exit(0); -+ exit(1); -+} -diff --git a/src/free_subid_range.c b/src/free_subid_range.c -index 36858875..de6bc58f 100644 ---- a/src/free_subid_range.c -+++ b/src/free_subid_range.c -@@ -37,9 +37,9 @@ int main(int argc, char *argv[]) - range.start = atoi(argv[1]); - range.count = atoi(argv[2]); - if (group) -- ok = free_subgid_range(&range); -+ ok = ungrant_subgid_range(&range); - else -- ok = free_subuid_range(&range); -+ ok = ungrant_subuid_range(&range); - - if (!ok) { - fprintf(stderr, "Failed freeing id range\n"); -diff --git a/src/list_subid_ranges.c b/src/list_subid_ranges.c -index cdba610e..440ef911 100644 ---- a/src/list_subid_ranges.c -+++ b/src/list_subid_ranges.c -@@ -15,7 +15,7 @@ void usage(void) - - int main(int argc, char *argv[]) - { -- int i; -+ int i, count=0; - struct subordinate_range **ranges; - - Prog = Basename (argv[0]); -@@ -23,19 +23,19 @@ int main(int argc, char *argv[]) - usage(); - } - if (argc == 3 && strcmp(argv[1], "-g") == 0) -- ranges = get_subgid_ranges(argv[2]); -+ count = get_subgid_ranges(argv[2], &ranges); - else if (argc == 2 && strcmp(argv[1], "-h") == 0) - usage(); - else -- ranges = get_subuid_ranges(argv[1]); -+ count = get_subuid_ranges(argv[1], &ranges); - if (!ranges) { - fprintf(stderr, "Error fetching ranges\n"); - exit(1); - } -- for (i = 0; ranges[i]; i++) { -+ for (i = 0; i < count; i++) { - printf("%d: %s %lu %lu\n", i, ranges[i]->owner, - ranges[i]->start, ranges[i]->count); - } -- subid_free_ranges(ranges); -+ subid_free_ranges(ranges, count); - return 0; - } -diff --git a/tests/libsubid/04_nss/Makefile b/tests/libsubid/04_nss/Makefile -new file mode 100644 -index 00000000..6cd3225f ---- /dev/null -+++ b/tests/libsubid/04_nss/Makefile -@@ -0,0 +1,12 @@ -+all: test_nss libsubid_zzz.so -+ -+test_nss: test_nss.c ../../../lib/nss.c -+ gcc -c -I../../../lib/ -I../../.. -o test_nss.o test_nss.c -+ gcc -o test_nss test_nss.o ../../../libmisc/.libs/libmisc.a ../../../lib/.libs/libshadow.a -ldl -+ -+libsubid_zzz.so: libsubid_zzz.c -+ gcc -c -I../../../lib/ -I../../.. -I../../../libmisc -I../../../libsubid libsubid_zzz.c -+ gcc -L../../../libsubid -shared -o libsubid_zzz.so libsubid_zzz.o ../../../lib/.libs/libshadow.a -ldl -+ -+clean: -+ rm -f *.o *.so test_nss -diff --git a/tests/libsubid/04_nss/empty b/tests/libsubid/04_nss/empty -new file mode 100644 -index 00000000..e69de29b -diff --git a/tests/libsubid/04_nss/libsubid_zzz.c b/tests/libsubid/04_nss/libsubid_zzz.c -new file mode 100644 -index 00000000..b56a4bae ---- /dev/null -+++ b/tests/libsubid/04_nss/libsubid_zzz.c -@@ -0,0 +1,146 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+enum subid_status shadow_subid_has_any_range(const char *owner, enum subid_type t, bool *result) -+{ -+ if (strcmp(owner, "ubuntu") == 0) { -+ *result = true; -+ return SUBID_STATUS_SUCCESS; -+ } -+ if (strcmp(owner, "error") == 0) { -+ *result = false; -+ return SUBID_STATUS_ERROR; -+ } -+ if (strcmp(owner, "unknown") == 0) { -+ *result = false; -+ return SUBID_STATUS_UNKNOWN_USER; -+ } -+ if (strcmp(owner, "conn") == 0) { -+ *result = false; -+ return SUBID_STATUS_ERROR_CONN; -+ } -+ if (t == ID_TYPE_UID) { -+ *result = strcmp(owner, "user1") == 0; -+ return SUBID_STATUS_SUCCESS; -+ } -+ -+ *result = strcmp(owner, "group1") == 0; -+ return SUBID_STATUS_SUCCESS; -+} -+ -+enum subid_status shadow_subid_has_range(const char *owner, unsigned long start, unsigned long count, enum subid_type t, bool *result) -+{ -+ if (strcmp(owner, "ubuntu") == 0 && -+ start >= 200000 && -+ count <= 100000) { -+ *result = true; -+ return SUBID_STATUS_SUCCESS; -+ } -+ *result = false; -+ if (strcmp(owner, "error") == 0) -+ return SUBID_STATUS_ERROR; -+ if (strcmp(owner, "unknown") == 0) -+ return SUBID_STATUS_UNKNOWN_USER; -+ if (strcmp(owner, "conn") == 0) -+ return SUBID_STATUS_ERROR_CONN; -+ -+ if (t == ID_TYPE_UID && strcmp(owner, "user1") != 0) -+ return SUBID_STATUS_SUCCESS; -+ if (t == ID_TYPE_GID && strcmp(owner, "group1") != 0) -+ return SUBID_STATUS_SUCCESS; -+ -+ if (start < 100000) -+ return SUBID_STATUS_SUCCESS; -+ if (count >= 65536) -+ return SUBID_STATUS_SUCCESS; -+ *result = true; -+ return SUBID_STATUS_SUCCESS; -+} -+ -+// So if 'user1' or 'ubuntu' is defined in passwd, we'll return those values, -+// to ease manual testing. For automated testing, if you return those values, -+// we'll return 1000 for ubuntu and 1001 otherwise. -+static uid_t getnamuid(const char *name) { -+ struct passwd *pw; -+ -+ pw = getpwnam(name); -+ if (pw) -+ return pw->pw_uid; -+ -+ // For testing purposes -+ return strcmp(name, "ubuntu") == 0 ? (uid_t)1000 : (uid_t)1001; -+} -+ -+static int alloc_uid(uid_t **uids, uid_t id) { -+ *uids = malloc(sizeof(uid_t)); -+ if (!*uids) -+ return -1; -+ *uids[0] = id; -+ return 1; -+} -+ -+enum subid_status shadow_subid_find_subid_owners(unsigned long id, enum subid_type id_type, uid_t **uids, int *count) -+{ -+ if (id >= 100000 && id < 165536) { -+ *count = alloc_uid(uids, getnamuid("user1")); -+ if (*count == 1) -+ return SUBID_STATUS_SUCCESS; -+ return SUBID_STATUS_ERROR; // out of memory -+ } -+ if (id >= 200000 && id < 300000) { -+ *count = alloc_uid(uids, getnamuid("ubuntu")); -+ if (*count == 1) -+ return SUBID_STATUS_SUCCESS; -+ return SUBID_STATUS_ERROR; // out of memory -+ } -+ *count = 0; // nothing found -+ return SUBID_STATUS_SUCCESS; -+} -+ -+enum subid_status shadow_subid_list_owner_ranges(const char *owner, enum subid_type id_type, struct subordinate_range ***in_ranges, int *count) -+{ -+ struct subordinate_range **ranges; -+ -+ *count = 0; -+ if (strcmp(owner, "error") == 0) -+ return SUBID_STATUS_ERROR; -+ if (strcmp(owner, "unknown") == 0) -+ return SUBID_STATUS_UNKNOWN_USER; -+ if (strcmp(owner, "conn") == 0) -+ return SUBID_STATUS_ERROR_CONN; -+ -+ *ranges = NULL; -+ if (strcmp(owner, "user1") != 0 && strcmp(owner, "ubuntu") != 0 && -+ strcmp(owner, "group1") != 0) -+ return SUBID_STATUS_SUCCESS; -+ if (id_type == ID_TYPE_GID && strcmp(owner, "user1") == 0) -+ return SUBID_STATUS_SUCCESS; -+ if (id_type == ID_TYPE_UID && strcmp(owner, "group1") == 0) -+ return SUBID_STATUS_SUCCESS; -+ ranges = (struct subordinate_range **)malloc(sizeof(struct subordinate_range *)); -+ if (!*ranges) -+ return SUBID_STATUS_ERROR; -+ ranges[0] = (struct subordinate_range *)malloc(sizeof(struct subordinate_range)); -+ if (!ranges[0]) { -+ free(*ranges); -+ *ranges = NULL; -+ return SUBID_STATUS_ERROR; -+ } -+ ranges[0]->owner = strdup(owner); -+ if (strcmp(owner, "user1") == 0 || strcmp(owner, "group1") == 0) { -+ ranges[0]->start = 100000; -+ ranges[0]->count = 65536; -+ } else { -+ ranges[0]->start = 200000; -+ ranges[0]->count = 100000; -+ } -+ -+ *count = 1; -+ *in_ranges = ranges; -+ -+ return SUBID_STATUS_SUCCESS; -+} -diff --git a/tests/libsubid/04_nss/nsswitch1.conf b/tests/libsubid/04_nss/nsswitch1.conf -new file mode 100644 -index 00000000..43764a39 ---- /dev/null -+++ b/tests/libsubid/04_nss/nsswitch1.conf -@@ -0,0 +1,20 @@ -+# /etc/nsswitch.conf -+# -+# Example configuration of GNU Name Service Switch functionality. -+# If you have the `glibc-doc-reference' and `info' packages installed, try: -+# `info libc "Name Service Switch"' for information about this file. -+ -+passwd: files systemd -+group: files systemd -+shadow: files -+gshadow: files -+ -+hosts: files mdns4_minimal [NOTFOUND=return] dns -+networks: files -+ -+protocols: db files -+services: db files -+ethers: db files -+rpc: db files -+ -+netgroup: nis -diff --git a/tests/libsubid/04_nss/nsswitch2.conf b/tests/libsubid/04_nss/nsswitch2.conf -new file mode 100644 -index 00000000..d371a36c ---- /dev/null -+++ b/tests/libsubid/04_nss/nsswitch2.conf -@@ -0,0 +1,22 @@ -+# /etc/nsswitch.conf -+# -+# Example configuration of GNU Name Service Switch functionality. -+# If you have the `glibc-doc-reference' and `info' packages installed, try: -+# `info libc "Name Service Switch"' for information about this file. -+ -+passwd: files systemd -+group: files systemd -+shadow: files -+gshadow: files -+ -+hosts: files mdns4_minimal [NOTFOUND=return] dns -+networks: files -+ -+protocols: db files -+services: db files -+ethers: db files -+rpc: db files -+ -+netgroup: nis -+ -+subid: files -diff --git a/tests/libsubid/04_nss/nsswitch3.conf b/tests/libsubid/04_nss/nsswitch3.conf -new file mode 100644 -index 00000000..19f2d934 ---- /dev/null -+++ b/tests/libsubid/04_nss/nsswitch3.conf -@@ -0,0 +1,22 @@ -+# /etc/nsswitch.conf -+# -+# Example configuration of GNU Name Service Switch functionality. -+# If you have the `glibc-doc-reference' and `info' packages installed, try: -+# `info libc "Name Service Switch"' for information about this file. -+ -+passwd: files systemd -+group: files systemd -+shadow: files -+gshadow: files -+ -+hosts: files mdns4_minimal [NOTFOUND=return] dns -+networks: files -+ -+protocols: db files -+services: db files -+ethers: db files -+rpc: db files -+ -+netgroup: nis -+ -+subid: zzz -diff --git a/tests/libsubid/04_nss/subidnss.test b/tests/libsubid/04_nss/subidnss.test -new file mode 100755 -index 00000000..3d40dc8c ---- /dev/null -+++ b/tests/libsubid/04_nss/subidnss.test -@@ -0,0 +1,22 @@ -+#!/bin/sh -+ -+set -e -+ -+cd $(dirname $0) -+ -+. ../../common/config.sh -+. ../../common/log.sh -+ -+make -+ -+export LD_LIBRARY_PATH=.:../../../lib/.libs:$LD_LIBRARY_PATH -+ -+./test_nss 1 -+./test_nss 2 -+./test_nss 3 -+ -+unshare -Urm ./test_range -+ -+log_status "$0" "SUCCESS" -+ -+trap '' 0 -diff --git a/tests/libsubid/04_nss/test_nss.c b/tests/libsubid/04_nss/test_nss.c -new file mode 100644 -index 00000000..5d903ab4 ---- /dev/null -+++ b/tests/libsubid/04_nss/test_nss.c -@@ -0,0 +1,72 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+extern bool nss_is_initialized(); -+extern struct subid_nss_ops *get_subid_nss_handle(); -+ -+void test1() { -+ // nsswitch1 has no subid: entry -+ setenv("LD_LIBRARY_PATH", ".", 1); -+ printf("Test with no subid entry\n"); -+ nss_init("./nsswitch1.conf"); -+ if (!nss_is_initialized() || get_subid_nss_handle()) -+ exit(1); -+ // second run should change nothing -+ printf("Test with no subid entry, second run\n"); -+ nss_init("./nsswitch1.conf"); -+ if (!nss_is_initialized() || get_subid_nss_handle()) -+ exit(1); -+} -+ -+void test2() { -+ // nsswitch2 has a subid: files entry -+ printf("test with 'files' subid entry\n"); -+ nss_init("./nsswitch2.conf"); -+ if (!nss_is_initialized() || get_subid_nss_handle()) -+ exit(1); -+ // second run should change nothing -+ printf("test with 'files' subid entry, second run\n"); -+ nss_init("./nsswitch2.conf"); -+ if (!nss_is_initialized() || get_subid_nss_handle()) -+ exit(1); -+} -+ -+void test3() { -+ // nsswitch3 has a subid: testnss entry -+ printf("test with 'test' subid entry\n"); -+ nss_init("./nsswitch3.conf"); -+ if (!nss_is_initialized() || !get_subid_nss_handle()) -+ exit(1); -+ // second run should change nothing -+ printf("test with 'test' subid entry, second run\n"); -+ nss_init("./nsswitch3.conf"); -+ if (!nss_is_initialized() || !get_subid_nss_handle()) -+ exit(1); -+} -+ -+const char *Prog; -+ -+int main(int argc, char *argv[]) -+{ -+ int which; -+ -+ Prog = Basename(argv[0]); -+ -+ if (argc < 1) -+ exit(1); -+ -+ which = atoi(argv[1]); -+ switch(which) { -+ case 1: test1(); break; -+ case 2: test2(); break; -+ case 3: test3(); break; -+ default: exit(1); -+ } -+ -+ printf("nss parsing tests done\n"); -+ exit(0); -+} -diff --git a/tests/libsubid/04_nss/test_range b/tests/libsubid/04_nss/test_range -new file mode 100755 -index 00000000..356764fb ---- /dev/null -+++ b/tests/libsubid/04_nss/test_range -@@ -0,0 +1,50 @@ -+#!/bin/sh -+ -+set -x -+ -+echo "starting check_range tests" -+ -+export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH -+mount --bind ./nsswitch3.conf /etc/nsswitch.conf -+cleanup1() { -+ umount /etc/nsswitch.conf -+} -+trap cleanup1 EXIT HUP INT TERM -+../../../src/check_subid_range user1 u 100000 65535 -+if [ $? -ne 0 ]; then -+ exit 1 -+fi -+../../../src/check_subid_range user2 u 100000 65535 -+if [ $? -eq 0 ]; then -+ exit 1 -+fi -+../../../src/check_subid_range unknown u 100000 65535 -+if [ $? -eq 0 ]; then -+ exit 1 -+fi -+../../../src/check_subid_range error u 100000 65535 -+if [ $? -eq 0 ]; then -+ exit 1 -+fi -+../../../src/check_subid_range user1 u 1000 65535 -+if [ $? -eq 0 ]; then -+ exit 1 -+fi -+ -+umount /etc/nsswitch.conf -+ -+mount --bind ./nsswitch1.conf /etc/nsswitch.conf -+mount --bind ./empty /etc/subuid -+ -+cleanup2() { -+ umount /etc/subuid -+ umount /etc/nsswitch.conf -+} -+trap cleanup2 EXIT HUP INT TERM -+../../../src/check_subid_range user1 u 100000 65535 -+if [ $? -eq 0 ]; then -+ exit 1 -+fi -+ -+echo "check_range tests complete" -+exit 0 -diff --git a/tests/run_some b/tests/run_some -index 15b4816a..e6f6eb5a 100755 ---- a/tests/run_some -+++ b/tests/run_some -@@ -127,6 +127,7 @@ run_test ./newuidmap/01_newuidmap/newuidmap.test - run_test ./libsubid/01_list_ranges/list_ranges.test - run_test ./libsubid/02_get_subid_owners/get_subid_owners.test - run_test ./libsubid/03_add_remove/add_remove_subids.test -+run_test ./libsubid/04_nss/subidnss.test - - echo - echo "$succeeded test(s) passed" --- -2.30.2 - - -From 0f4347d1483191b2142546416a9eefe0c9459600 Mon Sep 17 00:00:00 2001 -From: Serge Hallyn -Date: Thu, 15 Apr 2021 09:52:29 -0500 -Subject: [PATCH 3/6] clean up libsubid headers - -Move libsubid/api.h into libsubid/subid.h, and document the api in subid.h - -Signed-off-by: Serge Hallyn ---- - libsubid/api.c | 2 +- - libsubid/api.h | 17 ------- - libsubid/subid.h | 105 ++++++++++++++++++++++++++++++++++++++++ - src/free_subid_range.c | 2 +- - src/get_subid_owners.c | 2 +- - src/list_subid_ranges.c | 2 +- - src/new_subid_range.c | 2 +- - 7 files changed, 110 insertions(+), 22 deletions(-) - delete mode 100644 libsubid/api.h - -diff --git a/libsubid/api.c b/libsubid/api.c -index 737e1c8b..a1b5bb3f 100644 ---- a/libsubid/api.c -+++ b/libsubid/api.c -@@ -36,7 +36,7 @@ - #include - #include "subordinateio.h" - #include "idmapping.h" --#include "api.h" -+#include "subid.h" - - static - int get_subid_ranges(const char *owner, enum subid_type id_type, struct subordinate_range ***ranges) -diff --git a/libsubid/api.h b/libsubid/api.h -deleted file mode 100644 -index 97b04e25..00000000 ---- a/libsubid/api.h -+++ /dev/null -@@ -1,17 +0,0 @@ --#include "subid.h" --#include -- --int get_subuid_ranges(const char *owner, struct subordinate_range ***ranges); --int get_subgid_ranges(const char *owner, struct subordinate_range ***ranges); --void subid_free_ranges(struct subordinate_range **ranges, int count); -- --int get_subuid_owners(uid_t uid, uid_t **owner); --int get_subgid_owners(gid_t gid, uid_t **owner); -- --/* range should be pre-allocated with owner and count filled in, start is -- * ignored, can be 0 */ --bool grant_subuid_range(struct subordinate_range *range, bool reuse); --bool grant_subgid_range(struct subordinate_range *range, bool reuse); -- --bool ungrant_subuid_range(struct subordinate_range *range); --bool ungrant_subgid_range(struct subordinate_range *range); -diff --git a/libsubid/subid.h b/libsubid/subid.h -index 2f27ad8a..769463f6 100644 ---- a/libsubid/subid.h -+++ b/libsubid/subid.h -@@ -21,5 +21,110 @@ enum subid_status { - SUBID_STATUS_ERROR = 3, - }; - -+/* -+ * get_subuid_ranges: return a list of UID ranges for a user -+ * -+ * @owner: username being queried -+ * @ranges: a pointer to a subordinate range ** in which the result will be -+ * returned. -+ * -+ * returns: number of ranges found, ir < 0 on error. -+ */ -+int get_subuid_ranges(const char *owner, struct subordinate_range ***ranges); -+ -+/* -+ * get_subgid_ranges: return a list of GID ranges for a user -+ * -+ * @owner: username being queried -+ * @ranges: a pointer to a subordinate range ** in which the result will be -+ * returned. -+ * -+ * returns: number of ranges found, ir < 0 on error. -+ */ -+int get_subgid_ranges(const char *owner, struct subordinate_range ***ranges); -+ -+/* -+ * subid_free_ranges: free an array of subordinate_ranges returned by either -+ * get_subuid_ranges() or get_subgid_ranges(). -+ * -+ * @ranges: the ranges to free -+ * @count: the number of ranges in @ranges -+ */ -+void subid_free_ranges(struct subordinate_range **ranges, int count); -+ -+/* -+ * get_subuid_owners: return a list of uids to which the given uid has been -+ * delegated. -+ * -+ * @uid: The subuid being queried -+ * @owners: a pointer to an array of uids into which the results are placed. -+ * The returned array must be freed by the caller. -+ * -+ * Returns the number of uids returned, or < 0 on error. -+ */ -+int get_subuid_owners(uid_t uid, uid_t **owner); -+ -+/* -+ * get_subgid_owners: return a list of uids to which the given gid has been -+ * delegated. -+ * -+ * @uid: The subgid being queried -+ * @owners: a pointer to an array of uids into which the results are placed. -+ * The returned array must be freed by the caller. -+ * -+ * Returns the number of uids returned, or < 0 on error. -+ */ -+int get_subgid_owners(gid_t gid, uid_t **owner); -+ -+/* -+ * grant_subuid_range: assign a subuid range to a user -+ * -+ * @range: pointer to a struct subordinate_range detailing the UID range -+ * to allocate. ->owner must be the username, and ->count must be -+ * filled in. ->start is ignored, and will contain the start -+ * of the newly allocated range, upon success. -+ * -+ * Returns true if the delegation succeeded, false otherwise. If true, -+ * then the range from (range->start, range->start + range->count) will -+ * be delegated to range->owner. -+ */ -+bool grant_subuid_range(struct subordinate_range *range, bool reuse); -+ -+/* -+ * grant_subsid_range: assign a subgid range to a user -+ * -+ * @range: pointer to a struct subordinate_range detailing the GID range -+ * to allocate. ->owner must be the username, and ->count must be -+ * filled in. ->start is ignored, and will contain the start -+ * of the newly allocated range, upon success. -+ * -+ * Returns true if the delegation succeeded, false otherwise. If true, -+ * then the range from (range->start, range->start + range->count) will -+ * be delegated to range->owner. -+ */ -+bool grant_subgid_range(struct subordinate_range *range, bool reuse); -+ -+/* -+ * ungrant_subuid_range: remove a subuid allocation. -+ * -+ * @range: pointer to a struct subordinate_range detailing the UID allocation -+ * to remove. -+ * -+ * Returns true if successful, false if it failed, for instance if the -+ * delegation did not exist. -+ */ -+bool ungrant_subuid_range(struct subordinate_range *range); -+ -+/* -+ * ungrant_subuid_range: remove a subgid allocation. -+ * -+ * @range: pointer to a struct subordinate_range detailing the GID allocation -+ * to remove. -+ * -+ * Returns true if successful, false if it failed, for instance if the -+ * delegation did not exist. -+ */ -+bool ungrant_subgid_range(struct subordinate_range *range); -+ - #define SUBID_NFIELDS 3 - #endif -diff --git a/src/free_subid_range.c b/src/free_subid_range.c -index de6bc58f..3701a262 100644 ---- a/src/free_subid_range.c -+++ b/src/free_subid_range.c -@@ -1,6 +1,6 @@ - #include - #include --#include "api.h" -+#include "subid.h" - #include "stdlib.h" - #include "prototypes.h" - -diff --git a/src/get_subid_owners.c b/src/get_subid_owners.c -index a4385540..409e3fea 100644 ---- a/src/get_subid_owners.c -+++ b/src/get_subid_owners.c -@@ -1,5 +1,5 @@ - #include --#include "api.h" -+#include "subid.h" - #include "stdlib.h" - #include "prototypes.h" - -diff --git a/src/list_subid_ranges.c b/src/list_subid_ranges.c -index 440ef911..21b2c192 100644 ---- a/src/list_subid_ranges.c -+++ b/src/list_subid_ranges.c -@@ -1,5 +1,5 @@ - #include --#include "api.h" -+#include "subid.h" - #include "stdlib.h" - #include "prototypes.h" - -diff --git a/src/new_subid_range.c b/src/new_subid_range.c -index 6d7b033b..dde196b3 100644 ---- a/src/new_subid_range.c -+++ b/src/new_subid_range.c -@@ -1,6 +1,6 @@ - #include - #include --#include "api.h" -+#include "subid.h" - #include "stdlib.h" - #include "prototypes.h" - --- -2.30.2 - diff --git a/shadow-4.8.1-libsubid_simplify_ranges_variable.patch b/shadow-4.8.1-libsubid_simplify_ranges_variable.patch deleted file mode 100644 index 4cd848b..0000000 --- a/shadow-4.8.1-libsubid_simplify_ranges_variable.patch +++ /dev/null @@ -1,264 +0,0 @@ -diff -up shadow-4.8.1/configure.ac.libsubid_simplify_ranges_variable shadow-4.8.1/configure.ac ---- shadow-4.8.1/configure.ac.libsubid_simplify_ranges_variable 2021-05-24 15:02:56.165917066 +0200 -+++ shadow-4.8.1/configure.ac 2021-05-24 15:02:56.184917324 +0200 -@@ -1,6 +1,6 @@ - dnl Process this file with autoconf to produce a configure script. - AC_PREREQ([2.69]) --m4_define([libsubid_abi_major], 2) -+m4_define([libsubid_abi_major], 3) - m4_define([libsubid_abi_minor], 0) - m4_define([libsubid_abi_micro], 0) - m4_define([libsubid_abi], [libsubid_abi_major.libsubid_abi_minor.libsubid_abi_micro]) -diff -up shadow-4.8.1/lib/prototypes.h.libsubid_simplify_ranges_variable shadow-4.8.1/lib/prototypes.h ---- shadow-4.8.1/lib/prototypes.h.libsubid_simplify_ranges_variable 2021-05-24 15:02:56.184917324 +0200 -+++ shadow-4.8.1/lib/prototypes.h 2021-05-24 16:38:57.610619467 +0200 -@@ -309,16 +309,15 @@ struct subid_nss_ops { - * - * @owner - string representing username being queried - * @id_type - subuid or subgid -- * @ranges - pointer to an array of struct subordinate_range pointers, or -- * NULL. The returned array of struct subordinate_range and its -- * members must be freed by the caller. -+ * @ranges - pointer to an array of struct subid_range, or NULL. The -+ * returned array must be freed by the caller. - * @count - pointer to an integer into which the number of returned ranges - * is written. - - * returns success if the module was able to determine an answer, - * else an error status. - */ -- enum subid_status (*list_owner_ranges)(const char *owner, enum subid_type id_type, struct subordinate_range ***ranges, int *count); -+ enum subid_status (*list_owner_ranges)(const char *owner, enum subid_type id_type, struct subid_range **ranges, int *count); - - /* - * nss_find_subid_owners: find uids who own a given subuid or subgid. -diff -up shadow-4.8.1/libsubid/api.c.libsubid_simplify_ranges_variable shadow-4.8.1/libsubid/api.c ---- shadow-4.8.1/libsubid/api.c.libsubid_simplify_ranges_variable 2021-05-24 15:03:01.467989079 +0200 -+++ shadow-4.8.1/libsubid/api.c 2021-05-24 16:42:32.091584531 +0200 -@@ -68,26 +68,21 @@ bool libsubid_init(const char *progname, - } - - static --int get_subid_ranges(const char *owner, enum subid_type id_type, struct subordinate_range ***ranges) -+int get_subid_ranges(const char *owner, enum subid_type id_type, struct subid_range **ranges) - { - return list_owner_ranges(owner, id_type, ranges); - } - --int get_subuid_ranges(const char *owner, struct subordinate_range ***ranges) -+int get_subuid_ranges(const char *owner, struct subid_range **ranges) - { - return get_subid_ranges(owner, ID_TYPE_UID, ranges); - } - --int get_subgid_ranges(const char *owner, struct subordinate_range ***ranges) -+int get_subgid_ranges(const char *owner, struct subid_range **ranges) - { - return get_subid_ranges(owner, ID_TYPE_GID, ranges); - } - --void subid_free_ranges(struct subordinate_range **ranges, int count) --{ -- return free_subordinate_ranges(ranges, count); --} -- - static - int get_subid_owner(unsigned long id, enum subid_type id_type, uid_t **owner) - { -diff -up shadow-4.8.1/libsubid/subid.h.libsubid_simplify_ranges_variable shadow-4.8.1/libsubid/subid.h ---- shadow-4.8.1/libsubid/subid.h.libsubid_simplify_ranges_variable 2021-05-24 15:03:01.468989093 +0200 -+++ shadow-4.8.1/libsubid/subid.h 2021-05-24 16:43:49.697657383 +0200 -@@ -3,6 +3,15 @@ - - #ifndef SUBID_RANGE_DEFINED - #define SUBID_RANGE_DEFINED 1 -+ -+/* subid_range is just a starting point and size of a range */ -+struct subid_range { -+ unsigned long start; -+ unsigned long count; -+}; -+ -+/* subordinage_range is a subid_range plus an owner, representing -+ * a range in /etc/subuid or /etc/subgid */ - struct subordinate_range { - const char *owner; - unsigned long start; -@@ -41,32 +50,27 @@ bool libsubid_init(const char *progname, - * get_subuid_ranges: return a list of UID ranges for a user - * - * @owner: username being queried -- * @ranges: a pointer to a subordinate range ** in which the result will be -- * returned. -+ * @ranges: a pointer to an array of subid_range structs in which the result -+ * will be returned. -+ * -+ * The caller must free(ranges) when done. - * - * returns: number of ranges found, ir < 0 on error. - */ --int get_subuid_ranges(const char *owner, struct subordinate_range ***ranges); -+int get_subuid_ranges(const char *owner, struct subid_range **ranges); - - /* - * get_subgid_ranges: return a list of GID ranges for a user - * - * @owner: username being queried -- * @ranges: a pointer to a subordinate range ** in which the result will be -- * returned. -+ * @ranges: a pointer to an array of subid_range structs in which the result -+ * will be returned. - * -- * returns: number of ranges found, ir < 0 on error. -- */ --int get_subgid_ranges(const char *owner, struct subordinate_range ***ranges); -- --/* -- * subid_free_ranges: free an array of subordinate_ranges returned by either -- * get_subuid_ranges() or get_subgid_ranges(). -+ * The caller must free(ranges) when done. - * -- * @ranges: the ranges to free -- * @count: the number of ranges in @ranges -+ * returns: number of ranges found, ir < 0 on error. - */ --void subid_free_ranges(struct subordinate_range **ranges, int count); -+int get_subgid_ranges(const char *owner, struct subid_range **ranges); - - /* - * get_subuid_owners: return a list of uids to which the given uid has been -diff -up shadow-4.8.1/lib/subordinateio.c.libsubid-simplify shadow-4.8.1/lib/subordinateio.c ---- shadow-4.8.1/lib/subordinateio.c.libsubid-simplify 2021-05-24 17:27:38.721035241 +0200 -+++ shadow-4.8.1/lib/subordinateio.c 2021-05-24 17:28:06.481420946 +0200 -@@ -11,6 +11,7 @@ - #include - #include "commonio.h" - #include "subordinateio.h" -+#include "../libsubid/subid.h" - #include - #include - #include -@@ -308,25 +309,21 @@ static bool have_range(struct commonio_d - return false; - } - --static bool append_range(struct subordinate_range ***ranges, const struct subordinate_range *new, int n) -+static bool append_range(struct subid_range **ranges, const struct subordinate_range *new, int n) - { -- struct subordinate_range *tmp; - if (!*ranges) { -- *ranges = malloc(sizeof(struct subordinate_range *)); -+ *ranges = malloc(sizeof(struct subid_range)); - if (!*ranges) - return false; - } else { -- struct subordinate_range **new; -- new = realloc(*ranges, (n + 1) * (sizeof(struct subordinate_range *))); -- if (!new) -+ struct subid_range *alloced; -+ alloced = realloc(*ranges, (n + 1) * (sizeof(struct subid_range))); -+ if (!alloced) - return false; -- *ranges = new; -+ *ranges = alloced; - } -- (*ranges)[n] = NULL; -- tmp = subordinate_dup(new); -- if (!tmp) -- return false; -- (*ranges)[n] = tmp; -+ (*ranges)[n].start = new->start; -+ (*ranges)[n].count = new->count; - return true; - } - -@@ -785,10 +782,10 @@ gid_t sub_gid_find_free_range(gid_t min, - * - * The caller must free the subordinate range list. - */ --int list_owner_ranges(const char *owner, enum subid_type id_type, struct subordinate_range ***in_ranges) -+int list_owner_ranges(const char *owner, enum subid_type id_type, struct subid_range **in_ranges) - { - // TODO - need to handle owner being either uid or username -- struct subordinate_range **ranges = NULL; -+ struct subid_range *ranges = NULL; - const struct subordinate_range *range; - struct commonio_db *db; - enum subid_status status; -@@ -826,7 +823,7 @@ int list_owner_ranges(const char *owner, - while ((range = commonio_next(db)) != NULL) { - if (0 == strcmp(range->owner, owner)) { - if (!append_range(&ranges, range, count++)) { -- free_subordinate_ranges(ranges, count-1); -+ free(ranges); - ranges = NULL; - count = -1; - goto out; -diff -up shadow-4.8.1/lib/subordinateio.h.libsubid_simplify_ranges_variable shadow-4.8.1/lib/subordinateio.h ---- shadow-4.8.1/lib/subordinateio.h.libsubid_simplify_ranges_variable 2021-05-24 15:03:01.467989079 +0200 -+++ shadow-4.8.1/lib/subordinateio.h 2021-05-24 16:40:56.978269647 +0200 -@@ -25,7 +25,7 @@ extern int sub_uid_unlock (void); - extern int sub_uid_add (const char *owner, uid_t start, unsigned long count); - extern int sub_uid_remove (const char *owner, uid_t start, unsigned long count); - extern uid_t sub_uid_find_free_range(uid_t min, uid_t max, unsigned long count); --extern int list_owner_ranges(const char *owner, enum subid_type id_type, struct subordinate_range ***ranges); -+extern int list_owner_ranges(const char *owner, enum subid_type id_type, struct subid_range **ranges); - extern bool new_subid_range(struct subordinate_range *range, enum subid_type id_type, bool reuse); - extern bool release_subid_range(struct subordinate_range *range, enum subid_type id_type); - extern int find_subid_owners(unsigned long id, enum subid_type id_type, uid_t **uids); -diff -up shadow-4.8.1/src/list_subid_ranges.c.libsubid_simplify_ranges_variable shadow-4.8.1/src/list_subid_ranges.c ---- shadow-4.8.1/src/list_subid_ranges.c.libsubid_simplify_ranges_variable 2021-05-24 15:03:01.468989093 +0200 -+++ shadow-4.8.1/src/list_subid_ranges.c 2021-05-24 16:45:10.884779740 +0200 -@@ -17,27 +17,29 @@ void usage(void) - int main(int argc, char *argv[]) - { - int i, count=0; -- struct subordinate_range **ranges; -+ struct subid_range *ranges; -+ const char *owner; - - Prog = Basename (argv[0]); - shadow_logfd = stderr; -- if (argc < 2) { -+ if (argc < 2) - usage(); -- } -- if (argc == 3 && strcmp(argv[1], "-g") == 0) -- count = get_subgid_ranges(argv[2], &ranges); -- else if (argc == 2 && strcmp(argv[1], "-h") == 0) -+ owner = argv[1]; -+ if (argc == 3 && strcmp(argv[1], "-g") == 0) { -+ owner = argv[2]; -+ count = get_subgid_ranges(owner, &ranges); -+ } else if (argc == 2 && strcmp(argv[1], "-h") == 0) { - usage(); -- else -- count = get_subuid_ranges(argv[1], &ranges); -+ } else { -+ count = get_subuid_ranges(owner, &ranges); -+ } - if (!ranges) { - fprintf(stderr, "Error fetching ranges\n"); - exit(1); - } - for (i = 0; i < count; i++) { -- printf("%d: %s %lu %lu\n", i, ranges[i]->owner, -- ranges[i]->start, ranges[i]->count); -+ printf("%d: %s %lu %lu\n", i, owner, -+ ranges[i].start, ranges[i].count); - } -- subid_free_ranges(ranges, count); - return 0; - } -diff -up shadow-4.8.1/tests/libsubid/04_nss/libsubid_zzz.c.libsubid_simplify_ranges_variable shadow-4.8.1/tests/libsubid/04_nss/libsubid_zzz.c ---- shadow-4.8.1/tests/libsubid/04_nss/libsubid_zzz.c.libsubid_simplify_ranges_variable 2021-05-24 15:02:56.166917079 +0200 -+++ shadow-4.8.1/tests/libsubid/04_nss/libsubid_zzz.c 2021-05-24 15:03:01.469989106 +0200 -@@ -113,7 +113,7 @@ enum subid_status shadow_subid_list_owne - if (strcmp(owner, "conn") == 0) - return SUBID_STATUS_ERROR_CONN; - -- *ranges = NULL; -+ *in_ranges = NULL; - if (strcmp(owner, "user1") != 0 && strcmp(owner, "ubuntu") != 0 && - strcmp(owner, "group1") != 0) - return SUBID_STATUS_SUCCESS; diff --git a/shadow-4.8.1-man-include-lastlog-file-caveat.patch b/shadow-4.8.1-man-include-lastlog-file-caveat.patch deleted file mode 100644 index 7be60c5..0000000 --- a/shadow-4.8.1-man-include-lastlog-file-caveat.patch +++ /dev/null @@ -1,33 +0,0 @@ -From df6ec1d1693c8c80c323b40d6fc82bb549363db3 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Mon, 29 Mar 2021 05:26:28 +0200 -Subject: [PATCH] man: include lastlog file caveat (#313) - -man/lastlog.8.xml: add another point to the caveats section regarding -the handling of the lastlog file by external tools. - -Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=951564 ---- - man/lastlog.8.xml | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/man/lastlog.8.xml b/man/lastlog.8.xml -index fc096c8f..7e68282f 100644 ---- a/man/lastlog.8.xml -+++ b/man/lastlog.8.xml -@@ -233,5 +233,12 @@ - is no entries for users with UID between 170 and 800 lastlog will appear - to hang as it processes entries with UIDs 171-799). - -+ -+ Having high UIDs can create problems when handling the -+ /var/log/lastlog with external tools. Although the -+ actual file is sparse and does not use too much space, certain -+ applications are not designed to identify sparse files by default and may -+ require a specific option to handle them. -+ - - --- -2.30.2 - diff --git a/shadow-4.8.1-man-mention-nss-in-newuidmap.patch b/shadow-4.8.1-man-mention-nss-in-newuidmap.patch deleted file mode 100644 index e26cfa7..0000000 --- a/shadow-4.8.1-man-mention-nss-in-newuidmap.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 186b1b7ac1a68d0fcc618a22da1a99232b420911 Mon Sep 17 00:00:00 2001 -From: Serge Hallyn -Date: Tue, 4 May 2021 14:39:26 -0500 -Subject: [PATCH] manpages: mention NSS in new[ug]idmap manpages - -Closes #328 - -Signed-off-by: Serge Hallyn ---- - man/newgidmap.1.xml | 3 ++- - man/newuidmap.1.xml | 3 ++- - 2 files changed, 4 insertions(+), 2 deletions(-) - -diff --git a/man/newgidmap.1.xml b/man/newgidmap.1.xml -index 71b03e56..76fc1e30 100644 ---- a/man/newgidmap.1.xml -+++ b/man/newgidmap.1.xml -@@ -88,7 +88,8 @@ - DESCRIPTION - - The newgidmap sets /proc/[pid]/gid_map based on its -- command line arguments and the gids allowed in /etc/subgid. -+ command line arguments and the gids allowed (either in /etc/subgid or -+ through the configured NSS subid module). - Note that the root user is not exempted from the requirement for a valid - /etc/subgid entry. - -diff --git a/man/newuidmap.1.xml b/man/newuidmap.1.xml -index a6f1f085..44eca50a 100644 ---- a/man/newuidmap.1.xml -+++ b/man/newuidmap.1.xml -@@ -88,7 +88,8 @@ - DESCRIPTION - - The newuidmap sets /proc/[pid]/uid_map based on its -- command line arguments and the uids allowed in /etc/subuid. -+ command line arguments and the uids allowed (either in /etc/subuid or -+ through the configured NSS subid module). - Note that the root user is not exempted from the requirement for a valid - /etc/subuid entry. - --- -2.30.2 - diff --git a/shadow-4.8.1-man_clarify_subid_delegation.patch b/shadow-4.8.1-man_clarify_subid_delegation.patch deleted file mode 100644 index b7d01b8..0000000 --- a/shadow-4.8.1-man_clarify_subid_delegation.patch +++ /dev/null @@ -1,246 +0,0 @@ -From d5b15f8633d0eabed885cd16feda224ec2d59072 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Mon, 24 May 2021 12:14:43 +0200 -Subject: [PATCH] man: clarify subid delegation - -Clarify that the subid delegation can only come from one source. -Moreover, add an example of what might happen if the subid source is NSS -and useradd is executed. - -Related: https://github.com/shadow-maint/shadow/issues/331 ---- - man/newgidmap.1.xml | 12 +++++++++--- - man/newuidmap.1.xml | 10 ++++++++-- - 2 files changed, 17 insertions(+), 5 deletions(-) - -diff --git a/man/newgidmap.1.xml b/man/newgidmap.1.xml -index 76fc1e30..7aaf34bf 100644 ---- a/man/newgidmap.1.xml -+++ b/man/newgidmap.1.xml -@@ -88,9 +88,15 @@ - DESCRIPTION - - The newgidmap sets /proc/[pid]/gid_map based on its -- command line arguments and the gids allowed (either in /etc/subgid or -- through the configured NSS subid module). -- Note that the root user is not exempted from the requirement for a valid -+ command line arguments and the gids allowed. The subid delegation can come either from files -+ (/etc/subgid) or from the configured NSS subid module. Only one of them -+ can be chosen at a time. So, for example, if the subid source is configured as NSS and -+ groupadd is executed, then the command will fail and the entry will not be -+ created in /etc/subgid. -+ -+ -+ -+ Note that the root group is not exempted from the requirement for a valid - /etc/subgid entry. - - -diff --git a/man/newuidmap.1.xml b/man/newuidmap.1.xml -index 44eca50a..4bc1ef7a 100644 ---- a/man/newuidmap.1.xml -+++ b/man/newuidmap.1.xml -@@ -88,8 +88,14 @@ - DESCRIPTION - - The newuidmap sets /proc/[pid]/uid_map based on its -- command line arguments and the uids allowed (either in /etc/subuid or -- through the configured NSS subid module). -+ command line arguments and the uids allowed. The subid delegation can come either from files -+ (/etc/subuid) or from the configured NSS subid module. Only one of them -+ can be chosen at a time. So, for example, if the subid source is configured as NSS and -+ useradd is executed, then the command will fail and the entry will not be -+ created in /etc/subuid. -+ -+ -+ - Note that the root user is not exempted from the requirement for a valid - /etc/subuid entry. - --- -2.30.2 - -From 68ebbf936038e4e4c8b5105bd3246ef9709b6354 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Mon, 7 Jun 2021 11:50:56 +0200 -Subject: [PATCH 1/2] man: clarify subid delegation behaviour - -Following the discussion https://github.com/shadow-maint/shadow/pull/345 -I have changed the documentation to clarify the behaviour of subid -delegation when any subid source except files is configured. ---- - man/newgidmap.1.xml | 11 +++++------ - man/newuidmap.1.xml | 11 +++++------ - 2 files changed, 10 insertions(+), 12 deletions(-) - -diff --git a/man/newgidmap.1.xml b/man/newgidmap.1.xml -index 7aaf34bf..681aefcb 100644 ---- a/man/newgidmap.1.xml -+++ b/man/newgidmap.1.xml -@@ -87,12 +87,11 @@ - - DESCRIPTION - -- The newgidmap sets /proc/[pid]/gid_map based on its -- command line arguments and the gids allowed. The subid delegation can come either from files -- (/etc/subgid) or from the configured NSS subid module. Only one of them -- can be chosen at a time. So, for example, if the subid source is configured as NSS and -- groupadd is executed, then the command will fail and the entry will not be -- created in /etc/subgid. -+ The newgidmap sets /proc/[pid]/gid_map -+ based on its command line arguments and the gids allowed. Subgid -+ delegation can either be managed via /etc/subgid -+ or through the configured NSS subid module. These options are mutually -+ exclusive. - - - -diff --git a/man/newuidmap.1.xml b/man/newuidmap.1.xml -index 4bc1ef7a..09e65d80 100644 ---- a/man/newuidmap.1.xml -+++ b/man/newuidmap.1.xml -@@ -87,12 +87,11 @@ - - DESCRIPTION - -- The newuidmap sets /proc/[pid]/uid_map based on its -- command line arguments and the uids allowed. The subid delegation can come either from files -- (/etc/subuid) or from the configured NSS subid module. Only one of them -- can be chosen at a time. So, for example, if the subid source is configured as NSS and -- useradd is executed, then the command will fail and the entry will not be -- created in /etc/subuid. -+ The newuidmap sets /proc/[pid]/uid_map -+ based on its command line arguments and the uids allowed. Subuid -+ delegation can either be managed via /etc/subuid or -+ through the configured NSS subid module. These options are mutually -+ exclusive. - - - --- -2.31.1 - - -From 0faec51bf0ec24e6e3d098cc55ed42584dd24efe Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Fri, 11 Jun 2021 15:25:42 +0200 -Subject: [PATCH 2/2] man: definition and configuration of subid - -Define the subid functionality and explain the way to configure its -delegation. ---- - man/subgid.5.xml | 32 +++++++++++++++++++++++++++++++- - man/subuid.5.xml | 32 +++++++++++++++++++++++++++++++- - 2 files changed, 62 insertions(+), 2 deletions(-) - -diff --git a/man/subgid.5.xml b/man/subgid.5.xml -index 70c561c4..02f421ab 100644 ---- a/man/subgid.5.xml -+++ b/man/subgid.5.xml -@@ -38,6 +38,11 @@ - Biederman - Creation, 2013 - -+ -+ Iker -+ Pedrosa -+ Developer, 2021 -+ - - - subgid -@@ -48,11 +53,36 @@ - - - subgid -- the subordinate gid file -+ the configuration for subordinate group ids - - - - DESCRIPTION -+ -+ Subgid authorizes a group id to map ranges of group ids from its namespace -+ into child namespaces. -+ -+ -+ The delegation of the subordinate gids can be configured via the -+ subid field in -+ /etc/nsswitch.conf file. Only one value can be set -+ as the delegation source. Setting this field to -+ files configures the delegation of gids to -+ /etc/subgid. Setting any other value treats -+ the delegation as a plugin following with a name of the form -+ libsubid_$value.so. If the value or plugin is -+ missing, then the subordinate gid delegation falls back to -+ files. -+ -+ -+ Note, that groupadd will only create entries in -+ /etc/subgid if subid delegation is managed via subid -+ files. -+ -+ -+ -+ -+ LOCAL SUBORDINATE DELEGATION - - Each line in /etc/subgid contains - a user name and a range of subordinate group ids that user -diff --git a/man/subuid.5.xml b/man/subuid.5.xml -index ec6a85f5..990d162e 100644 ---- a/man/subuid.5.xml -+++ b/man/subuid.5.xml -@@ -38,6 +38,11 @@ - Biederman - Creation, 2013 - -+ -+ Iker -+ Pedrosa -+ Developer, 2021 -+ - - - subuid -@@ -48,11 +53,36 @@ - - - subuid -- the subordinate uid file -+ the configuration for subordinate user ids - - - - DESCRIPTION -+ -+ Subuid authorizes a user id to map ranges of user ids from its namespace -+ into child namespaces. -+ -+ -+ The delegation of the subordinate uids can be configured via the -+ subid field in -+ /etc/nsswitch.conf file. Only one value can be set -+ as the delegation source. Setting this field to -+ files configures the delegation of uids to -+ /etc/subuid. Setting any other value treats -+ the delegation as a plugin following with a name of the form -+ libsubid_$value.so. If the value or plugin is -+ missing, then the subordinate uid delegation falls back to -+ files. -+ -+ -+ Note, that useradd will only create entries in -+ /etc/subuid if subid delegation is managed via subid -+ files. -+ -+ -+ -+ -+ LOCAL SUBORDINATE DELEGATION - - Each line in /etc/subuid contains - a user name and a range of subordinate user ids that user --- -2.31.1 - diff --git a/shadow-4.8.1-manfix.patch b/shadow-4.8.1-manfix.patch deleted file mode 100644 index 29f06a7..0000000 --- a/shadow-4.8.1-manfix.patch +++ /dev/null @@ -1,341 +0,0 @@ -diff -up shadow-4.8.1/man/chage.1.xml.manfix shadow-4.8.1/man/chage.1.xml ---- shadow-4.8.1/man/chage.1.xml.manfix 2019-10-05 01:28:34.000000000 +0200 -+++ shadow-4.8.1/man/chage.1.xml 2020-03-17 15:34:48.750414984 +0100 -@@ -102,6 +102,9 @@ - Set the number of days since January 1st, 1970 when the password - was last changed. The date may also be expressed in the format - YYYY-MM-DD (or the format more commonly used in your area). -+ If the LAST_DAY is set to -+ 0 the user is forced to change his password -+ on the next log on. - - - -@@ -119,6 +122,13 @@ - system again. - - -+ For example the following can be used to set an account to expire -+ in 180 days: -+ -+ -+ chage -E $(date -d +180days +%Y-%m-%d) -+ -+ - Passing the number -1 as the - EXPIRE_DATE will remove an account - expiration date. -@@ -239,6 +249,18 @@ - The chage program requires a shadow password file to - be available. - -+ -+ The chage program will report only the information from the shadow -+ password file. This implies that configuration from other sources -+ (e.g. LDAP or empty password hash field from the passwd file) that -+ affect the user's login will not be shown in the chage output. -+ -+ -+ The chage program will also not report any -+ inconsistency between the shadow and passwd files (e.g. missing x in -+ the passwd file). The pwck can be used to check -+ for this kind of inconsistencies. -+ - The chage command is restricted to the root - user, except for the option, which may be used by - an unprivileged user to determine when their password or account is due -diff -up shadow-4.8.1/man/groupadd.8.xml.manfix shadow-4.8.1/man/groupadd.8.xml ---- shadow-4.8.1/man/groupadd.8.xml.manfix 2020-03-17 15:34:48.745414917 +0100 -+++ shadow-4.8.1/man/groupadd.8.xml 2020-03-17 15:34:48.750414984 +0100 -@@ -320,13 +320,13 @@ - - 4 - -- GID not unique (when not used) -+ GID is already used (when called without ) - - - - 9 - -- group name not unique -+ group name is already used - - - -diff -up shadow-4.8.1/man/groupmems.8.xml.manfix shadow-4.8.1/man/groupmems.8.xml ---- shadow-4.8.1/man/groupmems.8.xml.manfix 2020-03-17 15:34:48.750414984 +0100 -+++ shadow-4.8.1/man/groupmems.8.xml 2020-03-17 15:41:13.383588722 +0100 -@@ -179,20 +179,10 @@ - - SETUP - -- The groupmems executable should be in mode -- 2710 as user root and in group -- groups. The system administrator can add users to -- group groups to allow or disallow them using the -- groupmems utility to manage their own group -- membership list. -+ In this operating system the groupmems executable -+ is not setuid and regular users cannot use it to manipulate -+ the membership of their own group. - -- -- -- $ groupadd -r groups -- $ chmod 2710 groupmems -- $ chown root.groups groupmems -- $ groupmems -g groups -a gk4 -- - - - -diff -up shadow-4.8.1/man/ja/man5/login.defs.5.manfix shadow-4.8.1/man/ja/man5/login.defs.5 ---- shadow-4.8.1/man/ja/man5/login.defs.5.manfix 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/man/ja/man5/login.defs.5 2020-03-17 15:34:48.750414984 +0100 -@@ -147,10 +147,6 @@ 以下の参照表は、 - shadow パスワード機能のどのプログラムが - どのパラメータを使用するかを示したものである。 - .na --.IP chfn 12 --CHFN_AUTH CHFN_RESTRICT --.IP chsh 12 --CHFN_AUTH - .IP groupadd 12 - GID_MAX GID_MIN - .IP newusers 12 -diff -up shadow-4.8.1/man/login.defs.5.xml.manfix shadow-4.8.1/man/login.defs.5.xml ---- shadow-4.8.1/man/login.defs.5.xml.manfix 2020-01-17 16:47:56.000000000 +0100 -+++ shadow-4.8.1/man/login.defs.5.xml 2020-03-17 15:34:48.750414984 +0100 -@@ -164,6 +164,17 @@ - long numeric parameters is machine-dependent. - - -+ -+ Please note that the parameters in this configuration file control the -+ behavior of the tools from the shadow-utils component. None of these -+ tools uses the PAM mechanism, and the utilities that use PAM (such as the -+ passwd command) should be configured elsewhere. The only values that -+ affect PAM modules are ENCRYPT_METHOD and SHA_CRYPT_MAX_ROUNDS -+ for pam_unix module, FAIL_DELAY for pam_faildelay module, -+ and UMASK for pam_umask module. Refer to -+ pam(8) for more information. -+ -+ - The following configuration items are provided: - - -@@ -256,16 +267,6 @@ - - - -- chfn -- -- -- CHFN_AUTH -- CHFN_RESTRICT -- LOGIN_STRING -- -- -- -- - chgpasswd - - -@@ -286,14 +287,6 @@ - - - -- -- chsh -- -- -- CHSH_AUTH LOGIN_STRING -- -- -- - - - -@@ -359,34 +352,6 @@ - LASTLOG_UID_MAX - - -- -- login -- -- -- CONSOLE -- CONSOLE_GROUPS DEFAULT_HOME -- ENV_HZ ENV_PATH ENV_SUPATH -- ENV_TZ ENVIRON_FILE -- ERASECHAR FAIL_DELAY -- FAILLOG_ENAB -- FAKE_SHELL -- FTMP_FILE -- HUSHLOGIN_FILE -- ISSUE_FILE -- KILLCHAR -- LASTLOG_ENAB LASTLOG_UID_MAX -- LOGIN_RETRIES -- LOGIN_STRING -- LOGIN_TIMEOUT LOG_OK_LOGINS LOG_UNKFAIL_ENAB -- MAIL_CHECK_ENAB MAIL_DIR MAIL_FILE -- MOTD_FILE NOLOGINS_FILE PORTTIME_CHECKS_ENAB -- QUOTAS_ENAB -- TTYGROUP TTYPERM TTYTYPE_FILE -- ULIMIT UMASK -- USERGROUPS_ENAB -- -- -- - - - newgrp / sg -@@ -415,17 +380,6 @@ - - - -- -- passwd -- -- -- ENCRYPT_METHOD MD5_CRYPT_ENAB OBSCURE_CHECKS_ENAB -- PASS_ALWAYS_WARN PASS_CHANGE_TRIES PASS_MAX_LEN PASS_MIN_LEN -- SHA_CRYPT_MAX_ROUNDS -- SHA_CRYPT_MIN_ROUNDS -- -- -- - - pwck - -@@ -452,32 +406,6 @@ - - - -- -- su -- -- -- CONSOLE -- CONSOLE_GROUPS DEFAULT_HOME -- ENV_HZ ENVIRON_FILE -- ENV_PATH ENV_SUPATH -- ENV_TZ LOGIN_STRING MAIL_CHECK_ENAB -- MAIL_DIR MAIL_FILE QUOTAS_ENAB -- SULOG_FILE SU_NAME -- SU_WHEEL_ONLY -- SYSLOG_SU_ENAB -- USERGROUPS_ENAB -- -- -- -- -- sulogin -- -- -- ENV_HZ -- ENV_TZ -- -- -- - - useradd - -diff -up shadow-4.8.1/man/shadow.5.xml.manfix shadow-4.8.1/man/shadow.5.xml ---- shadow-4.8.1/man/shadow.5.xml.manfix 2019-12-01 17:52:32.000000000 +0100 -+++ shadow-4.8.1/man/shadow.5.xml 2020-03-17 15:34:48.750414984 +0100 -@@ -129,7 +129,7 @@ - - - The date of the last password change, expressed as the number -- of days since Jan 1, 1970. -+ of days since Jan 1, 1970 00:00 UTC. - - - The value 0 has a special meaning, which is that the user -@@ -208,8 +208,8 @@ - - - After expiration of the password and this expiration period is -- elapsed, no login is possible using the current user's -- password. The user should contact her administrator. -+ elapsed, no login is possible for the user. -+ The user should contact her administrator. - - - An empty field means that there are no enforcement of an -@@ -224,7 +224,7 @@ - - - The date of expiration of the account, expressed as the number -- of days since Jan 1, 1970. -+ of days since Jan 1, 1970 00:00 UTC. - - - Note that an account expiration differs from a password -diff -up shadow-4.8.1/man/useradd.8.xml.manfix shadow-4.8.1/man/useradd.8.xml ---- shadow-4.8.1/man/useradd.8.xml.manfix 2020-03-17 15:34:48.745414917 +0100 -+++ shadow-4.8.1/man/useradd.8.xml 2020-03-17 15:34:48.751414997 +0100 -@@ -359,6 +359,11 @@ - is not enabled, no home - directories are created. - -+ -+ The directory where the user's home directory is created must -+ exist and have proper SELinux context and permissions. Otherwise -+ the user's home directory cannot be created or accessed. -+ - - - -diff -up shadow-4.8.1/man/usermod.8.xml.manfix shadow-4.8.1/man/usermod.8.xml ---- shadow-4.8.1/man/usermod.8.xml.manfix 2019-12-20 06:58:23.000000000 +0100 -+++ shadow-4.8.1/man/usermod.8.xml 2020-03-17 15:34:48.751414997 +0100 -@@ -143,7 +143,8 @@ - If the - option is given, the contents of the current home directory will - be moved to the new home directory, which is created if it does -- not already exist. -+ not already exist. If the current home directory does not exist -+ the new home directory will not be created. - - - -@@ -205,6 +206,12 @@ - The group ownership of files outside of the user's home directory - must be fixed manually. - -+ -+ The change of the group ownership of files inside of the user's -+ home directory is also not done if the home dir owner uid is -+ different from the current or new user id. This is safety measure -+ for special home directories such as /. -+ - - - -@@ -267,7 +274,8 @@ - - - Move the content of the user's home directory to the new -- location. -+ location. If the current home directory does not exist -+ the new home directory will not be created. - - - This option is only valid in combination with the -@@ -381,6 +389,12 @@ - must be fixed manually. - - -+ The change of the user ownership of files inside of the user's -+ home directory is also not done if the home dir owner uid is -+ different from the current or new user id. This is safety measure -+ for special home directories such as /. -+ -+ - No checks will be performed with regard to the - , , - , or diff --git a/shadow-4.8.1-salt_c_comments.patch b/shadow-4.8.1-salt_c_comments.patch deleted file mode 100644 index 1ec77e4..0000000 --- a/shadow-4.8.1-salt_c_comments.patch +++ /dev/null @@ -1,75 +0,0 @@ -From dbf230e4cf823dd6b6a3bad6d29dfad4f0ffa8fc Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= -Date: Mon, 14 Jun 2021 23:28:28 +0200 -Subject: [PATCH] libmisc/salt.c: Add comments how the minmum buffer length is - computed. -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -In the previous commit we refactored the functions converting the -rounds number into a string for use with the crypt() function, to -not require any static buffer anymore. - -Add some clarifying comments about how the minimum required buffer -length is computed inside of these functions. - -Signed-off-by: Björn Esser ---- - libmisc/salt.c | 29 +++++++++++++++++++++++++---- - 1 file changed, 25 insertions(+), 4 deletions(-) - -diff --git a/libmisc/salt.c b/libmisc/salt.c -index 98982ed1..e17093fc 100644 ---- a/libmisc/salt.c -+++ b/libmisc/salt.c -@@ -216,7 +216,14 @@ static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, /*@null@*/int *pref - return; - } - -- /* Check if the result buffer is long enough. */ -+ /* -+ * Check if the result buffer is long enough. -+ * We are going to write a maximum of 17 bytes, -+ * plus one byte for the terminator. -+ * rounds=XXXXXXXXX$ -+ * 00000000011111111 -+ * 12345678901234567 -+ */ - assert (GENSALT_SETTING_SIZE > buf_begin + 17); - - (void) snprintf (buf + buf_begin, 18, "rounds=%lu$", rounds); -@@ -274,7 +281,14 @@ static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, /*@null@*/int *p - rounds = 19; - } - -- /* Check if the result buffer is long enough. */ -+ /* -+ * Check if the result buffer is long enough. -+ * We are going to write three bytes, -+ * plus one byte for the terminator. -+ * XX$ -+ * 000 -+ * 123 -+ */ - assert (GENSALT_SETTING_SIZE > buf_begin + 3); - - (void) snprintf (buf + buf_begin, 4, "%2.2lu$", rounds); -@@ -308,8 +322,15 @@ static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, /*@null@*/int *p - cost = Y_COST_MAX; - } - -- /* Check if the result buffer is long enough. */ -- assert (GENSALT_SETTING_SIZE > buf_begin + 3); -+ /* -+ * Check if the result buffer is long enough. -+ * We are going to write four bytes, -+ * plus one byte for the terminator. -+ * jXX$ -+ * 0000 -+ * 1234 -+ */ -+ assert (GENSALT_SETTING_SIZE > buf_begin + 4); - - buf[buf_begin + 0] = 'j'; - if (cost < 3) { diff --git a/shadow-4.8.1-salt_c_fix_fread.patch b/shadow-4.8.1-salt_c_fix_fread.patch deleted file mode 100644 index 754b292..0000000 --- a/shadow-4.8.1-salt_c_fix_fread.patch +++ /dev/null @@ -1,29 +0,0 @@ -From ffd35d89021a9b8375a9246082afc6fc270a93ee Mon Sep 17 00:00:00 2001 -From: steven Y Gui -Date: Wed, 14 Jul 2021 16:17:48 +0800 -Subject: [PATCH] fread returns element count, not element size -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Björn Esser ---- - libmisc/salt.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmisc/salt.c b/libmisc/salt.c -index 9fd34332..91d528fd 100644 ---- a/libmisc/salt.c -+++ b/libmisc/salt.c -@@ -168,7 +168,7 @@ static long read_random_bytes (void) - #else - FILE *f = fopen ("/dev/urandom", "r"); - -- if (fread (&randval, sizeof (randval), 1, f) != sizeof (randval)) { -+ if (fread (&randval, sizeof (randval), 1, f) != 1) { - fclose(f); - goto fail; - } --- -2.31.1 - diff --git a/shadow-4.8.1-salt_c_sanitize_code.patch b/shadow-4.8.1-salt_c_sanitize_code.patch deleted file mode 100644 index 1ca1d3b..0000000 --- a/shadow-4.8.1-salt_c_sanitize_code.patch +++ /dev/null @@ -1,555 +0,0 @@ -From 14b108728a5d55c3d478a170c39f0e2ffd4de1b0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= -Date: Mon, 14 Jun 2021 23:28:28 +0200 -Subject: [PATCH] libmisc/salt.c: Sanitize code. -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -* Move all pre-processor defines to the top of the file. -* Unify the gensalt() function to be useable for all supported - hash methods. -* Drop the gensalt_{b,yes}crypt() functions in favor of the - previous change. -* Refactor the functions converting the rounds number into - a string for use with the crypt() function, to not require - any static buffer anymore. -* Clarify the comment about how crypt_make_salt() chooses the used - hash method from the settings in the login.defs file. -* Use memset() to fill static buffers with zero before using them. -* Use a fixed amount of 16 random base64-chars for the - sha{256,512}crypt hash methods, which is effectively still less - than the recommendation from NIST (>= 128 bits), but the maximum - those methods can effectively use (approx. 90 bits). -* Rename ROUNDS_{MIN,MAX} to SHA_ROUNDS_{MIN,MAX}. -* Bugfixes in the logic of setting rounds in BCRYPT_salt_rounds(). -* Likewise for YESCRYPT_salt_cost(). -* Fix formatting and white-space errors. - -Signed-off-by: Björn Esser ---- - libmisc/salt.c | 332 ++++++++++++++++++++++--------------------------- - 1 file changed, 147 insertions(+), 185 deletions(-) - -diff --git a/libmisc/salt.c b/libmisc/salt.c -index 5dc521ef..98982ed1 100644 ---- a/libmisc/salt.c -+++ b/libmisc/salt.c -@@ -12,6 +12,7 @@ - #ident "$Id$" - - #include -+#include - #include - #include - #include -@@ -19,6 +20,59 @@ - #include "defines.h" - #include "getdef.h" - -+/* Add the salt prefix. */ -+#define MAGNUM(array,ch) (array)[0]=(array)[2]='$',(array)[1]=(ch),(array)[3]='\0' -+ -+#ifdef USE_BCRYPT -+/* Use $2b$ as prefix for compatibility with OpenBSD's bcrypt. */ -+#define BCRYPTMAGNUM(array) (array)[0]=(array)[3]='$',(array)[1]='2',(array)[2]='b',(array)[4]='\0' -+#define BCRYPT_SALT_SIZE 22 -+/* Default number of rounds if not explicitly specified. */ -+#define B_ROUNDS_DEFAULT 13 -+/* Minimum number of rounds. */ -+#define B_ROUNDS_MIN 4 -+/* Maximum number of rounds. */ -+#define B_ROUNDS_MAX 31 -+#endif /* USE_BCRYPT */ -+ -+#ifdef USE_SHA_CRYPT -+/* Fixed salt len for sha{256,512}crypt. */ -+#define SHA_CRYPT_SALT_SIZE 16 -+/* Default number of rounds if not explicitly specified. */ -+#define SHA_ROUNDS_DEFAULT 5000 -+/* Minimum number of rounds. */ -+#define SHA_ROUNDS_MIN 1000 -+/* Maximum number of rounds. */ -+#define SHA_ROUNDS_MAX 999999999 -+#endif -+ -+#ifdef USE_YESCRYPT -+/* -+ * Default number of base64 characters used for the salt. -+ * 24 characters gives a 144 bits (18 bytes) salt. Unlike the more -+ * traditional 128 bits (16 bytes) salt, this 144 bits salt is always -+ * represented by the same number of base64 characters without padding -+ * issue, even with a non-standard base64 encoding scheme. -+ */ -+#define YESCRYPT_SALT_SIZE 24 -+/* Default cost if not explicitly specified. */ -+#define Y_COST_DEFAULT 5 -+/* Minimum cost. */ -+#define Y_COST_MIN 1 -+/* Maximum cost. */ -+#define Y_COST_MAX 11 -+#endif -+ -+/* Fixed salt len for md5crypt. */ -+#define MD5_CRYPT_SALT_SIZE 8 -+ -+/* Generate salt of size salt_size. */ -+#define MAX_SALT_SIZE 44 -+#define MIN_SALT_SIZE 8 -+ -+/* Maximum size of the generated salt string. */ -+#define GENSALT_SETTING_SIZE 100 -+ - /* local function prototypes */ - static void seedRNG (void); - static /*@observer@*/const char *gensalt (size_t salt_size); -@@ -26,19 +80,17 @@ static /*@observer@*/const char *gensalt (size_t salt_size); - static long shadow_random (long min, long max); - #endif /* USE_SHA_CRYPT || USE_BCRYPT */ - #ifdef USE_SHA_CRYPT --static /*@observer@*/const char *SHA_salt_rounds (/*@null@*/int *prefered_rounds); -+static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, /*@null@*/int *prefered_rounds); - #endif /* USE_SHA_CRYPT */ - #ifdef USE_BCRYPT --static /*@observer@*/const char *gensalt_bcrypt (void); --static /*@observer@*/const char *BCRYPT_salt_rounds (/*@null@*/int *prefered_rounds); -+static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, /*@null@*/int *prefered_rounds); - #endif /* USE_BCRYPT */ - #ifdef USE_YESCRYPT --static /*@observer@*/const char *gensalt_yescrypt (void); --static /*@observer@*/const char *YESCRYPT_salt_cost (/*@null@*/int *prefered_cost); -+static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, /*@null@*/int *prefered_cost); - #endif /* USE_YESCRYPT */ - - #ifndef HAVE_L64A --static /*@observer@*/char *l64a(long value) -+static /*@observer@*/char *l64a (long value) - { - static char buf[8]; - char *s = buf; -@@ -69,7 +121,7 @@ static /*@observer@*/char *l64a(long value) - - *s = '\0'; - -- return(buf); -+ return buf; - } - #endif /* !HAVE_L64A */ - -@@ -85,15 +137,6 @@ static void seedRNG (void) - } - } - --/* -- * Add the salt prefix. -- */ --#define MAGNUM(array,ch) (array)[0]=(array)[2]='$',(array)[1]=(ch),(array)[3]='\0' --#ifdef USE_BCRYPT --/* Use $2b$ as prefix for compatibility with OpenBSD's bcrypt. */ --#define BCRYPTMAGNUM(array) (array)[0]=(array)[3]='$',(array)[1]='2',(array)[2]='b',(array)[4]='\0' --#endif /* USE_BCRYPT */ -- - #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) - /* It is not clear what is the maximum value of random(). - * We assume 2^31-1.*/ -@@ -122,26 +165,21 @@ static long shadow_random (long min, long max) - #endif /* USE_SHA_CRYPT || USE_BCRYPT */ - - #ifdef USE_SHA_CRYPT --/* Default number of rounds if not explicitly specified. */ --#define ROUNDS_DEFAULT 5000 --/* Minimum number of rounds. */ --#define ROUNDS_MIN 1000 --/* Maximum number of rounds. */ --#define ROUNDS_MAX 999999999 - /* -- * Return a salt prefix specifying the rounds number for the SHA crypt methods. -+ * Fill a salt prefix specifying the rounds number for the SHA crypt methods -+ * to a buffer. - */ --static /*@observer@*/const char *SHA_salt_rounds (/*@null@*/int *prefered_rounds) -+static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, /*@null@*/int *prefered_rounds) - { -- static char rounds_prefix[18]; /* Max size: rounds=999999999$ */ -- long rounds; -+ unsigned long rounds; -+ const size_t buf_begin = strlen (buf); - - if (NULL == prefered_rounds) { - long min_rounds = getdef_long ("SHA_CRYPT_MIN_ROUNDS", -1); - long max_rounds = getdef_long ("SHA_CRYPT_MAX_ROUNDS", -1); - - if ((-1 == min_rounds) && (-1 == max_rounds)) { -- return ""; -+ rounds = SHA_ROUNDS_DEFAULT; - } - - if (-1 == min_rounds) { -@@ -156,196 +194,142 @@ static /*@observer@*/const char *SHA_salt_rounds (/*@null@*/int *prefered_rounds - max_rounds = min_rounds; - } - -- rounds = shadow_random (min_rounds, max_rounds); -+ rounds = (unsigned long) shadow_random (min_rounds, max_rounds); - } else if (0 == *prefered_rounds) { -- return ""; -+ rounds = SHA_ROUNDS_DEFAULT; - } else { -- rounds = *prefered_rounds; -+ rounds = (unsigned long) *prefered_rounds; - } - - /* Sanity checks. The libc should also check this, but this - * protects against a rounds_prefix overflow. */ -- if (rounds < ROUNDS_MIN) { -- rounds = ROUNDS_MIN; -+ if (rounds < SHA_ROUNDS_MIN) { -+ rounds = SHA_ROUNDS_MIN; -+ } -+ -+ if (rounds > SHA_ROUNDS_MAX) { -+ rounds = SHA_ROUNDS_MAX; - } - -- if (rounds > ROUNDS_MAX) { -- rounds = ROUNDS_MAX; -+ /* Nothing to do here if SHA_ROUNDS_DEFAULT is used. */ -+ if (rounds == SHA_ROUNDS_DEFAULT) { -+ return; - } - -- (void) snprintf (rounds_prefix, sizeof rounds_prefix, -- "rounds=%ld$", rounds); -+ /* Check if the result buffer is long enough. */ -+ assert (GENSALT_SETTING_SIZE > buf_begin + 17); - -- return rounds_prefix; -+ (void) snprintf (buf + buf_begin, 18, "rounds=%lu$", rounds); - } - #endif /* USE_SHA_CRYPT */ - - #ifdef USE_BCRYPT --/* Default number of rounds if not explicitly specified. */ --#define B_ROUNDS_DEFAULT 13 --/* Minimum number of rounds. */ --#define B_ROUNDS_MIN 4 --/* Maximum number of rounds. */ --#define B_ROUNDS_MAX 31 - /* -- * Return a salt prefix specifying the rounds number for the BCRYPT method. -+ * Fill a salt prefix specifying the rounds number for the BCRYPT method -+ * to a buffer. - */ --static /*@observer@*/const char *BCRYPT_salt_rounds (/*@null@*/int *prefered_rounds) -+static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, /*@null@*/int *prefered_rounds) - { -- static char rounds_prefix[4]; /* Max size: 31$ */ -- long rounds; -+ unsigned long rounds; -+ const size_t buf_begin = strlen (buf); - - if (NULL == prefered_rounds) { - long min_rounds = getdef_long ("BCRYPT_MIN_ROUNDS", -1); - long max_rounds = getdef_long ("BCRYPT_MAX_ROUNDS", -1); - -- if (((-1 == min_rounds) && (-1 == max_rounds)) || (0 == *prefered_rounds)) { -+ if ((-1 == min_rounds) && (-1 == max_rounds)) { - rounds = B_ROUNDS_DEFAULT; -- } -- else { -+ } else { - if (-1 == min_rounds) { - min_rounds = max_rounds; - } -- -+ - if (-1 == max_rounds) { - max_rounds = min_rounds; - } -- -+ - if (min_rounds > max_rounds) { - max_rounds = min_rounds; - } -- -- rounds = shadow_random (min_rounds, max_rounds); -+ -+ rounds = (unsigned long) shadow_random (min_rounds, max_rounds); - } -+ } else if (0 == *prefered_rounds) { -+ rounds = B_ROUNDS_DEFAULT; - } else { -- rounds = *prefered_rounds; -+ rounds = (unsigned long) *prefered_rounds; - } - -- /* -- * Sanity checks. -- * Use 19 as an upper bound for now, -- * because musl doesn't allow rounds >= 20. -- */ -+ /* Sanity checks. */ - if (rounds < B_ROUNDS_MIN) { - rounds = B_ROUNDS_MIN; - } - -+ /* -+ * Use 19 as an upper bound for now, -+ * because musl doesn't allow rounds >= 20. -+ */ - if (rounds > 19) { - /* rounds = B_ROUNDS_MAX; */ - rounds = 19; - } - -- (void) snprintf (rounds_prefix, sizeof rounds_prefix, -- "%2.2ld$", rounds); -- -- return rounds_prefix; --} -- --#define BCRYPT_SALT_SIZE 22 --/* -- * Generate a 22 character salt string for bcrypt. -- */ --static /*@observer@*/const char *gensalt_bcrypt (void) --{ -- static char salt[32]; -- -- salt[0] = '\0'; -+ /* Check if the result buffer is long enough. */ -+ assert (GENSALT_SETTING_SIZE > buf_begin + 3); - -- seedRNG (); -- strcat (salt, l64a (random())); -- do { -- strcat (salt, l64a (random())); -- } while (strlen (salt) < BCRYPT_SALT_SIZE); -- -- salt[BCRYPT_SALT_SIZE] = '\0'; -- -- return salt; -+ (void) snprintf (buf + buf_begin, 4, "%2.2lu$", rounds); - } - #endif /* USE_BCRYPT */ - - #ifdef USE_YESCRYPT --/* Default cost if not explicitly specified. */ --#define Y_COST_DEFAULT 5 --/* Minimum cost. */ --#define Y_COST_MIN 1 --/* Maximum cost. */ --#define Y_COST_MAX 11 - /* -- * Return a salt prefix specifying the cost for the YESCRYPT method. -+ * Fill a salt prefix specifying the cost for the YESCRYPT method -+ * to a buffer. - */ --static /*@observer@*/const char *YESCRYPT_salt_cost (/*@null@*/int *prefered_cost) -+static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, /*@null@*/int *prefered_cost) - { -- static char cost_prefix[5]; -- long cost; -+ unsigned long cost; -+ const size_t buf_begin = strlen (buf); - - if (NULL == prefered_cost) { - cost = getdef_num ("YESCRYPT_COST_FACTOR", Y_COST_DEFAULT); -+ } else if (0 == *prefered_cost) { -+ cost = Y_COST_DEFAULT; - } else { -- cost = *prefered_cost; -+ cost = (unsigned long) *prefered_cost; - } - -+ /* Sanity checks. */ - if (cost < Y_COST_MIN) { - cost = Y_COST_MIN; - } -+ - if (cost > Y_COST_MAX) { - cost = Y_COST_MAX; - } - -- cost_prefix[0] = 'j'; -+ /* Check if the result buffer is long enough. */ -+ assert (GENSALT_SETTING_SIZE > buf_begin + 3); -+ -+ buf[buf_begin + 0] = 'j'; - if (cost < 3) { -- cost_prefix[1] = 0x36 + cost; -+ buf[buf_begin + 1] = 0x36 + cost; - } else if (cost < 6) { -- cost_prefix[1] = 0x34 + cost; -+ buf[buf_begin + 1] = 0x34 + cost; - } else { -- cost_prefix[1] = 0x3b + cost; -+ buf[buf_begin + 1] = 0x3b + cost; - } -- cost_prefix[2] = cost >= 3 ? 'T' : '5'; -- cost_prefix[3] = '$'; -- cost_prefix[4] = 0; -- -- return cost_prefix; --} -- --/* -- * Default number of base64 characters used for the salt. -- * 24 characters gives a 144 bits (18 bytes) salt. Unlike the more -- * traditional 128 bits (16 bytes) salt, this 144 bits salt is always -- * represented by the same number of base64 characters without padding -- * issue, even with a non-standard base64 encoding scheme. -- */ --#define YESCRYPT_SALT_SIZE 24 --/* -- * Generate a 22 character salt string for yescrypt. -- */ --static /*@observer@*/const char *gensalt_yescrypt (void) --{ -- static char salt[32]; -- -- salt[0] = '\0'; -- -- seedRNG (); -- strcat (salt, l64a (random())); -- do { -- strcat (salt, l64a (random())); -- } while (strlen (salt) < YESCRYPT_SALT_SIZE); -- -- salt[YESCRYPT_SALT_SIZE] = '\0'; -- -- return salt; -+ buf[buf_begin + 2] = cost >= 3 ? 'T' : '5'; -+ buf[buf_begin + 3] = '$'; -+ buf[buf_begin + 4] = '\0'; - } - #endif /* USE_YESCRYPT */ - --/* -- * Generate salt of size salt_size. -- */ --#define MAX_SALT_SIZE 16 --#define MIN_SALT_SIZE 8 -- - static /*@observer@*/const char *gensalt (size_t salt_size) - { -- static char salt[32]; -+ static char salt[MAX_SALT_SIZE + 6]; - -- salt[0] = '\0'; -+ memset (salt, '\0', MAX_SALT_SIZE + 6); - - assert (salt_size >= MIN_SALT_SIZE && - salt_size <= MAX_SALT_SIZE); -@@ -368,8 +352,9 @@ static /*@observer@*/const char *gensalt (size_t salt_size) - * Other methods can be set with ENCRYPT_METHOD - * - * The method can be forced with the meth parameter. -- * If NULL, the method will be defined according to the MD5_CRYPT_ENAB and -- * ENCRYPT_METHOD login.defs variables. -+ * If NULL, the method will be defined according to the ENCRYPT_METHOD -+ * variable, and if not set according to the MD5_CRYPT_ENAB variable, -+ * which can both be set inside the login.defs file. - * - * If meth is specified, an additional parameter can be provided. - * * For the SHA256 and SHA512 method, this specifies the number of rounds -@@ -378,17 +363,11 @@ static /*@observer@*/const char *gensalt (size_t salt_size) - */ - /*@observer@*/const char *crypt_make_salt (/*@null@*//*@observer@*/const char *meth, /*@null@*/void *arg) - { -- /* Max result size for the SHA methods: -- * +3 $5$ -- * +17 rounds=999999999$ -- * +16 salt -- * +1 \0 -- */ -- static char result[40]; -- size_t salt_len = 8; -+ static char result[GENSALT_SETTING_SIZE]; -+ size_t salt_len = MAX_SALT_SIZE; - const char *method; - -- result[0] = '\0'; -+ memset (result, '\0', GENSALT_SETTING_SIZE); - - if (NULL != meth) - method = meth; -@@ -401,61 +380,44 @@ static /*@observer@*/const char *gensalt (size_t salt_size) - - if (0 == strcmp (method, "MD5")) { - MAGNUM(result, '1'); -+ salt_len = MD5_CRYPT_SALT_SIZE; - #ifdef USE_BCRYPT - } else if (0 == strcmp (method, "BCRYPT")) { - BCRYPTMAGNUM(result); -- strcat(result, BCRYPT_salt_rounds((int *)arg)); -+ salt_len = BCRYPT_SALT_SIZE; -+ BCRYPT_salt_rounds_to_buf (result, (int *) arg); - #endif /* USE_BCRYPT */ - #ifdef USE_YESCRYPT - } else if (0 == strcmp (method, "YESCRYPT")) { - MAGNUM(result, 'y'); -- strcat(result, YESCRYPT_salt_cost((int *)arg)); -+ salt_len = YESCRYPT_SALT_SIZE; -+ YESCRYPT_salt_cost_to_buf (result, (int *) arg); - #endif /* USE_YESCRYPT */ - #ifdef USE_SHA_CRYPT - } else if (0 == strcmp (method, "SHA256")) { - MAGNUM(result, '5'); -- strcat(result, SHA_salt_rounds((int *)arg)); -- salt_len = (size_t) shadow_random (8, 16); -+ salt_len = SHA_CRYPT_SALT_SIZE; -+ SHA_salt_rounds_to_buf (result, (int *) arg); - } else if (0 == strcmp (method, "SHA512")) { - MAGNUM(result, '6'); -- strcat(result, SHA_salt_rounds((int *)arg)); -- salt_len = (size_t) shadow_random (8, 16); -+ salt_len = SHA_CRYPT_SALT_SIZE; -+ SHA_salt_rounds_to_buf (result, (int *) arg); - #endif /* USE_SHA_CRYPT */ - } else if (0 != strcmp (method, "DES")) { - fprintf (shadow_logfd, - _("Invalid ENCRYPT_METHOD value: '%s'.\n" - "Defaulting to DES.\n"), - method); -- result[0] = '\0'; -+ salt_len = MAX_SALT_SIZE; -+ memset (result, '\0', GENSALT_SETTING_SIZE); - } - -- /* -- * Concatenate a pseudo random salt. -- */ -- assert (sizeof (result) > strlen (result) + salt_len); --#ifdef USE_BCRYPT -- if (0 == strcmp (method, "BCRYPT")) { -- strncat (result, gensalt_bcrypt (), -- sizeof (result) - strlen (result) - 1); -- return result; -- } else { --#endif /* USE_BCRYPT */ --#ifdef USE_YESCRYPT -- if (0 == strcmp (method, "YESCRYPT")) { -- strncat (result, gensalt_yescrypt (), -- sizeof (result) - strlen (result) - 1); -- return result; -- } else { --#endif /* USE_YESCRYPT */ -- strncat (result, gensalt (salt_len), -- sizeof (result) - strlen (result) - 1); --#ifdef USE_YESCRYPT -- } --#endif /* USE_YESCRYPT */ --#ifdef USE_BCRYPT -- } --#endif /* USE_BCRYPT */ -+ /* Check if the result buffer is long enough. */ -+ assert (GENSALT_SETTING_SIZE > strlen (result) + salt_len); -+ -+ /* Concatenate a pseudo random salt. */ -+ strncat (result, gensalt (salt_len), -+ GENSALT_SETTING_SIZE - strlen (result) - 1); - - return result; - } -- diff --git a/shadow-4.8.1-salt_c_use_dev_urandom.patch b/shadow-4.8.1-salt_c_use_dev_urandom.patch deleted file mode 100644 index ba37b77..0000000 --- a/shadow-4.8.1-salt_c_use_dev_urandom.patch +++ /dev/null @@ -1,114 +0,0 @@ -From bc8257cf73328e450511b13cbd35e1994feccb30 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= -Date: Wed, 23 Jun 2021 16:06:47 +0200 -Subject: [PATCH] libmisc/salt.c: Obtain random bytes from /dev/urandom. -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Using the random() function to obtain pseudo-random bytes -for generating salt strings is considered to be dangerous. -See CWE-327. - -We really should use a more reliable source for obtaining -pseudo-random bytes like /dev/urandom. - -Fixes #376. - -Signed-off-by: Björn Esser ---- - libmisc/salt.c | 45 ++++++++++++++++++++++++--------------------- - 1 file changed, 24 insertions(+), 21 deletions(-) - -diff --git a/libmisc/salt.c b/libmisc/salt.c -index e17093fc..af9f011f 100644 ---- a/libmisc/salt.c -+++ b/libmisc/salt.c -@@ -11,11 +11,10 @@ - - #ident "$Id$" - --#include --#include --#include --#include - #include -+#include -+#include -+#include - #include "prototypes.h" - #include "defines.h" - #include "getdef.h" -@@ -74,7 +73,7 @@ - #define GENSALT_SETTING_SIZE 100 - - /* local function prototypes */ --static void seedRNG (void); -+static long read_random_bytes (void); - static /*@observer@*/const char *gensalt (size_t salt_size); - #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) - static long shadow_random (long min, long max); -@@ -125,23 +124,27 @@ static /*@observer@*/char *l64a (long value) - } - #endif /* !HAVE_L64A */ - --static void seedRNG (void) -+/* Read sizeof (long) random bytes from /dev/urandom. */ -+static long read_random_bytes (void) - { -- struct timeval tv; -- static int seeded = 0; -+ long randval = 0; -+ FILE *f = fopen ("/dev/urandom", "r"); - -- if (0 == seeded) { -- (void) gettimeofday (&tv, NULL); -- srandom (tv.tv_sec ^ tv.tv_usec ^ getpid ()); -- seeded = 1; -+ if (fread (&randval, sizeof (randval), 1, f) != sizeof (randval)) -+ { -+ fprintf (shadow_logfd, -+ _("Unable to read from /dev/urandom.\n")); -+ -+ fclose(f); -+ exit (1); - } -+ -+ fclose(f); -+ -+ return randval; - } - - #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) --/* It is not clear what is the maximum value of random(). -- * We assume 2^31-1.*/ --#define RANDOM_MAX 0x7FFFFFFF -- - /* - * Return a random number between min and max (both included). - * -@@ -151,8 +154,9 @@ static long shadow_random (long min, long max) - { - double drand; - long ret; -- seedRNG (); -- drand = (double) (max - min + 1) * random () / RANDOM_MAX; -+ -+ drand = (double) (read_random_bytes () & RAND_MAX) / (double) RAND_MAX; -+ drand *= (double) (max - min + 1); - /* On systems were this is not random() range is lower, we favor - * higher numbers of salt. */ - ret = (long) (max + 1 - drand); -@@ -354,10 +358,9 @@ static /*@observer@*/const char *gensalt (size_t salt_size) - - assert (salt_size >= MIN_SALT_SIZE && - salt_size <= MAX_SALT_SIZE); -- seedRNG (); -- strcat (salt, l64a (random())); -+ strcat (salt, l64a (read_random_bytes ())); - do { -- strcat (salt, l64a (random())); -+ strcat (salt, l64a (read_random_bytes ())); - } while (strlen (salt) < salt_size); - - salt[salt_size] = '\0'; diff --git a/shadow-4.8.1-useradd-man-clarification.patch b/shadow-4.8.1-useradd-man-clarification.patch deleted file mode 100644 index 9fdb652..0000000 --- a/shadow-4.8.1-useradd-man-clarification.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 6543c600d841e4f7779269412d470e50eae25b13 Mon Sep 17 00:00:00 2001 -From: ikerexxe -Date: Wed, 4 Mar 2020 14:50:04 +0100 -Subject: [PATCH] useradd: clarify the useradd -d parameter behavior in man - page - -Explanation: clarify the useradd -d parameter as it does create directory HOME_DIR if it doesn't exit. - -Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1677005 - -Changelog: [serge] minor tweak to the text ---- - man/useradd.8.xml | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/man/useradd.8.xml b/man/useradd.8.xml -index 03612ce8..023c0d69 100644 ---- a/man/useradd.8.xml -+++ b/man/useradd.8.xml -@@ -181,8 +181,10 @@ - login directory. The default is to append the - LOGIN name to - BASE_DIR and use that as the login -- directory name. The directory HOME_DIR -- does not have to exist but will not be created if it is missing. -+ directory name. If the directory -+ HOME_DIR does not exist, then it -+ will be created unless the option is -+ specified. - - - --- -2.25.1 - diff --git a/shadow-4.8.1-useradd_SUB_UID_COUNT-0.patch b/shadow-4.8.1-useradd_SUB_UID_COUNT-0.patch deleted file mode 100644 index f393368..0000000 --- a/shadow-4.8.1-useradd_SUB_UID_COUNT-0.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 663824ef4ca927aa2b4319b69e0bfa68282ec719 Mon Sep 17 00:00:00 2001 -From: Serge Hallyn -Date: Sat, 22 May 2021 11:42:02 -0500 -Subject: [PATCH] Fix useradd with SUB_UID_COUNT=0 - -Closes #298 - -Fix useradd when SUB_UID_COUNT=0 in login.defs. - -Signed-off-by: Serge Hallyn ---- - src/useradd.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/src/useradd.c b/src/useradd.c -index 06accb2f..9862ae55 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -2386,6 +2386,8 @@ int main (int argc, char **argv) - #ifdef ENABLE_SUBIDS - uid_t uid_min; - uid_t uid_max; -+ unsigned long subuid_count; -+ unsigned long subgid_count; - #endif - - /* -@@ -2427,9 +2429,11 @@ int main (int argc, char **argv) - #ifdef ENABLE_SUBIDS - uid_min = (uid_t) getdef_ulong ("UID_MIN", 1000UL); - uid_max = (uid_t) getdef_ulong ("UID_MAX", 60000UL); -- is_sub_uid = sub_uid_file_present () && !rflg && -+ subuid_count = getdef_ulong ("SUB_UID_COUNT", 65536); -+ subgid_count = getdef_ulong ("SUB_GID_COUNT", 65536); -+ is_sub_uid = subuid_count > 0 && sub_uid_file_present () && !rflg && - (!user_id || (user_id <= uid_max && user_id >= uid_min)); -- is_sub_gid = sub_gid_file_present () && !rflg && -+ is_sub_gid = subgid_count > 0 && sub_gid_file_present () && !rflg && - (!user_id || (user_id <= uid_max && user_id >= uid_min)); - #endif /* ENABLE_SUBIDS */ - --- -2.30.2 - diff --git a/shadow-4.8.1-useradd_create_relative_home_path_correctly.patch b/shadow-4.8.1-useradd_create_relative_home_path_correctly.patch deleted file mode 100644 index a318f7a..0000000 --- a/shadow-4.8.1-useradd_create_relative_home_path_correctly.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff -up shadow-4.8.1/src/useradd.c.useradd_create_relative_home_path_correctly shadow-4.8.1/src/useradd.c ---- shadow-4.8.1/src/useradd.c.useradd_create_relative_home_path_correctly 2021-06-28 16:10:23.928435372 +0200 -+++ shadow-4.8.1/src/useradd.c 2021-06-28 16:11:30.784495046 +0200 -@@ -2140,7 +2140,6 @@ static void create_home (void) - Prog, user_home); - fail_exit (E_HOMEDIR); - } -- ++bhome; - - #ifdef WITH_SELINUX - if (set_selinux_file_context (prefix_user_home, NULL) != 0) { -@@ -2157,7 +2156,11 @@ static void create_home (void) - */ - cp = strtok (bhome, "/"); - while (cp) { -- strcat (path, "/"); -+ /* Avoid turning a relative path into an absolute path. -+ */ -+ if (bhome[0] == '/' || strlen (path) != 0) { -+ strcat (path, "/"); -+ } - strcat (path, cp); - if (access (path, F_OK) != 0) { - /* Check if parent directory is BTRFS, fail if requesting diff --git a/shadow-4.8.1-yescrypt-support.patch b/shadow-4.8.1-yescrypt-support.patch deleted file mode 100644 index aff941b..0000000 --- a/shadow-4.8.1-yescrypt-support.patch +++ /dev/null @@ -1,960 +0,0 @@ -From 5cd04d03f94622c12220d4a6352824af081b8531 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rodolphe=20Br=C3=A9ard?= -Date: Sun, 27 Dec 2020 21:09:25 +0100 -Subject: [PATCH] Add yescrypt support - ---- - configure.ac | 13 +++++ - etc/login.defs | 14 +++++ - lib/encrypt.c | 3 ++ - lib/getdef.c | 3 ++ - libmisc/obscure.c | 3 ++ - libmisc/salt.c | 94 +++++++++++++++++++++++++++++++- - src/chgpasswd.c | 113 ++++++++++++++++++++------------------ - src/chpasswd.c | 107 +++++++++++++++++++----------------- - src/newusers.c | 134 +++++++++++++++++++++++++--------------------- - src/passwd.c | 3 ++ - 10 files changed, 322 insertions(+), 165 deletions(-) - -Index: shadow-4.8.1/configure.ac -=================================================================== ---- shadow-4.8.1.orig/configure.ac -+++ shadow-4.8.1/configure.ac -@@ -290,6 +290,9 @@ AC_ARG_WITH(sha-crypt, - AC_ARG_WITH(bcrypt, - [AC_HELP_STRING([--with-bcrypt], [allow the bcrypt password encryption algorithm @<:@default=no@:>@])], - [with_bcrypt=$withval], [with_bcrypt=no]) -+AC_ARG_WITH(yescrypt, -+ [AC_HELP_STRING([--with-yescrypt], [allow the yescrypt password encryption algorithm @<:@default=no@:>@])], -+ [with_yescrypt=$withval], [with_yescrypt=no]) - AC_ARG_WITH(nscd, - [AC_HELP_STRING([--with-nscd], [enable support for nscd @<:@default=yes@:>@])], - [with_nscd=$withval], [with_nscd=yes]) -@@ -322,6 +325,11 @@ if test "$with_bcrypt" = "yes"; then - AC_DEFINE(USE_BCRYPT, 1, [Define to allow the bcrypt password encryption algorithm]) - fi - -+AM_CONDITIONAL(USE_YESCRYPT, test "x$with_yescrypt" = "xyes") -+if test "$with_yescrypt" = "yes"; then -+ AC_DEFINE(USE_YESCRYPT, 1, [Define to allow the yescrypt password encryption algorithm]) -+fi -+ - if test "$with_nscd" = "yes"; then - AC_CHECK_FUNC(posix_spawn, - [AC_DEFINE(USE_NSCD, 1, [Define to support flushing of nscd caches])], -@@ -402,6 +410,10 @@ AC_SUBST(LIBCRYPT) - AC_CHECK_LIB(crypt, crypt, [LIBCRYPT=-lcrypt], - [AC_MSG_ERROR([crypt() not found])]) - -+AC_SUBST(LIYESCRYPT) -+AC_CHECK_LIB(crypt, crypt, [LIYESCRYPT=-lcrypt], -+ [AC_MSG_ERROR([crypt() not found])]) -+ - AC_SUBST(LIBACL) - if test "$with_acl" != "no"; then - AC_CHECK_HEADERS(acl/libacl.h attr/error_context.h, [acl_header="yes"], [acl_header="no"]) -@@ -752,6 +764,7 @@ echo " shadow group support: $enable_sh - echo " S/Key support: $with_skey" - echo " SHA passwords encryption: $with_sha_crypt" - echo " bcrypt passwords encryption: $with_bcrypt" -+echo " yescrypt passwords encryption: $with_yescrypt" - echo " nscd support: $with_nscd" - echo " sssd support: $with_sssd" - echo " subordinate IDs support: $enable_subids" -Index: shadow-4.8.1/etc/login.defs -=================================================================== ---- shadow-4.8.1.orig/etc/login.defs -+++ shadow-4.8.1/etc/login.defs -@@ -326,6 +326,7 @@ CHFN_RESTRICT rwh - # If set to SHA256, SHA256-based algorithm will be used for encrypting password - # If set to SHA512, SHA512-based algorithm will be used for encrypting password - # If set to BCRYPT, BCRYPT-based algorithm will be used for encrypting password -+# If set to YESCRYPT, YESCRYPT-based algorithm will be used for encrypting password - # If set to DES, DES-based algorithm will be used for encrypting password (default) - # Overrides the MD5_CRYPT_ENAB option - # -@@ -366,6 +367,19 @@ CHFN_RESTRICT rwh - #BCRYPT_MAX_ROUNDS 13 - - # -+# Only works if ENCRYPT_METHOD is set to YESCRYPT. -+# -+# Define the YESCRYPT cost factor. -+# With a higher cost factor, it is more difficult to brute-force the password. -+# However, more CPU time and more memory will be needed to authenticate users -+# if this value is increased. -+# -+# If not specified, a cost factor of 5 will be used. -+# The value must be within the 1-11 range. -+# -+#YESCRYPT_COST_FACTOR 5 -+ -+# - # List of groups to add to the user's supplementary group set - # when logging in from the console (as determined by the CONSOLE - # setting). Default is none. -Index: shadow-4.8.1/lib/encrypt.c -=================================================================== ---- shadow-4.8.1.orig/lib/encrypt.c -+++ shadow-4.8.1/lib/encrypt.c -@@ -74,6 +74,9 @@ - case '6': - method = "SHA512"; - break; -+ case 'y': -+ method = "YESCRYPT"; -+ break; - default: - { - static char nummethod[4] = "$x$"; -Index: shadow-4.8.1/lib/getdef.c -=================================================================== ---- shadow-4.8.1.orig/lib/getdef.c -+++ shadow-4.8.1/lib/getdef.c -@@ -117,6 +117,9 @@ static struct itemdef def_table[] = { - {"BCRYPT_MAX_ROUNDS", NULL}, - {"BCRYPT_MIN_ROUNDS", NULL}, - #endif -+#ifdef USE_YESCRYPT -+ {"YESCRYPT_COST_FACTOR", NULL}, -+#endif - {"SUB_GID_COUNT", NULL}, - {"SUB_GID_MAX", NULL}, - {"SUB_GID_MIN", NULL}, -Index: shadow-4.8.1/libmisc/obscure.c -=================================================================== ---- shadow-4.8.1.orig/libmisc/obscure.c -+++ shadow-4.8.1/libmisc/obscure.c -@@ -272,6 +272,9 @@ static /*@observer@*//*@null@*/const cha - #ifdef USE_BCRYPT - || (strcmp (result, "BCRYPT") == 0) - #endif -+#ifdef USE_YESCRYPT -+ || (strcmp (result, "YESCRYPT") == 0) -+#endif - ) { - return NULL; - } -Index: shadow-4.8.1/libmisc/salt.c -=================================================================== ---- shadow-4.8.1.orig/libmisc/salt.c -+++ shadow-4.8.1/libmisc/salt.c -@@ -32,6 +32,10 @@ static /*@observer@*/const char *SHA_sal - static /*@observer@*/const char *gensalt_bcrypt (void); - static /*@observer@*/const char *BCRYPT_salt_rounds (/*@null@*/int *prefered_rounds); - #endif /* USE_BCRYPT */ -+#ifdef USE_YESCRYPT -+static /*@observer@*/const char *gensalt_yescrypt (void); -+static /*@observer@*/const char *YESCRYPT_salt_cost (/*@null@*/long *prefered_rounds); -+#endif /* USE_YESCRYPT */ - - #ifndef HAVE_L64A - static /*@observer@*/char *l64a(long value) -@@ -263,6 +267,78 @@ static /*@observer@*/const char *gensalt - } - #endif /* USE_BCRYPT */ - -+#ifdef USE_YESCRYPT -+/* Default cost if not explicitly specified. */ -+#define Y_COST_DEFAULT 5 -+/* Minimum cost. */ -+#define Y_COST_MIN 1 -+/* Maximum cost. */ -+#define Y_COST_MAX 11 -+/* -+ * Return a salt prefix specifying the cost for the YESCRYPT method. -+ */ -+static /*@observer@*/const char *YESCRYPT_salt_cost (/*@null@*/long *prefered_cost) -+{ -+ static char cost_prefix[5]; -+ long cost; -+ -+ if (NULL == prefered_cost) { -+ cost = getdef_num ("YESCRYPT_COST_FACTOR", Y_COST_DEFAULT); -+ } else { -+ cost = *prefered_cost; -+ } -+ -+ if (cost < Y_COST_MIN) { -+ cost = Y_COST_MIN; -+ } -+ if (cost > Y_COST_MAX) { -+ cost = Y_COST_MAX; -+ } -+ -+ cost_prefix[0] = 'j'; -+ if (cost < 3) { -+ cost_prefix[1] = 0x36 + cost; -+ } else if (cost < 6) { -+ cost_prefix[1] = 0x34 + cost; -+ } else { -+ cost_prefix[1] = 0x3b + cost; -+ } -+ cost_prefix[2] = cost >= 3 ? 'T' : '5'; -+ cost_prefix[3] = '$'; -+ cost_prefix[4] = 0; -+ -+ return cost_prefix; -+} -+ -+/* -+ * Default number of base64 characters used for the salt. -+ * 24 characters gives a 144 bits (18 bytes) salt. Unlike the more -+ * traditional 128 bits (16 bytes) salt, this 144 bits salt is always -+ * represented by the same number of base64 characters without padding -+ * issue, even with a non-standard base64 encoding scheme. -+ */ -+#define YESCRYPT_SALT_SIZE 24 -+/* -+ * Generate a 22 character salt string for yescrypt. -+ */ -+static /*@observer@*/const char *gensalt_yescrypt (void) -+{ -+ static char salt[32]; -+ -+ salt[0] = '\0'; -+ -+ seedRNG (); -+ strcat (salt, l64a (random())); -+ do { -+ strcat (salt, l64a (random())); -+ } while (strlen (salt) < YESCRYPT_SALT_SIZE); -+ -+ salt[YESCRYPT_SALT_SIZE] = '\0'; -+ -+ return salt; -+} -+#endif /* USE_YESCRYPT */ -+ - /* - * Generate salt of size salt_size. - */ -@@ -302,6 +378,7 @@ static /*@observer@*/const char *gensalt - * If meth is specified, an additional parameter can be provided. - * * For the SHA256 and SHA512 method, this specifies the number of rounds - * (if not NULL). -+ * * For the YESCRYPT method, this specifies the cost factor (if not NULL). - */ - /*@observer@*/const char *crypt_make_salt (/*@null@*//*@observer@*/const char *meth, /*@null@*/void *arg) - { -@@ -333,6 +410,11 @@ static /*@observer@*/const char *gensalt - BCRYPTMAGNUM(result); - strcat(result, BCRYPT_salt_rounds((int *)arg)); - #endif /* USE_BCRYPT */ -+#ifdef USE_YESCRYPT -+ } else if (0 == strcmp (method, "YESCRYPT")) { -+ MAGNUM(result, 'y'); -+ strcat(result, YESCRYPT_salt_cost((int *)arg)); -+#endif /* USE_YESCRYPT */ - #ifdef USE_SHA_CRYPT - } else if (0 == strcmp (method, "SHA256")) { - MAGNUM(result, '5'); -@@ -362,11 +444,21 @@ static /*@observer@*/const char *gensalt - return result; - } else { - #endif /* USE_BCRYPT */ -+#ifdef USE_YESCRYPT -+ if (0 == strcmp (method, "YESCRYPT")) { -+ strncat (result, gensalt_yescrypt (), -+ sizeof (result) - strlen (result) - 1); -+ return result; -+ } else { -+#endif /* USE_YESCRYPT */ - strncat (result, gensalt (salt_len), - sizeof (result) - strlen (result) - 1); -+#ifdef USE_YESCRYPT -+ } -+#endif /* USE_YESCRYPT */ - #ifdef USE_BCRYPT - } --#endif /* USE_BCRYPT */ -+#endif /* USE_BCRYPT */ - - return result; - } -Index: shadow-4.8.1/src/chgpasswd.c -=================================================================== ---- shadow-4.8.1.orig/src/chgpasswd.c -+++ shadow-4.8.1/src/chgpasswd.c -@@ -69,9 +69,9 @@ const char *Prog; - FILE *shadow_logfd = NULL; - static bool eflg = false; - static bool md5flg = false; --#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) -+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) - static bool sflg = false; --#endif /* USE_SHA_CRYPT || USE_BCRYPT */ -+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ - - static /*@null@*//*@observer@*/const char *crypt_method = NULL; - #define cflg (NULL != crypt_method) -@@ -81,6 +81,9 @@ static long sha_rounds = 5000; - #ifdef USE_BCRYPT - static long bcrypt_rounds = 13; - #endif -+#ifdef USE_YESCRYPT -+static long yescrypt_cost = 5; -+#endif - - #ifdef SHADOWGRP - static bool is_shadow_grp; -@@ -139,14 +142,15 @@ static /*@noreturn@*/void usage (int sta - Prog); - (void) fprintf (usageout, - _(" -c, --crypt-method METHOD the crypt method (one of %s)\n"), --#if !defined(USE_SHA_CRYPT) && !defined(USE_BCRYPT) - "NONE DES MD5" --#elif defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) -- "NONE DES MD5 SHA256 SHA512 BCRYPT" --#elif defined(USE_SHA_CRYPT) -- "NONE DES MD5 SHA256 SHA512" --#else -- "NONE DES MD5 BCRYPT" -+#if defined(USE_SHA_CRYPT) -+ " SHA256 SHA512" -+#endif -+#if defined(USE_BCRYPT) -+ " BCRYPT" -+#endif -+#if defined(USE_YESCRYPT) -+ " YESCRYPT" - #endif - ); - (void) fputs (_(" -e, --encrypted supplied passwords are encrypted\n"), usageout); -@@ -155,11 +159,11 @@ static /*@noreturn@*/void usage (int sta - " the MD5 algorithm\n"), - usageout); - (void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout); --#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) -- (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA or BCRYPT\n" -- " crypt algorithms\n"), -+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) -+ (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT\n" -+ " or YESCRYPT crypt algorithms\n"), - usageout); --#endif /* USE_SHA_CRYPT || USE_BCRYPT */ -+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ - (void) fputs ("\n", usageout); - - exit (status); -@@ -173,19 +177,22 @@ static /*@noreturn@*/void usage (int sta - static void process_flags (int argc, char **argv) - { - int c; -+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) -+ int bad_s; -+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ - static struct option long_options[] = { - {"crypt-method", required_argument, NULL, 'c'}, - {"encrypted", no_argument, NULL, 'e'}, - {"help", no_argument, NULL, 'h'}, - {"md5", no_argument, NULL, 'm'}, - {"root", required_argument, NULL, 'R'}, --#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) -+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) - {"sha-rounds", required_argument, NULL, 's'}, --#endif /* USE_SHA_CRYPT || USE_BCRYPT */ -+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ - {NULL, 0, NULL, '\0'} - }; - while ((c = getopt_long (argc, argv, --#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) -+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) - "c:ehmR:s:", - #else - "c:ehmR:", -@@ -206,40 +213,36 @@ static void process_flags (int argc, cha - break; - case 'R': /* no-op, handled in process_root_flag () */ - break; --#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) -+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) - case 's': - sflg = true; -+ bad_s = 0; -+#if defined(USE_SHA_CRYPT) - if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512"))) -- && (0 == getlong(optarg, &sha_rounds))) -- || ( (0 == strcmp (crypt_method, "BCRYPT")) -+ && (0 == getlong(optarg, &sha_rounds)))) { -+ bad_s = 1; -+ } -+#endif /* USE_SHA_CRYPT */ -+#if defined(USE_BCRYPT) -+ if (( (0 == strcmp (crypt_method, "BCRYPT")) - && (0 == getlong(optarg, &bcrypt_rounds)))) { -+ bad_s = 1; -+ } -+#endif /* USE_BCRYPT */ -+#if defined(USE_YESCRYPT) -+ if (( (0 == strcmp (crypt_method, "YESCRYPT")) -+ && (0 == getlong(optarg, &yescrypt_cost)))) { -+ bad_s = 1; -+ } -+#endif /* USE_YESCRYPT */ -+ if (bad_s != 0) { - fprintf (stderr, - _("%s: invalid numeric argument '%s'\n"), - Prog, optarg); - usage (E_USAGE); - } - break; --#elif defined(USE_SHA_CRYPT) -- case 's': -- sflg = true; -- if (0 == getlong(optarg, &sha_rounds)) { -- fprintf (stderr, -- _("%s: invalid numeric argument '%s'\n"), -- Prog, optarg); -- usage (E_USAGE); -- } -- break; --#elif defined(USE_BCRYPT) -- case 's': -- sflg = true; -- if (0 == getlong(optarg, &bcrypt_rounds)) { -- fprintf (stderr, -- _("%s: invalid numeric argument '%s'\n"), -- Prog, optarg); -- usage (E_USAGE); -- } -- break; --#endif -+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ - - default: - usage (E_USAGE); -@@ -258,7 +261,7 @@ static void process_flags (int argc, cha - */ - static void check_flags (void) - { --#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) -+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) - if (sflg && !cflg) { - fprintf (stderr, - _("%s: %s flag is only allowed with the %s flag\n"), -@@ -282,10 +285,13 @@ static void check_flags (void) - #ifdef USE_SHA_CRYPT - && (0 != strcmp (crypt_method, "SHA256")) - && (0 != strcmp (crypt_method, "SHA512")) --#endif -+#endif /* USE_SHA_CRYPT */ - #ifdef USE_BCRYPT - && (0 != strcmp (crypt_method, "BCRYPT")) --#endif -+#endif /* USE_BCRYPT */ -+#ifdef USE_YESCRYPT -+ && (0 != strcmp (crypt_method, "YESCRYPT")) -+#endif /* USE_YESCRYPT */ - ) { - fprintf (stderr, - _("%s: unsupported crypt method: %s\n"), -@@ -592,23 +598,24 @@ int main (int argc, char **argv) - if (md5flg) { - crypt_method = "MD5"; - } --#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) -+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) - if (sflg) { -+#if defined(USE_SHA_CRYPT) - if ( (0 == strcmp (crypt_method, "SHA256")) - || (0 == strcmp (crypt_method, "SHA512"))) { - arg = &sha_rounds; - } -- else if (0 == strcmp (crypt_method, "BCRYPT")) { -+#endif /* USE_SHA_CRYPT */ -+#if defined(USE_BCRYPT) -+ if (0 == strcmp (crypt_method, "BCRYPT")) { - arg = &bcrypt_rounds; - } -- } --#elif defined(USE_SHA_CRYPT) -- if (sflg) { -- arg = &sha_rounds; -- } --#elif defined(USE_BCRYPT) -- if (sflg) { -- arg = &bcrypt_rounds; -+#endif /* USE_BCRYPT */ -+#if defined(USE_YESCRYPT) -+ if (0 == strcmp (crypt_method, "YESCRYPT")) { -+ arg = &yescrypt_cost; -+ } -+#endif /* USE_YESCRYPT */ - } - #endif - salt = crypt_make_salt (crypt_method, arg); -Index: shadow-4.8.1/src/chpasswd.c -=================================================================== ---- shadow-4.8.1.orig/src/chpasswd.c -+++ shadow-4.8.1/src/chpasswd.c -@@ -66,7 +66,7 @@ const char *Prog; - FILE *shadow_logfd = NULL; - static bool eflg = false; - static bool md5flg = false; --#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) -+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) - static bool sflg = false; - #endif - -@@ -78,6 +78,9 @@ static long sha_rounds = 5000; - #ifdef USE_BCRYPT - static long bcrypt_rounds = 13; - #endif -+#ifdef USE_YESCRYPT -+static long yescrypt_cost = 5; -+#endif - - static bool is_shadow_pwd; - static bool pw_locked = false; -@@ -129,14 +132,15 @@ static /*@noreturn@*/void usage (int sta - Prog); - (void) fprintf (usageout, - _(" -c, --crypt-method METHOD the crypt method (one of %s)\n"), --#if !defined(USE_SHA_CRYPT) && !defined(USE_BCRYPT) - "NONE DES MD5" --#elif defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) -- "NONE DES MD5 SHA256 SHA512 BCRYPT" --#elif defined(USE_SHA_CRYPT) -- "NONE DES MD5 SHA256 SHA512" --#else -- "NONE DES MD5 BCRYPT" -+#if defined(USE_SHA_CRYPT) -+ " SHA256 SHA512" -+#endif -+#if defined(USE_BCRYPT) -+ " BCRYPT" -+#endif -+#if defined(USE_YESCRYPT) -+ " YESCRYPT" - #endif - ); - (void) fputs (_(" -e, --encrypted supplied passwords are encrypted\n"), usageout); -@@ -145,11 +149,11 @@ static /*@noreturn@*/void usage (int sta - " the MD5 algorithm\n"), - usageout); - (void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout); --#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) -- (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA or BCRYPT\n" -- " crypt algorithms\n"), -+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) -+ (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT\n" -+ " or YESCRYPT crypt algorithms\n"), - usageout); --#endif /* USE_SHA_CRYPT || USE_BCRYPT */ -+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ - (void) fputs ("\n", usageout); - - exit (status); -@@ -163,20 +167,23 @@ static /*@noreturn@*/void usage (int sta - static void process_flags (int argc, char **argv) - { - int c; -+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) -+ int bad_s; -+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ - static struct option long_options[] = { - {"crypt-method", required_argument, NULL, 'c'}, - {"encrypted", no_argument, NULL, 'e'}, - {"help", no_argument, NULL, 'h'}, - {"md5", no_argument, NULL, 'm'}, - {"root", required_argument, NULL, 'R'}, --#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) -+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) - {"sha-rounds", required_argument, NULL, 's'}, --#endif /* USE_SHA_CRYPT || USE_BCRYPT */ -+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ - {NULL, 0, NULL, '\0'} - }; - - while ((c = getopt_long (argc, argv, --#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) -+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) - "c:ehmR:s:", - #else - "c:ehmR:", -@@ -197,40 +204,36 @@ static void process_flags (int argc, cha - break; - case 'R': /* no-op, handled in process_root_flag () */ - break; --#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) -+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) - case 's': - sflg = true; -+ bad_s = 0; -+#if defined(USE_SHA_CRYPT) - if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512"))) -- && (0 == getlong(optarg, &sha_rounds))) -- || ( (0 == strcmp (crypt_method, "BCRYPT")) -+ && (0 == getlong(optarg, &sha_rounds)))) { -+ bad_s = 1; -+ } -+#endif /* USE_SHA_CRYPT */ -+#if defined(USE_BCRYPT) -+ if (( (0 == strcmp (crypt_method, "BCRYPT")) - && (0 == getlong(optarg, &bcrypt_rounds)))) { -+ bad_s = 1; -+ } -+#endif /* USE_BCRYPT */ -+#if defined(USE_YESCRYPT) -+ if (( (0 == strcmp (crypt_method, "YESCRYPT")) -+ && (0 == getlong(optarg, &yescrypt_cost)))) { -+ bad_s = 1; -+ } -+#endif /* USE_YESCRYPT */ -+ if (bad_s != 0) { - fprintf (stderr, - _("%s: invalid numeric argument '%s'\n"), - Prog, optarg); - usage (E_USAGE); - } - break; --#elif defined(USE_SHA_CRYPT) -- case 's': -- sflg = true; -- if (0 == getlong(optarg, &sha_rounds)) { -- fprintf (stderr, -- _("%s: invalid numeric argument '%s'\n"), -- Prog, optarg); -- usage (E_USAGE); -- } -- break; --#elif defined(USE_BCRYPT) -- case 's': -- sflg = true; -- if (0 == getlong(optarg, &bcrypt_rounds)) { -- fprintf (stderr, -- _("%s: invalid numeric argument '%s'\n"), -- Prog, optarg); -- usage (E_USAGE); -- } -- break; --#endif -+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ - - default: - usage (E_USAGE); -@@ -249,7 +252,7 @@ static void process_flags (int argc, cha - */ - static void check_flags (void) - { --#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) -+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) - if (sflg && !cflg) { - fprintf (stderr, - _("%s: %s flag is only allowed with the %s flag\n"), -@@ -277,6 +280,9 @@ static void check_flags (void) - #ifdef USE_BCRYPT - && (0 != strcmp (crypt_method, "BCRYPT")) - #endif /* USE_BCRYPT */ -+#ifdef USE_YESCRYPT -+ && (0 != strcmp (crypt_method, "YESCRYPT")) -+#endif /* USE_YESCRYPT */ - ) { - fprintf (stderr, - _("%s: unsupported crypt method: %s\n"), -@@ -604,23 +610,24 @@ int main (int argc, char **argv) - if (md5flg) { - crypt_method = "MD5"; - } --#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) -+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) - if (sflg) { -+#if defined(USE_SHA_CRYPT) - if ( (0 == strcmp (crypt_method, "SHA256")) - || (0 == strcmp (crypt_method, "SHA512"))) { - arg = &sha_rounds; - } -- else if (0 == strcmp (crypt_method, "BCRYPT")) { -+#endif /* USE_SHA_CRYPT */ -+#if defined(USE_BCRYPT) -+ if (0 == strcmp (crypt_method, "BCRYPT")) { - arg = &bcrypt_rounds; - } -- } --#elif defined(USE_SHA_CRYPT) -- if (sflg) { -- arg = &sha_rounds; -- } --#elif defined(USE_BCRYPT) -- if (sflg) { -- arg = &bcrypt_rounds; -+#endif /* USE_BCRYPT */ -+#if defined(USE_YESCRYPT) -+ if (0 == strcmp (crypt_method, "YESCRYPT")) { -+ arg = &yescrypt_cost; -+ } -+#endif /* USE_YESCRYPT */ - } - #endif - salt = crypt_make_salt (crypt_method, arg); -Index: shadow-4.8.1/src/newusers.c -=================================================================== ---- shadow-4.8.1.orig/src/newusers.c -+++ shadow-4.8.1/src/newusers.c -@@ -90,6 +90,9 @@ static long sha_rounds = 5000; - #ifdef USE_BCRYPT - static long bcrypt_rounds = 13; - #endif /* USE_BCRYPT */ -+#ifdef USE_YESCRYPT -+static long yescrypt_cost = 5; -+#endif /* USE_YESCRYPT */ - #endif /* !USE_PAM */ - - static bool is_shadow; -@@ -140,14 +143,15 @@ static void usage (int status) - #ifndef USE_PAM - (void) fprintf (usageout, - _(" -c, --crypt-method METHOD the crypt method (one of %s)\n"), --#if !defined(USE_SHA_CRYPT) && !defined(USE_BCRYPT) -- "NONE DES MD5" --#elif defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) -- "NONE DES MD5 SHA256 SHA512 BCRYPT" --#elif defined(USE_SHA_CRYPT) -- "NONE DES MD5 SHA256 SHA512" --#else -- "NONE DES MD5 BCRYPT" -+ "NONE DES MD5" -+#if defined(USE_SHA_CRYPT) -+ " SHA256 SHA512" -+#endif -+#if defined(USE_BCRYPT) -+ " BCRYPT" -+#endif -+#if defined(USE_YESCRYPT) -+ " YESCRYPT" - #endif - ); - #endif /* !USE_PAM */ -@@ -155,11 +159,11 @@ static void usage (int status) - (void) fputs (_(" -r, --system create system accounts\n"), usageout); - (void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout); - #ifndef USE_PAM --#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) -- (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA or BCRYPT\n" -- " crypt algorithms\n"), -+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) -+ (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT\n" -+ " or YESCRYPT crypt algorithms\n"), - usageout); --#endif /* USE_SHA_CRYPT || USE_BCRYPT */ -+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ - #endif /* !USE_PAM */ - (void) fputs ("\n", usageout); - -@@ -434,25 +438,28 @@ static int update_passwd (struct passwd - void *crypt_arg = NULL; - char *cp; - if (NULL != crypt_method) { --#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) -+#if defined(USE_SHA_CRYPT) - if (sflg) { - if ( (0 == strcmp (crypt_method, "SHA256")) - || (0 == strcmp (crypt_method, "SHA512"))) { - crypt_arg = &sha_rounds; - } -- else if (0 == strcmp (crypt_method, "BCRYPT")) { -- crypt_arg = &bcrypt_rounds; -- } - } --#elif defined(USE_SHA_CRYPT) -+#endif /* USE_SHA_CRYPT */ -+#if defined(USE_BCRYPT) - if (sflg) { -- crypt_arg = &sha_rounds; -+ if (0 == strcmp (crypt_method, "BCRYPT")) { -+ crypt_arg = &bcrypt_rounds; -+ } - } --#elif defined(USE_BCRYPT) -+#endif /* USE_BCRYPT */ -+#if defined(USE_YESCRYPT) - if (sflg) { -- crypt_arg = &bcrypt_rounds; -+ if (0 == strcmp (crypt_method, "YESCRYPT")) { -+ crypt_arg = &yescrypt_cost; -+ } - } --#endif -+#endif /* USE_YESCRYPT */ - } - - if ((NULL != crypt_method) && (0 == strcmp(crypt_method, "NONE"))) { -@@ -485,25 +492,28 @@ static int add_passwd (struct passwd *pw - #ifndef USE_PAM - void *crypt_arg = NULL; - if (NULL != crypt_method) { --#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) -+#if defined(USE_SHA_CRYPT) - if (sflg) { - if ( (0 == strcmp (crypt_method, "SHA256")) - || (0 == strcmp (crypt_method, "SHA512"))) { - crypt_arg = &sha_rounds; - } -- else if (0 == strcmp (crypt_method, "BCRYPT")) { -- crypt_arg = &bcrypt_rounds; -- } - } --#elif defined(USE_SHA_CRYPT) -+#endif /* USE_SHA_CRYPT */ -+#if defined(USE_BCRYPT) - if (sflg) { -- crypt_arg = &sha_rounds; -+ if (0 == strcmp (crypt_method, "BCRYPT")) { -+ crypt_arg = &bcrypt_rounds; -+ } - } --#elif defined(USE_BCRYPT) -+#endif /* USE_BCRYPT */ -+#if defined(USE_YESCRYPT) - if (sflg) { -- crypt_arg = &bcrypt_rounds; -+ if (0 == strcmp (crypt_method, "YESCRYPT")) { -+ crypt_arg = &yescrypt_cost; -+ } - } --#endif -+#endif /* USE_PAM */ - } - - /* -@@ -620,6 +630,9 @@ static int add_passwd (struct passwd *pw - static void process_flags (int argc, char **argv) - { - int c; -+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) -+ int bad_s; -+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ - static struct option long_options[] = { - {"badnames", no_argument, NULL, 'b'}, - #ifndef USE_PAM -@@ -629,20 +642,20 @@ static void process_flags (int argc, cha - {"system", no_argument, NULL, 'r'}, - {"root", required_argument, NULL, 'R'}, - #ifndef USE_PAM --#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) -+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) - {"sha-rounds", required_argument, NULL, 's'}, --#endif /* USE_SHA_CRYPT || USE_BCRYPT */ -+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ - #endif /* !USE_PAM */ - {NULL, 0, NULL, '\0'} - }; - - while ((c = getopt_long (argc, argv, - #ifndef USE_PAM --#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) -+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) - "c:bhrs:", --#else /* !USE_SHA_CRYPT && !USE_BCRYPT */ -+#else /* !USE_SHA_CRYPT && !USE_BCRYPT && !USE_YESCRYPT */ - "c:bhr", --#endif /* USE_SHA_CRYPT || USE_BCRYPT */ -+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ - #else /* USE_PAM */ - "bhr", - #endif -@@ -665,40 +678,36 @@ static void process_flags (int argc, cha - case 'R': /* no-op, handled in process_root_flag () */ - break; - #ifndef USE_PAM --#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) -+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) - case 's': - sflg = true; -+ bad_s = 0; -+#if defined(USE_SHA_CRYPT) - if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512"))) -- && (0 == getlong(optarg, &sha_rounds))) -- || ( (0 == strcmp (crypt_method, "BCRYPT")) -+ && (0 == getlong(optarg, &sha_rounds)))) { -+ bad_s = 1; -+ } -+#endif /* USE_SHA_CRYPT */ -+#if defined(USE_BCRYPT) -+ if (( (0 == strcmp (crypt_method, "BCRYPT")) - && (0 == getlong(optarg, &bcrypt_rounds)))) { -+ bad_s = 1; -+ } -+#endif /* USE_BCRYPT */ -+#if defined(USE_YESCRYPT) -+ if (( (0 == strcmp (crypt_method, "YESCRYPT")) -+ && (0 == getlong(optarg, &yescrypt_cost)))) { -+ bad_s = 1; -+ } -+#endif /* USE_YESCRYPT */ -+ if (bad_s != 0) { - fprintf (stderr, - _("%s: invalid numeric argument '%s'\n"), - Prog, optarg); - usage (EXIT_FAILURE); - } - break; --#elif defined(USE_SHA_CRYPT) -- case 's': -- sflg = true; -- if (0 == getlong(optarg, &sha_rounds)) { -- fprintf (stderr, -- _("%s: invalid numeric argument '%s'\n"), -- Prog, optarg); -- usage (EXIT_FAILURE); -- } -- break; --#elif defined(USE_BCRYPT) -- case 's': -- sflg = true; -- if (0 == getlong(optarg, &bcrypt_rounds)) { -- fprintf (stderr, -- _("%s: invalid numeric argument '%s'\n"), -- Prog, optarg); -- usage (EXIT_FAILURE); -- } -- break; --#endif -+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ - #endif /* !USE_PAM */ - default: - usage (EXIT_FAILURE); -@@ -732,14 +741,14 @@ static void process_flags (int argc, cha - static void check_flags (void) - { - #ifndef USE_PAM --#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) -+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) - if (sflg && !cflg) { - fprintf (stderr, - _("%s: %s flag is only allowed with the %s flag\n"), - Prog, "-s", "-c"); - usage (EXIT_FAILURE); - } --#endif -+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ - - if (cflg) { - if ( (0 != strcmp (crypt_method, "DES")) -@@ -752,6 +761,9 @@ static void check_flags (void) - #ifdef USE_BCRYPT - && (0 != strcmp (crypt_method, "BCRYPT")) - #endif /* USE_BCRYPT */ -+#ifdef USE_YESCRYPT -+ && (0 != strcmp (crypt_method, "YESCRYPT")) -+#endif /* USE_YESCRYPT */ - ) { - fprintf (stderr, - _("%s: unsupported crypt method: %s\n"), -Index: shadow-4.8.1/src/passwd.c -=================================================================== ---- shadow-4.8.1.orig/src/passwd.c -+++ shadow-4.8.1/src/passwd.c -@@ -283,7 +283,10 @@ static int new_password (const struct pa - #endif /* USE_SHA_CRYPT */ - #ifdef USE_BCRYPT - || (strcmp (method, "BCRYPT") == 0) --#endif /* USE_SHA_CRYPT */ -+#endif /* USE_BCRYPT*/ -+#ifdef USE_YESCRYPT -+ || (strcmp (method, "YESCRYPT") == 0) -+#endif /* USE_YESCRYPT*/ - - ) { - pass_max_len = -1; diff --git a/shadow-4.8.1-audit-update.patch b/shadow-4.9-audit-update.patch similarity index 99% rename from shadow-4.8.1-audit-update.patch rename to shadow-4.9-audit-update.patch index 1b9586a..99513ef 100644 --- a/shadow-4.8.1-audit-update.patch +++ b/shadow-4.9-audit-update.patch @@ -1537,24 +1537,6 @@ diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1592,7 +1540,7 @@ static void close_files (void) - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); - #ifdef WITH_AUDIT - audit_logger (AUDIT_ADD_USER, Prog, -- "unlocking group file", -+ "unlocking-group-file", - user_name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); - #endif -@@ -1606,7 +1554,7 @@ static void close_files (void) - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - #ifdef WITH_AUDIT - audit_logger (AUDIT_ADD_USER, Prog, -- "unlocking gshadow file", -+ "unlocking-gshadow-file", - user_name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); - #endif @@ -1622,7 +1570,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); #ifdef WITH_AUDIT @@ -1644,7 +1626,7 @@ diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c } if (chown (path, 0, 0) < 0) { @@ -2168,8 +2109,8 @@ static void create_home (void) - chmod (prefix_user_home, mode); + } home_added = true; #ifdef WITH_AUDIT - audit_logger (AUDIT_ADD_USER, Prog, @@ -1705,8 +1687,8 @@ diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c + user_name, (unsigned int) user_id, + SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ - rv = E_SE_UPDATE; - } + fail_exit (E_SE_UPDATE); + } diff -up shadow-4.8.1/src/userdel.c.audit-update shadow-4.8.1/src/userdel.c --- shadow-4.8.1/src/userdel.c.audit-update 2020-03-17 16:53:44.368943259 +0100 +++ shadow-4.8.1/src/userdel.c 2020-03-17 16:53:44.373943325 +0100 diff --git a/shadow-4.1.5.1-default-range.patch b/shadow-4.9-default-range.patch similarity index 72% rename from shadow-4.1.5.1-default-range.patch rename to shadow-4.9-default-range.patch index 2a9d640..f6e0427 100644 --- a/shadow-4.1.5.1-default-range.patch +++ b/shadow-4.9-default-range.patch @@ -1,7 +1,6 @@ -Index: shadow-4.5/lib/semanage.c -=================================================================== ---- shadow-4.5.orig/lib/semanage.c -+++ shadow-4.5/lib/semanage.c +diff -up shadow-4.9/lib/semanage.c.default-range shadow-4.9/lib/semanage.c +--- shadow-4.9/lib/semanage.c.default-range 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/lib/semanage.c 2021-08-02 12:43:16.822817392 +0200 @@ -143,6 +143,7 @@ static int semanage_user_mod (semanage_h goto done; } @@ -9,7 +8,7 @@ Index: shadow-4.5/lib/semanage.c +#if 0 ret = semanage_seuser_set_mlsrange (handle, seuser, DEFAULT_SERANGE); if (ret != 0) { - fprintf (stderr, + fprintf (shadow_logfd, @@ -150,6 +151,7 @@ static int semanage_user_mod (semanage_h ret = 1; goto done; @@ -25,7 +24,7 @@ Index: shadow-4.5/lib/semanage.c +#if 0 ret = semanage_seuser_set_mlsrange (handle, seuser, DEFAULT_SERANGE); if (ret != 0) { - fprintf (stderr, + fprintf (shadow_logfd, @@ -208,6 +211,7 @@ static int semanage_user_add (semanage_h ret = 1; goto done; diff --git a/shadow-4.9-manfix.patch b/shadow-4.9-manfix.patch new file mode 100644 index 0000000..46cba1a --- /dev/null +++ b/shadow-4.9-manfix.patch @@ -0,0 +1,180 @@ +diff -up shadow-4.8.1/man/groupmems.8.xml.manfix shadow-4.8.1/man/groupmems.8.xml +--- shadow-4.8.1/man/groupmems.8.xml.manfix 2020-03-17 15:34:48.750414984 +0100 ++++ shadow-4.8.1/man/groupmems.8.xml 2020-03-17 15:41:13.383588722 +0100 +@@ -179,20 +179,10 @@ + + SETUP + +- The groupmems executable should be in mode +- 2710 as user root and in group +- groups. The system administrator can add users to +- group groups to allow or disallow them using the +- groupmems utility to manage their own group +- membership list. ++ In this operating system the groupmems executable ++ is not setuid and regular users cannot use it to manipulate ++ the membership of their own group. + +- +- +- $ groupadd -r groups +- $ chmod 2710 groupmems +- $ chown root.groups groupmems +- $ groupmems -g groups -a gk4 +- + + + +diff -up shadow-4.8.1/man/ja/man5/login.defs.5.manfix shadow-4.8.1/man/ja/man5/login.defs.5 +--- shadow-4.8.1/man/ja/man5/login.defs.5.manfix 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/man/ja/man5/login.defs.5 2020-03-17 15:34:48.750414984 +0100 +@@ -147,10 +147,6 @@ 以下の参照表は、 + shadow パスワード機能のどのプログラムが + どのパラメータを使用するかを示したものである。 + .na +-.IP chfn 12 +-CHFN_AUTH CHFN_RESTRICT +-.IP chsh 12 +-CHFN_AUTH + .IP groupadd 12 + GID_MAX GID_MIN + .IP newusers 12 +diff -up shadow-4.8.1/man/login.defs.5.xml.manfix shadow-4.8.1/man/login.defs.5.xml +--- shadow-4.8.1/man/login.defs.5.xml.manfix 2020-01-17 16:47:56.000000000 +0100 ++++ shadow-4.8.1/man/login.defs.5.xml 2020-03-17 15:34:48.750414984 +0100 +@@ -164,6 +164,17 @@ + long numeric parameters is machine-dependent. + + ++ ++ Please note that the parameters in this configuration file control the ++ behavior of the tools from the shadow-utils component. None of these ++ tools uses the PAM mechanism, and the utilities that use PAM (such as the ++ passwd command) should be configured elsewhere. The only values that ++ affect PAM modules are ENCRYPT_METHOD and SHA_CRYPT_MAX_ROUNDS ++ for pam_unix module, FAIL_DELAY for pam_faildelay module, ++ and UMASK for pam_umask module. Refer to ++ pam(8) for more information. ++ ++ + The following configuration items are provided: + + +@@ -256,16 +267,6 @@ + + + +- chfn +- +- +- CHFN_AUTH +- CHFN_RESTRICT +- LOGIN_STRING +- +- +- +- + chgpasswd + + +@@ -286,14 +287,6 @@ + + + +- +- chsh +- +- +- CHSH_AUTH LOGIN_STRING +- +- +- + + + +@@ -359,34 +352,6 @@ + LASTLOG_UID_MAX + + +- +- login +- +- +- CONSOLE +- CONSOLE_GROUPS DEFAULT_HOME +- ENV_HZ ENV_PATH ENV_SUPATH +- ENV_TZ ENVIRON_FILE +- ERASECHAR FAIL_DELAY +- FAILLOG_ENAB +- FAKE_SHELL +- FTMP_FILE +- HUSHLOGIN_FILE +- ISSUE_FILE +- KILLCHAR +- LASTLOG_ENAB LASTLOG_UID_MAX +- LOGIN_RETRIES +- LOGIN_STRING +- LOGIN_TIMEOUT LOG_OK_LOGINS LOG_UNKFAIL_ENAB +- MAIL_CHECK_ENAB MAIL_DIR MAIL_FILE +- MOTD_FILE NOLOGINS_FILE PORTTIME_CHECKS_ENAB +- QUOTAS_ENAB +- TTYGROUP TTYPERM TTYTYPE_FILE +- ULIMIT UMASK +- USERGROUPS_ENAB +- +- +- + + + newgrp / sg +@@ -415,17 +380,6 @@ + + + +- +- passwd +- +- +- ENCRYPT_METHOD MD5_CRYPT_ENAB OBSCURE_CHECKS_ENAB +- PASS_ALWAYS_WARN PASS_CHANGE_TRIES PASS_MAX_LEN PASS_MIN_LEN +- SHA_CRYPT_MAX_ROUNDS +- SHA_CRYPT_MIN_ROUNDS +- +- +- + + pwck + +@@ -452,32 +406,6 @@ + + + +- +- su +- +- +- CONSOLE +- CONSOLE_GROUPS DEFAULT_HOME +- ENV_HZ ENVIRON_FILE +- ENV_PATH ENV_SUPATH +- ENV_TZ LOGIN_STRING MAIL_CHECK_ENAB +- MAIL_DIR MAIL_FILE QUOTAS_ENAB +- SULOG_FILE SU_NAME +- SU_WHEEL_ONLY +- SYSLOG_SU_ENAB +- USERGROUPS_ENAB +- +- +- +- +- sulogin +- +- +- ENV_HZ +- ENV_TZ +- +- +- + + useradd + diff --git a/shadow-4.9-move-create-home.patch b/shadow-4.9-move-create-home.patch new file mode 100644 index 0000000..94bb84c --- /dev/null +++ b/shadow-4.9-move-create-home.patch @@ -0,0 +1,64 @@ +diff --git a/src/useradd.c b/src/useradd.c +index baeffb35..02e1402c 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -2644,27 +2644,12 @@ int main (int argc, char **argv) + + usr_update (); + +- if (mflg) { +- create_home (); +- if (home_added) { +- copy_tree (def_template, prefix_user_home, false, false, +- (uid_t)-1, user_id, (gid_t)-1, user_gid); +- } else { +- fprintf (stderr, +- _("%s: warning: the home directory %s already exists.\n" +- "%s: Not copying any file from skel directory into it.\n"), +- Prog, user_home, Prog); +- } +- +- } +- +- /* Do not create mail directory for system accounts */ +- if (!rflg) { +- create_mail (); +- } +- + close_files (); + ++ nscd_flush_cache ("passwd"); ++ nscd_flush_cache ("group"); ++ sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP); ++ + /* + * tallylog_reset needs to be able to lookup + * a valid existing user name, +@@ -2695,9 +2680,24 @@ int main (int argc, char **argv) + exit(1); + } + +- nscd_flush_cache ("passwd"); +- nscd_flush_cache ("group"); +- sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP); ++ if (mflg) { ++ create_home (); ++ if (home_added) { ++ copy_tree (def_template, prefix_user_home, false, true, ++ (uid_t)-1, user_id, (gid_t)-1, user_gid); ++ } else { ++ fprintf (stderr, ++ _("%s: warning: the home directory %s already exists.\n" ++ "%s: Not copying any file from skel directory into it.\n"), ++ Prog, user_home, Prog); ++ } ++ ++ } ++ ++ /* Do not create mail directory for system accounts */ ++ if (!rflg) { ++ create_mail (); ++ } + + return E_SUCCESS; + } diff --git a/shadow-4.9-newuidmap-libeconf-dependency.patch b/shadow-4.9-newuidmap-libeconf-dependency.patch new file mode 100644 index 0000000..a1907a6 --- /dev/null +++ b/shadow-4.9-newuidmap-libeconf-dependency.patch @@ -0,0 +1,15 @@ +diff --git a/src/Makefile.am b/src/Makefile.am +index 7c1a3491..6cc873be 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -96,8 +96,8 @@ LIBCRYPT_NOPAM = $(LIBCRYPT) + endif + + chage_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) +-newuidmap_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP) -ldl +-newgidmap_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP) -ldl ++newuidmap_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP) $(LIBECONF) -ldl ++newgidmap_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP) $(LIBECONF) -ldl + chfn_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF) + chgpasswd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF) + chsh_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF) diff --git a/shadow-4.2.1-null-tm.patch b/shadow-4.9-null-tm.patch similarity index 75% rename from shadow-4.2.1-null-tm.patch rename to shadow-4.9-null-tm.patch index b1dd1c4..249b27b 100644 --- a/shadow-4.2.1-null-tm.patch +++ b/shadow-4.9-null-tm.patch @@ -1,24 +1,3 @@ -Index: shadow-4.5/src/faillog.c -=================================================================== ---- shadow-4.5.orig/src/faillog.c -+++ shadow-4.5/src/faillog.c -@@ -163,10 +163,14 @@ static void print_one (/*@null@*/const s - } - - tm = localtime (&fl.fail_time); -+ if (tm == NULL) { -+ cp = "(unknown)"; -+ } else { - #ifdef HAVE_STRFTIME -- strftime (ptime, sizeof (ptime), "%D %H:%M:%S %z", tm); -- cp = ptime; -+ strftime (ptime, sizeof (ptime), "%D %H:%M:%S %z", tm); -+ cp = ptime; - #endif -+ } - printf ("%-9s %5d %5d ", - pw->pw_name, fl.fail_cnt, fl.fail_max); - /* FIXME: cp is not defined ifndef HAVE_STRFTIME */ Index: shadow-4.5/src/chage.c =================================================================== --- shadow-4.5.orig/src/chage.c diff --git a/shadow-4.6-redhat.patch b/shadow-4.9-redhat.patch similarity index 65% rename from shadow-4.6-redhat.patch rename to shadow-4.9-redhat.patch index 7a8be2e..9dfb3e8 100644 --- a/shadow-4.6-redhat.patch +++ b/shadow-4.9-redhat.patch @@ -1,16 +1,16 @@ -diff -up shadow-4.6/src/useradd.c.redhat shadow-4.6/src/useradd.c ---- shadow-4.6/src/useradd.c.redhat 2018-04-29 18:42:37.000000000 +0200 -+++ shadow-4.6/src/useradd.c 2018-05-28 13:37:16.695651258 +0200 -@@ -98,7 +98,7 @@ const char *Prog; - static gid_t def_group = 100; +diff -up shadow-4.9/src/useradd.c.redhat shadow-4.9/src/useradd.c +--- shadow-4.9/src/useradd.c.redhat 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/src/useradd.c 2021-08-02 11:45:11.942867250 +0200 +@@ -104,7 +104,7 @@ FILE *shadow_logfd = NULL; + static gid_t def_group = 1000; static const char *def_gname = "other"; static const char *def_home = "/home"; --static const char *def_shell = ""; +-static const char *def_shell = "/bin/bash"; +static const char *def_shell = "/sbin/nologin"; static const char *def_template = SKEL_DIR; - static const char *def_create_mail_spool = "no"; + static const char *def_create_mail_spool = "yes"; -@@ -108,7 +108,7 @@ static const char *def_expire = ""; +@@ -114,7 +114,7 @@ static const char *def_expire = ""; #define VALID(s) (strcspn (s, ":\n") == strlen (s)) static const char *user_name = ""; @@ -19,7 +19,7 @@ diff -up shadow-4.6/src/useradd.c.redhat shadow-4.6/src/useradd.c static uid_t user_id; static gid_t user_gid; static const char *user_comment = ""; -@@ -1114,9 +1114,9 @@ static void process_flags (int argc, cha +@@ -1204,9 +1204,9 @@ static void process_flags (int argc, cha }; while ((c = getopt_long (argc, argv, #ifdef WITH_SELINUX @@ -31,7 +31,7 @@ diff -up shadow-4.6/src/useradd.c.redhat shadow-4.6/src/useradd.c #endif /* !WITH_SELINUX */ long_options, NULL)) != -1) { switch (c) { -@@ -1267,6 +1267,7 @@ static void process_flags (int argc, cha +@@ -1363,6 +1363,7 @@ static void process_flags (int argc, cha case 'M': Mflg = true; break; diff --git a/shadow-4.9-usermod-allow-all-group-types.patch b/shadow-4.9-usermod-allow-all-group-types.patch new file mode 100644 index 0000000..fada15e --- /dev/null +++ b/shadow-4.9-usermod-allow-all-group-types.patch @@ -0,0 +1,322 @@ +From e481437ab9ebe9a8bf8fbaabe986d42b2f765991 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Tue, 3 Aug 2021 08:57:20 +0200 +Subject: [PATCH] usermod: allow all group types with -G option + +The only way of removing a group from the supplementary list is to use +-G option, and list all groups that the user is a member of except for +the one that wants to be removed. The problem lies when there's a user +that contains both local and remote groups, and the group to be removed +is a local one. As we need to include the remote group with -G option +the command will fail. + +This reverts commit 140510de9de4771feb3af1d859c09604043a4c9b. This way, +it would be possible to remove the remote groups from the supplementary +list. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1967641 +Resolves: https://github.com/shadow-maint/shadow/issues/338 + +Signed-off-by: Iker Pedrosa +--- + src/usermod.c | 220 ++++++++++++++++++-------------------------------- + 1 file changed, 77 insertions(+), 143 deletions(-) + +diff --git a/src/usermod.c b/src/usermod.c +index 03bb9b9d..a0c03afa 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -187,7 +187,6 @@ static bool sub_gid_locked = false; + static void date_to_str (/*@unique@*//*@out@*/char *buf, size_t maxsize, + long int date); + static int get_groups (char *); +-static struct group * get_local_group (char * grp_name); + static /*@noreturn@*/void usage (int status); + static void new_pwent (struct passwd *); + static void new_spent (struct spwd *); +@@ -201,9 +200,7 @@ static void grp_update (void); + + static void process_flags (int, char **); + static void close_files (void); +-static void close_group_files (void); + static void open_files (void); +-static void open_group_files (void); + static void usr_update (void); + static void move_home (void); + static void update_lastlog (void); +@@ -260,11 +257,6 @@ static int get_groups (char *list) + return 0; + } + +- /* +- * Open the group files +- */ +- open_group_files (); +- + /* + * So long as there is some data to be converted, strip off each + * name and look it up. A mix of numerical and string values for +@@ -284,7 +276,7 @@ static int get_groups (char *list) + * Names starting with digits are treated as numerical GID + * values, otherwise the string is looked up as is. + */ +- grp = get_local_group (list); ++ grp = prefix_getgr_nam_gid (list); + + /* + * There must be a match, either by GID value or by +@@ -334,8 +326,6 @@ static int get_groups (char *list) + gr_free ((struct group *)grp); + } while (NULL != list); + +- close_group_files (); +- + user_groups[ngroups] = (char *) 0; + + /* +@@ -348,44 +338,6 @@ static int get_groups (char *list) + return 0; + } + +-/* +- * get_local_group - checks if a given group name exists locally +- * +- * get_local_group() checks if a given group name exists locally. +- * If the name exists the group information is returned, otherwise NULL is +- * returned. +- */ +-static struct group * get_local_group(char * grp_name) +-{ +- const struct group *grp; +- struct group *result_grp = NULL; +- long long int gid; +- char *endptr; +- +- gid = strtoll (grp_name, &endptr, 10); +- if ( ('\0' != *grp_name) +- && ('\0' == *endptr) +- && (ERANGE != errno) +- && (gid == (gid_t)gid)) { +- grp = gr_locate_gid ((gid_t) gid); +- } +- else { +- grp = gr_locate(grp_name); +- } +- +- if (grp != NULL) { +- result_grp = __gr_dup (grp); +- if (NULL == result_grp) { +- fprintf (stderr, +- _("%s: Out of memory. Cannot find group '%s'.\n"), +- Prog, grp_name); +- fail_exit (E_GRP_UPDATE); +- } +- } +- +- return result_grp; +-} +- + #ifdef ENABLE_SUBIDS + struct ulong_range + { +@@ -1523,7 +1475,50 @@ static void close_files (void) + } + + if (Gflg || lflg) { +- close_group_files (); ++ if (gr_close () == 0) { ++ fprintf (stderr, ++ _("%s: failure while writing changes to %s\n"), ++ Prog, gr_dbname ()); ++ SYSLOG ((LOG_ERR, ++ "failure while writing changes to %s", ++ gr_dbname ())); ++ fail_exit (E_GRP_UPDATE); ++ } ++#ifdef SHADOWGRP ++ if (is_shadow_grp) { ++ if (sgr_close () == 0) { ++ fprintf (stderr, ++ _("%s: failure while writing changes to %s\n"), ++ Prog, sgr_dbname ()); ++ SYSLOG ((LOG_ERR, ++ "failure while writing changes to %s", ++ sgr_dbname ())); ++ fail_exit (E_GRP_UPDATE); ++ } ++ } ++#endif ++#ifdef SHADOWGRP ++ if (is_shadow_grp) { ++ if (sgr_unlock () == 0) { ++ fprintf (stderr, ++ _("%s: failed to unlock %s\n"), ++ Prog, sgr_dbname ()); ++ SYSLOG ((LOG_ERR, ++ "failed to unlock %s", ++ sgr_dbname ())); ++ /* continue */ ++ } ++ } ++#endif ++ if (gr_unlock () == 0) { ++ fprintf (stderr, ++ _("%s: failed to unlock %s\n"), ++ Prog, gr_dbname ()); ++ SYSLOG ((LOG_ERR, ++ "failed to unlock %s", ++ gr_dbname ())); ++ /* continue */ ++ } + } + + if (is_shadow_pwd) { +@@ -1592,60 +1587,6 @@ static void close_files (void) + #endif + } + +-/* +- * close_group_files - close all of the files that were opened +- * +- * close_group_files() closes all of the files that were opened related +- * with groups. This causes any modified entries to be written out. +- */ +-static void close_group_files (void) +-{ +- if (gr_close () == 0) { +- fprintf (stderr, +- _("%s: failure while writing changes to %s\n"), +- Prog, gr_dbname ()); +- SYSLOG ((LOG_ERR, +- "failure while writing changes to %s", +- gr_dbname ())); +- fail_exit (E_GRP_UPDATE); +- } +-#ifdef SHADOWGRP +- if (is_shadow_grp) { +- if (sgr_close () == 0) { +- fprintf (stderr, +- _("%s: failure while writing changes to %s\n"), +- Prog, sgr_dbname ()); +- SYSLOG ((LOG_ERR, +- "failure while writing changes to %s", +- sgr_dbname ())); +- fail_exit (E_GRP_UPDATE); +- } +- } +-#endif +-#ifdef SHADOWGRP +- if (is_shadow_grp) { +- if (sgr_unlock () == 0) { +- fprintf (stderr, +- _("%s: failed to unlock %s\n"), +- Prog, sgr_dbname ()); +- SYSLOG ((LOG_ERR, +- "failed to unlock %s", +- sgr_dbname ())); +- /* continue */ +- } +- } +-#endif +- if (gr_unlock () == 0) { +- fprintf (stderr, +- _("%s: failed to unlock %s\n"), +- Prog, gr_dbname ()); +- SYSLOG ((LOG_ERR, +- "failed to unlock %s", +- gr_dbname ())); +- /* continue */ +- } +-} +- + /* + * open_files - lock and open the password files + * +@@ -1681,7 +1622,38 @@ static void open_files (void) + } + + if (Gflg || lflg) { +- open_group_files (); ++ /* ++ * Lock and open the group file. This will load all of the ++ * group entries. ++ */ ++ if (gr_lock () == 0) { ++ fprintf (stderr, ++ _("%s: cannot lock %s; try again later.\n"), ++ Prog, gr_dbname ()); ++ fail_exit (E_GRP_UPDATE); ++ } ++ gr_locked = true; ++ if (gr_open (O_CREAT | O_RDWR) == 0) { ++ fprintf (stderr, ++ _("%s: cannot open %s\n"), ++ Prog, gr_dbname ()); ++ fail_exit (E_GRP_UPDATE); ++ } ++#ifdef SHADOWGRP ++ if (is_shadow_grp && (sgr_lock () == 0)) { ++ fprintf (stderr, ++ _("%s: cannot lock %s; try again later.\n"), ++ Prog, sgr_dbname ()); ++ fail_exit (E_GRP_UPDATE); ++ } ++ sgr_locked = true; ++ if (is_shadow_grp && (sgr_open (O_CREAT | O_RDWR) == 0)) { ++ fprintf (stderr, ++ _("%s: cannot open %s\n"), ++ Prog, sgr_dbname ()); ++ fail_exit (E_GRP_UPDATE); ++ } ++#endif + } + #ifdef ENABLE_SUBIDS + if (vflg || Vflg) { +@@ -1717,44 +1689,6 @@ static void open_files (void) + #endif /* ENABLE_SUBIDS */ + } + +-/* +- * open_group_files - lock and open the group files +- * +- * open_group_files() loads all of the group entries. +- */ +-static void open_group_files (void) +-{ +- if (gr_lock () == 0) { +- fprintf (stderr, +- _("%s: cannot lock %s; try again later.\n"), +- Prog, gr_dbname ()); +- fail_exit (E_GRP_UPDATE); +- } +- gr_locked = true; +- if (gr_open (O_CREAT | O_RDWR) == 0) { +- fprintf (stderr, +- _("%s: cannot open %s\n"), +- Prog, gr_dbname ()); +- fail_exit (E_GRP_UPDATE); +- } +- +-#ifdef SHADOWGRP +- if (is_shadow_grp && (sgr_lock () == 0)) { +- fprintf (stderr, +- _("%s: cannot lock %s; try again later.\n"), +- Prog, sgr_dbname ()); +- fail_exit (E_GRP_UPDATE); +- } +- sgr_locked = true; +- if (is_shadow_grp && (sgr_open (O_CREAT | O_RDWR) == 0)) { +- fprintf (stderr, +- _("%s: cannot open %s\n"), +- Prog, sgr_dbname ()); +- fail_exit (E_GRP_UPDATE); +- } +-#endif +-} +- + /* + * usr_update - create the user entries + * +-- +2.31.1 + diff --git a/shadow-utils.spec b/shadow-utils.spec index c6caf48..c1becdd 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils -Version: 4.8.1 -Release: 20%{?dist} +Version: 4.9 +Release: 1%{?dist} Epoch: 2 URL: https://github.com/shadow-maint/shadow Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -17,111 +17,37 @@ Source6: shadow-utils.HOME_MODE.xml ### Patches ### # Misc small changes - most probably non-upstreamable -Patch0: shadow-4.6-redhat.patch +Patch0: shadow-4.9-redhat.patch # Be more lenient with acceptable user/group names - non upstreamable Patch1: shadow-4.8-goodname.patch -# https://github.com/shadow-maint/shadow/commit/7384865775b0203b9cf5337a047744f0a4555868 -Patch2: shadow-4.1.5.1-info-parent-dir.patch -# Misc SElinux related changes - upstreamability unknown -Patch6: shadow-4.8-selinux.patch -# https://github.com/shadow-maint/shadow/commit/a8361e741040cd926c9c93aac89820052531b1a3 -Patch11: shadow-4.1.5.1-logmsg.patch +# Move create home to the end of main - upstreamability unknown +Patch2: shadow-4.9-move-create-home.patch # SElinux related - upstreamability unknown -Patch14: shadow-4.1.5.1-default-range.patch -# Misc manual page changes -# https://github.com/shadow-maint/shadow/commit/c0818ab01d1896784245eedec9495e1e6e0260af -# Changes in man/groupmems.8.xml, man/ja/man5/login.defs.5 and man/login.defs.5.xml not upstreamed -Patch15: shadow-4.8.1-manfix.patch -# https://github.com/shadow-maint/shadow/commit/f4cbf38ad7801bab6fae50e9b5a2effc3c48a1ea -Patch17: shadow-4.1.5.1-userdel-helpfix.patch +Patch3: shadow-4.9-default-range.patch +# Misc manual page changes - non-upstreamable +Patch4: shadow-4.9-manfix.patch # Date parsing improvement - could be upstreamed -Patch19: shadow-4.2.1-date-parsing.patch +Patch5: shadow-4.2.1-date-parsing.patch # Additional error message - could be upstreamed -Patch21: shadow-4.6-move-home.patch +Patch6: shadow-4.6-move-home.patch # Audit message changes - upstreamability unknown -Patch22: shadow-4.8.1-audit-update.patch +Patch7: shadow-4.9-audit-update.patch # Changes related to password unlocking - could be upstreamed -Patch23: shadow-4.5-usermod-unlock.patch +Patch8: shadow-4.5-usermod-unlock.patch # Additional SElinux related changes - upstreamability unknown -Patch28: shadow-4.8-selinux-perms.patch +Patch9: shadow-4.8-selinux-perms.patch # Handle NULL return from *time funcs - could be upstreamed -Patch29: shadow-4.2.1-null-tm.patch -# SElinux related - upstreamability unknown -Patch31: shadow-4.6-getenforce.patch -# https://github.com/shadow-maint/shadow/commit/c93897a8d71b9b1790caf3b2dee38dbe62518ae3 -Patch32: shadow-4.8-crypt_h.patch +Patch10: shadow-4.9-null-tm.patch # Handle /etc/passwd corruption - could be upstreamed -Patch33: shadow-4.8-long-entry.patch +Patch11: shadow-4.8-long-entry.patch # Limit uid/gid allocation to non-zero - could be upstreamed -Patch38: shadow-4.6-sysugid-min-limit.patch +Patch12: shadow-4.6-sysugid-min-limit.patch # Ignore LOGIN_PLAIN_PROMPT in login.defs - upstreamability unknown -Patch40: shadow-4.8-ignore-login-prompt.patch -# Generate /var/spool/mail/$USER with the proper SELinux user identity - already upstreamed -Patch42: shadow-4.8-useradd-selinux-mail.patch -# Clarify useradd man regarding "-d" parameter - already upstreamed -Patch43: shadow-4.8.1-useradd-man-clarification.patch -# https://github.com/shadow-maint/shadow/commit/140510de9de4771feb3af1d859c09604043a4c9b -# https://github.com/shadow-maint/shadow/commit/8762f465d487a52bf68f9c0b7c3c1eb3caea7bc9 -Patch44: shadow-4.8.1-check-local-groups.patch -# https://github.com/shadow-maint/shadow/commit/599cc003daf833bffdc9cbe0d33dc8b3e7ec74c8 -Patch45: shadow-4.8.1-commonio-force-lock-file-sync.patch -# https://github.com/shadow-maint/shadow/commit/df6ec1d1693c8c80c323b40d6fc82bb549363db3 -Patch46: shadow-4.8.1-man-include-lastlog-file-caveat.patch -# https://github.com/shadow-maint/shadow/commit/0a7888b1fad613a052b988b01a71933b67296e68 -# https://github.com/shadow-maint/shadow/commit/607f1dd549cf9abc87af1cf29275f0d2d11eea29 -# https://github.com/shadow-maint/shadow/commit/b5fb1b38eea2fb0489ed088c82daf6700e72363e -# https://github.com/shadow-maint/shadow/commit/43a917cce54019799a8de037fd63780a2b640afc -Patch47: shadow-4.8.1-libsubid_creation.patch -# https://github.com/shadow-maint/shadow/commit/514c1328b6c90d817ae0a9f7addfb3c9a11a275a -# https://github.com/shadow-maint/shadow/commit/8492dee6632e340dee76eee895c3e30877bebf45 -# https://github.com/shadow-maint/shadow/commit/0f4347d1483191b2142546416a9eefe0c9459600 -Patch48: shadow-4.8.1-libsubid_nsswitch_support.patch -# https://github.com/shadow-maint/shadow/commit/186b1b7ac1a68d0fcc618a22da1a99232b420911 -Patch49: shadow-4.8.1-man-mention-nss-in-newuidmap.patch -# https://github.com/shadow-maint/shadow/commit/f9831a4a1a20b0e8fe47cc72ec20018ec04dbb90 -Patch50: shadow-4.8.1-libsubid_not_print_error_messages.patch -# https://github.com/shadow-maint/shadow/commit/c6cab4a7bafa18d9d65a333cac1261e7b5e32bc9 -Patch51: shadow-4.8.1-libsubid_init_return_false.patch -# https://github.com/shadow-maint/shadow/commit/2f1f45d64fc7c10e7a3cbe00e89f63714343e526 -Patch52: shadow-4.8.1-useradd_SUB_UID_COUNT-0.patch -# https://github.com/shadow-maint/shadow/commit/ea7af4e1543c63590d4107ae075fea385028997d -Patch53: shadow-4.8.1-libsubid_simplify_ranges_variable.patch -# https://github.com/shadow-maint/shadow/commit/0fe42f571c69f0105d31305f995c9887aeb9525e -Patch54: shadow-4.8.1-libsubid_init_not_print_error_messages.patch -# https://github.com/shadow-maint/shadow/commit/ec1951c181faed188464396b2cfdd2efb726c7f3 -Patch55: shadow-4.8.1-libsubid_fix_newusers_nss_provides_subids.patch -# https://github.com/shadow-maint/shadow/commit/087112244327be50abc24f9ec8afbf60ae8b2dec -# https://github.com/shadow-maint/shadow/pull/353 -Patch56: shadow-4.8.1-man_clarify_subid_delegation.patch -# https://github.com/shadow-maint/shadow/commit/bd920ab36a6c641e4a8769f8c7f8ca738ec61820 -Patch57: shadow-4.8.1-libsubid_make_logfd_not_extern.patch -# https://github.com/shadow-maint/shadow/commit/5cd04d03f94622c12220d4a6352824af081b8531 -Patch58: shadow-4.8.1-yescrypt-support.patch -# https://github.com/shadow-maint/shadow/commit/7a3bb4d0ea8166acc539c788a8ce943acf4a6aa7 -Patch59: shadow-4.8.1-fix_YESCRYPT_salt_cost_param_type.patch -# https://github.com/shadow-maint/shadow/commit/c44b71cec25d60efc51aec9de3abce1f6efbfcf5 -# https://github.com/shadow-maint/shadow/commit/fd9d79a1a3438ba7703939cfcd45fc266782c64e -# https://github.com/shadow-maint/shadow/commit/8281c82e324b57b3a4b520afad26b43ce128d521 -# https://github.com/shadow-maint/shadow/commit/1aed7ae945aafaeb253fc89a7ecedeaedf72654e -# https://github.com/shadow-maint/shadow/commit/5d0d7841971cc53d9a9d1aefe12f00204115bf6a -# https://github.com/shadow-maint/shadow/commit/e65cc6aebcb4132fa413f00a905216a5b35b3d57 -Patch60: shadow-4.8.1-covscan_fixes.patch -# https://github.com/shadow-maint/shadow/commit/738d92a4bd99a2038aa5f97b2fc85daa7011e403 -Patch61: shadow-4.8.1-fix_bcrypt_prefix.patch -# https://github.com/shadow-maint/shadow/commit/14b108728a5d55c3d478a170c39f0e2ffd4de1b0 -Patch62: shadow-4.8.1-salt_c_sanitize_code.patch -# https://github.com/shadow-maint/shadow/commit/dbf230e4cf823dd6b6a3bad6d29dfad4f0ffa8fc -Patch63: shadow-4.8.1-salt_c_comments.patch -# https://github.com/shadow-maint/shadow/commit/bc8257cf73328e450511b13cbd35e1994feccb30 -Patch64: shadow-4.8.1-salt_c_use_dev_urandom.patch -# https://github.com/shadow-maint/shadow/commit/2c542f6c65f858b3dba20f58db4da56572f67a54 -Patch65: shadow-4.8.1-useradd_create_relative_home_path_correctly.patch -# https://github.com/shadow-maint/shadow/commit/c82ed0c15e0e9e47df0b4c22672b72e35f061a9d -Patch66: shadow-4.8.1-getentropy_random_bytes.patch -# https://github.com/shadow-maint/shadow/commit/ea04eb301d08c0c58f1120f87d4ec184d3983ce5 -Patch67: shadow-4.8.1-crypt_gensalt.patch -# https://github.com/shadow-maint/shadow/commit/ffd35d89021a9b8375a9246082afc6fc270a93ee -Patch68: shadow-4.8.1-salt_c_fix_fread.patch +Patch13: shadow-4.8-ignore-login-prompt.patch +# https://github.com/shadow-maint/shadow/pull/395 +Patch14: shadow-4.9-newuidmap-libeconf-dependency.patch +# https://github.com/shadow-maint/shadow/pull/397 +Patch15: shadow-4.9-usermod-allow-all-group-types.patch License: BSD and GPLv2+ BuildRequires: make @@ -171,50 +97,20 @@ Development files for shadow-utils-subid. %setup -q -n shadow-%{version} %patch0 -p1 -b .redhat %patch1 -p1 -b .goodname -%patch2 -p1 -b .info-parent-dir -%patch6 -p1 -b .selinux -%patch11 -p1 -b .logmsg -%patch14 -p1 -b .default-range -%patch15 -p1 -b .manfix -%patch17 -p1 -b .userdel -%patch19 -p1 -b .date-parsing -%patch21 -p1 -b .move-home -%patch22 -p1 -b .audit-update -%patch23 -p1 -b .unlock -%patch28 -p1 -b .selinux-perms -%patch29 -p1 -b .null-tm -%patch31 -p1 -b .getenforce -%patch32 -p1 -b .crypt_h -%patch33 -p1 -b .long-entry -%patch38 -p1 -b .sysugid-min-limit -%patch40 -p1 -b .login-prompt -%patch42 -p1 -b .useradd-selinux-mail -%patch43 -p1 -b .useradd-man-clarification -%patch44 -p1 -b .check-local-groups -%patch45 -p1 -b .commonio-force-lock-file-sync -%patch46 -p1 -b .man-include-lastlog-file-caveat -%patch47 -p1 -b .libsubid_creation -%patch48 -p1 -b .libsubid_nsswitch_support -%patch49 -p1 -b .man-mention-nss-in-newuidmap -%patch50 -p1 -b .libsubid_not_print_error_messages -%patch51 -p1 -b .libsubid_init_return_false -%patch52 -p1 -b .useradd_SUB_UID_COUNT-0 -%patch53 -p1 -b .libsubid_simplify_ranges_variable -%patch54 -p1 -b .libsubid_init_not_print_error_messages -%patch55 -p1 -b .libsubid_fix_newusers_nss_provides_subids -%patch56 -p1 -b .man_clarify_subid_delegation -%patch57 -p1 -b .libsubid_make_logfd_not_extern -%patch58 -p1 -b .yescrypt -%patch59 -p1 -b .YESCRYPT_salt_cost_param_type -%patch60 -p1 -b .covscan_fixes -%patch61 -p1 -b .bcrypt_prefix -%patch62 -p1 -b .sanitize_code -%patch63 -p1 -b .comments -%patch64 -p1 -b .use_dev_urandom -%patch65 -p1 -b .useradd_create_relative_home_path_correctly -%patch66 -p1 -b .getentropy_random_bytes -%patch67 -p1 -b .crypt_gensalt -%patch68 -p1 -b .fix_fread +%patch2 -p1 -b .move-create-home +%patch3 -p1 -b .default-range +%patch4 -p1 -b .manfix +%patch5 -p1 -b .date-parsing +%patch6 -p1 -b .move-home +%patch7 -p1 -b .audit-update +%patch8 -p1 -b .unlock +%patch9 -p1 -b .selinux-perms +%patch10 -p1 -b .null-tm +%patch11 -p1 -b .long-entry +%patch12 -p1 -b .sysugid-min-limit +%patch13 -p1 -b .login-prompt +%patch14 -p1 -b .newuidmap-libeconf-dependency +%patch15 -p1 -b .usermod-allow-all-group-types iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -385,6 +281,11 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la %{_libdir}/libsubid.so %changelog +* Wed Aug 4 2021 Iker Pedrosa - 2:4.9-1 +- Rebase to version 4.9 +- usermod: allow all group types with -G option (#1975327) +- Clean spec file + * Fri Jul 23 2021 Fedora Release Engineering - 2:4.8.1-20 - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild diff --git a/sources b/sources index 0e0c57a..803fac0 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (shadow-4.8.1.tar.xz) = 780a983483d847ed3c91c82064a0fa902b6f4185225978241bc3bc03fcc3aa143975b46aee43151c6ba43efcfdb1819516b76ba7ad3d1d3c34fcc38ea42e917b -SHA512 (shadow-4.8.1.tar.xz.asc) = ec7686263c81d3feb8ee4314c3323a9a3ada74aafaaf99f4f0d9af9b1341f8c5ff5477ecf98dd94dbb7d921f532d655b0b6a87d94c71893f35dc9bc54c84dd42 +SHA512 (shadow-4.9.tar.xz) = 254cda49bb14505a7604821e7fa898bf4bf317d648e9ddc881ab80a6860d52053dfffacad6feab87c7d16608c35ed6b6cee99e7757eac930da3a7b31cdcd4b95 +SHA512 (shadow-4.9.tar.xz.asc) = 16c0ff7be263c9d471b05656c9a1d14da8ec9b17544910323ca6ab854126d1a03ece221e0caf610e65a9b1d080b4cd1b8b46973f20e3ae45ea0e5581ce6c90d9 From 3a328328567ec0e4ec8f6e3dacdba36022b121a2 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Wed, 11 Aug 2021 14:58:12 +0200 Subject: [PATCH 048/134] useradd: avoid generating an empty subid range (#1990653) Signed-off-by: Iker Pedrosa --- ...d-avoid-generating-empty-subid-range.patch | 79 +++++++++++++++++++ shadow-utils.spec | 12 ++- 2 files changed, 88 insertions(+), 3 deletions(-) create mode 100644 shadow-4.9-useradd-avoid-generating-empty-subid-range.patch diff --git a/shadow-4.9-useradd-avoid-generating-empty-subid-range.patch b/shadow-4.9-useradd-avoid-generating-empty-subid-range.patch new file mode 100644 index 0000000..b94fd60 --- /dev/null +++ b/shadow-4.9-useradd-avoid-generating-empty-subid-range.patch @@ -0,0 +1,79 @@ +diff --git a/src/useradd.c b/src/useradd.c +index baeffb35..9abeea6e 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -142,9 +142,7 @@ static bool is_sub_gid = false; + static bool sub_uid_locked = false; + static bool sub_gid_locked = false; + static uid_t sub_uid_start; /* New subordinate uid range */ +-static unsigned long sub_uid_count; + static gid_t sub_gid_start; /* New subordinate gid range */ +-static unsigned long sub_gid_count; + #endif /* ENABLE_SUBIDS */ + static bool pw_locked = false; + static bool gr_locked = false; +@@ -234,7 +232,7 @@ static void open_shadow (void); + static void faillog_reset (uid_t); + static void lastlog_reset (uid_t); + static void tallylog_reset (const char *); +-static void usr_update (void); ++static void usr_update (unsigned long subuid_count, unsigned long subgid_count); + static void create_home (void); + static void create_mail (void); + static void check_uid_range(int rflg, uid_t user_id); +@@ -2092,7 +2090,7 @@ static void tallylog_reset (const char *user_name) + * usr_update() creates the password file entries for this user + * and will update the group entries if required. + */ +-static void usr_update (void) ++static void usr_update (unsigned long subuid_count, unsigned long subgid_count) + { + struct passwd pwent; + struct spwd spent; +@@ -2155,14 +2153,14 @@ static void usr_update (void) + } + #ifdef ENABLE_SUBIDS + if (is_sub_uid && +- (sub_uid_add(user_name, sub_uid_start, sub_uid_count) == 0)) { ++ (sub_uid_add(user_name, sub_uid_start, subuid_count) == 0)) { + fprintf (stderr, + _("%s: failed to prepare the new %s entry\n"), + Prog, sub_uid_dbname ()); + fail_exit (E_SUB_UID_UPDATE); + } + if (is_sub_gid && +- (sub_gid_add(user_name, sub_gid_start, sub_gid_count) == 0)) { ++ (sub_gid_add(user_name, sub_gid_start, subgid_count) == 0)) { + fprintf (stderr, + _("%s: failed to prepare the new %s entry\n"), + Prog, sub_uid_dbname ()); +@@ -2624,16 +2622,16 @@ int main (int argc, char **argv) + } + + #ifdef ENABLE_SUBIDS +- if (is_sub_uid && sub_uid_count != 0) { +- if (find_new_sub_uids(&sub_uid_start, &sub_uid_count) < 0) { ++ if (is_sub_uid && subuid_count != 0) { ++ if (find_new_sub_uids(&sub_uid_start, &subuid_count) < 0) { + fprintf (stderr, + _("%s: can't create subordinate user IDs\n"), + Prog); + fail_exit(E_SUB_UID_UPDATE); + } + } +- if (is_sub_gid && sub_gid_count != 0) { +- if (find_new_sub_gids(&sub_gid_start, &sub_gid_count) < 0) { ++ if (is_sub_gid && subgid_count != 0) { ++ if (find_new_sub_gids(&sub_gid_start, &subgid_count) < 0) { + fprintf (stderr, + _("%s: can't create subordinate group IDs\n"), + Prog); +@@ -2642,7 +2640,7 @@ int main (int argc, char **argv) + } + #endif /* ENABLE_SUBIDS */ + +- usr_update (); ++ usr_update (subuid_count, subgid_count); + + close_files (); + diff --git a/shadow-utils.spec b/shadow-utils.spec index c1becdd..47d61e0 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.9 -Release: 1%{?dist} +Release: 2%{?dist} Epoch: 2 URL: https://github.com/shadow-maint/shadow Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -44,10 +44,12 @@ Patch11: shadow-4.8-long-entry.patch Patch12: shadow-4.6-sysugid-min-limit.patch # Ignore LOGIN_PLAIN_PROMPT in login.defs - upstreamability unknown Patch13: shadow-4.8-ignore-login-prompt.patch -# https://github.com/shadow-maint/shadow/pull/395 +# https://github.com/shadow-maint/shadow/commit/c6847011e8b656adacd9a0d2a78418cad0de34cb Patch14: shadow-4.9-newuidmap-libeconf-dependency.patch -# https://github.com/shadow-maint/shadow/pull/397 +# https://github.com/shadow-maint/shadow/commit/e481437ab9ebe9a8bf8fbaabe986d42b2f765991 Patch15: shadow-4.9-usermod-allow-all-group-types.patch +# https://github.com/shadow-maint/shadow/pull/399 +Patch16: shadow-4.9-useradd-avoid-generating-empty-subid-range.patch License: BSD and GPLv2+ BuildRequires: make @@ -111,6 +113,7 @@ Development files for shadow-utils-subid. %patch13 -p1 -b .login-prompt %patch14 -p1 -b .newuidmap-libeconf-dependency %patch15 -p1 -b .usermod-allow-all-group-types +%patch16 -p1 -b .useradd-avoid-generating-empty-subid-range iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -281,6 +284,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la %{_libdir}/libsubid.so %changelog +* Mon Aug 9 2021 Iker Pedrosa - 2:4.9-2 +- useradd: avoid generating an empty subid range (#1990653) + * Wed Aug 4 2021 Iker Pedrosa - 2:4.9-1 - Rebase to version 4.9 - usermod: allow all group types with -G option (#1975327) From fbc8eba072226a39bbe8dc9008e43428ce595900 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Tue, 17 Aug 2021 09:49:01 +0200 Subject: [PATCH 049/134] libmisc: fix default value in SHA_get_salt_rounds() Signed-off-by: Iker Pedrosa --- ...default-value-in-SHA_get_salt_rounds.patch | 60 +++++++++++++++++++ shadow-utils.spec | 10 +++- 2 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 shadow-4.9-libmisc-fix-default-value-in-SHA_get_salt_rounds.patch diff --git a/shadow-4.9-libmisc-fix-default-value-in-SHA_get_salt_rounds.patch b/shadow-4.9-libmisc-fix-default-value-in-SHA_get_salt_rounds.patch new file mode 100644 index 0000000..5eaaec9 --- /dev/null +++ b/shadow-4.9-libmisc-fix-default-value-in-SHA_get_salt_rounds.patch @@ -0,0 +1,60 @@ +From 234e8fa7b134d1ebabfdad980a3ae5b63c046c62 Mon Sep 17 00:00:00 2001 +From: Mike Gilbert +Date: Sat, 14 Aug 2021 13:24:34 -0400 +Subject: [PATCH] libmisc: fix default value in SHA_get_salt_rounds() + +If SHA_CRYPT_MIN_ROUNDS and SHA_CRYPT_MAX_ROUNDS are both unspecified, +use SHA_ROUNDS_DEFAULT. + +Previously, the code fell through, calling shadow_random(-1, -1). This +ultimately set rounds = (unsigned long) -1, which ends up being a very +large number! This then got capped to SHA_ROUNDS_MAX later in the +function. + +The new behavior matches BCRYPT_get_salt_rounds(). + +Bug: https://bugs.gentoo.org/808195 +Fixes: https://github.com/shadow-maint/shadow/issues/393 +--- + libmisc/salt.c | 21 +++++++++++---------- + 1 file changed, 11 insertions(+), 10 deletions(-) + +diff --git a/libmisc/salt.c b/libmisc/salt.c +index 91d528fd..30eefb9c 100644 +--- a/libmisc/salt.c ++++ b/libmisc/salt.c +@@ -223,20 +223,21 @@ static /*@observer@*/const unsigned long SHA_get_salt_rounds (/*@null@*/int *pre + if ((-1 == min_rounds) && (-1 == max_rounds)) { + rounds = SHA_ROUNDS_DEFAULT; + } ++ else { ++ if (-1 == min_rounds) { ++ min_rounds = max_rounds; ++ } + +- if (-1 == min_rounds) { +- min_rounds = max_rounds; +- } ++ if (-1 == max_rounds) { ++ max_rounds = min_rounds; ++ } + +- if (-1 == max_rounds) { +- max_rounds = min_rounds; +- } ++ if (min_rounds > max_rounds) { ++ max_rounds = min_rounds; ++ } + +- if (min_rounds > max_rounds) { +- max_rounds = min_rounds; ++ rounds = (unsigned long) shadow_random (min_rounds, max_rounds); + } +- +- rounds = (unsigned long) shadow_random (min_rounds, max_rounds); + } else if (0 == *prefered_rounds) { + rounds = SHA_ROUNDS_DEFAULT; + } else { +-- +2.31.1 + diff --git a/shadow-utils.spec b/shadow-utils.spec index 47d61e0..f753ae7 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.9 -Release: 2%{?dist} +Release: 3%{?dist} Epoch: 2 URL: https://github.com/shadow-maint/shadow Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz @@ -48,8 +48,10 @@ Patch13: shadow-4.8-ignore-login-prompt.patch Patch14: shadow-4.9-newuidmap-libeconf-dependency.patch # https://github.com/shadow-maint/shadow/commit/e481437ab9ebe9a8bf8fbaabe986d42b2f765991 Patch15: shadow-4.9-usermod-allow-all-group-types.patch -# https://github.com/shadow-maint/shadow/pull/399 +# https://github.com/shadow-maint/shadow/commit/9dd720a28578eef5be8171697aae0906e4c53249 Patch16: shadow-4.9-useradd-avoid-generating-empty-subid-range.patch +# https://github.com/shadow-maint/shadow/commit/234e8fa7b134d1ebabfdad980a3ae5b63c046c62 +Patch17: shadow-4.9-libmisc-fix-default-value-in-SHA_get_salt_rounds.patch License: BSD and GPLv2+ BuildRequires: make @@ -114,6 +116,7 @@ Development files for shadow-utils-subid. %patch14 -p1 -b .newuidmap-libeconf-dependency %patch15 -p1 -b .usermod-allow-all-group-types %patch16 -p1 -b .useradd-avoid-generating-empty-subid-range +%patch17 -p1 -b .libmisc-fix-default-value-in-SHA_get_salt_rounds iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -284,6 +287,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la %{_libdir}/libsubid.so %changelog +* Tue Aug 17 2021 Iker Pedrosa - 2:4.9-3 +- libmisc: fix default value in SHA_get_salt_rounds() + * Mon Aug 9 2021 Iker Pedrosa - 2:4.9-2 - useradd: avoid generating an empty subid range (#1990653) From 981bd7a0930fc16277f0149fe6054a5f49c5bdfe Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Tue, 21 Sep 2021 10:37:43 +0200 Subject: [PATCH 050/134] - login.defs: include HMAC_CRYPTO_ALGO key - Clean spec file: organize dependencies and move License location Signed-off-by: Iker Pedrosa --- shadow-utils.login.defs | 10 ++++++++++ shadow-utils.spec | 41 +++++++++++++++++++++++++++++------------ 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/shadow-utils.login.defs b/shadow-utils.login.defs index 486203b..a6c34a1 100644 --- a/shadow-utils.login.defs +++ b/shadow-utils.login.defs @@ -293,3 +293,13 @@ CREATE_HOME yes # missing. # #FORCE_SHADOW yes + +# +# Select the HMAC cryptography algorithm. +# Used in pam_timestamp module to calculate the keyed-hash message +# authentication code. +# +# Note: It is recommended to check hmac(3) to see the possible algorithms +# that are available in your system. +# +HMAC_CRYPTO_ALGO SHA512 diff --git a/shadow-utils.spec b/shadow-utils.spec index f753ae7..051708d 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,8 +1,9 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.9 -Release: 3%{?dist} +Release: 4%{?dist} Epoch: 2 +License: BSD and GPLv2+ URL: https://github.com/shadow-maint/shadow Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz Source1: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz.asc @@ -53,19 +54,31 @@ Patch16: shadow-4.9-useradd-avoid-generating-empty-subid-range.patch # https://github.com/shadow-maint/shadow/commit/234e8fa7b134d1ebabfdad980a3ae5b63c046c62 Patch17: shadow-4.9-libmisc-fix-default-value-in-SHA_get_salt_rounds.patch -License: BSD and GPLv2+ -BuildRequires: make -BuildRequires: gcc -BuildRequires: libselinux-devel >= 1.25.2-1 -BuildRequires: audit-libs-devel >= 1.6.5 -BuildRequires: libsemanage-devel -BuildRequires: libacl-devel, libattr-devel -BuildRequires: bison, flex, docbook-style-xsl, docbook-dtds -BuildRequires: autoconf, automake, libtool, gettext-devel -BuildRequires: /usr/bin/xsltproc, /usr/bin/itstool -Requires: libselinux >= 1.25.2-1 +### Dependencies ### Requires: audit-libs >= 1.6.5 +Requires: libselinux >= 1.25.2-1 Requires: setup + +### Build Dependencies ### +BuildRequires: audit-libs-devel >= 1.6.5 +BuildRequires: autoconf +BuildRequires: automake +BuildRequires: bison +BuildRequires: docbook-dtds +BuildRequires: docbook-style-xsl +BuildRequires: flex +BuildRequires: gcc +BuildRequires: gettext-devel +BuildRequires: itstool +BuildRequires: libacl-devel +BuildRequires: libattr-devel +BuildRequires: libselinux-devel >= 1.25.2-1 +BuildRequires: libsemanage-devel +BuildRequires: libtool +BuildRequires: libxslt +BuildRequires: make + +### Provides ### Provides: shadow = %{epoch}:%{version}-%{release} %description @@ -287,6 +300,10 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la %{_libdir}/libsubid.so %changelog +* Thu Sep 23 2021 Iker Pedrosa - 2:4.9-4 +- login.defs: include HMAC_CRYPTO_ALGO key +- Clean spec file: organize dependencies and move License location + * Tue Aug 17 2021 Iker Pedrosa - 2:4.9-3 - libmisc: fix default value in SHA_get_salt_rounds() From 11164c2c0a8816d49e94ca0343e421016e606603 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Wed, 27 Oct 2021 12:02:57 +0200 Subject: [PATCH 051/134] useradd: generate home and mail directories with selinux user attribute Signed-off-by: Iker Pedrosa --- shadow-4.9-move-create-home.patch | 40 +++++++++--- ....9-semanage-close-the-selabel-handle.patch | 61 +++++++++++++++++++ shadow-utils.spec | 10 ++- 3 files changed, 101 insertions(+), 10 deletions(-) create mode 100644 shadow-4.9-semanage-close-the-selabel-handle.patch diff --git a/shadow-4.9-move-create-home.patch b/shadow-4.9-move-create-home.patch index 94bb84c..0ed6ea7 100644 --- a/shadow-4.9-move-create-home.patch +++ b/shadow-4.9-move-create-home.patch @@ -1,8 +1,22 @@ +From 09c752f00f9dfc610f66d68be38c9e5be8ca7f15 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Fri, 8 Oct 2021 13:09:59 +0200 +Subject: [PATCH] useradd: create directories after the SELinux user + +Create the home and mail folders after the SELinux user has been set for +the added user. This will allow the folders to be created with the +SELinux user label. + +Signed-off-by: Iker Pedrosa +--- + src/useradd.c | 46 +++++++++++++++++++++++----------------------- + 1 file changed, 23 insertions(+), 23 deletions(-) + diff --git a/src/useradd.c b/src/useradd.c -index baeffb35..02e1402c 100644 +index 6269c01c..b463a170 100644 --- a/src/useradd.c +++ b/src/useradd.c -@@ -2644,27 +2644,12 @@ int main (int argc, char **argv) +@@ -2670,27 +2670,12 @@ int main (int argc, char **argv) usr_update (); @@ -34,17 +48,14 @@ index baeffb35..02e1402c 100644 /* * tallylog_reset needs to be able to lookup * a valid existing user name, -@@ -2695,9 +2680,24 @@ int main (int argc, char **argv) - exit(1); +@@ -2716,15 +2701,30 @@ int main (int argc, char **argv) } + #endif /* WITH_SELINUX */ -- nscd_flush_cache ("passwd"); -- nscd_flush_cache ("group"); -- sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP); + if (mflg) { + create_home (); + if (home_added) { -+ copy_tree (def_template, prefix_user_home, false, true, ++ copy_tree (def_template, prefix_user_home, false, false, + (uid_t)-1, user_id, (gid_t)-1, user_gid); + } else { + fprintf (stderr, @@ -59,6 +70,19 @@ index baeffb35..02e1402c 100644 + if (!rflg) { + create_mail (); + } ++ + if (run_parts ("/etc/shadow-maint/useradd-post.d", (char*)user_name, + "useradd")) { + exit(1); + } +- nscd_flush_cache ("passwd"); +- nscd_flush_cache ("group"); +- sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP); +- return E_SUCCESS; } + +-- +2.31.1 + diff --git a/shadow-4.9-semanage-close-the-selabel-handle.patch b/shadow-4.9-semanage-close-the-selabel-handle.patch new file mode 100644 index 0000000..11a23e4 --- /dev/null +++ b/shadow-4.9-semanage-close-the-selabel-handle.patch @@ -0,0 +1,61 @@ +From 234af5cf67fc1a3ba99fc246ba65869a3c416545 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Fri, 8 Oct 2021 13:13:13 +0200 +Subject: [PATCH] semanage: close the selabel handle + +Close the selabel handle to update the file_context. This means that the +file_context will be remmaped and used by selabel_lookup() to return +the appropriate context to label the home folder. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1993081 + +Signed-off-by: Iker Pedrosa +--- + lib/prototypes.h | 1 + + lib/selinux.c | 5 +++++ + lib/semanage.c | 1 + + 3 files changed, 7 insertions(+) + +diff --git a/lib/prototypes.h b/lib/prototypes.h +index 1d1586d4..b697e0ec 100644 +--- a/lib/prototypes.h ++++ b/lib/prototypes.h +@@ -392,6 +392,7 @@ extern /*@observer@*/const char *crypt_make_salt (/*@null@*//*@observer@*/const + /* selinux.c */ + #ifdef WITH_SELINUX + extern int set_selinux_file_context (const char *dst_name, mode_t mode); ++extern void reset_selinux_handle (void); + extern int reset_selinux_file_context (void); + extern int check_selinux_permit (const char *perm_name); + #endif +diff --git a/lib/selinux.c b/lib/selinux.c +index c83545f9..b075d4c0 100644 +--- a/lib/selinux.c ++++ b/lib/selinux.c +@@ -50,6 +50,11 @@ static void cleanup(void) + } + } + ++void reset_selinux_handle (void) ++{ ++ cleanup(); ++} ++ + /* + * set_selinux_file_context - Set the security context before any file or + * directory creation. +diff --git a/lib/semanage.c b/lib/semanage.c +index 0d30456a..a5bf9218 100644 +--- a/lib/semanage.c ++++ b/lib/semanage.c +@@ -293,6 +293,7 @@ int set_seuser (const char *login_name, const char *seuser_name) + } + + ret = 0; ++ reset_selinux_handle(); + + done: + semanage_seuser_key_free (key); +-- +2.31.1 + diff --git a/shadow-utils.spec b/shadow-utils.spec index 051708d..871a2e1 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.9 -Release: 4%{?dist} +Release: 5%{?dist} Epoch: 2 License: BSD and GPLv2+ URL: https://github.com/shadow-maint/shadow @@ -21,7 +21,7 @@ Source6: shadow-utils.HOME_MODE.xml Patch0: shadow-4.9-redhat.patch # Be more lenient with acceptable user/group names - non upstreamable Patch1: shadow-4.8-goodname.patch -# Move create home to the end of main - upstreamability unknown +# https://github.com/shadow-maint/shadow/commit/09c752f00f9dfc610f66d68be38c9e5be8ca7f15 Patch2: shadow-4.9-move-create-home.patch # SElinux related - upstreamability unknown Patch3: shadow-4.9-default-range.patch @@ -53,6 +53,8 @@ Patch15: shadow-4.9-usermod-allow-all-group-types.patch Patch16: shadow-4.9-useradd-avoid-generating-empty-subid-range.patch # https://github.com/shadow-maint/shadow/commit/234e8fa7b134d1ebabfdad980a3ae5b63c046c62 Patch17: shadow-4.9-libmisc-fix-default-value-in-SHA_get_salt_rounds.patch +# https://github.com/shadow-maint/shadow/commit/234af5cf67fc1a3ba99fc246ba65869a3c416545 +Patch18: shadow-4.9-semanage-close-the-selabel-handle.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -130,6 +132,7 @@ Development files for shadow-utils-subid. %patch15 -p1 -b .usermod-allow-all-group-types %patch16 -p1 -b .useradd-avoid-generating-empty-subid-range %patch17 -p1 -b .libmisc-fix-default-value-in-SHA_get_salt_rounds +%patch18 -p1 -b .semanage-close-the-selabel-handle iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -300,6 +303,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la %{_libdir}/libsubid.so %changelog +* Wed Oct 27 2021 Iker Pedrosa - 2:4.9-5 +- useradd: generate home and mail directories with selinux user attribute + * Thu Sep 23 2021 Iker Pedrosa - 2:4.9-4 - login.defs: include HMAC_CRYPTO_ALGO key - Clean spec file: organize dependencies and move License location From 4a03ec740c3bfa806e27fe66994d41827063eb2e Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Thu, 4 Nov 2021 12:47:10 +0100 Subject: [PATCH 052/134] useradd: revert fix memleak of grp (#2018697) Signed-off-by: Iker Pedrosa --- shadow-4.9-revert-useradd-fix-memleak.patch | 30 +++++++++++++++++++++ shadow-utils.spec | 8 +++++- 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 shadow-4.9-revert-useradd-fix-memleak.patch diff --git a/shadow-4.9-revert-useradd-fix-memleak.patch b/shadow-4.9-revert-useradd-fix-memleak.patch new file mode 100644 index 0000000..e8251f2 --- /dev/null +++ b/shadow-4.9-revert-useradd-fix-memleak.patch @@ -0,0 +1,30 @@ +From 4624e9fca1b02b64e25e8b2280a0186182ab73ba Mon Sep 17 00:00:00 2001 +From: Serge Hallyn +Date: Sat, 14 Aug 2021 19:37:24 -0500 +Subject: [PATCH] Revert "useradd.c:fix memleaks of grp" + +In some cases, the value which was being freed is not actually +safe to free. + +Closes #394 + +This reverts commit c44b71cec25d60efc51aec9de3abce1f6efbfcf5. +--- + src/useradd.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/src/useradd.c b/src/useradd.c +index f90127cd..0d3f390d 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -413,7 +413,6 @@ static void get_defaults (void) + } else { + def_group = grp->gr_gid; + def_gname = xstrdup (grp->gr_name); +- gr_free(grp); + } + } + +-- +2.31.1 + diff --git a/shadow-utils.spec b/shadow-utils.spec index 871a2e1..d4a715a 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.9 -Release: 5%{?dist} +Release: 6%{?dist} Epoch: 2 License: BSD and GPLv2+ URL: https://github.com/shadow-maint/shadow @@ -55,6 +55,8 @@ Patch16: shadow-4.9-useradd-avoid-generating-empty-subid-range.patch Patch17: shadow-4.9-libmisc-fix-default-value-in-SHA_get_salt_rounds.patch # https://github.com/shadow-maint/shadow/commit/234af5cf67fc1a3ba99fc246ba65869a3c416545 Patch18: shadow-4.9-semanage-close-the-selabel-handle.patch +# https://github.com/shadow-maint/shadow/commit/4624e9fca1b02b64e25e8b2280a0186182ab73ba +Patch19: shadow-4.9-revert-useradd-fix-memleak.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -133,6 +135,7 @@ Development files for shadow-utils-subid. %patch16 -p1 -b .useradd-avoid-generating-empty-subid-range %patch17 -p1 -b .libmisc-fix-default-value-in-SHA_get_salt_rounds %patch18 -p1 -b .semanage-close-the-selabel-handle +%patch19 -p1 -b .revert-useradd-fix-memleak iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -303,6 +306,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la %{_libdir}/libsubid.so %changelog +* Thu Nov 4 2021 Iker Pedrosa - 2:4.9-6 +- useradd: revert fix memleak of grp (#2018697) + * Wed Oct 27 2021 Iker Pedrosa - 2:4.9-5 - useradd: generate home and mail directories with selinux user attribute From a2d5d3dbdafbbe5adcf8c987ab6441684596d033 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Fri, 12 Nov 2021 15:47:43 +0100 Subject: [PATCH 053/134] useradd: change SELinux labels for home files (#2022658) Signed-off-by: Iker Pedrosa --- shadow-4.9-useradd-copy-tree-argument.patch | 13 +++++++++++++ shadow-utils.spec | 8 +++++++- 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 shadow-4.9-useradd-copy-tree-argument.patch diff --git a/shadow-4.9-useradd-copy-tree-argument.patch b/shadow-4.9-useradd-copy-tree-argument.patch new file mode 100644 index 0000000..f6b9827 --- /dev/null +++ b/shadow-4.9-useradd-copy-tree-argument.patch @@ -0,0 +1,13 @@ +diff --git a/src/useradd.c b/src/useradd.c +index b463a170..f7c97958 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -2704,7 +2704,7 @@ int main (int argc, char **argv) + if (mflg) { + create_home (); + if (home_added) { +- copy_tree (def_template, prefix_user_home, false, false, ++ copy_tree (def_template, prefix_user_home, false, true, + (uid_t)-1, user_id, (gid_t)-1, user_gid); + } else { + fprintf (stderr, diff --git a/shadow-utils.spec b/shadow-utils.spec index d4a715a..44e89c1 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.9 -Release: 6%{?dist} +Release: 7%{?dist} Epoch: 2 License: BSD and GPLv2+ URL: https://github.com/shadow-maint/shadow @@ -57,6 +57,8 @@ Patch17: shadow-4.9-libmisc-fix-default-value-in-SHA_get_salt_rounds.patch Patch18: shadow-4.9-semanage-close-the-selabel-handle.patch # https://github.com/shadow-maint/shadow/commit/4624e9fca1b02b64e25e8b2280a0186182ab73ba Patch19: shadow-4.9-revert-useradd-fix-memleak.patch +# https://github.com/shadow-maint/shadow/pull/439 +Patch20: shadow-4.9-useradd-copy-tree-argument.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -136,6 +138,7 @@ Development files for shadow-utils-subid. %patch17 -p1 -b .libmisc-fix-default-value-in-SHA_get_salt_rounds %patch18 -p1 -b .semanage-close-the-selabel-handle %patch19 -p1 -b .revert-useradd-fix-memleak +%patch20 -p1 -b .useradd-copy-tree-argument iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -306,6 +309,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la %{_libdir}/libsubid.so %changelog +* Fri Nov 12 2021 Iker Pedrosa - 2:4.9-7 +- useradd: change SELinux labels for home files (#2022658) + * Thu Nov 4 2021 Iker Pedrosa - 2:4.9-6 - useradd: revert fix memleak of grp (#2018697) From 957f0eb09e9fa1983f1723f459739412b566a232 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Fri, 19 Nov 2021 09:44:08 +0100 Subject: [PATCH 054/134] - getsubids: provide system binary and man page (#1980780) - pwck: fix segfault when calling fprintf() (#2021339) - newgrp: fix segmentation fault (#2019553) - groupdel: fix SIGSEGV when passwd does not exist (#1986111) Signed-off-by: Iker Pedrosa --- shadow-4.9-getsubids.patch | 245 ++++++++++++++++++ ...x-sigsegv-when-passwd-does-not-exist.patch | 13 + ...ow-4.9-newgrp-fix-segmentation-fault.patch | 35 +++ ...ck-fix-segfault-when-calling-fprintf.patch | 30 +++ shadow-utils.spec | 24 +- 5 files changed, 345 insertions(+), 2 deletions(-) create mode 100644 shadow-4.9-getsubids.patch create mode 100644 shadow-4.9-groupdel-fix-sigsegv-when-passwd-does-not-exist.patch create mode 100644 shadow-4.9-newgrp-fix-segmentation-fault.patch create mode 100644 shadow-4.9-pwck-fix-segfault-when-calling-fprintf.patch diff --git a/shadow-4.9-getsubids.patch b/shadow-4.9-getsubids.patch new file mode 100644 index 0000000..b9f2449 --- /dev/null +++ b/shadow-4.9-getsubids.patch @@ -0,0 +1,245 @@ +diff -up shadow-4.9/man/getsubids.1.xml.getsubids shadow-4.9/man/getsubids.1.xml +--- shadow-4.9/man/getsubids.1.xml.getsubids 2021-11-18 16:27:33.951053120 +0100 ++++ shadow-4.9/man/getsubids.1.xml 2021-11-18 16:27:33.951053120 +0100 +@@ -0,0 +1,141 @@ ++ ++ ++ ++]> ++ ++ ++ ++ ++ Iker ++ Pedrosa ++ Creation, 2021 ++ ++ ++ ++ getsubids ++ 1 ++ User Commands ++ shadow-utils ++ &SHADOW_UTILS_VERSION; ++ ++ ++ getsubids ++ get the subordinate id ranges for a user ++ ++ ++ ++ ++ getsubids ++ ++ options ++ ++ ++ USER ++ ++ ++ ++ ++ ++ DESCRIPTION ++ ++ The getsubids command lists the subordinate user ID ++ ranges for a given user. The subordinate group IDs can be listed using ++ the option. ++ ++ ++ ++ ++ OPTIONS ++ ++ The options which apply to the getsubids command are: ++ ++ ++ ++ ++ ++ ++ ++ ++ List the subordinate group ID ranges. ++ ++ ++ ++ ++ ++ ++ ++ EXAMPLE ++ ++ For example, to obtain the subordinate UIDs of the testuser: ++ ++ ++ ++$ getsubids testuser ++0: testuser 100000 65536 ++ ++ ++ ++ This command output provides (in order from left to right) the list ++ index, username, UID range start, and number of UIDs in range. ++ ++ ++ ++ ++ SEE ALSO ++ ++ ++ login.defs5 ++ , ++ ++ newgidmap1 ++ , ++ ++ newuidmap1 ++ , ++ ++ subgid5 ++ , ++ ++ subuid5 ++ , ++ ++ useradd8 ++ , ++ ++ userdel8 ++ . ++ ++ usermod8 ++ , ++ ++ ++ +diff -up shadow-4.9/man/Makefile.am.getsubids shadow-4.9/man/Makefile.am +--- shadow-4.9/man/Makefile.am.getsubids 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/man/Makefile.am 2021-11-18 16:27:33.951053120 +0100 +@@ -62,6 +62,7 @@ man_MANS += $(man_nopam) + endif + + man_subids = \ ++ man1/getsubids.1 \ + man1/newgidmap.1 \ + man1/newuidmap.1 \ + man5/subgid.5 \ +@@ -80,6 +81,7 @@ man_XMANS = \ + expiry.1.xml \ + faillog.5.xml \ + faillog.8.xml \ ++ getsubids.1.xml \ + gpasswd.1.xml \ + groupadd.8.xml \ + groupdel.8.xml \ +diff -up shadow-4.9/src/getsubids.c.getsubids shadow-4.9/src/getsubids.c +--- shadow-4.9/src/getsubids.c.getsubids 2021-11-18 16:27:33.951053120 +0100 ++++ shadow-4.9/src/getsubids.c 2021-11-18 16:27:33.951053120 +0100 +@@ -0,0 +1,46 @@ ++#include ++#include ++#include ++#include "subid.h" ++#include "prototypes.h" ++ ++const char *Prog; ++FILE *shadow_logfd = NULL; ++ ++void usage(void) ++{ ++ fprintf(stderr, "Usage: %s [-g] user\n", Prog); ++ fprintf(stderr, " list subuid ranges for user\n"); ++ fprintf(stderr, " pass -g to list subgid ranges\n"); ++ exit(EXIT_FAILURE); ++} ++ ++int main(int argc, char *argv[]) ++{ ++ int i, count=0; ++ struct subid_range *ranges; ++ const char *owner; ++ ++ Prog = Basename (argv[0]); ++ shadow_logfd = stderr; ++ if (argc < 2) ++ usage(); ++ owner = argv[1]; ++ if (argc == 3 && strcmp(argv[1], "-g") == 0) { ++ owner = argv[2]; ++ count = get_subgid_ranges(owner, &ranges); ++ } else if (argc == 2 && strcmp(argv[1], "-h") == 0) { ++ usage(); ++ } else { ++ count = get_subuid_ranges(owner, &ranges); ++ } ++ if (!ranges) { ++ fprintf(stderr, "Error fetching ranges\n"); ++ exit(1); ++ } ++ for (i = 0; i < count; i++) { ++ printf("%d: %s %lu %lu\n", i, owner, ++ ranges[i].start, ranges[i].count); ++ } ++ return 0; ++} +diff -up shadow-4.9/src/list_subid_ranges.c.getsubids shadow-4.9/src/list_subid_ranges.c +diff -up shadow-4.9/src/Makefile.am.getsubids shadow-4.9/src/Makefile.am +--- shadow-4.9/src/Makefile.am.getsubids 2021-11-18 16:27:33.943053061 +0100 ++++ shadow-4.9/src/Makefile.am 2021-11-18 16:28:03.647272392 +0100 +@@ -157,8 +157,8 @@ if FCAPS + setcap cap_setgid+ep $(DESTDIR)$(ubindir)/newgidmap + endif + +-noinst_PROGRAMS += list_subid_ranges \ +- get_subid_owners \ ++bin_PROGRAMS += getsubids ++noinst_PROGRAMS += get_subid_owners \ + new_subid_range \ + free_subid_range \ + check_subid_range +@@ -174,13 +174,13 @@ MISCLIBS = \ + $(LIBCRYPT) \ + $(LIBTCB) + +-list_subid_ranges_LDADD = \ ++getsubids_LDADD = \ + $(top_builddir)/lib/libshadow.la \ + $(top_builddir)/libmisc/libmisc.la \ + $(top_builddir)/libsubid/libsubid.la \ + $(MISCLIBS) -ldl + +-list_subid_ranges_CPPFLAGS = \ ++getsubids_CPPFLAGS = \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/libmisc \ + -I$(top_srcdir)/libsubid diff --git a/shadow-4.9-groupdel-fix-sigsegv-when-passwd-does-not-exist.patch b/shadow-4.9-groupdel-fix-sigsegv-when-passwd-does-not-exist.patch new file mode 100644 index 0000000..658156a --- /dev/null +++ b/shadow-4.9-groupdel-fix-sigsegv-when-passwd-does-not-exist.patch @@ -0,0 +1,13 @@ +diff -up shadow-4.9/libmisc/prefix_flag.c.groupdel-fix-sigsegv-when-passwd-does-not-exist shadow-4.9/libmisc/prefix_flag.c +--- shadow-4.9/libmisc/prefix_flag.c.groupdel-fix-sigsegv-when-passwd-does-not-exist 2021-11-19 09:21:36.997091941 +0100 ++++ shadow-4.9/libmisc/prefix_flag.c 2021-11-19 09:22:19.001341010 +0100 +@@ -288,6 +288,9 @@ extern struct passwd* prefix_getpwent() + if(!passwd_db_file) { + return getpwent(); + } ++ if (!fp_pwent) { ++ return NULL; ++ } + return fgetpwent(fp_pwent); + } + extern void prefix_endpwent() diff --git a/shadow-4.9-newgrp-fix-segmentation-fault.patch b/shadow-4.9-newgrp-fix-segmentation-fault.patch new file mode 100644 index 0000000..49332a1 --- /dev/null +++ b/shadow-4.9-newgrp-fix-segmentation-fault.patch @@ -0,0 +1,35 @@ +From 497e90751bc0d95cc998b0f06305040563903948 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Wed, 10 Nov 2021 12:02:04 +0100 +Subject: [PATCH] newgrp: fix segmentation fault + +Fix segmentation fault in newgrp when xgetspnam() returns a NULL value +that is immediately freed. + +The error was committed in +https://github.com/shadow-maint/shadow/commit/e65cc6aebcb4132fa413f00a905216a5b35b3d57 + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2019553 + +Signed-off-by: Iker Pedrosa +--- + src/newgrp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/newgrp.c b/src/newgrp.c +index 730f47e8..566f1c89 100644 +--- a/src/newgrp.c ++++ b/src/newgrp.c +@@ -163,8 +163,8 @@ static void check_perms (const struct group *grp, + spwd = xgetspnam (pwd->pw_name); + if (NULL != spwd) { + pwd->pw_passwd = xstrdup (spwd->sp_pwdp); ++ spw_free (spwd); + } +- spw_free (spwd); + + if ((pwd->pw_passwd[0] == '\0') && (grp->gr_passwd[0] != '\0')) { + needspasswd = true; +-- +2.31.1 + diff --git a/shadow-4.9-pwck-fix-segfault-when-calling-fprintf.patch b/shadow-4.9-pwck-fix-segfault-when-calling-fprintf.patch new file mode 100644 index 0000000..e7761b7 --- /dev/null +++ b/shadow-4.9-pwck-fix-segfault-when-calling-fprintf.patch @@ -0,0 +1,30 @@ +From d8e54618feea201987c1f3cb402ed50d1d8b604f Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Mon, 15 Nov 2021 12:40:15 +0100 +Subject: [PATCH] pwck: fix segfault when calling fprintf() + +As shadow_logfd variable is not set at the beginning of the program if +something fails and fprintf() is called a segmentation fault happens. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2021339 + +Signed-off-by: Iker Pedrosa +--- + src/pwck.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/pwck.c b/src/pwck.c +index 4248944a..4ce86af2 100644 +--- a/src/pwck.c ++++ b/src/pwck.c +@@ -857,6 +857,7 @@ int main (int argc, char **argv) + * Get my name so that I can use it to report errors. + */ + Prog = Basename (argv[0]); ++ shadow_logfd = stderr; + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +-- +2.31.1 + diff --git a/shadow-utils.spec b/shadow-utils.spec index 44e89c1..e7e2970 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.9 -Release: 7%{?dist} +Release: 8%{?dist} Epoch: 2 License: BSD and GPLv2+ URL: https://github.com/shadow-maint/shadow @@ -57,8 +57,16 @@ Patch17: shadow-4.9-libmisc-fix-default-value-in-SHA_get_salt_rounds.patch Patch18: shadow-4.9-semanage-close-the-selabel-handle.patch # https://github.com/shadow-maint/shadow/commit/4624e9fca1b02b64e25e8b2280a0186182ab73ba Patch19: shadow-4.9-revert-useradd-fix-memleak.patch -# https://github.com/shadow-maint/shadow/pull/439 +# https://github.com/shadow-maint/shadow/commit/06eb4e4d76ac7f1ac86e68a89b2dc9be7c7323a2 Patch20: shadow-4.9-useradd-copy-tree-argument.patch +# https://github.com/shadow-maint/shadow/commit/d8e54618feea201987c1f3cb402ed50d1d8b604f +Patch21: shadow-4.9-pwck-fix-segfault-when-calling-fprintf.patch +# https://github.com/shadow-maint/shadow/commit/497e90751bc0d95cc998b0f06305040563903948 +Patch22: shadow-4.9-newgrp-fix-segmentation-fault.patch +# https://github.com/shadow-maint/shadow/commit/3b6ccf642c6bb2b7db087f09ee563ae9318af734 +Patch23: shadow-4.9-getsubids.patch +# https://github.com/shadow-maint/shadow/commit/a757b458ffb4fb9a40bcbb4f7869449431c67f83 +Patch24: shadow-4.9-groupdel-fix-sigsegv-when-passwd-does-not-exist.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -139,6 +147,10 @@ Development files for shadow-utils-subid. %patch18 -p1 -b .semanage-close-the-selabel-handle %patch19 -p1 -b .revert-useradd-fix-memleak %patch20 -p1 -b .useradd-copy-tree-argument +%patch21 -p1 -b .pwck-fix-segfault-when-calling-fprintf +%patch22 -p1 -b .newgrp-fix-segmentation-fault +%patch23 -p1 -b .getsubids +%patch24 -p1 -b .groupdel-fix-sigsegv-when-passwd-does-not-exist iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -303,12 +315,20 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la %files subid %{_libdir}/libsubid.so.* +%{_bindir}/getsubids +%{_mandir}/man1/getsubids.1* %files subid-devel %{includesubiddir}/subid.h %{_libdir}/libsubid.so %changelog +* Fri Nov 19 2021 Iker Pedrosa - 2:4.9-8 +- getsubids: provide system binary and man page (#1980780) +- pwck: fix segfault when calling fprintf() (#2021339) +- newgrp: fix segmentation fault (#2019553) +- groupdel: fix SIGSEGV when passwd does not exist (#1986111) + * Fri Nov 12 2021 Iker Pedrosa - 2:4.9-7 - useradd: change SELinux labels for home files (#2022658) From 77cc4a7c14037e8425c5c38c502c5ac521e5a4b6 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Mon, 17 Jan 2022 10:00:50 +0100 Subject: [PATCH 055/134] - nss: get shadow_logfd with log_get_logfd() (#2038811) - lib: make shadow_logfd and Prog not extern - lib: rename Prog to shadow_progname - lib: provide default values for shadow_progname - libsubid: use log_set_progname in subid_init Signed-off-by: Iker Pedrosa --- ...ake-shadow-logfd-and-prog-not-extern.patch | 2497 +++++++++++++++++ ...-get-shadow-logfd-with-log-get-logfd.patch | 48 + ...w-4.9-rename-prog-to-shadow-progname.patch | 507 ++++ shadow-4.9-shadow-progname-default-init.patch | 39 + shadow-utils.spec | 22 +- 5 files changed, 3112 insertions(+), 1 deletion(-) create mode 100644 shadow-4.9-make-shadow-logfd-and-prog-not-extern.patch create mode 100644 shadow-4.9-nss-get-shadow-logfd-with-log-get-logfd.patch create mode 100644 shadow-4.9-rename-prog-to-shadow-progname.patch create mode 100644 shadow-4.9-shadow-progname-default-init.patch diff --git a/shadow-4.9-make-shadow-logfd-and-prog-not-extern.patch b/shadow-4.9-make-shadow-logfd-and-prog-not-extern.patch new file mode 100644 index 0000000..d0b7059 --- /dev/null +++ b/shadow-4.9-make-shadow-logfd-and-prog-not-extern.patch @@ -0,0 +1,2497 @@ +diff -up shadow-4.9/lib/commonio.c.debug1 shadow-4.9/lib/commonio.c +--- shadow-4.9/lib/commonio.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/lib/commonio.c 2022-01-10 10:45:52.202132937 +0100 +@@ -51,6 +51,7 @@ + #endif /* WITH_TCB */ + #include "prototypes.h" + #include "commonio.h" ++#include "shadowlog_internal.h" + + /* local function prototypes */ + static int lrename (const char *, const char *); +diff -up shadow-4.9/lib/encrypt.c.debug1 shadow-4.9/lib/encrypt.c +--- shadow-4.9/lib/encrypt.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/lib/encrypt.c 2022-01-10 10:45:52.202132937 +0100 +@@ -39,6 +39,7 @@ + + #include "prototypes.h" + #include "defines.h" ++#include "shadowlog_internal.h" + + /*@exposed@*//*@null@*/char *pw_encrypt (const char *clear, const char *salt) + { +diff -up shadow-4.9/lib/getdef.c.debug1 shadow-4.9/lib/getdef.c +--- shadow-4.9/lib/getdef.c.debug1 2022-01-10 10:45:52.191132858 +0100 ++++ shadow-4.9/lib/getdef.c 2022-01-10 10:45:52.202132937 +0100 +@@ -44,6 +44,7 @@ + #include + #endif + #include "getdef.h" ++#include "shadowlog_internal.h" + /* + * A configuration item definition. + */ +diff -up shadow-4.9/lib/Makefile.am.debug1 shadow-4.9/lib/Makefile.am +--- shadow-4.9/lib/Makefile.am.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/lib/Makefile.am 2022-01-10 10:45:52.202132937 +0100 +@@ -34,6 +34,8 @@ libshadow_la_SOURCES = \ + nss.c \ + nscd.c \ + nscd.h \ ++ shadowlog.c \ ++ shadowlog.h \ + sssd.c \ + sssd.h \ + pam_defs.h \ +diff -up shadow-4.9/libmisc/addgrps.c.debug1 shadow-4.9/libmisc/addgrps.c +--- shadow-4.9/libmisc/addgrps.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/libmisc/addgrps.c 2022-01-10 10:45:52.203132944 +0100 +@@ -40,6 +40,7 @@ + #include + #include + #include ++#include "shadowlog.h" + + #ident "$Id$" + +@@ -58,6 +59,7 @@ int add_groups (const char *list) + char *token; + char buf[1024]; + int ret; ++ FILE *shadow_logfd = log_get_logfd(); + + if (strlen (list) >= sizeof (buf)) { + errno = EINVAL; +diff -up shadow-4.9/libmisc/audit_help.c.debug1 shadow-4.9/libmisc/audit_help.c +--- shadow-4.9/libmisc/audit_help.c.debug1 2022-01-10 10:45:52.184132808 +0100 ++++ shadow-4.9/libmisc/audit_help.c 2022-01-10 10:45:52.203132944 +0100 +@@ -45,6 +45,7 @@ + #include + #include + #include "prototypes.h" ++#include "shadowlog.h" + int audit_fd; + + void audit_help_open (void) +@@ -59,7 +60,7 @@ void audit_help_open (void) + return; + } + (void) fputs (_("Cannot open audit interface - aborting.\n"), +- shadow_logfd); ++ log_get_logfd()); + exit (EXIT_FAILURE); + } + } +diff -up shadow-4.9/libmisc/chowntty.c.debug1 shadow-4.9/libmisc/chowntty.c +--- shadow-4.9/libmisc/chowntty.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/libmisc/chowntty.c 2022-01-10 10:45:52.203132944 +0100 +@@ -43,6 +43,7 @@ + #include "defines.h" + #include + #include "getdef.h" ++#include "shadowlog.h" + + /* + * chown_tty() sets the login tty to be owned by the new user ID +@@ -75,6 +76,7 @@ void chown_tty (const struct passwd *inf + if ( (fchown (STDIN_FILENO, info->pw_uid, gid) != 0) + || (fchmod (STDIN_FILENO, (mode_t)getdef_num ("TTYPERM", 0600)) != 0)) { + int err = errno; ++ FILE *shadow_logfd = log_get_logfd(); + + fprintf (shadow_logfd, + _("Unable to change owner or mode of tty stdin: %s"), +diff -up shadow-4.9/libmisc/cleanup_group.c.debug1 shadow-4.9/libmisc/cleanup_group.c +--- shadow-4.9/libmisc/cleanup_group.c.debug1 2022-01-10 10:45:52.184132808 +0100 ++++ shadow-4.9/libmisc/cleanup_group.c 2022-01-10 10:47:02.241632844 +0100 +@@ -36,6 +36,7 @@ + #include "groupio.h" + #include "sgroupio.h" + #include "prototypes.h" ++#include "shadowlog.h" + + /* + * cleanup_report_add_group - Report failure to add a group to the system +@@ -48,7 +49,7 @@ void cleanup_report_add_group (void *gro + + SYSLOG ((LOG_ERR, "failed to add group %s", name)); + #ifdef WITH_AUDIT +- audit_logger (AUDIT_ADD_GROUP, Prog, ++ audit_logger (AUDIT_ADD_GROUP, log_get_progname(), + "", + name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); +@@ -66,7 +67,7 @@ void cleanup_report_del_group (void *gro + + SYSLOG ((LOG_ERR, "failed to remove group %s", name)); + #ifdef WITH_AUDIT +- audit_logger (AUDIT_DEL_GROUP, Prog, ++ audit_logger (AUDIT_DEL_GROUP, log_get_progname(), + "", + name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); +@@ -83,7 +84,7 @@ void cleanup_report_mod_group (void *cle + gr_dbname (), + info->action)); + #ifdef WITH_AUDIT +- audit_logger (AUDIT_GRP_MGMT, Prog, ++ audit_logger (AUDIT_GRP_MGMT, log_get_progname(), + info->audit_msg, + info->name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); +@@ -101,7 +102,7 @@ void cleanup_report_mod_gshadow (void *c + sgr_dbname (), + info->action)); + #ifdef WITH_AUDIT +- audit_logger (AUDIT_GRP_MGMT, Prog, ++ audit_logger (AUDIT_GRP_MGMT, log_get_progname(), + info->audit_msg, + info->name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); +@@ -121,7 +122,7 @@ void cleanup_report_add_group_group (voi + + SYSLOG ((LOG_ERR, "failed to add group %s to %s", name, gr_dbname ())); + #ifdef WITH_AUDIT +- audit_logger (AUDIT_ADD_GROUP, Prog, ++ audit_logger (AUDIT_ADD_GROUP, log_get_progname(), + "adding-group", + name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); +@@ -141,7 +142,7 @@ void cleanup_report_add_group_gshadow (v + + SYSLOG ((LOG_ERR, "failed to add group %s to %s", name, sgr_dbname ())); + #ifdef WITH_AUDIT +- audit_logger (AUDIT_GRP_MGMT, Prog, ++ audit_logger (AUDIT_GRP_MGMT, log_get_progname(), + "adding-shadow-group", + name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); +@@ -164,7 +165,7 @@ void cleanup_report_del_group_group (voi + "failed to remove group %s from %s", + name, gr_dbname ())); + #ifdef WITH_AUDIT +- audit_logger (AUDIT_DEL_GROUP, Prog, ++ audit_logger (AUDIT_DEL_GROUP, log_get_progname(), + "removing-group", + name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); +@@ -187,7 +188,7 @@ void cleanup_report_del_group_gshadow (v + "failed to remove group %s from %s", + name, sgr_dbname ())); + #ifdef WITH_AUDIT +- audit_logger (AUDIT_GRP_MGMT, Prog, ++ audit_logger (AUDIT_GRP_MGMT, log_get_progname(), + "removing-shadow-group", + name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); +@@ -203,9 +204,9 @@ void cleanup_report_del_group_gshadow (v + void cleanup_unlock_group (unused void *arg) + { + if (gr_unlock () == 0) { +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: failed to unlock %s\n"), +- Prog, gr_dbname ()); ++ log_get_progname(), gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + #ifdef WITH_AUDIT + audit_logger_message ("unlocking-group", +@@ -223,9 +224,9 @@ void cleanup_unlock_group (unused void * + void cleanup_unlock_gshadow (unused void *arg) + { + if (sgr_unlock () == 0) { +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: failed to unlock %s\n"), +- Prog, sgr_dbname ()); ++ log_get_progname(), sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + #ifdef WITH_AUDIT + audit_logger_message ("unlocking-gshadow", +diff -up shadow-4.9/libmisc/cleanup_user.c.debug1 shadow-4.9/libmisc/cleanup_user.c +--- shadow-4.9/libmisc/cleanup_user.c.debug1 2022-01-10 10:45:52.184132808 +0100 ++++ shadow-4.9/libmisc/cleanup_user.c 2022-01-10 10:47:49.539970421 +0100 +@@ -36,6 +36,7 @@ + #include "pwio.h" + #include "shadowio.h" + #include "prototypes.h" ++#include "shadowlog.h" + + /* + * cleanup_report_add_user - Report failure to add an user to the system +@@ -48,7 +49,7 @@ void cleanup_report_add_user (void *user + + SYSLOG ((LOG_ERR, "failed to add user %s", name)); + #ifdef WITH_AUDIT +- audit_logger (AUDIT_ADD_USER, Prog, ++ audit_logger (AUDIT_ADD_USER, log_get_progname(), + "", + name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); +@@ -65,7 +66,7 @@ void cleanup_report_mod_passwd (void *cl + pw_dbname (), + info->action)); + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_MGMT, Prog, ++ audit_logger (AUDIT_USER_MGMT, log_get_progname(), + info->audit_msg, + info->name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); +@@ -85,7 +86,7 @@ void cleanup_report_add_user_passwd (voi + + SYSLOG ((LOG_ERR, "failed to add user %s to %s", name, pw_dbname ())); + #ifdef WITH_AUDIT +- audit_logger (AUDIT_ADD_USER, Prog, ++ audit_logger (AUDIT_ADD_USER, log_get_progname(), + "adding-user", + name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); +@@ -105,7 +106,7 @@ void cleanup_report_add_user_shadow (voi + + SYSLOG ((LOG_ERR, "failed to add user %s to %s", name, spw_dbname ())); + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_MGMT, Prog, ++ audit_logger (AUDIT_USER_MGMT, log_get_progname(), + "adding-shadow-user", + name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); +@@ -120,9 +121,9 @@ void cleanup_report_add_user_shadow (voi + void cleanup_unlock_passwd (unused void *arg) + { + if (pw_unlock () == 0) { +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: failed to unlock %s\n"), +- Prog, pw_dbname ()); ++ log_get_progname(), pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + #ifdef WITH_AUDIT + audit_logger_message ("unlocking-passwd", +@@ -139,9 +140,9 @@ void cleanup_unlock_passwd (unused void + void cleanup_unlock_shadow (unused void *arg) + { + if (spw_unlock () == 0) { +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: failed to unlock %s\n"), +- Prog, spw_dbname ()); ++ log_get_progname(), spw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + #ifdef WITH_AUDIT + audit_logger_message ("unlocking-shadow", +diff -up shadow-4.9/libmisc/copydir.c.debug1 shadow-4.9/libmisc/copydir.c +--- shadow-4.9/libmisc/copydir.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/libmisc/copydir.c 2022-01-10 10:48:02.158060482 +0100 +@@ -55,6 +55,7 @@ + #ifdef WITH_ATTR + #include + #endif /* WITH_ATTR */ ++#include "shadowlog.h" + + + static /*@null@*/const char *src_orig; +@@ -116,6 +117,7 @@ static int fchown_if_needed (int fdst, c + static void error_acl (struct error_context *ctx, const char *fmt, ...) + { + va_list ap; ++ FILE *shadow_logfd = log_get_logfd(); + + /* ignore the case when destination does not support ACLs + * or extended attributes */ +@@ -125,7 +127,7 @@ static void error_acl (struct error_cont + } + + va_start (ap, fmt); +- (void) fprintf (shadow_logfd, _("%s: "), Prog); ++ (void) fprintf (shadow_logfd, _("%s: "), log_get_progname()); + if (vfprintf (shadow_logfd, fmt, ap) != 0) { + (void) fputs (_(": "), shadow_logfd); + } +@@ -248,9 +250,9 @@ int copy_tree (const char *src_root, con + } + + if (!S_ISDIR (sb.st_mode)) { +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + "%s: %s is not a directory", +- Prog, src_root); ++ log_get_progname(), src_root); + return -1; + } + +diff -up shadow-4.9/libmisc/env.c.debug1 shadow-4.9/libmisc/env.c +--- shadow-4.9/libmisc/env.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/libmisc/env.c 2022-01-10 10:45:52.203132944 +0100 +@@ -40,6 +40,7 @@ + #include + #include "prototypes.h" + #include "defines.h" ++#include "shadowlog.h" + /* + * NEWENVP_STEP must be a power of two. This is the number + * of (char *) pointers to allocate at a time, to avoid using +@@ -171,7 +172,7 @@ void addenv (const char *string, /*@null + } + newenvp = __newenvp; + } else { +- (void) fputs (_("Environment overflow\n"), shadow_logfd); ++ (void) fputs (_("Environment overflow\n"), log_get_logfd()); + newenvc--; + free (newenvp[newenvc]); + } +diff -up shadow-4.9/libmisc/find_new_gid.c.debug1 shadow-4.9/libmisc/find_new_gid.c +--- shadow-4.9/libmisc/find_new_gid.c.debug1 2022-01-10 10:45:52.191132858 +0100 ++++ shadow-4.9/libmisc/find_new_gid.c 2022-01-10 10:45:52.203132944 +0100 +@@ -38,6 +38,7 @@ + #include "prototypes.h" + #include "groupio.h" + #include "getdef.h" ++#include "shadowlog.h" + + /* + * get_ranges - Get the minimum and maximum ID ranges for the search +@@ -74,10 +75,10 @@ static int get_ranges (bool sys_group, g + + /* Check that the ranges make sense */ + if (*max_id < *min_id) { +- (void) fprintf (shadow_logfd, ++ (void) fprintf (log_get_logfd(), + _("%s: Invalid configuration: SYS_GID_MIN (%lu), " + "GID_MIN (%lu), SYS_GID_MAX (%lu)\n"), +- Prog, (unsigned long) *min_id, ++ log_get_progname(), (unsigned long) *min_id, + getdef_ulong ("GID_MIN", 1000UL), + (unsigned long) *max_id); + return EINVAL; +@@ -104,10 +105,10 @@ static int get_ranges (bool sys_group, g + + /* Check that the ranges make sense */ + if (*max_id < *min_id) { +- (void) fprintf (shadow_logfd, ++ (void) fprintf (log_get_logfd(), + _("%s: Invalid configuration: GID_MIN (%lu), " + "GID_MAX (%lu)\n"), +- Prog, (unsigned long) *min_id, ++ log_get_progname(), (unsigned long) *min_id, + (unsigned long) *max_id); + return EINVAL; + } +@@ -220,10 +221,10 @@ int find_new_gid (bool sys_group, + * more likely to want to stop and address the + * issue. + */ +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: Encountered error attempting to use " + "preferred GID: %s\n"), +- Prog, strerror (result)); ++ log_get_progname(), strerror (result)); + return -1; + } + } +@@ -250,9 +251,9 @@ int find_new_gid (bool sys_group, + /* Create an array to hold all of the discovered GIDs */ + used_gids = malloc (sizeof (bool) * (gid_max +1)); + if (NULL == used_gids) { +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: failed to allocate memory: %s\n"), +- Prog, strerror (errno)); ++ log_get_progname(), strerror (errno)); + return -1; + } + memset (used_gids, false, sizeof (bool) * (gid_max + 1)); +@@ -330,10 +331,10 @@ int find_new_gid (bool sys_group, + * + */ + if (!nospam) { +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: Can't get unique system GID (%s). " + "Suppressing additional messages.\n"), +- Prog, strerror (result)); ++ log_get_progname(), strerror (result)); + SYSLOG ((LOG_ERR, + "Error checking available GIDs: %s", + strerror (result))); +@@ -373,10 +374,10 @@ int find_new_gid (bool sys_group, + * + */ + if (!nospam) { +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: Can't get unique system GID (%s). " + "Suppressing additional messages.\n"), +- Prog, strerror (result)); ++ log_get_progname(), strerror (result)); + SYSLOG ((LOG_ERR, + "Error checking available GIDs: %s", + strerror (result))); +@@ -433,10 +434,10 @@ int find_new_gid (bool sys_group, + * + */ + if (!nospam) { +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: Can't get unique GID (%s). " + "Suppressing additional messages.\n"), +- Prog, strerror (result)); ++ log_get_progname(), strerror (result)); + SYSLOG ((LOG_ERR, + "Error checking available GIDs: %s", + strerror (result))); +@@ -476,10 +477,10 @@ int find_new_gid (bool sys_group, + * + */ + if (!nospam) { +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: Can't get unique GID (%s). " + "Suppressing additional messages.\n"), +- Prog, strerror (result)); ++ log_get_progname(), strerror (result)); + SYSLOG ((LOG_ERR, + "Error checking available GIDs: %s", + strerror (result))); +@@ -495,9 +496,9 @@ int find_new_gid (bool sys_group, + } + + /* The code reached here and found no available IDs in the range */ +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: Can't get unique GID (no more available GIDs)\n"), +- Prog); ++ log_get_progname()); + SYSLOG ((LOG_WARN, "no more available GIDs on the system")); + free (used_gids); + return -1; +diff -up shadow-4.9/libmisc/find_new_sub_gids.c.debug1 shadow-4.9/libmisc/find_new_sub_gids.c +--- shadow-4.9/libmisc/find_new_sub_gids.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/libmisc/find_new_sub_gids.c 2022-01-10 10:45:52.203132944 +0100 +@@ -37,6 +37,7 @@ + #include "prototypes.h" + #include "subordinateio.h" + #include "getdef.h" ++#include "shadowlog.h" + + /* + * find_new_sub_gids - Find a new unused range of GIDs. +@@ -60,18 +61,18 @@ int find_new_sub_gids (gid_t *range_star + count = getdef_ulong ("SUB_GID_COUNT", 65536); + + if (min > max || count >= max || (min + count - 1) > max) { +- (void) fprintf (shadow_logfd, ++ (void) fprintf (log_get_logfd(), + _("%s: Invalid configuration: SUB_GID_MIN (%lu)," + " SUB_GID_MAX (%lu), SUB_GID_COUNT (%lu)\n"), +- Prog, min, max, count); ++ log_get_progname(), min, max, count); + return -1; + } + + start = sub_gid_find_free_range(min, max, count); + if (start == (gid_t)-1) { +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: Can't get unique subordinate GID range\n"), +- Prog); ++ log_get_progname()); + SYSLOG ((LOG_WARN, "no more available subordinate GIDs on the system")); + return -1; + } +diff -up shadow-4.9/libmisc/find_new_sub_uids.c.debug1 shadow-4.9/libmisc/find_new_sub_uids.c +--- shadow-4.9/libmisc/find_new_sub_uids.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/libmisc/find_new_sub_uids.c 2022-01-10 10:45:52.203132944 +0100 +@@ -37,6 +37,7 @@ + #include "prototypes.h" + #include "subordinateio.h" + #include "getdef.h" ++#include "shadowlog.h" + + /* + * find_new_sub_uids - Find a new unused range of UIDs. +@@ -60,18 +61,18 @@ int find_new_sub_uids (uid_t *range_star + count = getdef_ulong ("SUB_UID_COUNT", 65536); + + if (min > max || count >= max || (min + count - 1) > max) { +- (void) fprintf (shadow_logfd, ++ (void) fprintf (log_get_logfd(), + _("%s: Invalid configuration: SUB_UID_MIN (%lu)," + " SUB_UID_MAX (%lu), SUB_UID_COUNT (%lu)\n"), +- Prog, min, max, count); ++ log_get_progname(), min, max, count); + return -1; + } + + start = sub_uid_find_free_range(min, max, count); + if (start == (uid_t)-1) { +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: Can't get unique subordinate UID range\n"), +- Prog); ++ log_get_progname()); + SYSLOG ((LOG_WARN, "no more available subordinate UIDs on the system")); + return -1; + } +diff -up shadow-4.9/libmisc/find_new_uid.c.debug1 shadow-4.9/libmisc/find_new_uid.c +--- shadow-4.9/libmisc/find_new_uid.c.debug1 2022-01-10 10:45:52.191132858 +0100 ++++ shadow-4.9/libmisc/find_new_uid.c 2022-01-10 10:45:52.204132951 +0100 +@@ -38,6 +38,7 @@ + #include "prototypes.h" + #include "pwio.h" + #include "getdef.h" ++#include "shadowlog.h" + + /* + * get_ranges - Get the minimum and maximum ID ranges for the search +@@ -74,10 +75,10 @@ static int get_ranges (bool sys_user, ui + + /* Check that the ranges make sense */ + if (*max_id < *min_id) { +- (void) fprintf (shadow_logfd, ++ (void) fprintf (log_get_logfd(), + _("%s: Invalid configuration: SYS_UID_MIN (%lu), " + "UID_MIN (%lu), SYS_UID_MAX (%lu)\n"), +- Prog, (unsigned long) *min_id, ++ log_get_progname(), (unsigned long) *min_id, + getdef_ulong ("UID_MIN", 1000UL), + (unsigned long) *max_id); + return EINVAL; +@@ -104,10 +105,10 @@ static int get_ranges (bool sys_user, ui + + /* Check that the ranges make sense */ + if (*max_id < *min_id) { +- (void) fprintf (shadow_logfd, ++ (void) fprintf (log_get_logfd(), + _("%s: Invalid configuration: UID_MIN (%lu), " + "UID_MAX (%lu)\n"), +- Prog, (unsigned long) *min_id, ++ log_get_progname(), (unsigned long) *min_id, + (unsigned long) *max_id); + return EINVAL; + } +@@ -220,10 +221,10 @@ int find_new_uid(bool sys_user, + * more likely to want to stop and address the + * issue. + */ +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: Encountered error attempting to use " + "preferred UID: %s\n"), +- Prog, strerror (result)); ++ log_get_progname(), strerror (result)); + return -1; + } + } +@@ -250,9 +251,9 @@ int find_new_uid(bool sys_user, + /* Create an array to hold all of the discovered UIDs */ + used_uids = malloc (sizeof (bool) * (uid_max +1)); + if (NULL == used_uids) { +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: failed to allocate memory: %s\n"), +- Prog, strerror (errno)); ++ log_get_progname(), strerror (errno)); + return -1; + } + memset (used_uids, false, sizeof (bool) * (uid_max + 1)); +@@ -330,10 +331,10 @@ int find_new_uid(bool sys_user, + * + */ + if (!nospam) { +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: Can't get unique system UID (%s). " + "Suppressing additional messages.\n"), +- Prog, strerror (result)); ++ log_get_progname(), strerror (result)); + SYSLOG ((LOG_ERR, + "Error checking available UIDs: %s", + strerror (result))); +@@ -373,10 +374,10 @@ int find_new_uid(bool sys_user, + * + */ + if (!nospam) { +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: Can't get unique system UID (%s). " + "Suppressing additional messages.\n"), +- Prog, strerror (result)); ++ log_get_progname(), strerror (result)); + SYSLOG((LOG_ERR, + "Error checking available UIDs: %s", + strerror (result))); +@@ -433,10 +434,10 @@ int find_new_uid(bool sys_user, + * + */ + if (!nospam) { +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: Can't get unique UID (%s). " + "Suppressing additional messages.\n"), +- Prog, strerror (result)); ++ log_get_progname(), strerror (result)); + SYSLOG ((LOG_ERR, + "Error checking available UIDs: %s", + strerror (result))); +@@ -476,10 +477,10 @@ int find_new_uid(bool sys_user, + * + */ + if (!nospam) { +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: Can't get unique UID (%s). " + "Suppressing additional messages.\n"), +- Prog, strerror (result)); ++ log_get_progname(), strerror (result)); + SYSLOG ((LOG_ERR, + "Error checking available UIDs: %s", + strerror (result))); +@@ -495,9 +496,9 @@ int find_new_uid(bool sys_user, + } + + /* The code reached here and found no available IDs in the range */ +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: Can't get unique UID (no more available UIDs)\n"), +- Prog); ++ log_get_progname()); + SYSLOG ((LOG_WARN, "no more available UIDs on the system")); + free (used_uids); + return -1; +diff -up shadow-4.9/libmisc/gettime.c.debug1 shadow-4.9/libmisc/gettime.c +--- shadow-4.9/libmisc/gettime.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/libmisc/gettime.c 2022-01-10 10:45:52.204132951 +0100 +@@ -36,6 +36,7 @@ + #include + #include "defines.h" + #include "prototypes.h" ++#include "shadowlog.h" + + /* + * gettime() returns the time as the number of seconds since the Epoch +@@ -50,6 +51,7 @@ + char *source_date_epoch; + time_t fallback; + unsigned long long epoch; ++ FILE *shadow_logfd = log_get_logfd(); + + fallback = time (NULL); + source_date_epoch = shadow_getenv ("SOURCE_DATE_EPOCH"); +diff -up shadow-4.9/libmisc/idmapping.c.debug1 shadow-4.9/libmisc/idmapping.c +--- shadow-4.9/libmisc/idmapping.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/libmisc/idmapping.c 2022-01-10 10:45:52.204132951 +0100 +@@ -40,6 +40,7 @@ + #include + #include + #endif ++#include "shadowlog.h" + + struct map_range *get_map_ranges(int ranges, int argc, char **argv) + { +@@ -47,28 +48,28 @@ struct map_range *get_map_ranges(int ran + int idx, argidx; + + if (ranges < 0 || argc < 0) { +- fprintf(shadow_logfd, "%s: error calculating number of arguments\n", Prog); ++ fprintf(log_get_logfd(), "%s: error calculating number of arguments\n", log_get_progname()); + return NULL; + } + + if (ranges != ((argc + 2) / 3)) { +- fprintf(shadow_logfd, "%s: ranges: %u is wrong for argc: %d\n", Prog, ranges, argc); ++ fprintf(log_get_logfd(), "%s: ranges: %u is wrong for argc: %d\n", log_get_progname(), ranges, argc); + return NULL; + } + + if ((ranges * 3) > argc) { +- fprintf(shadow_logfd, "ranges: %u argc: %d\n", ++ fprintf(log_get_logfd(), "ranges: %u argc: %d\n", + ranges, argc); +- fprintf(shadow_logfd, ++ fprintf(log_get_logfd(), + _( "%s: Not enough arguments to form %u mappings\n"), +- Prog, ranges); ++ log_get_progname(), ranges); + return NULL; + } + + mappings = calloc(ranges, sizeof(*mappings)); + if (!mappings) { +- fprintf(shadow_logfd, _( "%s: Memory allocation failure\n"), +- Prog); ++ fprintf(log_get_logfd(), _( "%s: Memory allocation failure\n"), ++ log_get_progname()); + exit(EXIT_FAILURE); + } + +@@ -88,24 +89,24 @@ struct map_range *get_map_ranges(int ran + return NULL; + } + if (ULONG_MAX - mapping->upper <= mapping->count || ULONG_MAX - mapping->lower <= mapping->count) { +- fprintf(shadow_logfd, _( "%s: subuid overflow detected.\n"), Prog); ++ fprintf(log_get_logfd(), _( "%s: subuid overflow detected.\n"), log_get_progname()); + exit(EXIT_FAILURE); + } + if (mapping->upper > UINT_MAX || + mapping->lower > UINT_MAX || + mapping->count > UINT_MAX) { +- fprintf(shadow_logfd, _( "%s: subuid overflow detected.\n"), Prog); ++ fprintf(log_get_logfd(), _( "%s: subuid overflow detected.\n"), log_get_progname()); + exit(EXIT_FAILURE); + } + if (mapping->lower + mapping->count > UINT_MAX || + mapping->upper + mapping->count > UINT_MAX) { +- fprintf(shadow_logfd, _( "%s: subuid overflow detected.\n"), Prog); ++ fprintf(log_get_logfd(), _( "%s: subuid overflow detected.\n"), log_get_progname()); + exit(EXIT_FAILURE); + } + if (mapping->lower + mapping->count < mapping->lower || + mapping->upper + mapping->count < mapping->upper) { + /* this one really shouldn't be possible given previous checks */ +- fprintf(shadow_logfd, _( "%s: subuid overflow detected.\n"), Prog); ++ fprintf(log_get_logfd(), _( "%s: subuid overflow detected.\n"), log_get_progname()); + exit(EXIT_FAILURE); + } + } +@@ -176,19 +177,19 @@ void write_mapping(int proc_dir_fd, int + } else if (strcmp(map_file, "gid_map") == 0) { + cap = CAP_SETGID; + } else { +- fprintf(shadow_logfd, _("%s: Invalid map file %s specified\n"), Prog, map_file); ++ fprintf(log_get_logfd(), _("%s: Invalid map file %s specified\n"), log_get_progname(), map_file); + exit(EXIT_FAILURE); + } + + /* Align setuid- and fscaps-based new{g,u}idmap behavior. */ + if (geteuid() == 0 && geteuid() != ruid) { + if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) { +- fprintf(shadow_logfd, _("%s: Could not prctl(PR_SET_KEEPCAPS)\n"), Prog); ++ fprintf(log_get_logfd(), _("%s: Could not prctl(PR_SET_KEEPCAPS)\n"), log_get_progname()); + exit(EXIT_FAILURE); + } + + if (seteuid(ruid) < 0) { +- fprintf(shadow_logfd, _("%s: Could not seteuid to %d\n"), Prog, ruid); ++ fprintf(log_get_logfd(), _("%s: Could not seteuid to %d\n"), log_get_progname(), ruid); + exit(EXIT_FAILURE); + } + } +@@ -204,7 +205,7 @@ void write_mapping(int proc_dir_fd, int + data[0].effective |= CAP_TO_MASK(CAP_SETFCAP); + data[0].permitted = data[0].effective; + if (capset(&hdr, data) < 0) { +- fprintf(shadow_logfd, _("%s: Could not set caps\n"), Prog); ++ fprintf(log_get_logfd(), _("%s: Could not set caps\n"), log_get_progname()); + exit(EXIT_FAILURE); + } + #endif +@@ -222,7 +223,7 @@ void write_mapping(int proc_dir_fd, int + mapping->lower, + mapping->count); + if ((written <= 0) || (written >= (bufsize - (pos - buf)))) { +- fprintf(shadow_logfd, _("%s: snprintf failed!\n"), Prog); ++ fprintf(log_get_logfd(), _("%s: snprintf failed!\n"), log_get_progname()); + exit(EXIT_FAILURE); + } + pos += written; +@@ -231,13 +232,13 @@ void write_mapping(int proc_dir_fd, int + /* Write the mapping to the mapping file */ + fd = openat(proc_dir_fd, map_file, O_WRONLY); + if (fd < 0) { +- fprintf(shadow_logfd, _("%s: open of %s failed: %s\n"), +- Prog, map_file, strerror(errno)); ++ fprintf(log_get_logfd(), _("%s: open of %s failed: %s\n"), ++ log_get_progname(), map_file, strerror(errno)); + exit(EXIT_FAILURE); + } + if (write(fd, buf, pos - buf) != (pos - buf)) { +- fprintf(shadow_logfd, _("%s: write to %s failed: %s\n"), +- Prog, map_file, strerror(errno)); ++ fprintf(log_get_logfd(), _("%s: write to %s failed: %s\n"), ++ log_get_progname(), map_file, strerror(errno)); + exit(EXIT_FAILURE); + } + close(fd); +diff -up shadow-4.9/libmisc/limits.c.debug1 shadow-4.9/libmisc/limits.c +--- shadow-4.9/libmisc/limits.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/libmisc/limits.c 2022-01-10 10:45:52.204132951 +0100 +@@ -50,6 +50,7 @@ + #include "defines.h" + #include + #include "getdef.h" ++#include "shadowlog.h" + #ifdef HAVE_SYS_RESOURCE_H + #include + #define LIMITS +@@ -548,7 +549,7 @@ void setup_limits (const struct passwd * + #ifdef LIMITS + if (info->pw_uid != 0) { + if ((setup_user_limits (info->pw_name) & LOGIN_ERROR_LOGIN) != 0) { +- (void) fputs (_("Too many logins.\n"), shadow_logfd); ++ (void) fputs (_("Too many logins.\n"), log_get_logfd()); + (void) sleep (2); /* XXX: Should be FAIL_DELAY */ + exit (EXIT_FAILURE); + } +diff -up shadow-4.9/libmisc/pam_pass.c.debug1 shadow-4.9/libmisc/pam_pass.c +--- shadow-4.9/libmisc/pam_pass.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/libmisc/pam_pass.c 2022-01-10 10:45:52.204132951 +0100 +@@ -46,11 +46,13 @@ + #include "defines.h" + #include "pam_defs.h" + #include "prototypes.h" ++#include "shadowlog.h" + + void do_pam_passwd (const char *user, bool silent, bool change_expired) + { + pam_handle_t *pamh = NULL; + int flags = 0, ret; ++ FILE *shadow_logfd = log_get_logfd(); + + if (silent) + flags |= PAM_SILENT; +diff -up shadow-4.9/libmisc/pam_pass_non_interactive.c.debug1 shadow-4.9/libmisc/pam_pass_non_interactive.c +--- shadow-4.9/libmisc/pam_pass_non_interactive.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/libmisc/pam_pass_non_interactive.c 2022-01-10 10:45:52.204132951 +0100 +@@ -38,6 +38,7 @@ + #include + #include + #include "prototypes.h" ++#include "shadowlog.h" + + /*@null@*/ /*@only@*/static const char *non_interactive_password = NULL; + static int ni_conv (int num_msg, +@@ -76,9 +77,9 @@ static int ni_conv (int num_msg, + + switch (msg[count]->msg_style) { + case PAM_PROMPT_ECHO_ON: +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: PAM modules requesting echoing are not supported.\n"), +- Prog); ++ log_get_progname()); + goto failed_conversation; + case PAM_PROMPT_ECHO_OFF: + responses[count].resp = strdup (non_interactive_password); +@@ -88,7 +89,7 @@ static int ni_conv (int num_msg, + break; + case PAM_ERROR_MSG: + if ( (NULL == msg[count]->msg) +- || (fprintf (shadow_logfd, "%s\n", msg[count]->msg) <0)) { ++ || (fprintf (log_get_logfd(), "%s\n", msg[count]->msg) <0)) { + goto failed_conversation; + } + responses[count].resp = NULL; +@@ -101,9 +102,9 @@ static int ni_conv (int num_msg, + responses[count].resp = NULL; + break; + default: +- (void) fprintf (shadow_logfd, ++ (void) fprintf (log_get_logfd(), + _("%s: conversation type %d not supported.\n"), +- Prog, msg[count]->msg_style); ++ log_get_progname(), msg[count]->msg_style); + goto failed_conversation; + } + } +@@ -143,19 +144,19 @@ int do_pam_passwd_non_interactive (const + + ret = pam_start (pam_service, username, &non_interactive_pam_conv, &pamh); + if (ret != PAM_SUCCESS) { +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: (user %s) pam_start failure %d\n"), +- Prog, username, ret); ++ log_get_progname(), username, ret); + return 1; + } + + non_interactive_password = password; + ret = pam_chauthtok (pamh, 0); + if (ret != PAM_SUCCESS) { +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: (user %s) pam_chauthtok() failed, error:\n" + "%s\n"), +- Prog, username, pam_strerror (pamh, ret)); ++ log_get_progname(), username, pam_strerror (pamh, ret)); + } + + (void) pam_end (pamh, PAM_SUCCESS); +diff -up shadow-4.9/libmisc/prefix_flag.c.debug1 shadow-4.9/libmisc/prefix_flag.c +--- shadow-4.9/libmisc/prefix_flag.c.debug1 2022-01-10 10:45:52.201132929 +0100 ++++ shadow-4.9/libmisc/prefix_flag.c 2022-01-10 10:45:52.204132951 +0100 +@@ -48,6 +48,7 @@ + #include "subordinateio.h" + #endif /* ENABLE_SUBIDS */ + #include "getdef.h" ++#include "shadowlog.h" + + static char *passwd_db_file = NULL; + static char *spw_db_file = NULL; +@@ -83,18 +84,18 @@ extern const char* process_prefix_flag ( + && (val = argv[i] + 9)) + || (strcmp (argv[i], short_opt) == 0)) { + if (NULL != prefix) { +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: multiple --prefix options\n"), +- Prog); ++ log_get_progname()); + exit (E_BAD_ARG); + } + + if (val) { + prefix = val; + } else if (i + 1 == argc) { +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: option '%s' requires an argument\n"), +- Prog, argv[i]); ++ log_get_progname(), argv[i]); + exit (E_BAD_ARG); + } else { + prefix = argv[++ i]; +@@ -110,9 +111,9 @@ extern const char* process_prefix_flag ( + /* should we prevent symbolic link from being used as a prefix? */ + + if ( prefix[0] != '/') { +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: prefix must be an absolute path\n"), +- Prog); ++ log_get_progname()); + exit (E_BAD_ARG); + } + size_t len; +diff -up shadow-4.9/libmisc/pwdcheck.c.debug1 shadow-4.9/libmisc/pwdcheck.c +--- shadow-4.9/libmisc/pwdcheck.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/libmisc/pwdcheck.c 2022-01-10 10:45:52.204132951 +0100 +@@ -39,6 +39,7 @@ + #include "prototypes.h" + #include "defines.h" + #include "pwauth.h" ++#include "shadowlog.h" + + void passwd_check (const char *user, const char *passwd, unused const char *progname) + { +@@ -51,7 +52,7 @@ void passwd_check (const char *user, con + if (pw_auth (passwd, user, PW_LOGIN, (char *) 0) != 0) { + SYSLOG ((LOG_WARN, "incorrect password for `%s'", user)); + (void) sleep (1); +- fprintf (shadow_logfd, _("Incorrect password for %s.\n"), user); ++ fprintf (log_get_logfd(), _("Incorrect password for %s.\n"), user); + exit (EXIT_FAILURE); + } + } +diff -up shadow-4.9/libmisc/root_flag.c.debug1 shadow-4.9/libmisc/root_flag.c +--- shadow-4.9/libmisc/root_flag.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/libmisc/root_flag.c 2022-01-10 10:45:52.204132951 +0100 +@@ -38,6 +38,7 @@ + #include "prototypes.h" + /*@-exitarg@*/ + #include "exitcodes.h" ++#include "shadowlog.h" + + static void change_root (const char* newroot); + +@@ -65,18 +66,18 @@ extern void process_root_flag (const cha + && (val = argv[i] + 7)) + || (strcmp (argv[i], short_opt) == 0)) { + if (NULL != newroot) { +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: multiple --root options\n"), +- Prog); ++ log_get_progname()); + exit (E_BAD_ARG); + } + + if (val) { + newroot = val; + } else if (i + 1 == argc) { +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: option '%s' requires an argument\n"), +- Prog, argv[i]); ++ log_get_progname(), argv[i]); + exit (E_BAD_ARG); + } else { + newroot = argv[++ i]; +@@ -94,36 +95,36 @@ static void change_root (const char* new + /* Drop privileges */ + if ( (setregid (getgid (), getgid ()) != 0) + || (setreuid (getuid (), getuid ()) != 0)) { +- fprintf (shadow_logfd, _("%s: failed to drop privileges (%s)\n"), +- Prog, strerror (errno)); ++ fprintf (log_get_logfd(), _("%s: failed to drop privileges (%s)\n"), ++ log_get_progname(), strerror (errno)); + exit (EXIT_FAILURE); + } + + if ('/' != newroot[0]) { +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: invalid chroot path '%s'\n"), +- Prog, newroot); ++ log_get_progname(), newroot); + exit (E_BAD_ARG); + } + + if (access (newroot, F_OK) != 0) { +- fprintf(shadow_logfd, ++ fprintf(log_get_logfd(), + _("%s: cannot access chroot directory %s: %s\n"), +- Prog, newroot, strerror (errno)); ++ log_get_progname(), newroot, strerror (errno)); + exit (E_BAD_ARG); + } + + if (chdir (newroot) != 0) { +- fprintf(shadow_logfd, ++ fprintf(log_get_logfd(), + _("%s: cannot chdir to chroot directory %s: %s\n"), +- Prog, newroot, strerror (errno)); ++ log_get_progname(), newroot, strerror (errno)); + exit (E_BAD_ARG); + } + + if (chroot (newroot) != 0) { +- fprintf(shadow_logfd, ++ fprintf(log_get_logfd(), + _("%s: unable to chroot to directory %s: %s\n"), +- Prog, newroot, strerror (errno)); ++ log_get_progname(), newroot, strerror (errno)); + exit (E_BAD_ARG); + } + } +diff -up shadow-4.9/libmisc/salt.c.debug1 shadow-4.9/libmisc/salt.c +--- shadow-4.9/libmisc/salt.c.debug1 2022-01-10 10:45:52.195132887 +0100 ++++ shadow-4.9/libmisc/salt.c 2022-01-10 10:45:52.204132951 +0100 +@@ -21,6 +21,7 @@ + #include "prototypes.h" + #include "defines.h" + #include "getdef.h" ++#include "shadowlog.h" + + #if (defined CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY && \ + CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY) +@@ -178,7 +179,7 @@ static long read_random_bytes (void) + #endif + + fail: +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("Unable to obtain random bytes.\n")); + exit (1); + +@@ -506,7 +507,7 @@ static /*@observer@*/const char *gensalt + SHA_salt_rounds_to_buf (result, rounds); + #endif /* USE_SHA_CRYPT */ + } else if (0 != strcmp (method, "DES")) { +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("Invalid ENCRYPT_METHOD value: '%s'.\n" + "Defaulting to DES.\n"), + method); +@@ -532,7 +533,7 @@ static /*@observer@*/const char *gensalt + + /* Should not happen, but... */ + if (NULL == retval) { +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("Unable to generate a salt from setting " + "\"%s\", check your settings in " + "ENCRYPT_METHOD and the corresponding " +diff -up shadow-4.9/libmisc/setupenv.c.debug1 shadow-4.9/libmisc/setupenv.c +--- shadow-4.9/libmisc/setupenv.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/libmisc/setupenv.c 2022-01-10 10:45:52.204132951 +0100 +@@ -47,6 +47,7 @@ + #include "defines.h" + #include + #include "getdef.h" ++#include "shadowlog.h" + + #ifndef USE_PAM + static void +@@ -219,7 +220,7 @@ void setup_env (struct passwd *info) + static char temp_pw_dir[] = "/"; + + if (!getdef_bool ("DEFAULT_HOME") || chdir ("/") == -1) { +- fprintf (shadow_logfd, _("Unable to cd to '%s'\n"), ++ fprintf (log_get_logfd(), _("Unable to cd to '%s'\n"), + info->pw_dir); + SYSLOG ((LOG_WARN, + "unable to cd to `%s' for user `%s'\n", +diff -up shadow-4.9/libmisc/user_busy.c.debug1 shadow-4.9/libmisc/user_busy.c +--- shadow-4.9/libmisc/user_busy.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/libmisc/user_busy.c 2022-01-10 10:45:52.204132951 +0100 +@@ -45,6 +45,7 @@ + #ifdef ENABLE_SUBIDS + #include "subordinateio.h" + #endif /* ENABLE_SUBIDS */ ++#include "shadowlog.h" + + #ifdef __linux__ + static int check_status (const char *name, const char *sname, uid_t uid); +@@ -96,9 +97,9 @@ static int user_busy_utmp (const char *n + continue; + } + +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: user %s is currently logged in\n"), +- Prog, name); ++ log_get_progname(), name); + return 1; + } + +@@ -249,9 +250,9 @@ static int user_busy_processes (const ch + #ifdef ENABLE_SUBIDS + sub_uid_close(); + #endif +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: user %s is currently used by process %d\n"), +- Prog, name, pid); ++ log_get_progname(), name, pid); + return 1; + } + +@@ -273,9 +274,9 @@ static int user_busy_processes (const ch + #ifdef ENABLE_SUBIDS + sub_uid_close(); + #endif +- fprintf (shadow_logfd, ++ fprintf (log_get_logfd(), + _("%s: user %s is currently used by process %d\n"), +- Prog, name, pid); ++ log_get_progname(), name, pid); + return 1; + } + } +diff -up shadow-4.9/libmisc/xgetXXbyYY.c.debug1 shadow-4.9/libmisc/xgetXXbyYY.c +--- shadow-4.9/libmisc/xgetXXbyYY.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/libmisc/xgetXXbyYY.c 2022-01-10 10:45:52.204132951 +0100 +@@ -54,6 +54,7 @@ + #include + #include + #include "prototypes.h" ++#include "shadowlog.h" + + #define XFUNCTION_NAME XPREFIX (FUNCTION_NAME) + #define XPREFIX(name) XPREFIX1 (name) +@@ -74,7 +75,7 @@ + + result = malloc(sizeof(LOOKUP_TYPE)); + if (NULL == result) { +- fprintf (shadow_logfd, _("%s: out of memory\n"), ++ fprintf (log_get_logfd(), _("%s: out of memory\n"), + "x" STRINGIZE(FUNCTION_NAME)); + exit (13); + } +@@ -84,7 +85,7 @@ + LOOKUP_TYPE *resbuf = NULL; + buffer = (char *)realloc (buffer, length); + if (NULL == buffer) { +- fprintf (shadow_logfd, _("%s: out of memory\n"), ++ fprintf (log_get_logfd(), _("%s: out of memory\n"), + "x" STRINGIZE(FUNCTION_NAME)); + exit (13); + } +@@ -132,7 +133,7 @@ + if (result) { + result = DUP_FUNCTION(result); + if (NULL == result) { +- fprintf (shadow_logfd, _("%s: out of memory\n"), ++ fprintf (log_get_logfd(), _("%s: out of memory\n"), + "x" STRINGIZE(FUNCTION_NAME)); + exit (13); + } +diff -up shadow-4.9/libmisc/xmalloc.c.debug1 shadow-4.9/libmisc/xmalloc.c +--- shadow-4.9/libmisc/xmalloc.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/libmisc/xmalloc.c 2022-01-10 10:45:52.204132951 +0100 +@@ -47,6 +47,7 @@ + #include + #include "defines.h" + #include "prototypes.h" ++#include "shadowlog.h" + + /*@maynotreturn@*/ /*@only@*//*@out@*//*@notnull@*/char *xmalloc (size_t size) + { +@@ -54,9 +55,9 @@ + + ptr = (char *) malloc (size); + if (NULL == ptr) { +- (void) fprintf (shadow_logfd, ++ (void) fprintf (log_get_logfd(), + _("%s: failed to allocate memory: %s\n"), +- Prog, strerror (errno)); ++ log_get_progname(), strerror (errno)); + exit (13); + } + return ptr; +diff -up shadow-4.9/lib/nscd.c.debug1 shadow-4.9/lib/nscd.c +--- shadow-4.9/lib/nscd.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/lib/nscd.c 2022-01-10 10:45:52.202132937 +0100 +@@ -10,6 +10,7 @@ + #include "defines.h" + #include "prototypes.h" + #include "nscd.h" ++#include "shadowlog_internal.h" + + #define MSG_NSCD_FLUSH_CACHE_FAILED "%s: Failed to flush the nscd cache.\n" + +diff -up shadow-4.9/lib/nss.c.debug1 shadow-4.9/lib/nss.c +--- shadow-4.9/lib/nss.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/lib/nss.c 2022-01-10 10:45:52.202132937 +0100 +@@ -8,6 +8,7 @@ + #include + #include "prototypes.h" + #include "../libsubid/subid.h" ++#include "shadowlog_internal.h" + + #define NSSWITCH "/etc/nsswitch.conf" + +diff -up shadow-4.9/lib/prototypes.h.debug1 shadow-4.9/lib/prototypes.h +--- shadow-4.9/lib/prototypes.h.debug1 2022-01-10 10:45:52.195132887 +0100 ++++ shadow-4.9/lib/prototypes.h 2022-01-10 10:45:52.202132937 +0100 +@@ -59,9 +59,6 @@ + #include "defines.h" + #include "commonio.h" + +-extern /*@observer@*/ const char *Prog; /* Program name showed in error messages */ +-extern FILE *shadow_logfd; /* file descripter to which error messages are printed */ +- + /* addgrps.c */ + #if defined (HAVE_SETGROUPS) && ! defined (USE_PAM) + extern int add_groups (const char *); +diff -up shadow-4.9/lib/run_part.c.debug1 shadow-4.9/lib/run_part.c +--- shadow-4.9/lib/run_part.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/lib/run_part.c 2022-01-10 10:45:52.202132937 +0100 +@@ -8,6 +8,7 @@ + #include + #include + #include ++#include "shadowlog_internal.h" + + int run_part (char *script_path, char *name, char *action) + { +diff -up shadow-4.9/lib/selinux.c.debug1 shadow-4.9/lib/selinux.c +--- shadow-4.9/lib/selinux.c.debug1 2022-01-10 10:45:52.196132894 +0100 ++++ shadow-4.9/lib/selinux.c 2022-01-10 10:45:52.202132937 +0100 +@@ -38,6 +38,8 @@ + #include + #include "prototypes.h" + ++#include "shadowlog_internal.h" ++ + static bool selinux_checked = false; + static bool selinux_enabled; + static /*@null@*/struct selabel_handle *selabel_hnd = NULL; +diff -up shadow-4.9/lib/semanage.c.debug1 shadow-4.9/lib/semanage.c +--- shadow-4.9/lib/semanage.c.debug1 2022-01-10 10:45:52.196132894 +0100 ++++ shadow-4.9/lib/semanage.c 2022-01-10 10:45:52.202132937 +0100 +@@ -43,6 +43,7 @@ + #include + #include "prototypes.h" + ++#include "shadowlog_internal.h" + + #ifndef DEFAULT_SERANGE + #define DEFAULT_SERANGE "s0" +diff -up shadow-4.9/lib/shadowlog.c.debug1 shadow-4.9/lib/shadowlog.c +--- shadow-4.9/lib/shadowlog.c.debug1 2022-01-10 10:45:52.202132937 +0100 ++++ shadow-4.9/lib/shadowlog.c 2022-01-10 10:45:52.202132937 +0100 +@@ -0,0 +1,28 @@ ++#include "shadowlog.h" ++ ++#include "lib/shadowlog_internal.h" ++ ++void log_set_progname(const char *progname) ++{ ++ Prog = progname; ++} ++ ++const char *log_get_progname(void) ++{ ++ return Prog; ++} ++ ++void log_set_logfd(FILE *fd) ++{ ++ if (NULL != fd) ++ shadow_logfd = fd; ++ else ++ shadow_logfd = stderr; ++} ++ ++FILE *log_get_logfd(void) ++{ ++ if (shadow_logfd != NULL) ++ return shadow_logfd; ++ return stderr; ++} +diff -up shadow-4.9/lib/shadowlog.h.debug1 shadow-4.9/lib/shadowlog.h +--- shadow-4.9/lib/shadowlog.h.debug1 2022-01-10 10:45:52.202132937 +0100 ++++ shadow-4.9/lib/shadowlog.h 2022-01-10 10:45:52.202132937 +0100 +@@ -0,0 +1,41 @@ ++/* ++ * Copyright (c) 2021 , Serge Hallyn ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The name of the copyright holders or contributors may not be used to ++ * endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A ++ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/* $Id$ */ ++#ifndef _LOG_H ++#define _LOG_H ++#include ++ ++extern void log_set_progname(const char *); ++extern const char *log_get_progname(void); ++extern void log_set_logfd(FILE *fd); ++extern FILE *log_get_logfd(void); ++extern void log_dolog(char *, ...); ++ ++#endif +diff -up shadow-4.9/lib/shadowlog_internal.h.debug1 shadow-4.9/lib/shadowlog_internal.h +--- shadow-4.9/lib/shadowlog_internal.h.debug1 2022-01-10 10:45:52.202132937 +0100 ++++ shadow-4.9/lib/shadowlog_internal.h 2022-01-10 10:45:52.202132937 +0100 +@@ -0,0 +1,2 @@ ++const char *Prog; /* Program name showed in error messages */ ++FILE *shadow_logfd; /* file descripter to which error messages are printed */ +diff -up shadow-4.9/lib/spawn.c.debug1 shadow-4.9/lib/spawn.c +--- shadow-4.9/lib/spawn.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/lib/spawn.c 2022-01-10 10:45:52.202132937 +0100 +@@ -38,6 +38,8 @@ + #include "exitcodes.h" + #include "prototypes.h" + ++#include "shadowlog_internal.h" ++ + int run_command (const char *cmd, const char *argv[], + /*@null@*/const char *envp[], /*@out@*/int *status) + { +diff -up shadow-4.9/lib/sssd.c.debug1 shadow-4.9/lib/sssd.c +--- shadow-4.9/lib/sssd.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/lib/sssd.c 2022-01-10 10:45:52.203132944 +0100 +@@ -11,6 +11,8 @@ + #include "prototypes.h" + #include "sssd.h" + ++#include "shadowlog_internal.h" ++ + #define MSG_SSSD_FLUSH_CACHE_FAILED "%s: Failed to flush the sssd cache." + + int sssd_flush_cache (int dbflags) +diff -up shadow-4.9/libsubid/api.c.debug1 shadow-4.9/libsubid/api.c +--- shadow-4.9/libsubid/api.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/libsubid/api.c 2022-01-10 10:48:14.913151522 +0100 +@@ -38,12 +38,13 @@ + #include "subordinateio.h" + #include "idmapping.h" + #include "subid.h" ++#include "shadowlog.h" + + const char *Prog = "(libsubid)"; +-FILE *shadow_logfd; + + bool libsubid_init(const char *progname, FILE * logfd) + { ++ FILE *shadow_logfd; + if (progname) { + progname = strdup(progname); + if (progname) +@@ -53,14 +54,15 @@ bool libsubid_init(const char *progname, + } + + if (logfd) { +- shadow_logfd = logfd; ++ log_set_logfd(logfd); + return true; + } + shadow_logfd = fopen("/dev/null", "w"); + if (!shadow_logfd) { +- shadow_logfd = stderr; ++ log_set_logfd(stderr); + return false; + } ++ log_set_logfd(shadow_logfd); + return true; + } + +diff -up shadow-4.9/lib/tcbfuncs.c.debug1 shadow-4.9/lib/tcbfuncs.c +--- shadow-4.9/lib/tcbfuncs.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/lib/tcbfuncs.c 2022-01-10 10:45:52.203132944 +0100 +@@ -38,6 +38,8 @@ + #include "shadowio.h" + #include "tcbfuncs.h" + ++#include "shadowlog_internal.h" ++ + #define SHADOWTCB_HASH_BY 1000 + #define SHADOWTCB_LOCK_SUFFIX ".lock" + +diff -up shadow-4.9/src/chage.c.debug1 shadow-4.9/src/chage.c +--- shadow-4.9/src/chage.c.debug1 2022-01-10 10:45:52.188132837 +0100 ++++ shadow-4.9/src/chage.c 2022-01-10 10:45:52.205132958 +0100 +@@ -52,6 +52,7 @@ + #include "defines.h" + #include "pwio.h" + #include "shadowio.h" ++#include "shadowlog.h" + #ifdef WITH_TCB + #include "tcbfuncs.h" + #endif +@@ -62,7 +63,6 @@ + * Global variables + */ + const char *Prog; +-FILE *shadow_logfd = NULL; + + static bool + dflg = false, /* set last password change date */ +@@ -820,7 +820,8 @@ int main (int argc, char **argv) + * Get the program name so that error messages can use it. + */ + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + + sanitize_env (); + (void) setlocale (LC_ALL, ""); +diff -up shadow-4.9/src/check_subid_range.c.debug1 shadow-4.9/src/check_subid_range.c +--- shadow-4.9/src/check_subid_range.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/src/check_subid_range.c 2022-01-10 10:45:52.205132958 +0100 +@@ -16,9 +16,9 @@ + #include "prototypes.h" + #include "subordinateio.h" + #include "idmapping.h" ++#include "shadowlog.h" + + const char *Prog; +-FILE *shadow_logfd = NULL; + + int main(int argc, char **argv) + { +@@ -26,7 +26,8 @@ int main(int argc, char **argv) + unsigned long start, count; + bool check_uids; + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + + if (argc != 5) + exit(1); +diff -up shadow-4.9/src/chfn.c.debug1 shadow-4.9/src/chfn.c +--- shadow-4.9/src/chfn.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/src/chfn.c 2022-01-10 10:45:52.205132958 +0100 +@@ -52,12 +52,12 @@ + #include "pwio.h" + /*@-exitarg@*/ + #include "exitcodes.h" ++#include "shadowlog.h" + + /* + * Global variables. + */ + const char *Prog; +-FILE *shadow_logfd = NULL; + static char fullnm[BUFSIZ]; + static char roomno[BUFSIZ]; + static char workph[BUFSIZ]; +@@ -640,7 +640,8 @@ int main (int argc, char **argv) + * prefix to most error messages. + */ + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + + sanitize_env (); + (void) setlocale (LC_ALL, ""); +diff -up shadow-4.9/src/chgpasswd.c.debug1 shadow-4.9/src/chgpasswd.c +--- shadow-4.9/src/chgpasswd.c.debug1 2022-01-10 10:45:52.188132837 +0100 ++++ shadow-4.9/src/chgpasswd.c 2022-01-10 10:45:52.205132958 +0100 +@@ -61,12 +61,12 @@ + #endif + /*@-exitarg@*/ + #include "exitcodes.h" ++#include "shadowlog.h" + + /* + * Global variables + */ + const char *Prog; +-FILE *shadow_logfd = NULL; + static bool eflg = false; + static bool md5flg = false; + #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) +@@ -506,7 +506,8 @@ int main (int argc, char **argv) + int line = 0; + + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.9/src/chpasswd.c.debug1 shadow-4.9/src/chpasswd.c +--- shadow-4.9/src/chpasswd.c.debug1 2022-01-10 10:45:52.188132837 +0100 ++++ shadow-4.9/src/chpasswd.c 2022-01-10 10:45:52.205132958 +0100 +@@ -58,12 +58,12 @@ + #include "shadowio.h" + /*@-exitarg@*/ + #include "exitcodes.h" ++#include "shadowlog.h" + + /* + * Global variables + */ + const char *Prog; +-FILE *shadow_logfd = NULL; + static bool eflg = false; + static bool md5flg = false; + #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) +@@ -494,7 +494,8 @@ int main (int argc, char **argv) + int line = 0; + + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.9/src/chsh.c.debug1 shadow-4.9/src/chsh.c +--- shadow-4.9/src/chsh.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/src/chsh.c 2022-01-10 10:45:52.205132958 +0100 +@@ -51,6 +51,7 @@ + #endif + /*@-exitarg@*/ + #include "exitcodes.h" ++#include "shadowlog.h" + + #ifndef SHELLS_FILE + #define SHELLS_FILE "/etc/shells" +@@ -59,7 +60,6 @@ + * Global variables + */ + const char *Prog; /* Program name */ +-FILE *shadow_logfd = NULL; + static bool amroot; /* Real UID is root */ + static char loginsh[BUFSIZ]; /* Name of new login shell */ + /* command line options */ +@@ -442,7 +442,8 @@ int main (int argc, char **argv) + * most error messages. + */ + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.9/src/expiry.c.debug1 shadow-4.9/src/expiry.c +--- shadow-4.9/src/expiry.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/src/expiry.c 2022-01-10 10:45:52.205132958 +0100 +@@ -43,10 +43,10 @@ + #include "prototypes.h" + /*@-exitarg@*/ + #include "exitcodes.h" ++#include "shadowlog.h" + + /* Global variables */ + const char *Prog; +-FILE *shadow_logfd = NULL; + static bool cflg = false; + + /* local function prototypes */ +@@ -145,7 +145,8 @@ int main (int argc, char **argv) + struct spwd *spwd; + + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + + sanitize_env (); + +diff -up shadow-4.9/src/faillog.c.debug1 shadow-4.9/src/faillog.c +--- shadow-4.9/src/faillog.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/src/faillog.c 2022-01-10 10:45:52.205132958 +0100 +@@ -46,6 +46,7 @@ + #include "prototypes.h" + /*@-exitarg@*/ + #include "exitcodes.h" ++#include "shadowlog.h" + + /* local function prototypes */ + static /*@noreturn@*/void usage (int status); +@@ -62,7 +63,6 @@ static void reset (void); + * Global variables + */ + const char *Prog; /* Program name */ +-FILE *shadow_logfd = NULL; + static FILE *fail; /* failure file stream */ + static time_t seconds; /* that number of days in seconds */ + static unsigned long umin; /* if uflg and has_umin, only display users with uid >= umin */ +@@ -574,7 +574,8 @@ int main (int argc, char **argv) + * most error messages. + */ + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.9/src/free_subid_range.c.debug1 shadow-4.9/src/free_subid_range.c +--- shadow-4.9/src/free_subid_range.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/src/free_subid_range.c 2022-01-10 10:45:52.205132958 +0100 +@@ -3,11 +3,11 @@ + #include "subid.h" + #include "stdlib.h" + #include "prototypes.h" ++#include "shadowlog.h" + + /* Test program for the subid freeing routine */ + + const char *Prog; +-FILE *shadow_logfd = NULL; + + void usage(void) + { +@@ -24,7 +24,8 @@ int main(int argc, char *argv[]) + bool group = false; // get subuids by default + + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + while ((c = getopt(argc, argv, "g")) != EOF) { + switch(c) { + case 'g': group = true; break; +diff -up shadow-4.9/src/get_subid_owners.c.debug1 shadow-4.9/src/get_subid_owners.c +--- shadow-4.9/src/get_subid_owners.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/src/get_subid_owners.c 2022-01-10 10:45:52.205132958 +0100 +@@ -2,9 +2,9 @@ + #include "subid.h" + #include "stdlib.h" + #include "prototypes.h" ++#include "shadowlog.h" + + const char *Prog; +-FILE *shadow_logfd = NULL; + + void usage(void) + { +@@ -20,7 +20,8 @@ int main(int argc, char *argv[]) + uid_t *uids; + + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + if (argc < 2) { + usage(); + } +diff -up shadow-4.9/src/getsubids.c.debug1 shadow-4.9/src/getsubids.c +--- shadow-4.9/src/getsubids.c.debug1 2022-01-10 10:45:52.200132922 +0100 ++++ shadow-4.9/src/getsubids.c 2022-01-10 10:45:52.205132958 +0100 +@@ -3,9 +3,9 @@ + #include + #include "subid.h" + #include "prototypes.h" ++#include "shadowlog.h" + + const char *Prog; +-FILE *shadow_logfd = NULL; + + void usage(void) + { +@@ -22,7 +22,8 @@ int main(int argc, char *argv[]) + const char *owner; + + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + if (argc < 2) + usage(); + owner = argv[1]; +diff -up shadow-4.9/src/gpasswd.c.debug1 shadow-4.9/src/gpasswd.c +--- shadow-4.9/src/gpasswd.c.debug1 2022-01-10 10:45:52.184132808 +0100 ++++ shadow-4.9/src/gpasswd.c 2022-01-10 10:45:52.205132958 +0100 +@@ -53,12 +53,12 @@ + /*@-exitarg@*/ + #include "exitcodes.h" + ++#include "shadowlog.h" + /* + * Global variables + */ + /* The name of this command, as it is invoked */ + const char *Prog; +-FILE *shadow_logfd = NULL; + + #ifdef SHADOWGRP + /* Indicate if shadow groups are enabled on the system +@@ -927,7 +927,8 @@ int main (int argc, char **argv) + */ + bywho = getuid (); + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + + OPENLOG ("gpasswd"); + setbuf (stdout, NULL); +diff -up shadow-4.9/src/groupadd.c.debug1 shadow-4.9/src/groupadd.c +--- shadow-4.9/src/groupadd.c.debug1 2022-01-10 10:45:52.184132808 +0100 ++++ shadow-4.9/src/groupadd.c 2022-01-10 10:45:52.205132958 +0100 +@@ -56,6 +56,7 @@ + #ifdef SHADOWGRP + #include "sgroupio.h" + #endif ++#include "shadowlog.h" + + /* + * exit status values +@@ -72,7 +73,6 @@ + * Global variables + */ + const char *Prog; +-FILE *shadow_logfd = NULL; + + static /*@null@*/char *group_name; + static gid_t group_id; +@@ -602,7 +602,8 @@ int main (int argc, char **argv) + * Get my name so that I can use it to report errors. + */ + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.9/src/groupdel.c.debug1 shadow-4.9/src/groupdel.c +--- shadow-4.9/src/groupdel.c.debug1 2022-01-10 10:45:52.185132815 +0100 ++++ shadow-4.9/src/groupdel.c 2022-01-10 10:45:52.205132958 +0100 +@@ -54,11 +54,11 @@ + #ifdef SHADOWGRP + #include "sgroupio.h" + #endif ++#include "shadowlog.h" + /* + * Global variables + */ + const char *Prog; +-FILE *shadow_logfd = NULL; + + static char *group_name; + static gid_t group_id = -1; +@@ -379,7 +379,8 @@ int main (int argc, char **argv) + * Get my name so that I can use it to report errors. + */ + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.9/src/groupmems.c.debug1 shadow-4.9/src/groupmems.c +--- shadow-4.9/src/groupmems.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/src/groupmems.c 2022-01-10 10:45:52.206132965 +0100 +@@ -47,6 +47,7 @@ + #ifdef SHADOWGRP + #include "sgroupio.h" + #endif ++#include "shadowlog.h" + + /* Exit Status Values */ + /*@-exitarg@*/ +@@ -65,7 +66,6 @@ + * Global variables + */ + const char *Prog; +-FILE *shadow_logfd = NULL; + + static char *adduser = NULL; + static char *deluser = NULL; +@@ -596,7 +596,8 @@ int main (int argc, char **argv) + * Get my name so that I can use it to report errors. + */ + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.9/src/groupmod.c.debug1 shadow-4.9/src/groupmod.c +--- shadow-4.9/src/groupmod.c.debug1 2022-01-10 10:45:52.185132815 +0100 ++++ shadow-4.9/src/groupmod.c 2022-01-10 10:45:52.206132965 +0100 +@@ -56,6 +56,7 @@ + #ifdef SHADOWGRP + #include "sgroupio.h" + #endif ++#include "shadowlog.h" + /* + * exit status values + */ +@@ -76,7 +77,6 @@ + * Global variables + */ + const char *Prog; +-FILE *shadow_logfd = NULL; + + #ifdef SHADOWGRP + static bool is_shadow_grp; +@@ -840,7 +840,8 @@ int main (int argc, char **argv) + * Get my name so that I can use it to report errors. + */ + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.9/src/groups.c.debug1 shadow-4.9/src/groups.c +--- shadow-4.9/src/groups.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/src/groups.c 2022-01-10 10:45:52.206132965 +0100 +@@ -39,11 +39,11 @@ + #include + #include "defines.h" + #include "prototypes.h" ++#include "shadowlog.h" + /* + * Global variables + */ + const char *Prog; +-FILE *shadow_logfd = NULL; + + /* local function prototypes */ + static void print_groups (const char *member); +@@ -127,7 +127,8 @@ int main (int argc, char **argv) + * Get the program name so that error messages can use it. + */ + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + + if (argc == 1) { + +diff -up shadow-4.9/src/grpck.c.debug1 shadow-4.9/src/grpck.c +--- shadow-4.9/src/grpck.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/src/grpck.c 2022-01-10 10:45:52.206132965 +0100 +@@ -45,6 +45,7 @@ + #include "nscd.h" + #include "sssd.h" + #include "prototypes.h" ++#include "shadowlog.h" + + #ifdef SHADOWGRP + #include "sgroupio.h" +@@ -66,7 +67,6 @@ + * Global variables + */ + const char *Prog; +-FILE *shadow_logfd = NULL; + + static const char *grp_file = GROUP_FILE; + static bool use_system_grp_file = true; +@@ -841,7 +841,8 @@ int main (int argc, char **argv) + * Get my name so that I can use it to report errors. + */ + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.9/src/grpconv.c.debug1 shadow-4.9/src/grpconv.c +--- shadow-4.9/src/grpconv.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/src/grpconv.c 2022-01-10 10:45:52.206132965 +0100 +@@ -55,11 +55,11 @@ + #ifdef SHADOWGRP + #include "groupio.h" + #include "sgroupio.h" ++#include "shadowlog.h" + /* + * Global variables + */ + const char *Prog; +-FILE *shadow_logfd = NULL; + + static bool gr_locked = false; + static bool sgr_locked = false; +@@ -147,7 +147,8 @@ int main (int argc, char **argv) + struct sgrp sgent; + + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.9/src/grpunconv.c.debug1 shadow-4.9/src/grpunconv.c +--- shadow-4.9/src/grpunconv.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/src/grpunconv.c 2022-01-10 10:45:52.206132965 +0100 +@@ -55,11 +55,11 @@ + #ifdef SHADOWGRP + #include "groupio.h" + #include "sgroupio.h" ++#include "shadowlog.h" + /* + * Global variables + */ + const char *Prog; +-FILE *shadow_logfd = NULL; + + static bool gr_locked = false; + static bool sgr_locked = false; +@@ -146,7 +146,8 @@ int main (int argc, char **argv) + const struct sgrp *sg; + + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.9/src/lastlog.c.debug1 shadow-4.9/src/lastlog.c +--- shadow-4.9/src/lastlog.c.debug1 2022-01-10 10:45:52.189132844 +0100 ++++ shadow-4.9/src/lastlog.c 2022-01-10 10:45:52.206132965 +0100 +@@ -50,6 +50,7 @@ + #include "getdef.h" + /*@-exitarg@*/ + #include "exitcodes.h" ++#include "shadowlog.h" + + /* + * Needed for MkLinux DR1/2/2.1 - J. +@@ -62,7 +63,6 @@ + * Global variables + */ + const char *Prog; /* Program name */ +-FILE *shadow_logfd = NULL; + static FILE *lastlogfile; /* lastlog file stream */ + static unsigned long umin; /* if uflg and has_umin, only display users with uid >= umin */ + static bool has_umin = false; +@@ -322,7 +322,8 @@ int main (int argc, char **argv) + * most error messages. + */ + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.9/src/login.c.debug1 shadow-4.9/src/login.c +--- shadow-4.9/src/login.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/src/login.c 2022-01-10 10:45:52.206132965 +0100 +@@ -53,6 +53,7 @@ + #include "pwauth.h" + /*@-exitarg@*/ + #include "exitcodes.h" ++#include "shadowlog.h" + + #ifdef USE_PAM + #include "pam_defs.h" +@@ -83,7 +84,6 @@ static pam_handle_t *pamh = NULL; + * Global variables + */ + const char *Prog; +-FILE *shadow_logfd = NULL; + + static const char *hostname = ""; + static /*@null@*/ /*@only@*/char *username = NULL; +@@ -578,7 +578,8 @@ int main (int argc, char **argv) + + amroot = (getuid () == 0); + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + + if (geteuid() != 0) { + fprintf (stderr, _("%s: Cannot possibly work without effective root\n"), Prog); +diff -up shadow-4.9/src/logoutd.c.debug1 shadow-4.9/src/logoutd.c +--- shadow-4.9/src/logoutd.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/src/logoutd.c 2022-01-10 10:45:52.206132965 +0100 +@@ -40,11 +40,11 @@ + #include + #include "defines.h" + #include "prototypes.h" ++#include "shadowlog.h" + /* + * Global variables + */ + const char *Prog; +-FILE *shadow_logfd = NULL; + + #ifndef DEFAULT_HUP_MESG + #define DEFAULT_HUP_MESG _("login time exceeded\n\n") +@@ -188,7 +188,8 @@ int main (int argc, char **argv) + * Start syslogging everything + */ + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + + OPENLOG ("logoutd"); + +diff -up shadow-4.9/src/newgidmap.c.debug1 shadow-4.9/src/newgidmap.c +--- shadow-4.9/src/newgidmap.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/src/newgidmap.c 2022-01-10 10:45:52.206132965 +0100 +@@ -41,12 +41,12 @@ + #include "subordinateio.h" + #include "getdef.h" + #include "idmapping.h" ++#include "shadowlog.h" + + /* + * Global variables + */ + const char *Prog; +-FILE *shadow_logfd = NULL; + + + static bool verify_range(struct passwd *pw, struct map_range *range, bool *allow_setgroups) +@@ -177,7 +177,8 @@ int main(int argc, char **argv) + bool allow_setgroups = false; + + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + + /* + * The valid syntax are +diff -up shadow-4.9/src/newgrp.c.debug1 shadow-4.9/src/newgrp.c +--- shadow-4.9/src/newgrp.c.debug1 2022-01-10 10:45:52.199132915 +0100 ++++ shadow-4.9/src/newgrp.c 2022-01-10 10:45:52.206132965 +0100 +@@ -44,12 +44,12 @@ + #include "prototypes.h" + /*@-exitarg@*/ + #include "exitcodes.h" ++#include "shadowlog.h" + + /* + * Global variables + */ + const char *Prog; +-FILE *shadow_logfd = NULL; + + extern char **newenvp; + extern char **environ; +@@ -446,7 +446,8 @@ int main (int argc, char **argv) + * don't need to re-exec anything. -- JWP + */ + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + is_newgrp = (strcmp (Prog, "newgrp") == 0); + OPENLOG (is_newgrp ? "newgrp" : "sg"); + argc--; +diff -up shadow-4.9/src/new_subid_range.c.debug1 shadow-4.9/src/new_subid_range.c +--- shadow-4.9/src/new_subid_range.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/src/new_subid_range.c 2022-01-10 10:45:52.206132965 +0100 +@@ -3,11 +3,11 @@ + #include "subid.h" + #include "stdlib.h" + #include "prototypes.h" ++#include "shadowlog.h" + + /* Test program for the subid creation routine */ + + const char *Prog; +-FILE *shadow_logfd = NULL; + + void usage(void) + { +@@ -27,7 +27,8 @@ int main(int argc, char *argv[]) + bool ok; + + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + while ((c = getopt(argc, argv, "gn")) != EOF) { + switch(c) { + case 'n': makenew = true; break; +diff -up shadow-4.9/src/newuidmap.c.debug1 shadow-4.9/src/newuidmap.c +--- shadow-4.9/src/newuidmap.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/src/newuidmap.c 2022-01-10 10:45:52.206132965 +0100 +@@ -41,12 +41,12 @@ + #include "subordinateio.h" + #include "getdef.h" + #include "idmapping.h" ++#include "shadowlog.h" + + /* + * Global variables + */ + const char *Prog; +-FILE *shadow_logfd = NULL; + + static bool verify_range(struct passwd *pw, struct map_range *range) + { +@@ -107,7 +107,8 @@ int main(int argc, char **argv) + int written; + + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + + /* + * The valid syntax are +diff -up shadow-4.9/src/newusers.c.debug1 shadow-4.9/src/newusers.c +--- shadow-4.9/src/newusers.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/src/newusers.c 2022-01-10 10:45:52.207132972 +0100 +@@ -70,12 +70,12 @@ + #include "subordinateio.h" + #endif /* ENABLE_SUBIDS */ + #include "chkname.h" ++#include "shadowlog.h" + + /* + * Global variables + */ + const char *Prog; +-FILE *shadow_logfd = NULL; + + static bool rflg = false; /* create a system account */ + #ifndef USE_PAM +@@ -1071,7 +1071,8 @@ int main (int argc, char **argv) + #endif /* USE_PAM */ + + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.9/src/passwd.c.debug1 shadow-4.9/src/passwd.c +--- shadow-4.9/src/passwd.c.debug1 2022-01-10 10:45:52.189132844 +0100 ++++ shadow-4.9/src/passwd.c 2022-01-10 10:45:52.207132972 +0100 +@@ -50,6 +50,7 @@ + #include "pwauth.h" + #include "pwio.h" + #include "shadowio.h" ++#include "shadowlog.h" + + /* + * exit status values +@@ -66,7 +67,6 @@ + * Global variables + */ + const char *Prog; /* Program name */ +-FILE *shadow_logfd = NULL; + + static char *name; /* The name of user whose password is being changed */ + static char *myname; /* The current user's name */ +@@ -761,7 +761,8 @@ int main (int argc, char **argv) + * most error messages. + */ + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.9/src/pwck.c.debug1 shadow-4.9/src/pwck.c +--- shadow-4.9/src/pwck.c.debug1 2022-01-10 10:45:52.198132908 +0100 ++++ shadow-4.9/src/pwck.c 2022-01-10 10:45:52.207132972 +0100 +@@ -52,6 +52,7 @@ + #ifdef WITH_TCB + #include "tcbfuncs.h" + #endif /* WITH_TCB */ ++#include "shadowlog.h" + + /* + * Exit codes +@@ -70,7 +71,6 @@ + * Global variables + */ + const char *Prog; +-FILE *shadow_logfd = NULL; + + static bool use_system_pw_file = true; + static bool use_system_spw_file = true; +@@ -857,7 +857,8 @@ int main (int argc, char **argv) + * Get my name so that I can use it to report errors. + */ + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.9/src/pwconv.c.debug1 shadow-4.9/src/pwconv.c +--- shadow-4.9/src/pwconv.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/src/pwconv.c 2022-01-10 10:45:52.207132972 +0100 +@@ -73,6 +73,7 @@ + #include "shadowio.h" + #include "nscd.h" + #include "sssd.h" ++#include "shadowlog.h" + + /* + * exit status values +@@ -89,7 +90,6 @@ + * Global variables + */ + const char *Prog; +-FILE *shadow_logfd = NULL; + + static bool spw_locked = false; + static bool pw_locked = false; +@@ -177,7 +177,8 @@ int main (int argc, char **argv) + struct spwd spent; + + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.9/src/pwunconv.c.debug1 shadow-4.9/src/pwunconv.c +--- shadow-4.9/src/pwunconv.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/src/pwunconv.c 2022-01-10 10:45:52.207132972 +0100 +@@ -48,12 +48,12 @@ + #include "shadowio.h" + /*@-exitarg@*/ + #include "exitcodes.h" ++#include "shadowlog.h" + + /* + * Global variables + */ + const char *Prog; +-FILE *shadow_logfd = NULL; + + static bool spw_locked = false; + static bool pw_locked = false; +@@ -138,7 +138,8 @@ int main (int argc, char **argv) + const struct spwd *spwd; + + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.9/src/su.c.debug1 shadow-4.9/src/su.c +--- shadow-4.9/src/su.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/src/su.c 2022-01-10 10:45:52.207132972 +0100 +@@ -77,12 +77,12 @@ + #endif /* USE_PAM */ + /*@-exitarg@*/ + #include "exitcodes.h" ++#include "shadowlog.h" + + /* + * Global variables + */ + const char *Prog; +-FILE *shadow_logfd = NULL; + static /*@observer@*/const char *caller_tty = NULL; /* Name of tty SU is run from */ + static bool caller_is_root = false; + static uid_t caller_uid; +@@ -717,7 +717,8 @@ static void save_caller_context (char ** + * most error messages. + */ + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + + caller_uid = getuid (); + caller_is_root = (caller_uid == 0); +diff -up shadow-4.9/src/sulogin.c.debug1 shadow-4.9/src/sulogin.c +--- shadow-4.9/src/sulogin.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/src/sulogin.c 2022-01-10 10:45:52.207132972 +0100 +@@ -45,12 +45,12 @@ + #include "pwauth.h" + /*@-exitarg@*/ + #include "exitcodes.h" ++#include "shadowlog.h" + + /* + * Global variables + */ + const char *Prog; +-FILE *shadow_logfd = NULL; + + static char name[BUFSIZ]; + static char pass[BUFSIZ]; +@@ -107,7 +107,8 @@ static RETSIGTYPE catch_signals (unused + #endif + + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); + (void) textdomain (PACKAGE); +diff -up shadow-4.9/src/useradd.c.debug1 shadow-4.9/src/useradd.c +--- shadow-4.9/src/useradd.c.debug1 2022-01-10 10:45:52.197132901 +0100 ++++ shadow-4.9/src/useradd.c 2022-01-10 10:45:52.207132972 +0100 +@@ -78,6 +78,7 @@ + #ifdef WITH_TCB + #include "tcbfuncs.h" + #endif ++#include "shadowlog.h" + + #ifndef SKEL_DIR + #define SKEL_DIR "/etc/skel" +@@ -96,7 +97,6 @@ + * Global variables + */ + const char *Prog; +-FILE *shadow_logfd = NULL; + + /* + * These defaults are used if there is no defaults file. +@@ -2359,7 +2359,8 @@ int main (int argc, char **argv) + * Get my name so that I can use it to report errors. + */ + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.9/src/userdel.c.debug1 shadow-4.9/src/userdel.c +--- shadow-4.9/src/userdel.c.debug1 2022-01-10 10:45:52.186132823 +0100 ++++ shadow-4.9/src/userdel.c 2022-01-10 10:45:52.208132979 +0100 +@@ -72,6 +72,7 @@ + #ifdef ENABLE_SUBIDS + #include "subordinateio.h" + #endif /* ENABLE_SUBIDS */ ++#include "shadowlog.h" + + /* + * exit status values +@@ -91,7 +92,6 @@ + * Global variables + */ + const char *Prog; +-FILE *shadow_logfd = NULL; + + static char *user_name; + static uid_t user_id; +@@ -944,7 +944,8 @@ int main (int argc, char **argv) + * Get my name so that I can use it to report errors. + */ + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); + (void) textdomain (PACKAGE); +diff -up shadow-4.9/src/usermod.c.debug1 shadow-4.9/src/usermod.c +--- shadow-4.9/src/usermod.c.debug1 2022-01-10 10:45:52.193132872 +0100 ++++ shadow-4.9/src/usermod.c 2022-01-10 10:45:52.208132979 +0100 +@@ -74,6 +74,7 @@ + #ifdef WITH_TCB + #include "tcbfuncs.h" + #endif ++#include "shadowlog.h" + + /* + * exit status values +@@ -105,7 +106,6 @@ + * Global variables + */ + const char *Prog; +-FILE *shadow_logfd = NULL; + + static char *user_name; + static char *user_newname; +@@ -2172,7 +2172,8 @@ int main (int argc, char **argv) + * Get my name so that I can use it to report errors. + */ + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); +diff -up shadow-4.9/src/vipw.c.debug1 shadow-4.9/src/vipw.c +--- shadow-4.9/src/vipw.c.debug1 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/src/vipw.c 2022-01-10 10:45:52.208132979 +0100 +@@ -53,6 +53,7 @@ + #include + #include "tcbfuncs.h" + #endif /* WITH_TCB */ ++#include "shadowlog.h" + + #define MSG_WARN_EDIT_OTHER_FILE _( \ + "You have modified %s.\n"\ +@@ -63,7 +64,6 @@ + * Global variables + */ + const char *Prog; +-FILE *shadow_logfd = NULL; + + static const char *filename, *fileeditname; + static bool filelocked = false; +@@ -482,7 +482,8 @@ int main (int argc, char **argv) + bool do_vipw; + + Prog = Basename (argv[0]); +- shadow_logfd = stderr; ++ log_set_progname(Prog); ++ log_set_logfd(stderr); + + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE, LOCALEDIR); diff --git a/shadow-4.9-nss-get-shadow-logfd-with-log-get-logfd.patch b/shadow-4.9-nss-get-shadow-logfd-with-log-get-logfd.patch new file mode 100644 index 0000000..4d8e792 --- /dev/null +++ b/shadow-4.9-nss-get-shadow-logfd-with-log-get-logfd.patch @@ -0,0 +1,48 @@ +From e101219ad71de11da3fdd1b3ec2620fd1a97b92c Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Mon, 10 Jan 2022 15:30:28 +0100 +Subject: [PATCH] nss: get shadow_logfd with log_get_logfd() + +If /etc/nsswitch.conf doesn't exist podman crashes because shadow_logfd +is NULL. In order to avoid that load the log file descriptor with the +log_get_logfd() helper function. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2038811 + +Signed-off-by: Iker Pedrosa +--- + lib/nss.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/lib/nss.c b/lib/nss.c +index 02742902..06fa48e5 100644 +--- a/lib/nss.c ++++ b/lib/nss.c +@@ -9,6 +9,7 @@ + #include "prototypes.h" + #include "../libsubid/subid.h" + #include "shadowlog_internal.h" ++#include "shadowlog.h" + + #define NSSWITCH "/etc/nsswitch.conf" + +@@ -42,6 +43,7 @@ void nss_init(const char *nsswitch_path) { + FILE *nssfp = NULL; + char *line = NULL, *p, *token, *saveptr; + size_t len = 0; ++ FILE *shadow_logfd = log_get_logfd(); + + if (atomic_flag_test_and_set(&nss_init_started)) { + // Another thread has started nss_init, wait for it to complete +@@ -57,7 +59,7 @@ void nss_init(const char *nsswitch_path) { + // subid: files + nssfp = fopen(nsswitch_path, "r"); + if (!nssfp) { +- fprintf(shadow_logfd, "Failed opening %s: %m", nsswitch_path); ++ fprintf(shadow_logfd, "Failed opening %s: %m\n", nsswitch_path); + atomic_store(&nss_init_completed, true); + return; + } +-- +2.34.1 + diff --git a/shadow-4.9-rename-prog-to-shadow-progname.patch b/shadow-4.9-rename-prog-to-shadow-progname.patch new file mode 100644 index 0000000..d3a73a3 --- /dev/null +++ b/shadow-4.9-rename-prog-to-shadow-progname.patch @@ -0,0 +1,507 @@ +diff -up shadow-4.9/lib/commonio.c.debug2 shadow-4.9/lib/commonio.c +--- shadow-4.9/lib/commonio.c.debug2 2022-01-10 10:57:47.535238522 +0100 ++++ shadow-4.9/lib/commonio.c 2022-01-10 10:57:47.544238586 +0100 +@@ -147,7 +147,7 @@ static int do_lock_file (const char *fil + if (log) { + (void) fprintf (shadow_logfd, + "%s: %s: %s\n", +- Prog, file, strerror (errno)); ++ shadow_progname, file, strerror (errno)); + } + return 0; + } +@@ -159,7 +159,7 @@ static int do_lock_file (const char *fil + if (log) { + (void) fprintf (shadow_logfd, + "%s: %s file write error: %s\n", +- Prog, file, strerror (errno)); ++ shadow_progname, file, strerror (errno)); + } + (void) close (fd); + unlink (file); +@@ -169,7 +169,7 @@ static int do_lock_file (const char *fil + if (log) { + (void) fprintf (shadow_logfd, + "%s: %s file sync error: %s\n", +- Prog, file, strerror (errno)); ++ shadow_progname, file, strerror (errno)); + } + (void) close (fd); + unlink (file); +@@ -182,7 +182,7 @@ static int do_lock_file (const char *fil + if ((0==retval) && log) { + (void) fprintf (shadow_logfd, + "%s: %s: lock file already used\n", +- Prog, file); ++ shadow_progname, file); + } + unlink (file); + return retval; +@@ -193,7 +193,7 @@ static int do_lock_file (const char *fil + if (log) { + (void) fprintf (shadow_logfd, + "%s: %s: %s\n", +- Prog, lock, strerror (errno)); ++ shadow_progname, lock, strerror (errno)); + } + unlink (file); + errno = EINVAL; +@@ -205,7 +205,7 @@ static int do_lock_file (const char *fil + if (log) { + (void) fprintf (shadow_logfd, + "%s: existing lock file %s without a PID\n", +- Prog, lock); ++ shadow_progname, lock); + } + unlink (file); + errno = EINVAL; +@@ -216,7 +216,7 @@ static int do_lock_file (const char *fil + if (log) { + (void) fprintf (shadow_logfd, + "%s: existing lock file %s with an invalid PID '%s'\n", +- Prog, lock, buf); ++ shadow_progname, lock, buf); + } + unlink (file); + errno = EINVAL; +@@ -226,7 +226,7 @@ static int do_lock_file (const char *fil + if (log) { + (void) fprintf (shadow_logfd, + "%s: lock %s already used by PID %lu\n", +- Prog, lock, (unsigned long) pid); ++ shadow_progname, lock, (unsigned long) pid); + } + unlink (file); + errno = EEXIST; +@@ -236,7 +236,7 @@ static int do_lock_file (const char *fil + if (log) { + (void) fprintf (shadow_logfd, + "%s: cannot get lock %s: %s\n", +- Prog, lock, strerror (errno)); ++ shadow_progname, lock, strerror (errno)); + } + unlink (file); + return 0; +@@ -248,13 +248,13 @@ static int do_lock_file (const char *fil + if ((0==retval) && log) { + (void) fprintf (shadow_logfd, + "%s: %s: lock file already used\n", +- Prog, file); ++ shadow_progname, file); + } + } else { + if (log) { + (void) fprintf (shadow_logfd, + "%s: cannot get lock %s: %s\n", +- Prog, lock, strerror (errno)); ++ shadow_progname, lock, strerror (errno)); + } + } + +@@ -449,7 +449,7 @@ int commonio_lock (struct commonio_db *d + if (geteuid () != 0) { + (void) fprintf (shadow_logfd, + "%s: Permission denied.\n", +- Prog); ++ shadow_progname); + } + return 0; /* failure */ + } +@@ -484,7 +484,7 @@ int commonio_lock (struct commonio_db *d + /* no unnecessary retries on "permission denied" errors */ + if (geteuid () != 0) { + (void) fprintf (shadow_logfd, "%s: Permission denied.\n", +- Prog); ++ shadow_progname); + return 0; + } + } +diff -up shadow-4.9/lib/nscd.c.debug2 shadow-4.9/lib/nscd.c +--- shadow-4.9/lib/nscd.c.debug2 2022-01-10 10:57:47.537238536 +0100 ++++ shadow-4.9/lib/nscd.c 2022-01-10 10:57:47.544238586 +0100 +@@ -26,7 +26,7 @@ int nscd_flush_cache (const char *servic + + if (run_command (cmd, spawnedArgs, spawnedEnv, &status) != 0) { + /* run_command writes its own more detailed message. */ +- (void) fprintf (shadow_logfd, _(MSG_NSCD_FLUSH_CACHE_FAILED), Prog); ++ (void) fprintf (shadow_logfd, _(MSG_NSCD_FLUSH_CACHE_FAILED), shadow_progname); + return -1; + } + +@@ -34,7 +34,7 @@ int nscd_flush_cache (const char *servic + if (!WIFEXITED (status)) { + (void) fprintf (shadow_logfd, + _("%s: nscd did not terminate normally (signal %d)\n"), +- Prog, WTERMSIG (status)); ++ shadow_progname, WTERMSIG (status)); + return -1; + } else if (code == E_CMD_NOTFOUND) { + /* nscd is not installed, or it is installed but uses an +@@ -45,8 +45,8 @@ int nscd_flush_cache (const char *servic + return 0; + } else if (code != 0) { + (void) fprintf (shadow_logfd, _("%s: nscd exited with status %d\n"), +- Prog, code); +- (void) fprintf (shadow_logfd, _(MSG_NSCD_FLUSH_CACHE_FAILED), Prog); ++ shadow_progname, code); ++ (void) fprintf (shadow_logfd, _(MSG_NSCD_FLUSH_CACHE_FAILED), shadow_progname); + return -1; + } + +diff -up shadow-4.9/lib/selinux.c.debug2 shadow-4.9/lib/selinux.c +--- shadow-4.9/lib/selinux.c.debug2 2022-01-10 10:57:47.538238543 +0100 ++++ shadow-4.9/lib/selinux.c 2022-01-10 10:57:47.544238586 +0100 +@@ -216,7 +216,7 @@ int check_selinux_permit (const char *pe + if (getprevcon_raw (&user_context_raw) != 0) { + fprintf (shadow_logfd, + _("%s: can not get previous SELinux process context: %s\n"), +- Prog, strerror (errno)); ++ shadow_progname, strerror (errno)); + SYSLOG ((LOG_WARN, + "can not get previous SELinux process context: %s", + strerror (errno))); +diff -up shadow-4.9/lib/shadowlog.c.debug2 shadow-4.9/lib/shadowlog.c +--- shadow-4.9/lib/shadowlog.c.debug2 2022-01-10 10:57:47.538238543 +0100 ++++ shadow-4.9/lib/shadowlog.c 2022-01-10 10:57:47.544238586 +0100 +@@ -2,14 +2,17 @@ + + #include "lib/shadowlog_internal.h" + ++const char *shadow_progname; ++FILE *shadow_logfd; ++ + void log_set_progname(const char *progname) + { +- Prog = progname; ++ shadow_progname = progname; + } + + const char *log_get_progname(void) + { +- return Prog; ++ return shadow_progname; + } + + void log_set_logfd(FILE *fd) +diff -up shadow-4.9/lib/shadowlog_internal.h.debug2 shadow-4.9/lib/shadowlog_internal.h +--- shadow-4.9/lib/shadowlog_internal.h.debug2 2022-01-10 10:57:47.538238543 +0100 ++++ shadow-4.9/lib/shadowlog_internal.h 2022-01-10 10:57:47.544238586 +0100 +@@ -1,2 +1,2 @@ +-const char *Prog; /* Program name showed in error messages */ +-FILE *shadow_logfd; /* file descripter to which error messages are printed */ ++extern const char *shadow_progname; /* Program name showed in error messages */ ++extern FILE *shadow_logfd; /* file descripter to which error messages are printed */ +diff -up shadow-4.9/lib/spawn.c.debug2 shadow-4.9/lib/spawn.c +--- shadow-4.9/lib/spawn.c.debug2 2022-01-10 10:57:47.538238543 +0100 ++++ shadow-4.9/lib/spawn.c 2022-01-10 10:57:47.544238586 +0100 +@@ -60,11 +60,11 @@ int run_command (const char *cmd, const + exit (E_CMD_NOTFOUND); + } + fprintf (shadow_logfd, "%s: cannot execute %s: %s\n", +- Prog, cmd, strerror (errno)); ++ shadow_progname, cmd, strerror (errno)); + exit (E_CMD_NOEXEC); + } else if ((pid_t)-1 == pid) { + fprintf (shadow_logfd, "%s: cannot execute %s: %s\n", +- Prog, cmd, strerror (errno)); ++ shadow_progname, cmd, strerror (errno)); + return -1; + } + +@@ -77,7 +77,7 @@ int run_command (const char *cmd, const + + if ((pid_t)-1 == wpid) { + fprintf (shadow_logfd, "%s: waitpid (status: %d): %s\n", +- Prog, *status, strerror (errno)); ++ shadow_progname, *status, strerror (errno)); + return -1; + } + +diff -up shadow-4.9/lib/sssd.c.debug2 shadow-4.9/lib/sssd.c +--- shadow-4.9/lib/sssd.c.debug2 2022-01-10 10:57:47.538238543 +0100 ++++ shadow-4.9/lib/sssd.c 2022-01-10 10:57:47.544238586 +0100 +@@ -48,22 +48,22 @@ int sssd_flush_cache (int dbflags) + free(sss_cache_args); + if (rv != 0) { + /* run_command writes its own more detailed message. */ +- SYSLOG ((LOG_WARN, MSG_SSSD_FLUSH_CACHE_FAILED, Prog)); ++ SYSLOG ((LOG_WARN, MSG_SSSD_FLUSH_CACHE_FAILED, shadow_progname)); + return -1; + } + + code = WEXITSTATUS (status); + if (!WIFEXITED (status)) { + SYSLOG ((LOG_WARN, "%s: sss_cache did not terminate normally (signal %d)", +- Prog, WTERMSIG (status))); ++ shadow_progname, WTERMSIG (status))); + return -1; + } else if (code == E_CMD_NOTFOUND) { + /* sss_cache is not installed, or it is installed but uses an + interpreter that is missing. Probably the former. */ + return 0; + } else if (code != 0) { +- SYSLOG ((LOG_WARN, "%s: sss_cache exited with status %d", Prog, code)); +- SYSLOG ((LOG_WARN, MSG_SSSD_FLUSH_CACHE_FAILED, Prog)); ++ SYSLOG ((LOG_WARN, "%s: sss_cache exited with status %d", shadow_progname, code)); ++ SYSLOG ((LOG_WARN, MSG_SSSD_FLUSH_CACHE_FAILED, shadow_progname)); + return -1; + } + +diff -up shadow-4.9/lib/tcbfuncs.c.debug2 shadow-4.9/lib/tcbfuncs.c +--- shadow-4.9/lib/tcbfuncs.c.debug2 2022-01-10 10:57:47.538238543 +0100 ++++ shadow-4.9/lib/tcbfuncs.c 2022-01-10 10:59:01.228764507 +0100 +@@ -74,7 +74,7 @@ shadowtcb_status shadowtcb_gain_priv (vo + * to exit soon. + */ + #define OUT_OF_MEMORY do { \ +- fprintf (shadow_logfd, _("%s: out of memory\n"), Prog); \ ++ fprintf (shadow_logfd, _("%s: out of memory\n"), shadow_progname); \ + (void) fflush (shadow_logfd); \ + } while (false) + +@@ -120,7 +120,7 @@ static /*@null@*/ char *shadowtcb_path_r + if (lstat (path, &st) != 0) { + fprintf (shadow_logfd, + _("%s: Cannot stat %s: %s\n"), +- Prog, path, strerror (errno)); ++ shadow_progname, path, strerror (errno)); + free (path); + return NULL; + } +@@ -136,7 +136,7 @@ static /*@null@*/ char *shadowtcb_path_r + if (!S_ISLNK (st.st_mode)) { + fprintf (shadow_logfd, + _("%s: %s is neither a directory, nor a symlink.\n"), +- Prog, path); ++ shadow_progname, path); + free (path); + return NULL; + } +@@ -144,7 +144,7 @@ static /*@null@*/ char *shadowtcb_path_r + if (-1 == ret) { + fprintf (shadow_logfd, + _("%s: Cannot read symbolic link %s: %s\n"), +- Prog, path, strerror (errno)); ++ shadow_progname, path, strerror (errno)); + free (path); + return NULL; + } +@@ -153,7 +153,7 @@ static /*@null@*/ char *shadowtcb_path_r + link[sizeof(link) - 1] = '\0'; + fprintf (shadow_logfd, + _("%s: Suspiciously long symlink: %s\n"), +- Prog, link); ++ shadow_progname, link); + return NULL; + } + link[(size_t)ret] = '\0'; +@@ -211,7 +211,7 @@ static shadowtcb_status mkdir_leading (c + if (stat (TCB_DIR, &st) != 0) { + fprintf (shadow_logfd, + _("%s: Cannot stat %s: %s\n"), +- Prog, TCB_DIR, strerror (errno)); ++ shadow_progname, TCB_DIR, strerror (errno)); + goto out_free_path; + } + while ((ind = strchr (ptr, '/'))) { +@@ -223,19 +223,19 @@ static shadowtcb_status mkdir_leading (c + if ((mkdir (dir, 0700) != 0) && (errno != EEXIST)) { + fprintf (shadow_logfd, + _("%s: Cannot create directory %s: %s\n"), +- Prog, dir, strerror (errno)); ++ shadow_progname, dir, strerror (errno)); + goto out_free_dir; + } + if (chown (dir, 0, st.st_gid) != 0) { + fprintf (shadow_logfd, + _("%s: Cannot change owner of %s: %s\n"), +- Prog, dir, strerror (errno)); ++ shadow_progname, dir, strerror (errno)); + goto out_free_dir; + } + if (chmod (dir, 0711) != 0) { + fprintf (shadow_logfd, + _("%s: Cannot change mode of %s: %s\n"), +- Prog, dir, strerror (errno)); ++ shadow_progname, dir, strerror (errno)); + goto out_free_dir; + } + free (dir); +@@ -265,7 +265,7 @@ static shadowtcb_status unlink_suffs (co + if ((unlink (tmp) != 0) && (errno != ENOENT)) { + fprintf (shadow_logfd, + _("%s: unlink: %s: %s\n"), +- Prog, tmp, strerror (errno)); ++ shadow_progname, tmp, strerror (errno)); + free (tmp); + return SHADOWTCB_FAILURE; + } +@@ -290,7 +290,7 @@ static shadowtcb_status rmdir_leading (c + if (errno != ENOTEMPTY) { + fprintf (shadow_logfd, + _("%s: Cannot remove directory %s: %s\n"), +- Prog, dir, strerror (errno)); ++ shadow_progname, dir, strerror (errno)); + ret = SHADOWTCB_FAILURE; + } + free (dir); +@@ -319,7 +319,7 @@ static shadowtcb_status move_dir (const + if (stat (olddir, &oldmode) != 0) { + fprintf (shadow_logfd, + _("%s: Cannot stat %s: %s\n"), +- Prog, olddir, strerror (errno)); ++ shadow_progname, olddir, strerror (errno)); + goto out_free; + } + old_uid = oldmode.st_uid; +@@ -346,7 +346,7 @@ static shadowtcb_status move_dir (const + if (rename (real_old_dir, real_new_dir) != 0) { + fprintf (shadow_logfd, + _("%s: Cannot rename %s to %s: %s\n"), +- Prog, real_old_dir, real_new_dir, strerror (errno)); ++ shadow_progname, real_old_dir, real_new_dir, strerror (errno)); + goto out_free; + } + if (rmdir_leading (real_old_dir_rel) == SHADOWTCB_FAILURE) { +@@ -355,7 +355,7 @@ static shadowtcb_status move_dir (const + if ((unlink (olddir) != 0) && (errno != ENOENT)) { + fprintf (shadow_logfd, + _("%s: Cannot remove %s: %s\n"), +- Prog, olddir, strerror (errno)); ++ shadow_progname, olddir, strerror (errno)); + goto out_free; + } + if (asprintf (&newdir, TCB_DIR "/%s", user_newname) == -1) { +@@ -369,7 +369,7 @@ static shadowtcb_status move_dir (const + && (symlink (real_new_dir_rel, newdir) != 0)) { + fprintf (shadow_logfd, + _("%s: Cannot create symbolic link %s: %s\n"), +- Prog, real_new_dir_rel, strerror (errno)); ++ shadow_progname, real_new_dir_rel, strerror (errno)); + goto out_free; + } + ret = SHADOWTCB_SUCCESS; +@@ -468,31 +468,31 @@ shadowtcb_status shadowtcb_move (/*@NULL + if (stat (tcbdir, &dirmode) != 0) { + fprintf (shadow_logfd, + _("%s: Cannot stat %s: %s\n"), +- Prog, tcbdir, strerror (errno)); ++ shadow_progname, tcbdir, strerror (errno)); + goto out_free; + } + if (chown (tcbdir, 0, 0) != 0) { + fprintf (shadow_logfd, + _("%s: Cannot change owners of %s: %s\n"), +- Prog, tcbdir, strerror (errno)); ++ shadow_progname, tcbdir, strerror (errno)); + goto out_free; + } + if (chmod (tcbdir, 0700) != 0) { + fprintf (shadow_logfd, + _("%s: Cannot change mode of %s: %s\n"), +- Prog, tcbdir, strerror (errno)); ++ shadow_progname, tcbdir, strerror (errno)); + goto out_free; + } + if (lstat (shadow, &filemode) != 0) { + if (errno != ENOENT) { + fprintf (shadow_logfd, + _("%s: Cannot lstat %s: %s\n"), +- Prog, shadow, strerror (errno)); ++ shadow_progname, shadow, strerror (errno)); + goto out_free; + } + fprintf (shadow_logfd, + _("%s: Warning, user %s has no tcb shadow file.\n"), +- Prog, user_newname); ++ shadow_progname, user_newname); + } else { + if (!S_ISREG (filemode.st_mode) || + filemode.st_nlink != 1) { +@@ -500,19 +500,19 @@ shadowtcb_status shadowtcb_move (/*@NULL + _("%s: Emergency: %s's tcb shadow is not a " + "regular file with st_nlink=1.\n" + "The account is left locked.\n"), +- Prog, user_newname); ++ shadow_progname, user_newname); + goto out_free; + } + if (chown (shadow, user_newid, filemode.st_gid) != 0) { + fprintf (shadow_logfd, + _("%s: Cannot change owner of %s: %s\n"), +- Prog, shadow, strerror (errno)); ++ shadow_progname, shadow, strerror (errno)); + goto out_free; + } + if (chmod (shadow, filemode.st_mode & 07777) != 0) { + fprintf (shadow_logfd, + _("%s: Cannot change mode of %s: %s\n"), +- Prog, shadow, strerror (errno)); ++ shadow_progname, shadow, strerror (errno)); + goto out_free; + } + } +@@ -522,7 +522,7 @@ shadowtcb_status shadowtcb_move (/*@NULL + if (chown (tcbdir, user_newid, dirmode.st_gid) != 0) { + fprintf (shadow_logfd, + _("%s: Cannot change owner of %s: %s\n"), +- Prog, tcbdir, strerror (errno)); ++ shadow_progname, tcbdir, strerror (errno)); + goto out_free; + } + ret = SHADOWTCB_SUCCESS; +@@ -547,7 +547,7 @@ shadowtcb_status shadowtcb_create (const + if (stat (TCB_DIR, &tcbdir_stat) != 0) { + fprintf (shadow_logfd, + _("%s: Cannot stat %s: %s\n"), +- Prog, TCB_DIR, strerror (errno)); ++ shadow_progname, TCB_DIR, strerror (errno)); + return SHADOWTCB_FAILURE; + } + shadowgid = tcbdir_stat.st_gid; +@@ -567,39 +567,39 @@ shadowtcb_status shadowtcb_create (const + if (mkdir (dir, 0700) != 0) { + fprintf (shadow_logfd, + _("%s: mkdir: %s: %s\n"), +- Prog, dir, strerror (errno)); ++ shadow_progname, dir, strerror (errno)); + goto out_free; + } + fd = open (shadow, O_RDWR | O_CREAT | O_TRUNC, 0600); + if (fd < 0) { + fprintf (shadow_logfd, + _("%s: Cannot open %s: %s\n"), +- Prog, shadow, strerror (errno)); ++ shadow_progname, shadow, strerror (errno)); + goto out_free; + } + close (fd); + if (chown (shadow, 0, authgid) != 0) { + fprintf (shadow_logfd, + _("%s: Cannot change owner of %s: %s\n"), +- Prog, shadow, strerror (errno)); ++ shadow_progname, shadow, strerror (errno)); + goto out_free; + } + if (chmod (shadow, (mode_t) ((authgid == shadowgid) ? 0600 : 0640)) != 0) { + fprintf (shadow_logfd, + _("%s: Cannot change mode of %s: %s\n"), +- Prog, shadow, strerror (errno)); ++ shadow_progname, shadow, strerror (errno)); + goto out_free; + } + if (chown (dir, 0, authgid) != 0) { + fprintf (shadow_logfd, + _("%s: Cannot change owner of %s: %s\n"), +- Prog, dir, strerror (errno)); ++ shadow_progname, dir, strerror (errno)); + goto out_free; + } + if (chmod (dir, (mode_t) ((authgid == shadowgid) ? 02700 : 02710)) != 0) { + fprintf (shadow_logfd, + _("%s: Cannot change mode of %s: %s\n"), +- Prog, dir, strerror (errno)); ++ shadow_progname, dir, strerror (errno)); + goto out_free; + } + if ( (shadowtcb_set_user (name) == SHADOWTCB_FAILURE) diff --git a/shadow-4.9-shadow-progname-default-init.patch b/shadow-4.9-shadow-progname-default-init.patch new file mode 100644 index 0000000..0c6d616 --- /dev/null +++ b/shadow-4.9-shadow-progname-default-init.patch @@ -0,0 +1,39 @@ +diff -up shadow-4.9/lib/shadowlog.c.debug3 shadow-4.9/lib/shadowlog.c +--- shadow-4.9/lib/shadowlog.c.debug3 2022-01-10 11:16:31.636261531 +0100 ++++ shadow-4.9/lib/shadowlog.c 2022-01-10 11:16:31.637261538 +0100 +@@ -2,8 +2,8 @@ + + #include "lib/shadowlog_internal.h" + +-const char *shadow_progname; +-FILE *shadow_logfd; ++const char *shadow_progname = "libshadow"; ++FILE *shadow_logfd = NULL; + + void log_set_progname(const char *progname) + { +diff -up shadow-4.9/libsubid/api.c.debug3 shadow-4.9/libsubid/api.c +--- shadow-4.9/libsubid/api.c.debug3 2022-01-10 11:16:31.637261538 +0100 ++++ shadow-4.9/libsubid/api.c 2022-01-10 11:17:15.431574120 +0100 +@@ -40,17 +40,16 @@ + #include "subid.h" + #include "shadowlog.h" + +-const char *Prog = "(libsubid)"; +- + bool libsubid_init(const char *progname, FILE * logfd) + { + FILE *shadow_logfd; + if (progname) { + progname = strdup(progname); +- if (progname) +- Prog = progname; +- else ++ if (!progname) + return false; ++ log_set_progname(progname); ++ } else { ++ log_set_progname("(libsubid)"); + } + + if (logfd) { diff --git a/shadow-utils.spec b/shadow-utils.spec index e7e2970..24ea670 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.9 -Release: 8%{?dist} +Release: 9%{?dist} Epoch: 2 License: BSD and GPLv2+ URL: https://github.com/shadow-maint/shadow @@ -67,6 +67,15 @@ Patch22: shadow-4.9-newgrp-fix-segmentation-fault.patch Patch23: shadow-4.9-getsubids.patch # https://github.com/shadow-maint/shadow/commit/a757b458ffb4fb9a40bcbb4f7869449431c67f83 Patch24: shadow-4.9-groupdel-fix-sigsegv-when-passwd-does-not-exist.patch +# https://github.com/shadow-maint/shadow/commit/79157cbad87f42cdc2068d72e798488572c68bb2 +Patch25: shadow-4.9-make-shadow-logfd-and-prog-not-extern.patch +# https://github.com/shadow-maint/shadow/commit/0e6fe5e728a45baff3977d73e81a27adb6ae30c6 +Patch26: shadow-4.9-rename-prog-to-shadow-progname.patch +# https://github.com/shadow-maint/shadow/commit/2b0bdef6f9a18382e92b0fb6d893c4339123ffac +# https://github.com/shadow-maint/shadow/commit/9750fd681919ed558a9b044248a284d567cddf1a +Patch27: shadow-4.9-shadow-progname-default-init.patch +# https://github.com/shadow-maint/shadow/commit/e101219ad71de11da3fdd1b3ec2620fd1a97b92c +Patch28: shadow-4.9-nss-get-shadow-logfd-with-log-get-logfd.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -151,6 +160,10 @@ Development files for shadow-utils-subid. %patch22 -p1 -b .newgrp-fix-segmentation-fault %patch23 -p1 -b .getsubids %patch24 -p1 -b .groupdel-fix-sigsegv-when-passwd-does-not-exist +%patch25 -p1 -b .make-shadow-logfd-and-prog-not-extern +%patch26 -p1 -b .rename-prog-to-shadow-progname +%patch27 -p1 -b .shadow-progname-default-init +%patch28 -p1 -b .nss-get-shadow-logfd-with-log-get-logfd iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -323,6 +336,13 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la %{_libdir}/libsubid.so %changelog +* Mon Jan 17 2022 Iker Pedrosa - 2:4.9-9 +- nss: get shadow_logfd with log_get_logfd() (#2038811) +- lib: make shadow_logfd and Prog not extern +- lib: rename Prog to shadow_progname +- lib: provide default values for shadow_progname +- libsubid: use log_set_progname in subid_init + * Fri Nov 19 2021 Iker Pedrosa - 2:4.9-8 - getsubids: provide system binary and man page (#1980780) - pwck: fix segfault when calling fprintf() (#2021339) From bfa562aaf2cde4102fe65661cb55b41098b8c886 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Sat, 22 Jan 2022 00:46:50 +0000 Subject: [PATCH 056/134] - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- shadow-utils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index 24ea670..bcbadf8 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.9 -Release: 9%{?dist} +Release: 10%{?dist} Epoch: 2 License: BSD and GPLv2+ URL: https://github.com/shadow-maint/shadow @@ -336,6 +336,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la %{_libdir}/libsubid.so %changelog +* Sat Jan 22 2022 Fedora Release Engineering - 2:4.9-10 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + * Mon Jan 17 2022 Iker Pedrosa - 2:4.9-9 - nss: get shadow_logfd with log_get_logfd() (#2038811) - lib: make shadow_logfd and Prog not extern From 2b851f7e96b3cafb7ec7b69cc24e37c0a601ef11 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Wed, 26 Jan 2022 09:29:37 +0100 Subject: [PATCH 057/134] - Rebase to version 4.11.1 (#2034038) - Fix release sources - Add explicit subid requirement for subid-devel Signed-off-by: Iker Pedrosa --- ....patch => shadow-4.11.1-audit-update.patch | 456 +-- shadow-4.11.1-null-tm.patch | 22 + ...redhat.patch => shadow-4.11.1-redhat.patch | 16 +- shadow-4.9-getsubids.patch | 245 -- ...x-sigsegv-when-passwd-does-not-exist.patch | 13 - ...default-value-in-SHA_get_salt_rounds.patch | 60 - ...ake-shadow-logfd-and-prog-not-extern.patch | 2497 ----------------- shadow-4.9-move-create-home.patch | 88 - ...ow-4.9-newgrp-fix-segmentation-fault.patch | 35 - ...ow-4.9-newuidmap-libeconf-dependency.patch | 15 - shadow-4.9-null-tm.patch | 70 - ...ck-fix-segfault-when-calling-fprintf.patch | 30 - ...w-4.9-rename-prog-to-shadow-progname.patch | 507 ---- shadow-4.9-revert-useradd-fix-memleak.patch | 30 - ....9-semanage-close-the-selabel-handle.patch | 61 - shadow-4.9-shadow-progname-default-init.patch | 39 - ...d-avoid-generating-empty-subid-range.patch | 79 - shadow-4.9-useradd-copy-tree-argument.patch | 13 - ...ow-4.9-usermod-allow-all-group-types.patch | 322 --- shadow-utils.spec | 75 +- 20 files changed, 276 insertions(+), 4397 deletions(-) rename shadow-4.9-audit-update.patch => shadow-4.11.1-audit-update.patch (84%) create mode 100644 shadow-4.11.1-null-tm.patch rename shadow-4.9-redhat.patch => shadow-4.11.1-redhat.patch (70%) delete mode 100644 shadow-4.9-getsubids.patch delete mode 100644 shadow-4.9-groupdel-fix-sigsegv-when-passwd-does-not-exist.patch delete mode 100644 shadow-4.9-libmisc-fix-default-value-in-SHA_get_salt_rounds.patch delete mode 100644 shadow-4.9-make-shadow-logfd-and-prog-not-extern.patch delete mode 100644 shadow-4.9-move-create-home.patch delete mode 100644 shadow-4.9-newgrp-fix-segmentation-fault.patch delete mode 100644 shadow-4.9-newuidmap-libeconf-dependency.patch delete mode 100644 shadow-4.9-null-tm.patch delete mode 100644 shadow-4.9-pwck-fix-segfault-when-calling-fprintf.patch delete mode 100644 shadow-4.9-rename-prog-to-shadow-progname.patch delete mode 100644 shadow-4.9-revert-useradd-fix-memleak.patch delete mode 100644 shadow-4.9-semanage-close-the-selabel-handle.patch delete mode 100644 shadow-4.9-shadow-progname-default-init.patch delete mode 100644 shadow-4.9-useradd-avoid-generating-empty-subid-range.patch delete mode 100644 shadow-4.9-useradd-copy-tree-argument.patch delete mode 100644 shadow-4.9-usermod-allow-all-group-types.patch diff --git a/shadow-4.9-audit-update.patch b/shadow-4.11.1-audit-update.patch similarity index 84% rename from shadow-4.9-audit-update.patch rename to shadow-4.11.1-audit-update.patch index 99513ef..65acae0 100644 --- a/shadow-4.9-audit-update.patch +++ b/shadow-4.11.1-audit-update.patch @@ -1,16 +1,16 @@ -diff -up shadow-4.8.1/libmisc/audit_help.c.audit-update shadow-4.8.1/libmisc/audit_help.c ---- shadow-4.8.1/libmisc/audit_help.c.audit-update 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/libmisc/audit_help.c 2020-03-17 16:53:44.371943299 +0100 -@@ -68,7 +68,7 @@ void audit_help_open (void) +diff -up shadow-4.11.1/libmisc/audit_help.c.audit-update shadow-4.11.1/libmisc/audit_help.c +--- shadow-4.11.1/libmisc/audit_help.c.audit-update 2022-01-03 01:46:53.000000000 +0100 ++++ shadow-4.11.1/libmisc/audit_help.c 2022-01-03 15:15:38.946046192 +0100 +@@ -46,7 +46,7 @@ void audit_help_open (void) * This function will log a message to the audit system using a predefined * message format. Parameter usage is as follows: * -- * type - type of message: AUDIT_USER_CHAUTHTOK for changing any account -+ * type - type of message: AUDIT_USER_MGMT for changing any account +- * type - type of message: AUDIT_USER_CHAUTHTOK for changing any account ++ * type - type of message: AUDIT_USER_MGMT for changing any account * attributes. * pgname - program's name * op - operation. "adding user", "changing finger info", "deleting group" -@@ -88,6 +88,39 @@ void audit_logger (int type, unused cons +@@ -66,6 +66,39 @@ void audit_logger (int type, unused cons } } @@ -50,71 +50,71 @@ diff -up shadow-4.8.1/libmisc/audit_help.c.audit-update shadow-4.8.1/libmisc/aud void audit_logger_message (const char *message, shadow_audit_result result) { if (audit_fd < 0) { -diff -up shadow-4.8.1/libmisc/cleanup_group.c.audit-update shadow-4.8.1/libmisc/cleanup_group.c ---- shadow-4.8.1/libmisc/cleanup_group.c.audit-update 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/libmisc/cleanup_group.c 2020-03-17 16:53:44.371943299 +0100 -@@ -83,7 +83,7 @@ void cleanup_report_mod_group (void *cle +diff -up shadow-4.11.1/libmisc/cleanup_group.c.audit-update shadow-4.11.1/libmisc/cleanup_group.c +--- shadow-4.11.1/libmisc/cleanup_group.c.audit-update 2022-01-03 14:57:01.777006776 +0100 ++++ shadow-4.11.1/libmisc/cleanup_group.c 2022-01-03 15:22:27.438770608 +0100 +@@ -61,7 +61,7 @@ void cleanup_report_mod_group (void *cle gr_dbname (), info->action)); #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_ACCT, Prog, -+ audit_logger (AUDIT_GRP_MGMT, Prog, +- audit_logger (AUDIT_USER_ACCT, log_get_progname(), ++ audit_logger (AUDIT_GRP_MGMT, log_get_progname(), info->audit_msg, info->name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); -@@ -101,7 +101,7 @@ void cleanup_report_mod_gshadow (void *c +@@ -79,7 +79,7 @@ void cleanup_report_mod_gshadow (void *c sgr_dbname (), info->action)); #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_ACCT, Prog, -+ audit_logger (AUDIT_GRP_MGMT, Prog, +- audit_logger (AUDIT_USER_ACCT, log_get_progname(), ++ audit_logger (AUDIT_GRP_MGMT, log_get_progname(), info->audit_msg, info->name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); -@@ -122,7 +122,7 @@ void cleanup_report_add_group_group (voi +@@ -100,7 +100,7 @@ void cleanup_report_add_group_group (voi SYSLOG ((LOG_ERR, "failed to add group %s to %s", name, gr_dbname ())); #ifdef WITH_AUDIT - audit_logger (AUDIT_ADD_GROUP, Prog, + audit_logger (AUDIT_ADD_GROUP, log_get_progname(), - "adding group to /etc/group", + "adding-group", name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -141,8 +141,8 @@ void cleanup_report_add_group_gshadow (v +@@ -119,8 +119,8 @@ void cleanup_report_add_group_gshadow (v SYSLOG ((LOG_ERR, "failed to add group %s to %s", name, sgr_dbname ())); #ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_GROUP, Prog, +- audit_logger (AUDIT_ADD_GROUP, log_get_progname(), - "adding group to /etc/gshadow", -+ audit_logger (AUDIT_GRP_MGMT, Prog, ++ audit_logger (AUDIT_GRP_MGMT, log_get_progname(), + "adding-shadow-group", name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -164,8 +164,8 @@ void cleanup_report_del_group_group (voi +@@ -142,8 +142,8 @@ void cleanup_report_del_group_group (voi "failed to remove group %s from %s", name, gr_dbname ())); #ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_GROUP, Prog, +- audit_logger (AUDIT_ADD_GROUP, log_get_progname(), - "removing group from /etc/group", -+ audit_logger (AUDIT_DEL_GROUP, Prog, ++ audit_logger (AUDIT_DEL_GROUP, log_get_progname(), + "removing-group", name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -187,8 +187,8 @@ void cleanup_report_del_group_gshadow (v +@@ -165,8 +165,8 @@ void cleanup_report_del_group_gshadow (v "failed to remove group %s from %s", name, sgr_dbname ())); #ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_GROUP, Prog, +- audit_logger (AUDIT_ADD_GROUP, log_get_progname(), - "removing group from /etc/gshadow", -+ audit_logger (AUDIT_GRP_MGMT, Prog, ++ audit_logger (AUDIT_GRP_MGMT, log_get_progname(), + "removing-shadow-group", name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -208,7 +208,7 @@ void cleanup_unlock_group (unused void * - Prog, gr_dbname ()); +@@ -186,7 +186,7 @@ void cleanup_unlock_group (unused void * + log_get_progname(), gr_dbname ()); SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); #ifdef WITH_AUDIT - audit_logger_message ("unlocking group file", @@ -122,8 +122,8 @@ diff -up shadow-4.8.1/libmisc/cleanup_group.c.audit-update shadow-4.8.1/libmisc/ SHADOW_AUDIT_FAILURE); #endif } -@@ -228,7 +228,7 @@ void cleanup_unlock_gshadow (unused void - Prog, sgr_dbname ()); +@@ -206,7 +206,7 @@ void cleanup_unlock_gshadow (unused void + log_get_progname(), sgr_dbname ()); SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); #ifdef WITH_AUDIT - audit_logger_message ("unlocking gshadow file", @@ -131,40 +131,40 @@ diff -up shadow-4.8.1/libmisc/cleanup_group.c.audit-update shadow-4.8.1/libmisc/ SHADOW_AUDIT_FAILURE); #endif } -diff -up shadow-4.8.1/libmisc/cleanup_user.c.audit-update shadow-4.8.1/libmisc/cleanup_user.c ---- shadow-4.8.1/libmisc/cleanup_user.c.audit-update 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/libmisc/cleanup_user.c 2020-03-17 16:53:44.371943299 +0100 -@@ -65,7 +65,7 @@ void cleanup_report_mod_passwd (void *cl +diff -up shadow-4.11.1/libmisc/cleanup_user.c.audit-update shadow-4.11.1/libmisc/cleanup_user.c +--- shadow-4.11.1/libmisc/cleanup_user.c.audit-update 2022-01-03 14:57:01.777006776 +0100 ++++ shadow-4.11.1/libmisc/cleanup_user.c 2022-01-03 15:21:22.593338130 +0100 +@@ -43,7 +43,7 @@ void cleanup_report_mod_passwd (void *cl pw_dbname (), info->action)); #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_ACCT, Prog, -+ audit_logger (AUDIT_USER_MGMT, Prog, +- audit_logger (AUDIT_USER_ACCT, log_get_progname(), ++ audit_logger (AUDIT_USER_MGMT, log_get_progname(), info->audit_msg, info->name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); -@@ -86,7 +86,7 @@ void cleanup_report_add_user_passwd (voi +@@ -64,7 +64,7 @@ void cleanup_report_add_user_passwd (voi SYSLOG ((LOG_ERR, "failed to add user %s to %s", name, pw_dbname ())); #ifdef WITH_AUDIT - audit_logger (AUDIT_ADD_USER, Prog, + audit_logger (AUDIT_ADD_USER, log_get_progname(), - "adding user to /etc/passwd", + "adding-user", name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -105,8 +105,8 @@ void cleanup_report_add_user_shadow (voi +@@ -83,8 +83,8 @@ void cleanup_report_add_user_shadow (voi SYSLOG ((LOG_ERR, "failed to add user %s to %s", name, spw_dbname ())); #ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_USER, Prog, +- audit_logger (AUDIT_ADD_USER, log_get_progname(), - "adding user to /etc/shadow", -+ audit_logger (AUDIT_USER_MGMT, Prog, ++ audit_logger (AUDIT_USER_MGMT, log_get_progname(), + "adding-shadow-user", name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -125,7 +125,7 @@ void cleanup_unlock_passwd (unused void - Prog, pw_dbname ()); +@@ -103,7 +103,7 @@ void cleanup_unlock_passwd (unused void + log_get_progname(), pw_dbname ()); SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); #ifdef WITH_AUDIT - audit_logger_message ("unlocking passwd file", @@ -172,8 +172,8 @@ diff -up shadow-4.8.1/libmisc/cleanup_user.c.audit-update shadow-4.8.1/libmisc/c SHADOW_AUDIT_FAILURE); #endif } -@@ -144,7 +144,7 @@ void cleanup_unlock_shadow (unused void - Prog, spw_dbname ()); +@@ -122,7 +122,7 @@ void cleanup_unlock_shadow (unused void + log_get_progname(), spw_dbname ()); SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); #ifdef WITH_AUDIT - audit_logger_message ("unlocking shadow file", @@ -181,10 +181,10 @@ diff -up shadow-4.8.1/libmisc/cleanup_user.c.audit-update shadow-4.8.1/libmisc/c SHADOW_AUDIT_FAILURE); #endif } -diff -up shadow-4.8.1/lib/prototypes.h.audit-update shadow-4.8.1/lib/prototypes.h ---- shadow-4.8.1/lib/prototypes.h.audit-update 2020-03-17 16:53:44.364943206 +0100 -+++ shadow-4.8.1/lib/prototypes.h 2020-03-17 16:53:44.371943299 +0100 -@@ -219,12 +219,21 @@ extern int audit_fd; +diff -up shadow-4.11.1/lib/prototypes.h.audit-update shadow-4.11.1/lib/prototypes.h +--- shadow-4.11.1/lib/prototypes.h.audit-update 2022-01-03 01:46:53.000000000 +0100 ++++ shadow-4.11.1/lib/prototypes.h 2022-01-03 14:57:01.777006776 +0100 +@@ -197,12 +197,21 @@ extern int audit_fd; extern void audit_help_open (void); /* Use AUDIT_NO_ID when a name is provided to audit_logger instead of an ID */ #define AUDIT_NO_ID ((unsigned int) -1) @@ -206,10 +206,10 @@ diff -up shadow-4.8.1/lib/prototypes.h.audit-update shadow-4.8.1/lib/prototypes. void audit_logger_message (const char *message, shadow_audit_result result); #endif -diff -up shadow-4.8.1/src/chage.c.audit-update shadow-4.8.1/src/chage.c ---- shadow-4.8.1/src/chage.c.audit-update 2019-11-12 01:18:25.000000000 +0100 -+++ shadow-4.8.1/src/chage.c 2020-03-17 16:53:44.371943299 +0100 -@@ -123,9 +123,10 @@ static /*@noreturn@*/void fail_exit (int +diff -up shadow-4.11.1/src/chage.c.audit-update shadow-4.11.1/src/chage.c +--- shadow-4.11.1/src/chage.c.audit-update 2022-01-03 01:46:53.000000000 +0100 ++++ shadow-4.11.1/src/chage.c 2022-01-03 14:57:01.777006776 +0100 +@@ -100,9 +100,10 @@ static /*@noreturn@*/void fail_exit (int #ifdef WITH_AUDIT if (E_SUCCESS != code) { @@ -223,7 +223,7 @@ diff -up shadow-4.8.1/src/chage.c.audit-update shadow-4.8.1/src/chage.c } #endif -@@ -883,11 +884,7 @@ int main (int argc, char **argv) +@@ -837,11 +838,7 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: Permission denied.\n"), Prog); fail_exit (E_NOPERM); } @@ -236,7 +236,7 @@ diff -up shadow-4.8.1/src/chage.c.audit-update shadow-4.8.1/src/chage.c list_fields (); fail_exit (E_SUCCESS); } -@@ -906,41 +903,43 @@ int main (int argc, char **argv) +@@ -860,41 +857,43 @@ int main (int argc, char **argv) } #ifdef WITH_AUDIT else { @@ -296,10 +296,10 @@ diff -up shadow-4.8.1/src/chage.c.audit-update shadow-4.8.1/src/chage.c user_name, (unsigned int) user_uid, 1); } #endif -diff -up shadow-4.8.1/src/gpasswd.c.audit-update shadow-4.8.1/src/gpasswd.c ---- shadow-4.8.1/src/gpasswd.c.audit-update 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/src/gpasswd.c 2020-03-17 16:53:44.371943299 +0100 -@@ -138,7 +138,7 @@ static void usage (int status) +diff -up shadow-4.11.1/src/gpasswd.c.audit-update shadow-4.11.1/src/gpasswd.c +--- shadow-4.11.1/src/gpasswd.c.audit-update 2022-01-03 01:46:53.000000000 +0100 ++++ shadow-4.11.1/src/gpasswd.c 2022-01-03 14:57:01.778006782 +0100 +@@ -116,7 +116,7 @@ static void usage (int status) (void) fputs (_(" -d, --delete USER remove USER from GROUP\n"), usageout); (void) fputs (_(" -h, --help display this help message and exit\n"), usageout); (void) fputs (_(" -Q, --root CHROOT_DIR directory to chroot into\n"), usageout); @@ -308,7 +308,7 @@ diff -up shadow-4.8.1/src/gpasswd.c.audit-update shadow-4.8.1/src/gpasswd.c (void) fputs (_(" -R, --restrict restrict access to GROUP to its members\n"), usageout); (void) fputs (_(" -M, --members USER,... set the list of members of GROUP\n"), usageout); #ifdef SHADOWGRP -@@ -397,21 +397,14 @@ static void open_files (void) +@@ -375,21 +375,14 @@ static void open_files (void) static void log_gpasswd_failure (const char *suffix) { @@ -333,7 +333,7 @@ diff -up shadow-4.8.1/src/gpasswd.c.audit-update shadow-4.8.1/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } else if (dflg) { -@@ -419,13 +412,9 @@ static void log_gpasswd_failure (const c +@@ -397,13 +390,9 @@ static void log_gpasswd_failure (const c "%s failed to remove user %s from group %s%s", myname, user, group, suffix)); #ifdef WITH_AUDIT @@ -350,7 +350,7 @@ diff -up shadow-4.8.1/src/gpasswd.c.audit-update shadow-4.8.1/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } else if (rflg) { -@@ -433,13 +422,9 @@ static void log_gpasswd_failure (const c +@@ -411,13 +400,9 @@ static void log_gpasswd_failure (const c "%s failed to remove password of group %s%s", myname, group, suffix)); #ifdef WITH_AUDIT @@ -367,7 +367,7 @@ diff -up shadow-4.8.1/src/gpasswd.c.audit-update shadow-4.8.1/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } else if (Rflg) { -@@ -447,13 +432,9 @@ static void log_gpasswd_failure (const c +@@ -425,13 +410,9 @@ static void log_gpasswd_failure (const c "%s failed to restrict access to group %s%s", myname, group, suffix)); #ifdef WITH_AUDIT @@ -384,7 +384,7 @@ diff -up shadow-4.8.1/src/gpasswd.c.audit-update shadow-4.8.1/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } else if (Aflg || Mflg) { -@@ -463,13 +444,9 @@ static void log_gpasswd_failure (const c +@@ -441,13 +422,9 @@ static void log_gpasswd_failure (const c "%s failed to set the administrators of group %s to %s%s", myname, group, admins, suffix)); #ifdef WITH_AUDIT @@ -401,7 +401,7 @@ diff -up shadow-4.8.1/src/gpasswd.c.audit-update shadow-4.8.1/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } -@@ -479,13 +456,9 @@ static void log_gpasswd_failure (const c +@@ -457,13 +434,9 @@ static void log_gpasswd_failure (const c "%s failed to set the members of group %s to %s%s", myname, group, members, suffix)); #ifdef WITH_AUDIT @@ -418,7 +418,7 @@ diff -up shadow-4.8.1/src/gpasswd.c.audit-update shadow-4.8.1/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } -@@ -494,13 +467,9 @@ static void log_gpasswd_failure (const c +@@ -472,13 +445,9 @@ static void log_gpasswd_failure (const c "%s failed to change password of group %s%s", myname, group, suffix)); #ifdef WITH_AUDIT @@ -435,7 +435,7 @@ diff -up shadow-4.8.1/src/gpasswd.c.audit-update shadow-4.8.1/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } -@@ -531,21 +500,14 @@ static void log_gpasswd_failure_gshadow +@@ -509,21 +478,14 @@ static void log_gpasswd_failure_gshadow static void log_gpasswd_success (const char *suffix) { @@ -460,7 +460,7 @@ diff -up shadow-4.8.1/src/gpasswd.c.audit-update shadow-4.8.1/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } else if (dflg) { -@@ -553,13 +515,9 @@ static void log_gpasswd_success (const c +@@ -531,13 +493,9 @@ static void log_gpasswd_success (const c "user %s removed by %s from group %s%s", user, myname, group, suffix)); #ifdef WITH_AUDIT @@ -477,7 +477,7 @@ diff -up shadow-4.8.1/src/gpasswd.c.audit-update shadow-4.8.1/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } else if (rflg) { -@@ -567,13 +525,9 @@ static void log_gpasswd_success (const c +@@ -545,13 +503,9 @@ static void log_gpasswd_success (const c "password of group %s removed by %s%s", group, myname, suffix)); #ifdef WITH_AUDIT @@ -494,7 +494,7 @@ diff -up shadow-4.8.1/src/gpasswd.c.audit-update shadow-4.8.1/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } else if (Rflg) { -@@ -581,13 +535,9 @@ static void log_gpasswd_success (const c +@@ -559,13 +513,9 @@ static void log_gpasswd_success (const c "access to group %s restricted by %s%s", group, myname, suffix)); #ifdef WITH_AUDIT @@ -511,7 +511,7 @@ diff -up shadow-4.8.1/src/gpasswd.c.audit-update shadow-4.8.1/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } else if (Aflg || Mflg) { -@@ -597,13 +547,9 @@ static void log_gpasswd_success (const c +@@ -575,13 +525,9 @@ static void log_gpasswd_success (const c "administrators of group %s set by %s to %s%s", group, myname, admins, suffix)); #ifdef WITH_AUDIT @@ -528,7 +528,7 @@ diff -up shadow-4.8.1/src/gpasswd.c.audit-update shadow-4.8.1/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } -@@ -613,13 +559,9 @@ static void log_gpasswd_success (const c +@@ -591,13 +537,9 @@ static void log_gpasswd_success (const c "members of group %s set by %s to %s%s", group, myname, members, suffix)); #ifdef WITH_AUDIT @@ -545,7 +545,7 @@ diff -up shadow-4.8.1/src/gpasswd.c.audit-update shadow-4.8.1/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } -@@ -628,13 +570,9 @@ static void log_gpasswd_success (const c +@@ -606,13 +548,9 @@ static void log_gpasswd_success (const c "password of group %s changed by %s%s", group, myname, suffix)); #ifdef WITH_AUDIT @@ -562,10 +562,10 @@ diff -up shadow-4.8.1/src/gpasswd.c.audit-update shadow-4.8.1/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } -diff -up shadow-4.8.1/src/groupadd.c.audit-update shadow-4.8.1/src/groupadd.c ---- shadow-4.8.1/src/groupadd.c.audit-update 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/src/groupadd.c 2020-03-17 16:53:44.372943312 +0100 -@@ -131,6 +131,15 @@ static /*@noreturn@*/void usage (int sta +diff -up shadow-4.11.1/src/groupadd.c.audit-update shadow-4.11.1/src/groupadd.c +--- shadow-4.11.1/src/groupadd.c.audit-update 2022-01-03 01:46:53.000000000 +0100 ++++ shadow-4.11.1/src/groupadd.c 2022-01-03 14:57:01.778006782 +0100 +@@ -111,6 +111,15 @@ static /*@noreturn@*/void usage (int sta exit (status); } @@ -581,7 +581,7 @@ diff -up shadow-4.8.1/src/groupadd.c.audit-update shadow-4.8.1/src/groupadd.c /* * new_grent - initialize the values in a group file entry * -@@ -214,7 +223,7 @@ static void grp_update (void) +@@ -207,7 +216,7 @@ static void grp_update (void) fprintf (stderr, _("%s: failed to prepare the new %s entry '%s'\n"), Prog, gr_dbname (), grp.gr_name); @@ -590,7 +590,7 @@ diff -up shadow-4.8.1/src/groupadd.c.audit-update shadow-4.8.1/src/groupadd.c } #ifdef SHADOWGRP /* -@@ -224,7 +233,7 @@ static void grp_update (void) +@@ -217,7 +226,7 @@ static void grp_update (void) fprintf (stderr, _("%s: failed to prepare the new %s entry '%s'\n"), Prog, sgr_dbname (), sgrp.sg_name); @@ -599,7 +599,7 @@ diff -up shadow-4.8.1/src/groupadd.c.audit-update shadow-4.8.1/src/groupadd.c } #endif /* SHADOWGRP */ } -@@ -248,7 +257,7 @@ static void check_new_name (void) +@@ -241,7 +250,7 @@ static void check_new_name (void) fprintf (stderr, _("%s: '%s' is not a valid group name\n"), Prog, group_name); @@ -608,7 +608,7 @@ diff -up shadow-4.8.1/src/groupadd.c.audit-update shadow-4.8.1/src/groupadd.c } /* -@@ -264,11 +273,11 @@ static void close_files (void) +@@ -257,11 +266,11 @@ static void close_files (void) fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, gr_dbname ()); @@ -622,7 +622,7 @@ diff -up shadow-4.8.1/src/groupadd.c.audit-update shadow-4.8.1/src/groupadd.c group_name, (unsigned int) group_id, SHADOW_AUDIT_SUCCESS); #endif -@@ -286,11 +295,11 @@ static void close_files (void) +@@ -279,11 +288,11 @@ static void close_files (void) fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sgr_dbname ()); @@ -637,7 +637,7 @@ diff -up shadow-4.8.1/src/groupadd.c.audit-update shadow-4.8.1/src/groupadd.c group_name, (unsigned int) group_id, SHADOW_AUDIT_SUCCESS); #endif -@@ -304,12 +313,6 @@ static void close_files (void) +@@ -297,12 +306,6 @@ static void close_files (void) #endif /* SHADOWGRP */ /* Report success at the system level */ @@ -650,7 +650,7 @@ diff -up shadow-4.8.1/src/groupadd.c.audit-update shadow-4.8.1/src/groupadd.c SYSLOG ((LOG_INFO, "new group: name=%s, GID=%u", group_name, (unsigned int) group_id)); del_cleanup (cleanup_report_add_group); -@@ -327,7 +330,7 @@ static void open_files (void) +@@ -320,7 +323,7 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, gr_dbname ()); @@ -659,7 +659,7 @@ diff -up shadow-4.8.1/src/groupadd.c.audit-update shadow-4.8.1/src/groupadd.c } add_cleanup (cleanup_unlock_group, NULL); -@@ -337,7 +340,7 @@ static void open_files (void) +@@ -330,7 +333,7 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, sgr_dbname ()); @@ -668,7 +668,7 @@ diff -up shadow-4.8.1/src/groupadd.c.audit-update shadow-4.8.1/src/groupadd.c } add_cleanup (cleanup_unlock_gshadow, NULL); } -@@ -353,7 +356,7 @@ static void open_files (void) +@@ -346,7 +349,7 @@ static void open_files (void) if (gr_open (O_CREAT | O_RDWR) == 0) { fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ()); SYSLOG ((LOG_WARN, "cannot open %s", gr_dbname ())); @@ -677,7 +677,7 @@ diff -up shadow-4.8.1/src/groupadd.c.audit-update shadow-4.8.1/src/groupadd.c } #ifdef SHADOWGRP -@@ -363,7 +366,7 @@ static void open_files (void) +@@ -356,7 +359,7 @@ static void open_files (void) _("%s: cannot open %s\n"), Prog, sgr_dbname ()); SYSLOG ((LOG_WARN, "cannot open %s", sgr_dbname ())); @@ -686,7 +686,7 @@ diff -up shadow-4.8.1/src/groupadd.c.audit-update shadow-4.8.1/src/groupadd.c } } #endif /* SHADOWGRP */ -@@ -496,7 +499,7 @@ static void check_flags (void) +@@ -493,7 +496,7 @@ static void check_flags (void) fprintf (stderr, _("%s: group '%s' already exists\n"), Prog, group_name); @@ -695,7 +695,7 @@ diff -up shadow-4.8.1/src/groupadd.c.audit-update shadow-4.8.1/src/groupadd.c } if (gflg && (prefix_getgrgid (group_id) != NULL)) { -@@ -515,7 +518,7 @@ static void check_flags (void) +@@ -512,7 +515,7 @@ static void check_flags (void) fprintf (stderr, _("%s: GID '%lu' already exists\n"), Prog, (unsigned long int) group_id); @@ -704,7 +704,7 @@ diff -up shadow-4.8.1/src/groupadd.c.audit-update shadow-4.8.1/src/groupadd.c } } } -@@ -543,7 +546,7 @@ static void check_perms (void) +@@ -540,7 +543,7 @@ static void check_perms (void) fprintf (stderr, _("%s: Cannot determine your user name.\n"), Prog); @@ -713,7 +713,7 @@ diff -up shadow-4.8.1/src/groupadd.c.audit-update shadow-4.8.1/src/groupadd.c } retval = pam_start ("groupadd", pampw->pw_name, &conv, &pamh); -@@ -563,7 +566,7 @@ static void check_perms (void) +@@ -560,7 +563,7 @@ static void check_perms (void) if (NULL != pamh) { (void) pam_end (pamh, retval); } @@ -722,7 +722,7 @@ diff -up shadow-4.8.1/src/groupadd.c.audit-update shadow-4.8.1/src/groupadd.c } (void) pam_end (pamh, retval); #endif /* USE_PAM */ -@@ -596,7 +599,7 @@ int main (int argc, char **argv) +@@ -595,7 +598,7 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: Cannot setup cleanup service.\n"), Prog); @@ -731,7 +731,7 @@ diff -up shadow-4.8.1/src/groupadd.c.audit-update shadow-4.8.1/src/groupadd.c } /* -@@ -618,7 +621,7 @@ int main (int argc, char **argv) +@@ -617,7 +620,7 @@ int main (int argc, char **argv) if (!gflg) { if (find_new_gid (rflg, &group_id, NULL) < 0) { @@ -740,10 +740,10 @@ diff -up shadow-4.8.1/src/groupadd.c.audit-update shadow-4.8.1/src/groupadd.c } } -diff -up shadow-4.8.1/src/groupdel.c.audit-update shadow-4.8.1/src/groupdel.c ---- shadow-4.8.1/src/groupdel.c.audit-update 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/src/groupdel.c 2020-03-17 16:53:44.372943312 +0100 -@@ -106,6 +106,15 @@ static /*@noreturn@*/void usage (int sta +diff -up shadow-4.11.1/src/groupdel.c.audit-update shadow-4.11.1/src/groupdel.c +--- shadow-4.11.1/src/groupdel.c.audit-update 2022-01-03 01:46:53.000000000 +0100 ++++ shadow-4.11.1/src/groupdel.c 2022-01-03 14:57:01.778006782 +0100 +@@ -84,6 +84,15 @@ static /*@noreturn@*/void usage (int sta exit (status); } @@ -759,7 +759,7 @@ diff -up shadow-4.8.1/src/groupdel.c.audit-update shadow-4.8.1/src/groupdel.c /* * grp_update - update group file entries * -@@ -132,7 +141,7 @@ static void grp_update (void) +@@ -110,7 +119,7 @@ static void grp_update (void) fprintf (stderr, _("%s: cannot remove entry '%s' from %s\n"), Prog, group_name, gr_dbname ()); @@ -768,7 +768,7 @@ diff -up shadow-4.8.1/src/groupdel.c.audit-update shadow-4.8.1/src/groupdel.c } #ifdef SHADOWGRP -@@ -144,7 +153,7 @@ static void grp_update (void) +@@ -122,7 +131,7 @@ static void grp_update (void) fprintf (stderr, _("%s: cannot remove entry '%s' from %s\n"), Prog, group_name, sgr_dbname ()); @@ -777,7 +777,7 @@ diff -up shadow-4.8.1/src/groupdel.c.audit-update shadow-4.8.1/src/groupdel.c } } #endif /* SHADOWGRP */ -@@ -163,12 +172,12 @@ static void close_files (void) +@@ -141,12 +150,12 @@ static void close_files (void) fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, gr_dbname ()); @@ -792,7 +792,7 @@ diff -up shadow-4.8.1/src/groupdel.c.audit-update shadow-4.8.1/src/groupdel.c group_name, (unsigned int) group_id, SHADOW_AUDIT_SUCCESS); #endif -@@ -188,12 +197,12 @@ static void close_files (void) +@@ -166,12 +175,12 @@ static void close_files (void) fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sgr_dbname ()); @@ -808,7 +808,7 @@ diff -up shadow-4.8.1/src/groupdel.c.audit-update shadow-4.8.1/src/groupdel.c group_name, (unsigned int) group_id, SHADOW_AUDIT_SUCCESS); #endif -@@ -207,13 +216,6 @@ static void close_files (void) +@@ -185,13 +194,6 @@ static void close_files (void) } #endif /* SHADOWGRP */ @@ -822,7 +822,7 @@ diff -up shadow-4.8.1/src/groupdel.c.audit-update shadow-4.8.1/src/groupdel.c SYSLOG ((LOG_INFO, "group '%s' removed\n", group_name)); del_cleanup (cleanup_report_del_group); } -@@ -230,7 +232,7 @@ static void open_files (void) +@@ -208,7 +210,7 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, gr_dbname ()); @@ -831,7 +831,7 @@ diff -up shadow-4.8.1/src/groupdel.c.audit-update shadow-4.8.1/src/groupdel.c } add_cleanup (cleanup_unlock_group, NULL); #ifdef SHADOWGRP -@@ -239,7 +241,7 @@ static void open_files (void) +@@ -217,7 +219,7 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, sgr_dbname ()); @@ -840,7 +840,7 @@ diff -up shadow-4.8.1/src/groupdel.c.audit-update shadow-4.8.1/src/groupdel.c } add_cleanup (cleanup_unlock_gshadow, NULL); } -@@ -257,7 +259,7 @@ static void open_files (void) +@@ -235,7 +237,7 @@ static void open_files (void) _("%s: cannot open %s\n"), Prog, gr_dbname ()); SYSLOG ((LOG_WARN, "cannot open %s", gr_dbname ())); @@ -849,7 +849,7 @@ diff -up shadow-4.8.1/src/groupdel.c.audit-update shadow-4.8.1/src/groupdel.c } #ifdef SHADOWGRP if (is_shadow_grp) { -@@ -266,7 +268,7 @@ static void open_files (void) +@@ -244,7 +246,7 @@ static void open_files (void) _("%s: cannot open %s\n"), Prog, sgr_dbname ()); SYSLOG ((LOG_WARN, "cannot open %s", sgr_dbname ())); @@ -858,7 +858,7 @@ diff -up shadow-4.8.1/src/groupdel.c.audit-update shadow-4.8.1/src/groupdel.c } } #endif /* SHADOWGRP */ -@@ -307,7 +309,7 @@ static void group_busy (gid_t gid) +@@ -285,7 +287,7 @@ static void group_busy (gid_t gid) fprintf (stderr, _("%s: cannot remove the primary group of user '%s'\n"), Prog, pwd->pw_name); @@ -867,7 +867,7 @@ diff -up shadow-4.8.1/src/groupdel.c.audit-update shadow-4.8.1/src/groupdel.c } /* -@@ -392,7 +394,7 @@ int main (int argc, char **argv) +@@ -373,7 +375,7 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: Cannot setup cleanup service.\n"), Prog); @@ -876,7 +876,7 @@ diff -up shadow-4.8.1/src/groupdel.c.audit-update shadow-4.8.1/src/groupdel.c } process_flags (argc, argv); -@@ -406,7 +408,7 @@ int main (int argc, char **argv) +@@ -387,7 +389,7 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: Cannot determine your user name.\n"), Prog); @@ -885,7 +885,7 @@ diff -up shadow-4.8.1/src/groupdel.c.audit-update shadow-4.8.1/src/groupdel.c } retval = pam_start ("groupdel", pampw->pw_name, &conv, &pamh); -@@ -427,7 +429,7 @@ int main (int argc, char **argv) +@@ -408,7 +410,7 @@ int main (int argc, char **argv) if (NULL != pamh) { (void) pam_end (pamh, retval); } @@ -894,7 +894,7 @@ diff -up shadow-4.8.1/src/groupdel.c.audit-update shadow-4.8.1/src/groupdel.c } (void) pam_end (pamh, retval); #endif /* USE_PAM */ -@@ -447,7 +449,7 @@ int main (int argc, char **argv) +@@ -428,7 +430,7 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: group '%s' does not exist\n"), Prog, group_name); @@ -903,7 +903,7 @@ diff -up shadow-4.8.1/src/groupdel.c.audit-update shadow-4.8.1/src/groupdel.c } group_id = grp->gr_gid; -@@ -471,7 +473,7 @@ int main (int argc, char **argv) +@@ -452,7 +454,7 @@ int main (int argc, char **argv) _("%s: %s is the NIS master\n"), Prog, nis_master); } @@ -912,10 +912,10 @@ diff -up shadow-4.8.1/src/groupdel.c.audit-update shadow-4.8.1/src/groupdel.c } #endif -diff -up shadow-4.8.1/src/groupmod.c.audit-update shadow-4.8.1/src/groupmod.c ---- shadow-4.8.1/src/groupmod.c.audit-update 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/src/groupmod.c 2020-03-17 16:53:44.372943312 +0100 -@@ -450,7 +450,7 @@ static void close_files (void) +diff -up shadow-4.11.1/src/groupmod.c.audit-update shadow-4.11.1/src/groupmod.c +--- shadow-4.11.1/src/groupmod.c.audit-update 2022-01-03 01:46:53.000000000 +0100 ++++ shadow-4.11.1/src/groupmod.c 2022-01-03 14:57:01.778006782 +0100 +@@ -468,7 +468,7 @@ static void close_files (void) exit (E_GRP_UPDATE); } #ifdef WITH_AUDIT @@ -924,7 +924,7 @@ diff -up shadow-4.8.1/src/groupmod.c.audit-update shadow-4.8.1/src/groupmod.c info_group.audit_msg, group_name, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); -@@ -473,7 +473,14 @@ static void close_files (void) +@@ -491,7 +491,14 @@ static void close_files (void) exit (E_GRP_UPDATE); } #ifdef WITH_AUDIT @@ -940,7 +940,7 @@ diff -up shadow-4.8.1/src/groupmod.c.audit-update shadow-4.8.1/src/groupmod.c info_gshadow.audit_msg, group_name, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); -@@ -496,7 +503,7 @@ static void close_files (void) +@@ -514,7 +521,7 @@ static void close_files (void) exit (E_GRP_UPDATE); } #ifdef WITH_AUDIT @@ -949,7 +949,7 @@ diff -up shadow-4.8.1/src/groupmod.c.audit-update shadow-4.8.1/src/groupmod.c info_passwd.audit_msg, group_name, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); -@@ -511,8 +518,8 @@ static void close_files (void) +@@ -529,8 +536,8 @@ static void close_files (void) } #ifdef WITH_AUDIT @@ -960,7 +960,7 @@ diff -up shadow-4.8.1/src/groupmod.c.audit-update shadow-4.8.1/src/groupmod.c group_name, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); #endif -@@ -524,6 +531,8 @@ static void close_files (void) +@@ -542,6 +549,8 @@ static void close_files (void) */ static void prepare_failure_reports (void) { @@ -969,7 +969,7 @@ diff -up shadow-4.8.1/src/groupmod.c.audit-update shadow-4.8.1/src/groupmod.c info_group.name = group_name; #ifdef SHADOWGRP info_gshadow.name = group_name; -@@ -536,76 +545,109 @@ static void prepare_failure_reports (voi +@@ -554,76 +563,109 @@ static void prepare_failure_reports (voi #endif info_passwd.audit_msg = xmalloc (512); @@ -1106,7 +1106,7 @@ diff -up shadow-4.8.1/src/groupmod.c.audit-update shadow-4.8.1/src/groupmod.c "%lu", (unsigned long int) group_newid); } info_group.audit_msg[511] = '\0'; -@@ -613,6 +655,11 @@ static void prepare_failure_reports (voi +@@ -631,6 +673,11 @@ static void prepare_failure_reports (voi info_gshadow.audit_msg[511] = '\0'; #endif info_passwd.audit_msg[511] = '\0'; @@ -1118,10 +1118,10 @@ diff -up shadow-4.8.1/src/groupmod.c.audit-update shadow-4.8.1/src/groupmod.c // FIXME: add a system cleanup add_cleanup (cleanup_report_mod_group, &info_group); -diff -up shadow-4.8.1/src/newgrp.c.audit-update shadow-4.8.1/src/newgrp.c ---- shadow-4.8.1/src/newgrp.c.audit-update 2020-01-12 15:19:28.000000000 +0100 -+++ shadow-4.8.1/src/newgrp.c 2020-03-17 16:53:44.372943312 +0100 -@@ -206,11 +206,12 @@ static void check_perms (const struct gr +diff -up shadow-4.11.1/src/newgrp.c.audit-update shadow-4.11.1/src/newgrp.c +--- shadow-4.11.1/src/newgrp.c.audit-update 2022-01-03 01:46:53.000000000 +0100 ++++ shadow-4.11.1/src/newgrp.c 2022-01-03 15:25:39.407050922 +0100 +@@ -185,11 +185,12 @@ static void check_perms (const struct gr strcmp (cpasswd, grp->gr_passwd) != 0) { #ifdef WITH_AUDIT snprintf (audit_buf, sizeof(audit_buf), @@ -1136,7 +1136,7 @@ diff -up shadow-4.8.1/src/newgrp.c.audit-update shadow-4.8.1/src/newgrp.c #endif SYSLOG ((LOG_INFO, "Invalid password for group '%s' from '%s'", -@@ -221,11 +222,12 @@ static void check_perms (const struct gr +@@ -200,11 +201,12 @@ static void check_perms (const struct gr } #ifdef WITH_AUDIT snprintf (audit_buf, sizeof(audit_buf), @@ -1151,7 +1151,7 @@ diff -up shadow-4.8.1/src/newgrp.c.audit-update shadow-4.8.1/src/newgrp.c #endif } -@@ -236,19 +238,6 @@ failure: +@@ -215,19 +217,6 @@ failure: * harm. -- JWP */ closelog (); @@ -1171,7 +1171,7 @@ diff -up shadow-4.8.1/src/newgrp.c.audit-update shadow-4.8.1/src/newgrp.c exit (EXIT_FAILURE); } -@@ -320,15 +309,27 @@ static void syslog_sg (const char *name, +@@ -299,15 +288,27 @@ static void syslog_sg (const char *name, is_newgrp ? "newgrp" : "sg", strerror (errno)); #ifdef WITH_AUDIT if (group) { @@ -1203,7 +1203,7 @@ diff -up shadow-4.8.1/src/newgrp.c.audit-update shadow-4.8.1/src/newgrp.c } #endif exit (EXIT_FAILURE); -@@ -458,7 +459,7 @@ int main (int argc, char **argv) +@@ -438,7 +439,7 @@ int main (int argc, char **argv) #ifdef WITH_AUDIT audit_logger (AUDIT_CHGRP_ID, Prog, "changing", NULL, @@ -1212,7 +1212,7 @@ diff -up shadow-4.8.1/src/newgrp.c.audit-update shadow-4.8.1/src/newgrp.c #endif SYSLOG ((LOG_WARN, "Cannot determine the user name of the caller (UID %lu)", (unsigned long) getuid ())); -@@ -574,15 +575,26 @@ int main (int argc, char **argv) +@@ -554,15 +555,26 @@ int main (int argc, char **argv) perror ("getgroups"); #ifdef WITH_AUDIT if (group) { @@ -1243,7 +1243,7 @@ diff -up shadow-4.8.1/src/newgrp.c.audit-update shadow-4.8.1/src/newgrp.c } #endif exit (EXIT_FAILURE); -@@ -739,10 +751,10 @@ int main (int argc, char **argv) +@@ -719,10 +731,10 @@ int main (int argc, char **argv) perror ("setgid"); #ifdef WITH_AUDIT snprintf (audit_buf, sizeof(audit_buf), @@ -1256,7 +1256,7 @@ diff -up shadow-4.8.1/src/newgrp.c.audit-update shadow-4.8.1/src/newgrp.c #endif exit (EXIT_FAILURE); } -@@ -751,10 +763,10 @@ int main (int argc, char **argv) +@@ -731,10 +743,10 @@ int main (int argc, char **argv) perror ("setuid"); #ifdef WITH_AUDIT snprintf (audit_buf, sizeof(audit_buf), @@ -1269,7 +1269,7 @@ diff -up shadow-4.8.1/src/newgrp.c.audit-update shadow-4.8.1/src/newgrp.c #endif exit (EXIT_FAILURE); } -@@ -768,10 +780,10 @@ int main (int argc, char **argv) +@@ -748,10 +760,10 @@ int main (int argc, char **argv) execl (SHELL, "sh", "-c", command, (char *) 0); #ifdef WITH_AUDIT snprintf (audit_buf, sizeof(audit_buf), @@ -1282,7 +1282,7 @@ diff -up shadow-4.8.1/src/newgrp.c.audit-update shadow-4.8.1/src/newgrp.c #endif perror (SHELL); exit ((errno == ENOENT) ? E_CMD_NOTFOUND : E_CMD_NOEXEC); -@@ -835,11 +847,11 @@ int main (int argc, char **argv) +@@ -815,11 +827,11 @@ int main (int argc, char **argv) } #ifdef WITH_AUDIT @@ -1296,7 +1296,7 @@ diff -up shadow-4.8.1/src/newgrp.c.audit-update shadow-4.8.1/src/newgrp.c #endif /* * Exec the login shell and go away. We are trying to get back to -@@ -863,15 +875,24 @@ int main (int argc, char **argv) +@@ -843,15 +855,24 @@ int main (int argc, char **argv) closelog (); #ifdef WITH_AUDIT if (NULL != group) { @@ -1313,7 +1313,7 @@ diff -up shadow-4.8.1/src/newgrp.c.audit-update shadow-4.8.1/src/newgrp.c + snprintf (audit_buf, sizeof(audit_buf), + "changing new_group=\"%s\"", group); + } - audit_logger (AUDIT_CHGRP_ID, Prog, + audit_logger (AUDIT_CHGRP_ID, Prog, audit_buf, NULL, - (unsigned int) getuid (), 0); + (unsigned int) getuid (), SHADOW_AUDIT_FAILURE); @@ -1325,10 +1325,10 @@ diff -up shadow-4.8.1/src/newgrp.c.audit-update shadow-4.8.1/src/newgrp.c } #endif exit (EXIT_FAILURE); -diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c ---- shadow-4.8.1/src/useradd.c.audit-update 2020-03-17 16:53:44.365943219 +0100 -+++ shadow-4.8.1/src/useradd.c 2020-03-17 17:03:11.614503929 +0100 -@@ -233,6 +233,8 @@ static void create_mail (void); +diff -up shadow-4.11.1/src/useradd.c.audit-update shadow-4.11.1/src/useradd.c +--- shadow-4.11.1/src/useradd.c.audit-update 2022-01-03 14:57:01.772006744 +0100 ++++ shadow-4.11.1/src/useradd.c 2022-01-03 14:57:01.787006838 +0100 +@@ -222,6 +222,8 @@ static void check_uid_range(int rflg, ui */ static void fail_exit (int code) { @@ -1337,7 +1337,7 @@ diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c if (home_added) { if (rmdir (prefix_user_home) != 0) { fprintf (stderr, -@@ -246,12 +248,6 @@ static void fail_exit (int code) +@@ -235,12 +237,6 @@ static void fail_exit (int code) if (spw_unlock () == 0) { fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); @@ -1350,7 +1350,7 @@ diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c /* continue */ } } -@@ -259,12 +255,6 @@ static void fail_exit (int code) +@@ -248,12 +244,6 @@ static void fail_exit (int code) if (pw_unlock () == 0) { fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); @@ -1363,7 +1363,7 @@ diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c /* continue */ } } -@@ -272,12 +262,6 @@ static void fail_exit (int code) +@@ -261,12 +251,6 @@ static void fail_exit (int code) if (gr_unlock () == 0) { fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); @@ -1376,7 +1376,7 @@ diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c /* continue */ } } -@@ -286,12 +270,6 @@ static void fail_exit (int code) +@@ -275,12 +259,6 @@ static void fail_exit (int code) if (sgr_unlock () == 0) { fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); @@ -1389,7 +1389,7 @@ diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c /* continue */ } } -@@ -301,12 +279,6 @@ static void fail_exit (int code) +@@ -290,12 +268,6 @@ static void fail_exit (int code) if (sub_uid_unlock () == 0) { fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); @@ -1402,7 +1402,7 @@ diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c /* continue */ } } -@@ -314,20 +286,19 @@ static void fail_exit (int code) +@@ -303,20 +275,19 @@ static void fail_exit (int code) if (sub_gid_unlock () == 0) { fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); @@ -1430,7 +1430,7 @@ diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -692,7 +663,7 @@ static int set_defaults (void) +@@ -719,7 +690,7 @@ static int set_defaults (void) } #ifdef WITH_AUDIT audit_logger (AUDIT_USYS_CONFIG, Prog, @@ -1439,7 +1439,7 @@ diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c NULL, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); #endif -@@ -974,12 +945,6 @@ static void grp_update (void) +@@ -1050,12 +1021,6 @@ static void grp_update (void) _("%s: Out of memory. Cannot update %s.\n"), Prog, gr_dbname ()); SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", gr_dbname (), user_name)); @@ -1452,7 +1452,7 @@ diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c fail_exit (E_GRP_UPDATE); /* XXX */ } -@@ -993,18 +958,12 @@ static void grp_update (void) +@@ -1069,18 +1034,12 @@ static void grp_update (void) _("%s: failed to prepare the new %s entry '%s'\n"), Prog, gr_dbname (), ngrp->gr_name); SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", gr_dbname (), user_name)); @@ -1474,7 +1474,7 @@ diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c SHADOW_AUDIT_SUCCESS); #endif SYSLOG ((LOG_INFO, -@@ -1049,12 +1008,6 @@ static void grp_update (void) +@@ -1125,12 +1084,6 @@ static void grp_update (void) _("%s: Out of memory. Cannot update %s.\n"), Prog, sgr_dbname ()); SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", sgr_dbname (), user_name)); @@ -1487,7 +1487,7 @@ diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c fail_exit (E_GRP_UPDATE); /* XXX */ } -@@ -1068,18 +1021,13 @@ static void grp_update (void) +@@ -1144,18 +1097,13 @@ static void grp_update (void) _("%s: failed to prepare the new %s entry '%s'\n"), Prog, sgr_dbname (), nsgrp->sg_name); SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", sgr_dbname (), user_name)); @@ -1510,7 +1510,7 @@ diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c SHADOW_AUDIT_SUCCESS); #endif SYSLOG ((LOG_INFO, -@@ -1452,7 +1400,7 @@ static void process_flags (int argc, cha +@@ -1528,7 +1476,7 @@ static void process_flags (int argc, cha Prog, user_name); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1519,7 +1519,7 @@ diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1567,7 +1515,7 @@ static void close_files (void) +@@ -1637,7 +1585,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1528,7 +1528,7 @@ diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1580,7 +1528,7 @@ static void close_files (void) +@@ -1650,7 +1598,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1537,7 +1537,7 @@ diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1622,7 +1570,7 @@ static void close_files (void) +@@ -1667,7 +1615,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1546,7 +1546,7 @@ diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1636,7 +1584,7 @@ static void close_files (void) +@@ -1681,7 +1629,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1555,7 +1555,7 @@ diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1828,7 +1776,7 @@ static void grp_add (void) +@@ -1942,7 +1890,7 @@ static void grp_add (void) Prog, gr_dbname (), grp.gr_name); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_GROUP, Prog, @@ -1564,7 +1564,7 @@ diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c grp.gr_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1844,7 +1792,7 @@ static void grp_add (void) +@@ -1958,7 +1906,7 @@ static void grp_add (void) Prog, sgr_dbname (), sgrp.sg_name); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_GROUP, Prog, @@ -1573,7 +1573,7 @@ diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c grp.gr_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1854,7 +1802,7 @@ static void grp_add (void) +@@ -1968,7 +1916,7 @@ static void grp_add (void) SYSLOG ((LOG_INFO, "new group: name=%s, GID=%u", user_name, user_gid)); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_GROUP, Prog, @@ -1582,7 +1582,7 @@ diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c grp.gr_name, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); #endif -@@ -2025,12 +1973,6 @@ static void usr_update (void) +@@ -2161,12 +2109,6 @@ static void usr_update (unsigned long su fprintf (stderr, _("%s: failed to prepare the new %s entry '%s'\n"), Prog, spw_dbname (), spent.sp_namp); @@ -1595,7 +1595,7 @@ diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c fail_exit (E_PW_UPDATE); } #ifdef ENABLE_SUBIDS -@@ -2051,9 +1993,14 @@ static void usr_update (void) +@@ -2187,9 +2129,14 @@ static void usr_update (unsigned long su #endif /* ENABLE_SUBIDS */ #ifdef WITH_AUDIT @@ -1612,7 +1612,7 @@ diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c SHADOW_AUDIT_SUCCESS); #endif /* -@@ -2140,12 +2087,6 @@ static void create_home (void) +@@ -2279,12 +2226,6 @@ static void create_home (void) fprintf (stderr, _("%s: cannot create directory %s\n"), Prog, path); @@ -1625,7 +1625,7 @@ diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c fail_exit (E_HOMEDIR); } if (chown (path, 0, 0) < 0) { -@@ -2168,8 +2109,8 @@ static void create_home (void) +@@ -2311,8 +2252,8 @@ static void create_home (void) } home_added = true; #ifdef WITH_AUDIT @@ -1636,7 +1636,7 @@ diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c user_name, (unsigned int) user_id, SHADOW_AUDIT_SUCCESS); #endif -@@ -2354,12 +2295,6 @@ int main (int argc, char **argv) +@@ -2552,12 +2493,6 @@ int main (int argc, char **argv) */ if (prefix_getpwnam (user_name) != NULL) { /* local, no need for xgetpwnam */ fprintf (stderr, _("%s: user '%s' already exists\n"), Prog, user_name); @@ -1649,7 +1649,7 @@ diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c fail_exit (E_NAME_IN_USE); } -@@ -2375,12 +2310,6 @@ int main (int argc, char **argv) +@@ -2573,12 +2508,6 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: group %s exists - if you want to add this user to that group, use -g.\n"), Prog, user_name); @@ -1662,7 +1662,7 @@ diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c fail_exit (E_NAME_IN_USE); } } -@@ -2410,12 +2339,6 @@ int main (int argc, char **argv) +@@ -2608,12 +2537,6 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: UID %lu is not unique\n"), Prog, (unsigned long) user_id); @@ -1675,7 +1675,7 @@ diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c fail_exit (E_UID_IN_USE); } } -@@ -2489,9 +2412,10 @@ int main (int argc, char **argv) +@@ -2688,9 +2611,10 @@ int main (int argc, char **argv) _("%s: warning: the user name %s to %s SELinux user mapping failed.\n"), Prog, user_name, user_selinux); #ifdef WITH_AUDIT @@ -1689,10 +1689,10 @@ diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c #endif /* WITH_AUDIT */ fail_exit (E_SE_UPDATE); } -diff -up shadow-4.8.1/src/userdel.c.audit-update shadow-4.8.1/src/userdel.c ---- shadow-4.8.1/src/userdel.c.audit-update 2020-03-17 16:53:44.368943259 +0100 -+++ shadow-4.8.1/src/userdel.c 2020-03-17 16:53:44.373943325 +0100 -@@ -222,9 +222,9 @@ static void update_groups (void) +diff -up shadow-4.11.1/src/userdel.c.audit-update shadow-4.11.1/src/userdel.c +--- shadow-4.11.1/src/userdel.c.audit-update 2022-01-03 01:46:53.000000000 +0100 ++++ shadow-4.11.1/src/userdel.c 2022-01-03 14:57:01.787006838 +0100 +@@ -202,9 +202,9 @@ static void update_groups (void) * Update the DBM group file with the new entry as well. */ #ifdef WITH_AUDIT @@ -1705,7 +1705,7 @@ diff -up shadow-4.8.1/src/userdel.c.audit-update shadow-4.8.1/src/userdel.c SHADOW_AUDIT_SUCCESS); #endif /* WITH_AUDIT */ SYSLOG ((LOG_INFO, "delete '%s' from group '%s'\n", -@@ -284,9 +284,9 @@ static void update_groups (void) +@@ -264,9 +264,9 @@ static void update_groups (void) exit (E_GRP_UPDATE); } #ifdef WITH_AUDIT @@ -1718,7 +1718,7 @@ diff -up shadow-4.8.1/src/userdel.c.audit-update shadow-4.8.1/src/userdel.c SHADOW_AUDIT_SUCCESS); #endif /* WITH_AUDIT */ SYSLOG ((LOG_INFO, "delete '%s' from shadow group '%s'\n", -@@ -363,9 +363,9 @@ static void remove_usergroup (void) +@@ -343,9 +343,9 @@ static void remove_usergroup (void) } #ifdef WITH_AUDIT @@ -1731,7 +1731,7 @@ diff -up shadow-4.8.1/src/userdel.c.audit-update shadow-4.8.1/src/userdel.c SHADOW_AUDIT_SUCCESS); #endif /* WITH_AUDIT */ SYSLOG ((LOG_INFO, -@@ -381,9 +381,9 @@ static void remove_usergroup (void) +@@ -361,9 +361,9 @@ static void remove_usergroup (void) fail_exit (E_GRP_UPDATE); } #ifdef WITH_AUDIT @@ -1744,7 +1744,7 @@ diff -up shadow-4.8.1/src/userdel.c.audit-update shadow-4.8.1/src/userdel.c SHADOW_AUDIT_SUCCESS); #endif /* WITH_AUDIT */ SYSLOG ((LOG_INFO, -@@ -545,7 +545,7 @@ static void fail_exit (int code) +@@ -525,7 +525,7 @@ static void fail_exit (int code) #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, @@ -1753,7 +1753,7 @@ diff -up shadow-4.8.1/src/userdel.c.audit-update shadow-4.8.1/src/userdel.c user_name, (unsigned int) user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -565,24 +565,12 @@ static void open_files (void) +@@ -545,24 +545,12 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, pw_dbname ()); @@ -1778,7 +1778,7 @@ diff -up shadow-4.8.1/src/userdel.c.audit-update shadow-4.8.1/src/userdel.c fail_exit (E_PW_UPDATE); } if (is_shadow_pwd) { -@@ -590,12 +578,6 @@ static void open_files (void) +@@ -570,12 +558,6 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, spw_dbname ()); @@ -1791,7 +1791,7 @@ diff -up shadow-4.8.1/src/userdel.c.audit-update shadow-4.8.1/src/userdel.c fail_exit (E_PW_UPDATE); } spw_locked = true; -@@ -603,12 +585,6 @@ static void open_files (void) +@@ -583,12 +565,6 @@ static void open_files (void) fprintf (stderr, _("%s: cannot open %s\n"), Prog, spw_dbname ()); @@ -1804,7 +1804,7 @@ diff -up shadow-4.8.1/src/userdel.c.audit-update shadow-4.8.1/src/userdel.c fail_exit (E_PW_UPDATE); } } -@@ -616,23 +592,11 @@ static void open_files (void) +@@ -596,23 +572,11 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, gr_dbname ()); @@ -1828,7 +1828,7 @@ diff -up shadow-4.8.1/src/userdel.c.audit-update shadow-4.8.1/src/userdel.c fail_exit (E_GRP_UPDATE); } #ifdef SHADOWGRP -@@ -641,24 +605,12 @@ static void open_files (void) +@@ -621,24 +585,12 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, sgr_dbname ()); @@ -1853,7 +1853,7 @@ diff -up shadow-4.8.1/src/userdel.c.audit-update shadow-4.8.1/src/userdel.c fail_exit (E_GRP_UPDATE); } } -@@ -669,24 +621,12 @@ static void open_files (void) +@@ -649,24 +601,12 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, sub_uid_dbname ()); @@ -1878,7 +1878,7 @@ diff -up shadow-4.8.1/src/userdel.c.audit-update shadow-4.8.1/src/userdel.c fail_exit (E_SUB_UID_UPDATE); } } -@@ -695,24 +635,12 @@ static void open_files (void) +@@ -675,24 +615,12 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, sub_gid_dbname ()); @@ -1903,7 +1903,7 @@ diff -up shadow-4.8.1/src/userdel.c.audit-update shadow-4.8.1/src/userdel.c fail_exit (E_SUB_GID_UPDATE); } } -@@ -757,7 +685,7 @@ static void update_user (void) +@@ -737,7 +665,7 @@ static void update_user (void) #endif /* ENABLE_SUBIDS */ #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, @@ -1912,7 +1912,7 @@ diff -up shadow-4.8.1/src/userdel.c.audit-update shadow-4.8.1/src/userdel.c user_name, (unsigned int) user_id, SHADOW_AUDIT_SUCCESS); #endif /* WITH_AUDIT */ -@@ -865,7 +793,7 @@ static int remove_mailbox (void) +@@ -845,7 +773,7 @@ static int remove_mailbox (void) SYSLOG ((LOG_ERR, "Cannot remove %s: %s", mailfile, strerror (errno))); #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, @@ -1921,7 +1921,7 @@ diff -up shadow-4.8.1/src/userdel.c.audit-update shadow-4.8.1/src/userdel.c user_name, (unsigned int) user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -882,7 +810,7 @@ static int remove_mailbox (void) +@@ -862,7 +790,7 @@ static int remove_mailbox (void) SYSLOG ((LOG_ERR, "Cannot remove %s: %s", mailfile, strerror (errno))); #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, @@ -1930,7 +1930,7 @@ diff -up shadow-4.8.1/src/userdel.c.audit-update shadow-4.8.1/src/userdel.c user_name, (unsigned int) user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -892,8 +820,8 @@ static int remove_mailbox (void) +@@ -872,8 +800,8 @@ static int remove_mailbox (void) #ifdef WITH_AUDIT else { @@ -1941,7 +1941,7 @@ diff -up shadow-4.8.1/src/userdel.c.audit-update shadow-4.8.1/src/userdel.c user_name, (unsigned int) user_id, SHADOW_AUDIT_SUCCESS); } -@@ -911,7 +839,7 @@ static int remove_mailbox (void) +@@ -891,7 +819,7 @@ static int remove_mailbox (void) mailfile, strerror (errno))); #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, @@ -1950,7 +1950,7 @@ diff -up shadow-4.8.1/src/userdel.c.audit-update shadow-4.8.1/src/userdel.c user_name, (unsigned int) user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -928,7 +856,7 @@ static int remove_mailbox (void) +@@ -908,7 +836,7 @@ static int remove_mailbox (void) SYSLOG ((LOG_ERR, "Cannot remove %s: %s", mailfile, strerror (errno))); #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, @@ -1959,7 +1959,7 @@ diff -up shadow-4.8.1/src/userdel.c.audit-update shadow-4.8.1/src/userdel.c user_name, (unsigned int) user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -938,8 +866,8 @@ static int remove_mailbox (void) +@@ -918,8 +846,8 @@ static int remove_mailbox (void) #ifdef WITH_AUDIT else { @@ -1970,7 +1970,7 @@ diff -up shadow-4.8.1/src/userdel.c.audit-update shadow-4.8.1/src/userdel.c user_name, (unsigned int) user_id, SHADOW_AUDIT_SUCCESS); } -@@ -1152,7 +1080,7 @@ int main (int argc, char **argv) +@@ -1138,7 +1066,7 @@ int main (int argc, char **argv) Prog, user_name); #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, @@ -1979,7 +1979,7 @@ diff -up shadow-4.8.1/src/userdel.c.audit-update shadow-4.8.1/src/userdel.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -1208,7 +1136,7 @@ int main (int argc, char **argv) +@@ -1194,7 +1122,7 @@ int main (int argc, char **argv) if (!fflg) { #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, @@ -1988,7 +1988,7 @@ diff -up shadow-4.8.1/src/userdel.c.audit-update shadow-4.8.1/src/userdel.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -1302,8 +1230,8 @@ int main (int argc, char **argv) +@@ -1288,8 +1216,8 @@ int main (int argc, char **argv) #ifdef WITH_AUDIT else { @@ -1999,7 +1999,7 @@ diff -up shadow-4.8.1/src/userdel.c.audit-update shadow-4.8.1/src/userdel.c user_name, (unsigned int) user_id, SHADOW_AUDIT_SUCCESS); } -@@ -1312,7 +1240,7 @@ int main (int argc, char **argv) +@@ -1298,7 +1226,7 @@ int main (int argc, char **argv) #ifdef WITH_AUDIT if (0 != errors) { audit_logger (AUDIT_DEL_USER, Prog, @@ -2008,7 +2008,7 @@ diff -up shadow-4.8.1/src/userdel.c.audit-update shadow-4.8.1/src/userdel.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); } -@@ -1325,8 +1253,8 @@ int main (int argc, char **argv) +@@ -1311,8 +1239,8 @@ int main (int argc, char **argv) _("%s: warning: the user name %s to SELinux user mapping removal failed.\n"), Prog, user_name); #ifdef WITH_AUDIT @@ -2019,10 +2019,10 @@ diff -up shadow-4.8.1/src/userdel.c.audit-update shadow-4.8.1/src/userdel.c user_name, (unsigned int) user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -diff -up shadow-4.8.1/src/usermod.c.audit-update shadow-4.8.1/src/usermod.c ---- shadow-4.8.1/src/usermod.c.audit-update 2020-03-17 16:53:44.370943285 +0100 -+++ shadow-4.8.1/src/usermod.c 2020-03-17 16:53:44.373943325 +0100 -@@ -457,8 +457,8 @@ static char *new_pw_passwd (char *pw_pas +diff -up shadow-4.11.1/src/usermod.c.audit-update shadow-4.11.1/src/usermod.c +--- shadow-4.11.1/src/usermod.c.audit-update 2022-01-03 14:57:01.776006769 +0100 ++++ shadow-4.11.1/src/usermod.c 2022-01-03 15:28:16.959101706 +0100 +@@ -417,8 +417,8 @@ static char *new_pw_passwd (char *pw_pas #ifdef WITH_AUDIT audit_logger (AUDIT_USER_CHAUTHTOK, Prog, @@ -2033,7 +2033,7 @@ diff -up shadow-4.8.1/src/usermod.c.audit-update shadow-4.8.1/src/usermod.c #endif SYSLOG ((LOG_INFO, "lock user '%s' password", user_newname)); strcpy (buf, "!"); -@@ -477,8 +477,8 @@ static char *new_pw_passwd (char *pw_pas +@@ -437,8 +437,8 @@ static char *new_pw_passwd (char *pw_pas #ifdef WITH_AUDIT audit_logger (AUDIT_USER_CHAUTHTOK, Prog, @@ -2044,7 +2044,7 @@ diff -up shadow-4.8.1/src/usermod.c.audit-update shadow-4.8.1/src/usermod.c #endif SYSLOG ((LOG_INFO, "unlock user '%s' password", user_newname)); s = pw_pass; -@@ -489,7 +489,7 @@ static char *new_pw_passwd (char *pw_pas +@@ -449,7 +449,7 @@ static char *new_pw_passwd (char *pw_pas } else if (pflg) { #ifdef WITH_AUDIT audit_logger (AUDIT_USER_CHAUTHTOK, Prog, @@ -2053,7 +2053,7 @@ diff -up shadow-4.8.1/src/usermod.c.audit-update shadow-4.8.1/src/usermod.c user_newname, (unsigned int) user_newid, 1); #endif SYSLOG ((LOG_INFO, "change user '%s' password", user_newname)); -@@ -518,8 +518,8 @@ static void new_pwent (struct passwd *pw +@@ -478,8 +478,8 @@ static void new_pwent (struct passwd *pw fail_exit (E_NAME_IN_USE); } #ifdef WITH_AUDIT @@ -2064,7 +2064,7 @@ diff -up shadow-4.8.1/src/usermod.c.audit-update shadow-4.8.1/src/usermod.c user_newname, (unsigned int) user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -539,8 +539,8 @@ static void new_pwent (struct passwd *pw +@@ -499,8 +499,8 @@ static void new_pwent (struct passwd *pw if (uflg) { #ifdef WITH_AUDIT @@ -2075,7 +2075,7 @@ diff -up shadow-4.8.1/src/usermod.c.audit-update shadow-4.8.1/src/usermod.c user_newname, (unsigned int) user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -550,8 +550,8 @@ static void new_pwent (struct passwd *pw +@@ -510,8 +510,8 @@ static void new_pwent (struct passwd *pw } if (gflg) { #ifdef WITH_AUDIT @@ -2086,7 +2086,7 @@ diff -up shadow-4.8.1/src/usermod.c.audit-update shadow-4.8.1/src/usermod.c user_newname, (unsigned int) user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -561,8 +561,8 @@ static void new_pwent (struct passwd *pw +@@ -521,8 +521,8 @@ static void new_pwent (struct passwd *pw } if (cflg) { #ifdef WITH_AUDIT @@ -2097,7 +2097,7 @@ diff -up shadow-4.8.1/src/usermod.c.audit-update shadow-4.8.1/src/usermod.c user_newname, (unsigned int) user_newid, 1); #endif pwent->pw_gecos = user_newcomment; -@@ -570,8 +570,8 @@ static void new_pwent (struct passwd *pw +@@ -530,8 +530,8 @@ static void new_pwent (struct passwd *pw if (dflg) { #ifdef WITH_AUDIT @@ -2108,7 +2108,7 @@ diff -up shadow-4.8.1/src/usermod.c.audit-update shadow-4.8.1/src/usermod.c user_newname, (unsigned int) user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -581,8 +581,8 @@ static void new_pwent (struct passwd *pw +@@ -547,8 +547,8 @@ static void new_pwent (struct passwd *pw } if (sflg) { #ifdef WITH_AUDIT @@ -2119,7 +2119,7 @@ diff -up shadow-4.8.1/src/usermod.c.audit-update shadow-4.8.1/src/usermod.c user_newname, (unsigned int) user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -612,8 +612,8 @@ static void new_spent (struct spwd *spen +@@ -578,8 +578,8 @@ static void new_spent (struct spwd *spen if (fflg) { #ifdef WITH_AUDIT @@ -2130,9 +2130,9 @@ diff -up shadow-4.8.1/src/usermod.c.audit-update shadow-4.8.1/src/usermod.c user_newname, (unsigned int) user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -629,8 +629,8 @@ static void new_spent (struct spwd *spen - date_to_str (old_exp, sizeof(old_exp), - user_expire * DAY); +@@ -593,8 +593,8 @@ static void new_spent (struct spwd *spen + date_to_str (sizeof(new_exp), new_exp, user_newexpire * DAY); + date_to_str (sizeof(old_exp), old_exp, user_expire * DAY); #ifdef WITH_AUDIT - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, - "changing expiration date", @@ -2141,7 +2141,7 @@ diff -up shadow-4.8.1/src/usermod.c.audit-update shadow-4.8.1/src/usermod.c user_newname, (unsigned int) user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -713,9 +713,9 @@ static /*@noreturn@*/void fail_exit (int +@@ -677,9 +677,9 @@ static /*@noreturn@*/void fail_exit (int #endif /* ENABLE_SUBIDS */ #ifdef WITH_AUDIT @@ -2154,7 +2154,7 @@ diff -up shadow-4.8.1/src/usermod.c.audit-update shadow-4.8.1/src/usermod.c #endif exit (code); } -@@ -769,9 +769,12 @@ static void update_group (void) +@@ -741,9 +741,12 @@ static void update_group (void) user_newname); changed = true; #ifdef WITH_AUDIT @@ -2170,7 +2170,7 @@ diff -up shadow-4.8.1/src/usermod.c.audit-update shadow-4.8.1/src/usermod.c #endif SYSLOG ((LOG_INFO, "change '%s' to '%s' in group '%s'", -@@ -785,9 +788,11 @@ static void update_group (void) +@@ -757,9 +760,11 @@ static void update_group (void) ngrp->gr_mem = del_list (ngrp->gr_mem, user_name); changed = true; #ifdef WITH_AUDIT @@ -2185,7 +2185,7 @@ diff -up shadow-4.8.1/src/usermod.c.audit-update shadow-4.8.1/src/usermod.c #endif SYSLOG ((LOG_INFO, "delete '%s' from group '%s'", -@@ -800,9 +805,11 @@ static void update_group (void) +@@ -772,9 +777,11 @@ static void update_group (void) ngrp->gr_mem = add_list (ngrp->gr_mem, user_newname); changed = true; #ifdef WITH_AUDIT @@ -2200,7 +2200,7 @@ diff -up shadow-4.8.1/src/usermod.c.audit-update shadow-4.8.1/src/usermod.c #endif SYSLOG ((LOG_INFO, "add '%s' to group '%s'", user_newname, ngrp->gr_name)); -@@ -877,9 +884,10 @@ static void update_gshadow (void) +@@ -859,9 +866,10 @@ static void update_gshadow (void) nsgrp->sg_adm = add_list (nsgrp->sg_adm, user_newname); changed = true; #ifdef WITH_AUDIT @@ -2214,7 +2214,7 @@ diff -up shadow-4.8.1/src/usermod.c.audit-update shadow-4.8.1/src/usermod.c #endif SYSLOG ((LOG_INFO, "change admin '%s' to '%s' in shadow group '%s'", -@@ -899,9 +907,10 @@ static void update_gshadow (void) +@@ -881,9 +889,10 @@ static void update_gshadow (void) user_newname); changed = true; #ifdef WITH_AUDIT @@ -2228,7 +2228,7 @@ diff -up shadow-4.8.1/src/usermod.c.audit-update shadow-4.8.1/src/usermod.c #endif SYSLOG ((LOG_INFO, "change '%s' to '%s' in shadow group '%s'", -@@ -915,9 +924,10 @@ static void update_gshadow (void) +@@ -897,9 +906,10 @@ static void update_gshadow (void) nsgrp->sg_mem = del_list (nsgrp->sg_mem, user_name); changed = true; #ifdef WITH_AUDIT @@ -2242,7 +2242,7 @@ diff -up shadow-4.8.1/src/usermod.c.audit-update shadow-4.8.1/src/usermod.c #endif SYSLOG ((LOG_INFO, "delete '%s' from shadow group '%s'", -@@ -930,9 +940,10 @@ static void update_gshadow (void) +@@ -912,9 +922,10 @@ static void update_gshadow (void) nsgrp->sg_mem = add_list (nsgrp->sg_mem, user_newname); changed = true; #ifdef WITH_AUDIT @@ -2256,7 +2256,7 @@ diff -up shadow-4.8.1/src/usermod.c.audit-update shadow-4.8.1/src/usermod.c #endif SYSLOG ((LOG_INFO, "add '%s' to shadow group '%s'", user_newname, nsgrp->sg_name)); -@@ -1799,8 +1810,8 @@ static void move_home (void) +@@ -1817,8 +1828,8 @@ static void move_home (void) #ifdef WITH_AUDIT if (uflg || gflg) { @@ -2267,7 +2267,7 @@ diff -up shadow-4.8.1/src/usermod.c.audit-update shadow-4.8.1/src/usermod.c user_newname, (unsigned int) user_newid, 1); } #endif -@@ -1818,8 +1829,8 @@ static void move_home (void) +@@ -1836,8 +1847,8 @@ static void move_home (void) fail_exit (E_HOMEDIR); } #ifdef WITH_AUDIT @@ -2278,7 +2278,7 @@ diff -up shadow-4.8.1/src/usermod.c.audit-update shadow-4.8.1/src/usermod.c user_newname, (unsigned int) user_newid, 1); #endif -@@ -1847,9 +1858,9 @@ static void move_home (void) +@@ -1865,9 +1876,9 @@ static void move_home (void) Prog, prefix_user_home); } #ifdef WITH_AUDIT @@ -2290,7 +2290,7 @@ diff -up shadow-4.8.1/src/usermod.c.audit-update shadow-4.8.1/src/usermod.c user_newname, (unsigned int) user_newid, 1); -@@ -2071,8 +2082,8 @@ static void move_mailbox (void) +@@ -2085,8 +2096,8 @@ static void move_mailbox (void) } #ifdef WITH_AUDIT else { @@ -2301,7 +2301,7 @@ diff -up shadow-4.8.1/src/usermod.c.audit-update shadow-4.8.1/src/usermod.c user_newname, (unsigned int) user_newid, 1); } #endif -@@ -2098,8 +2109,8 @@ static void move_mailbox (void) +@@ -2112,8 +2123,8 @@ static void move_mailbox (void) } #ifdef WITH_AUDIT else { @@ -2312,7 +2312,7 @@ diff -up shadow-4.8.1/src/usermod.c.audit-update shadow-4.8.1/src/usermod.c user_newname, (unsigned int) user_newid, 1); } #endif -@@ -2294,8 +2305,8 @@ int main (int argc, char **argv) +@@ -2310,8 +2321,8 @@ int main (int argc, char **argv) _("%s: warning: the user name %s to %s SELinux user mapping failed.\n"), Prog, user_name, user_selinux); #ifdef WITH_AUDIT @@ -2323,7 +2323,7 @@ diff -up shadow-4.8.1/src/usermod.c.audit-update shadow-4.8.1/src/usermod.c user_name, (unsigned int) user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -2307,8 +2318,8 @@ int main (int argc, char **argv) +@@ -2323,8 +2334,8 @@ int main (int argc, char **argv) _("%s: warning: the user name %s to SELinux user mapping removal failed.\n"), Prog, user_name); #ifdef WITH_AUDIT @@ -2334,7 +2334,7 @@ diff -up shadow-4.8.1/src/usermod.c.audit-update shadow-4.8.1/src/usermod.c user_name, (unsigned int) user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -2349,8 +2360,8 @@ int main (int argc, char **argv) +@@ -2365,8 +2376,8 @@ int main (int argc, char **argv) */ #ifdef WITH_AUDIT if (uflg || gflg) { diff --git a/shadow-4.11.1-null-tm.patch b/shadow-4.11.1-null-tm.patch new file mode 100644 index 0000000..b8d5fc8 --- /dev/null +++ b/shadow-4.11.1-null-tm.patch @@ -0,0 +1,22 @@ +diff -up shadow-4.11.1/src/chage.c.null-tm shadow-4.11.1/src/chage.c +diff -up shadow-4.11.1/src/lastlog.c.null-tm shadow-4.11.1/src/lastlog.c +--- shadow-4.11.1/src/lastlog.c.null-tm 2022-01-03 15:31:56.348555620 +0100 ++++ shadow-4.11.1/src/lastlog.c 2022-01-03 15:38:41.262229024 +0100 +@@ -151,9 +151,12 @@ static void print_one (/*@null@*/const s + + ll_time = ll.ll_time; + tm = localtime (&ll_time); +- strftime (ptime, sizeof (ptime), "%a %b %e %H:%M:%S %z %Y", tm); +- cp = ptime; +- ++ if (tm == NULL) { ++ cp = "(unknown)"; ++ } else { ++ strftime (ptime, sizeof (ptime), "%a %b %e %H:%M:%S %z %Y", tm); ++ cp = ptime; ++ } + if (ll.ll_time == (time_t) 0) { + cp = _("**Never logged in**\0"); + } +diff -up shadow-4.11.1/src/passwd.c.null-tm shadow-4.11.1/src/passwd.c +diff -up shadow-4.11.1/src/usermod.c.null-tm shadow-4.11.1/src/usermod.c diff --git a/shadow-4.9-redhat.patch b/shadow-4.11.1-redhat.patch similarity index 70% rename from shadow-4.9-redhat.patch rename to shadow-4.11.1-redhat.patch index 9dfb3e8..e5e6c60 100644 --- a/shadow-4.9-redhat.patch +++ b/shadow-4.11.1-redhat.patch @@ -1,7 +1,7 @@ -diff -up shadow-4.9/src/useradd.c.redhat shadow-4.9/src/useradd.c ---- shadow-4.9/src/useradd.c.redhat 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/src/useradd.c 2021-08-02 11:45:11.942867250 +0200 -@@ -104,7 +104,7 @@ FILE *shadow_logfd = NULL; +diff -up shadow-4.11.1/src/useradd.c.redhat shadow-4.11.1/src/useradd.c +--- shadow-4.11.1/src/useradd.c.redhat 2022-01-03 01:46:53.000000000 +0100 ++++ shadow-4.11.1/src/useradd.c 2022-01-03 14:53:12.988484829 +0100 +@@ -82,7 +82,7 @@ const char *Prog; static gid_t def_group = 1000; static const char *def_gname = "other"; static const char *def_home = "/home"; @@ -9,8 +9,8 @@ diff -up shadow-4.9/src/useradd.c.redhat shadow-4.9/src/useradd.c +static const char *def_shell = "/sbin/nologin"; static const char *def_template = SKEL_DIR; static const char *def_create_mail_spool = "yes"; - -@@ -114,7 +114,7 @@ static const char *def_expire = ""; + static const char *def_log_init = "yes"; +@@ -93,7 +93,7 @@ static const char *def_expire = ""; #define VALID(s) (strcspn (s, ":\n") == strlen (s)) static const char *user_name = ""; @@ -19,7 +19,7 @@ diff -up shadow-4.9/src/useradd.c.redhat shadow-4.9/src/useradd.c static uid_t user_id; static gid_t user_gid; static const char *user_comment = ""; -@@ -1204,9 +1204,9 @@ static void process_flags (int argc, cha +@@ -1219,9 +1219,9 @@ static void process_flags (int argc, cha }; while ((c = getopt_long (argc, argv, #ifdef WITH_SELINUX @@ -31,7 +31,7 @@ diff -up shadow-4.9/src/useradd.c.redhat shadow-4.9/src/useradd.c #endif /* !WITH_SELINUX */ long_options, NULL)) != -1) { switch (c) { -@@ -1363,6 +1363,7 @@ static void process_flags (int argc, cha +@@ -1378,6 +1378,7 @@ static void process_flags (int argc, cha case 'M': Mflg = true; break; diff --git a/shadow-4.9-getsubids.patch b/shadow-4.9-getsubids.patch deleted file mode 100644 index b9f2449..0000000 --- a/shadow-4.9-getsubids.patch +++ /dev/null @@ -1,245 +0,0 @@ -diff -up shadow-4.9/man/getsubids.1.xml.getsubids shadow-4.9/man/getsubids.1.xml ---- shadow-4.9/man/getsubids.1.xml.getsubids 2021-11-18 16:27:33.951053120 +0100 -+++ shadow-4.9/man/getsubids.1.xml 2021-11-18 16:27:33.951053120 +0100 -@@ -0,0 +1,141 @@ -+ -+ -+ -+]> -+ -+ -+ -+ -+ Iker -+ Pedrosa -+ Creation, 2021 -+ -+ -+ -+ getsubids -+ 1 -+ User Commands -+ shadow-utils -+ &SHADOW_UTILS_VERSION; -+ -+ -+ getsubids -+ get the subordinate id ranges for a user -+ -+ -+ -+ -+ getsubids -+ -+ options -+ -+ -+ USER -+ -+ -+ -+ -+ -+ DESCRIPTION -+ -+ The getsubids command lists the subordinate user ID -+ ranges for a given user. The subordinate group IDs can be listed using -+ the option. -+ -+ -+ -+ -+ OPTIONS -+ -+ The options which apply to the getsubids command are: -+ -+ -+ -+ -+ -+ -+ -+ -+ List the subordinate group ID ranges. -+ -+ -+ -+ -+ -+ -+ -+ EXAMPLE -+ -+ For example, to obtain the subordinate UIDs of the testuser: -+ -+ -+ -+$ getsubids testuser -+0: testuser 100000 65536 -+ -+ -+ -+ This command output provides (in order from left to right) the list -+ index, username, UID range start, and number of UIDs in range. -+ -+ -+ -+ -+ SEE ALSO -+ -+ -+ login.defs5 -+ , -+ -+ newgidmap1 -+ , -+ -+ newuidmap1 -+ , -+ -+ subgid5 -+ , -+ -+ subuid5 -+ , -+ -+ useradd8 -+ , -+ -+ userdel8 -+ . -+ -+ usermod8 -+ , -+ -+ -+ -diff -up shadow-4.9/man/Makefile.am.getsubids shadow-4.9/man/Makefile.am ---- shadow-4.9/man/Makefile.am.getsubids 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/man/Makefile.am 2021-11-18 16:27:33.951053120 +0100 -@@ -62,6 +62,7 @@ man_MANS += $(man_nopam) - endif - - man_subids = \ -+ man1/getsubids.1 \ - man1/newgidmap.1 \ - man1/newuidmap.1 \ - man5/subgid.5 \ -@@ -80,6 +81,7 @@ man_XMANS = \ - expiry.1.xml \ - faillog.5.xml \ - faillog.8.xml \ -+ getsubids.1.xml \ - gpasswd.1.xml \ - groupadd.8.xml \ - groupdel.8.xml \ -diff -up shadow-4.9/src/getsubids.c.getsubids shadow-4.9/src/getsubids.c ---- shadow-4.9/src/getsubids.c.getsubids 2021-11-18 16:27:33.951053120 +0100 -+++ shadow-4.9/src/getsubids.c 2021-11-18 16:27:33.951053120 +0100 -@@ -0,0 +1,46 @@ -+#include -+#include -+#include -+#include "subid.h" -+#include "prototypes.h" -+ -+const char *Prog; -+FILE *shadow_logfd = NULL; -+ -+void usage(void) -+{ -+ fprintf(stderr, "Usage: %s [-g] user\n", Prog); -+ fprintf(stderr, " list subuid ranges for user\n"); -+ fprintf(stderr, " pass -g to list subgid ranges\n"); -+ exit(EXIT_FAILURE); -+} -+ -+int main(int argc, char *argv[]) -+{ -+ int i, count=0; -+ struct subid_range *ranges; -+ const char *owner; -+ -+ Prog = Basename (argv[0]); -+ shadow_logfd = stderr; -+ if (argc < 2) -+ usage(); -+ owner = argv[1]; -+ if (argc == 3 && strcmp(argv[1], "-g") == 0) { -+ owner = argv[2]; -+ count = get_subgid_ranges(owner, &ranges); -+ } else if (argc == 2 && strcmp(argv[1], "-h") == 0) { -+ usage(); -+ } else { -+ count = get_subuid_ranges(owner, &ranges); -+ } -+ if (!ranges) { -+ fprintf(stderr, "Error fetching ranges\n"); -+ exit(1); -+ } -+ for (i = 0; i < count; i++) { -+ printf("%d: %s %lu %lu\n", i, owner, -+ ranges[i].start, ranges[i].count); -+ } -+ return 0; -+} -diff -up shadow-4.9/src/list_subid_ranges.c.getsubids shadow-4.9/src/list_subid_ranges.c -diff -up shadow-4.9/src/Makefile.am.getsubids shadow-4.9/src/Makefile.am ---- shadow-4.9/src/Makefile.am.getsubids 2021-11-18 16:27:33.943053061 +0100 -+++ shadow-4.9/src/Makefile.am 2021-11-18 16:28:03.647272392 +0100 -@@ -157,8 +157,8 @@ if FCAPS - setcap cap_setgid+ep $(DESTDIR)$(ubindir)/newgidmap - endif - --noinst_PROGRAMS += list_subid_ranges \ -- get_subid_owners \ -+bin_PROGRAMS += getsubids -+noinst_PROGRAMS += get_subid_owners \ - new_subid_range \ - free_subid_range \ - check_subid_range -@@ -174,13 +174,13 @@ MISCLIBS = \ - $(LIBCRYPT) \ - $(LIBTCB) - --list_subid_ranges_LDADD = \ -+getsubids_LDADD = \ - $(top_builddir)/lib/libshadow.la \ - $(top_builddir)/libmisc/libmisc.la \ - $(top_builddir)/libsubid/libsubid.la \ - $(MISCLIBS) -ldl - --list_subid_ranges_CPPFLAGS = \ -+getsubids_CPPFLAGS = \ - -I$(top_srcdir)/lib \ - -I$(top_srcdir)/libmisc \ - -I$(top_srcdir)/libsubid diff --git a/shadow-4.9-groupdel-fix-sigsegv-when-passwd-does-not-exist.patch b/shadow-4.9-groupdel-fix-sigsegv-when-passwd-does-not-exist.patch deleted file mode 100644 index 658156a..0000000 --- a/shadow-4.9-groupdel-fix-sigsegv-when-passwd-does-not-exist.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff -up shadow-4.9/libmisc/prefix_flag.c.groupdel-fix-sigsegv-when-passwd-does-not-exist shadow-4.9/libmisc/prefix_flag.c ---- shadow-4.9/libmisc/prefix_flag.c.groupdel-fix-sigsegv-when-passwd-does-not-exist 2021-11-19 09:21:36.997091941 +0100 -+++ shadow-4.9/libmisc/prefix_flag.c 2021-11-19 09:22:19.001341010 +0100 -@@ -288,6 +288,9 @@ extern struct passwd* prefix_getpwent() - if(!passwd_db_file) { - return getpwent(); - } -+ if (!fp_pwent) { -+ return NULL; -+ } - return fgetpwent(fp_pwent); - } - extern void prefix_endpwent() diff --git a/shadow-4.9-libmisc-fix-default-value-in-SHA_get_salt_rounds.patch b/shadow-4.9-libmisc-fix-default-value-in-SHA_get_salt_rounds.patch deleted file mode 100644 index 5eaaec9..0000000 --- a/shadow-4.9-libmisc-fix-default-value-in-SHA_get_salt_rounds.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 234e8fa7b134d1ebabfdad980a3ae5b63c046c62 Mon Sep 17 00:00:00 2001 -From: Mike Gilbert -Date: Sat, 14 Aug 2021 13:24:34 -0400 -Subject: [PATCH] libmisc: fix default value in SHA_get_salt_rounds() - -If SHA_CRYPT_MIN_ROUNDS and SHA_CRYPT_MAX_ROUNDS are both unspecified, -use SHA_ROUNDS_DEFAULT. - -Previously, the code fell through, calling shadow_random(-1, -1). This -ultimately set rounds = (unsigned long) -1, which ends up being a very -large number! This then got capped to SHA_ROUNDS_MAX later in the -function. - -The new behavior matches BCRYPT_get_salt_rounds(). - -Bug: https://bugs.gentoo.org/808195 -Fixes: https://github.com/shadow-maint/shadow/issues/393 ---- - libmisc/salt.c | 21 +++++++++++---------- - 1 file changed, 11 insertions(+), 10 deletions(-) - -diff --git a/libmisc/salt.c b/libmisc/salt.c -index 91d528fd..30eefb9c 100644 ---- a/libmisc/salt.c -+++ b/libmisc/salt.c -@@ -223,20 +223,21 @@ static /*@observer@*/const unsigned long SHA_get_salt_rounds (/*@null@*/int *pre - if ((-1 == min_rounds) && (-1 == max_rounds)) { - rounds = SHA_ROUNDS_DEFAULT; - } -+ else { -+ if (-1 == min_rounds) { -+ min_rounds = max_rounds; -+ } - -- if (-1 == min_rounds) { -- min_rounds = max_rounds; -- } -+ if (-1 == max_rounds) { -+ max_rounds = min_rounds; -+ } - -- if (-1 == max_rounds) { -- max_rounds = min_rounds; -- } -+ if (min_rounds > max_rounds) { -+ max_rounds = min_rounds; -+ } - -- if (min_rounds > max_rounds) { -- max_rounds = min_rounds; -+ rounds = (unsigned long) shadow_random (min_rounds, max_rounds); - } -- -- rounds = (unsigned long) shadow_random (min_rounds, max_rounds); - } else if (0 == *prefered_rounds) { - rounds = SHA_ROUNDS_DEFAULT; - } else { --- -2.31.1 - diff --git a/shadow-4.9-make-shadow-logfd-and-prog-not-extern.patch b/shadow-4.9-make-shadow-logfd-and-prog-not-extern.patch deleted file mode 100644 index d0b7059..0000000 --- a/shadow-4.9-make-shadow-logfd-and-prog-not-extern.patch +++ /dev/null @@ -1,2497 +0,0 @@ -diff -up shadow-4.9/lib/commonio.c.debug1 shadow-4.9/lib/commonio.c ---- shadow-4.9/lib/commonio.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/lib/commonio.c 2022-01-10 10:45:52.202132937 +0100 -@@ -51,6 +51,7 @@ - #endif /* WITH_TCB */ - #include "prototypes.h" - #include "commonio.h" -+#include "shadowlog_internal.h" - - /* local function prototypes */ - static int lrename (const char *, const char *); -diff -up shadow-4.9/lib/encrypt.c.debug1 shadow-4.9/lib/encrypt.c ---- shadow-4.9/lib/encrypt.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/lib/encrypt.c 2022-01-10 10:45:52.202132937 +0100 -@@ -39,6 +39,7 @@ - - #include "prototypes.h" - #include "defines.h" -+#include "shadowlog_internal.h" - - /*@exposed@*//*@null@*/char *pw_encrypt (const char *clear, const char *salt) - { -diff -up shadow-4.9/lib/getdef.c.debug1 shadow-4.9/lib/getdef.c ---- shadow-4.9/lib/getdef.c.debug1 2022-01-10 10:45:52.191132858 +0100 -+++ shadow-4.9/lib/getdef.c 2022-01-10 10:45:52.202132937 +0100 -@@ -44,6 +44,7 @@ - #include - #endif - #include "getdef.h" -+#include "shadowlog_internal.h" - /* - * A configuration item definition. - */ -diff -up shadow-4.9/lib/Makefile.am.debug1 shadow-4.9/lib/Makefile.am ---- shadow-4.9/lib/Makefile.am.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/lib/Makefile.am 2022-01-10 10:45:52.202132937 +0100 -@@ -34,6 +34,8 @@ libshadow_la_SOURCES = \ - nss.c \ - nscd.c \ - nscd.h \ -+ shadowlog.c \ -+ shadowlog.h \ - sssd.c \ - sssd.h \ - pam_defs.h \ -diff -up shadow-4.9/libmisc/addgrps.c.debug1 shadow-4.9/libmisc/addgrps.c ---- shadow-4.9/libmisc/addgrps.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/libmisc/addgrps.c 2022-01-10 10:45:52.203132944 +0100 -@@ -40,6 +40,7 @@ - #include - #include - #include -+#include "shadowlog.h" - - #ident "$Id$" - -@@ -58,6 +59,7 @@ int add_groups (const char *list) - char *token; - char buf[1024]; - int ret; -+ FILE *shadow_logfd = log_get_logfd(); - - if (strlen (list) >= sizeof (buf)) { - errno = EINVAL; -diff -up shadow-4.9/libmisc/audit_help.c.debug1 shadow-4.9/libmisc/audit_help.c ---- shadow-4.9/libmisc/audit_help.c.debug1 2022-01-10 10:45:52.184132808 +0100 -+++ shadow-4.9/libmisc/audit_help.c 2022-01-10 10:45:52.203132944 +0100 -@@ -45,6 +45,7 @@ - #include - #include - #include "prototypes.h" -+#include "shadowlog.h" - int audit_fd; - - void audit_help_open (void) -@@ -59,7 +60,7 @@ void audit_help_open (void) - return; - } - (void) fputs (_("Cannot open audit interface - aborting.\n"), -- shadow_logfd); -+ log_get_logfd()); - exit (EXIT_FAILURE); - } - } -diff -up shadow-4.9/libmisc/chowntty.c.debug1 shadow-4.9/libmisc/chowntty.c ---- shadow-4.9/libmisc/chowntty.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/libmisc/chowntty.c 2022-01-10 10:45:52.203132944 +0100 -@@ -43,6 +43,7 @@ - #include "defines.h" - #include - #include "getdef.h" -+#include "shadowlog.h" - - /* - * chown_tty() sets the login tty to be owned by the new user ID -@@ -75,6 +76,7 @@ void chown_tty (const struct passwd *inf - if ( (fchown (STDIN_FILENO, info->pw_uid, gid) != 0) - || (fchmod (STDIN_FILENO, (mode_t)getdef_num ("TTYPERM", 0600)) != 0)) { - int err = errno; -+ FILE *shadow_logfd = log_get_logfd(); - - fprintf (shadow_logfd, - _("Unable to change owner or mode of tty stdin: %s"), -diff -up shadow-4.9/libmisc/cleanup_group.c.debug1 shadow-4.9/libmisc/cleanup_group.c ---- shadow-4.9/libmisc/cleanup_group.c.debug1 2022-01-10 10:45:52.184132808 +0100 -+++ shadow-4.9/libmisc/cleanup_group.c 2022-01-10 10:47:02.241632844 +0100 -@@ -36,6 +36,7 @@ - #include "groupio.h" - #include "sgroupio.h" - #include "prototypes.h" -+#include "shadowlog.h" - - /* - * cleanup_report_add_group - Report failure to add a group to the system -@@ -48,7 +49,7 @@ void cleanup_report_add_group (void *gro - - SYSLOG ((LOG_ERR, "failed to add group %s", name)); - #ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_GROUP, Prog, -+ audit_logger (AUDIT_ADD_GROUP, log_get_progname(), - "", - name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); -@@ -66,7 +67,7 @@ void cleanup_report_del_group (void *gro - - SYSLOG ((LOG_ERR, "failed to remove group %s", name)); - #ifdef WITH_AUDIT -- audit_logger (AUDIT_DEL_GROUP, Prog, -+ audit_logger (AUDIT_DEL_GROUP, log_get_progname(), - "", - name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); -@@ -83,7 +84,7 @@ void cleanup_report_mod_group (void *cle - gr_dbname (), - info->action)); - #ifdef WITH_AUDIT -- audit_logger (AUDIT_GRP_MGMT, Prog, -+ audit_logger (AUDIT_GRP_MGMT, log_get_progname(), - info->audit_msg, - info->name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); -@@ -101,7 +102,7 @@ void cleanup_report_mod_gshadow (void *c - sgr_dbname (), - info->action)); - #ifdef WITH_AUDIT -- audit_logger (AUDIT_GRP_MGMT, Prog, -+ audit_logger (AUDIT_GRP_MGMT, log_get_progname(), - info->audit_msg, - info->name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); -@@ -121,7 +122,7 @@ void cleanup_report_add_group_group (voi - - SYSLOG ((LOG_ERR, "failed to add group %s to %s", name, gr_dbname ())); - #ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_GROUP, Prog, -+ audit_logger (AUDIT_ADD_GROUP, log_get_progname(), - "adding-group", - name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); -@@ -141,7 +142,7 @@ void cleanup_report_add_group_gshadow (v - - SYSLOG ((LOG_ERR, "failed to add group %s to %s", name, sgr_dbname ())); - #ifdef WITH_AUDIT -- audit_logger (AUDIT_GRP_MGMT, Prog, -+ audit_logger (AUDIT_GRP_MGMT, log_get_progname(), - "adding-shadow-group", - name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); -@@ -164,7 +165,7 @@ void cleanup_report_del_group_group (voi - "failed to remove group %s from %s", - name, gr_dbname ())); - #ifdef WITH_AUDIT -- audit_logger (AUDIT_DEL_GROUP, Prog, -+ audit_logger (AUDIT_DEL_GROUP, log_get_progname(), - "removing-group", - name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); -@@ -187,7 +188,7 @@ void cleanup_report_del_group_gshadow (v - "failed to remove group %s from %s", - name, sgr_dbname ())); - #ifdef WITH_AUDIT -- audit_logger (AUDIT_GRP_MGMT, Prog, -+ audit_logger (AUDIT_GRP_MGMT, log_get_progname(), - "removing-shadow-group", - name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); -@@ -203,9 +204,9 @@ void cleanup_report_del_group_gshadow (v - void cleanup_unlock_group (unused void *arg) - { - if (gr_unlock () == 0) { -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: failed to unlock %s\n"), -- Prog, gr_dbname ()); -+ log_get_progname(), gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); - #ifdef WITH_AUDIT - audit_logger_message ("unlocking-group", -@@ -223,9 +224,9 @@ void cleanup_unlock_group (unused void * - void cleanup_unlock_gshadow (unused void *arg) - { - if (sgr_unlock () == 0) { -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: failed to unlock %s\n"), -- Prog, sgr_dbname ()); -+ log_get_progname(), sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - #ifdef WITH_AUDIT - audit_logger_message ("unlocking-gshadow", -diff -up shadow-4.9/libmisc/cleanup_user.c.debug1 shadow-4.9/libmisc/cleanup_user.c ---- shadow-4.9/libmisc/cleanup_user.c.debug1 2022-01-10 10:45:52.184132808 +0100 -+++ shadow-4.9/libmisc/cleanup_user.c 2022-01-10 10:47:49.539970421 +0100 -@@ -36,6 +36,7 @@ - #include "pwio.h" - #include "shadowio.h" - #include "prototypes.h" -+#include "shadowlog.h" - - /* - * cleanup_report_add_user - Report failure to add an user to the system -@@ -48,7 +49,7 @@ void cleanup_report_add_user (void *user - - SYSLOG ((LOG_ERR, "failed to add user %s", name)); - #ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_USER, Prog, -+ audit_logger (AUDIT_ADD_USER, log_get_progname(), - "", - name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); -@@ -65,7 +66,7 @@ void cleanup_report_mod_passwd (void *cl - pw_dbname (), - info->action)); - #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_MGMT, Prog, -+ audit_logger (AUDIT_USER_MGMT, log_get_progname(), - info->audit_msg, - info->name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); -@@ -85,7 +86,7 @@ void cleanup_report_add_user_passwd (voi - - SYSLOG ((LOG_ERR, "failed to add user %s to %s", name, pw_dbname ())); - #ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_USER, Prog, -+ audit_logger (AUDIT_ADD_USER, log_get_progname(), - "adding-user", - name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); -@@ -105,7 +106,7 @@ void cleanup_report_add_user_shadow (voi - - SYSLOG ((LOG_ERR, "failed to add user %s to %s", name, spw_dbname ())); - #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_MGMT, Prog, -+ audit_logger (AUDIT_USER_MGMT, log_get_progname(), - "adding-shadow-user", - name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); -@@ -120,9 +121,9 @@ void cleanup_report_add_user_shadow (voi - void cleanup_unlock_passwd (unused void *arg) - { - if (pw_unlock () == 0) { -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: failed to unlock %s\n"), -- Prog, pw_dbname ()); -+ log_get_progname(), pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - #ifdef WITH_AUDIT - audit_logger_message ("unlocking-passwd", -@@ -139,9 +140,9 @@ void cleanup_unlock_passwd (unused void - void cleanup_unlock_shadow (unused void *arg) - { - if (spw_unlock () == 0) { -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: failed to unlock %s\n"), -- Prog, spw_dbname ()); -+ log_get_progname(), spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - #ifdef WITH_AUDIT - audit_logger_message ("unlocking-shadow", -diff -up shadow-4.9/libmisc/copydir.c.debug1 shadow-4.9/libmisc/copydir.c ---- shadow-4.9/libmisc/copydir.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/libmisc/copydir.c 2022-01-10 10:48:02.158060482 +0100 -@@ -55,6 +55,7 @@ - #ifdef WITH_ATTR - #include - #endif /* WITH_ATTR */ -+#include "shadowlog.h" - - - static /*@null@*/const char *src_orig; -@@ -116,6 +117,7 @@ static int fchown_if_needed (int fdst, c - static void error_acl (struct error_context *ctx, const char *fmt, ...) - { - va_list ap; -+ FILE *shadow_logfd = log_get_logfd(); - - /* ignore the case when destination does not support ACLs - * or extended attributes */ -@@ -125,7 +127,7 @@ static void error_acl (struct error_cont - } - - va_start (ap, fmt); -- (void) fprintf (shadow_logfd, _("%s: "), Prog); -+ (void) fprintf (shadow_logfd, _("%s: "), log_get_progname()); - if (vfprintf (shadow_logfd, fmt, ap) != 0) { - (void) fputs (_(": "), shadow_logfd); - } -@@ -248,9 +250,9 @@ int copy_tree (const char *src_root, con - } - - if (!S_ISDIR (sb.st_mode)) { -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - "%s: %s is not a directory", -- Prog, src_root); -+ log_get_progname(), src_root); - return -1; - } - -diff -up shadow-4.9/libmisc/env.c.debug1 shadow-4.9/libmisc/env.c ---- shadow-4.9/libmisc/env.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/libmisc/env.c 2022-01-10 10:45:52.203132944 +0100 -@@ -40,6 +40,7 @@ - #include - #include "prototypes.h" - #include "defines.h" -+#include "shadowlog.h" - /* - * NEWENVP_STEP must be a power of two. This is the number - * of (char *) pointers to allocate at a time, to avoid using -@@ -171,7 +172,7 @@ void addenv (const char *string, /*@null - } - newenvp = __newenvp; - } else { -- (void) fputs (_("Environment overflow\n"), shadow_logfd); -+ (void) fputs (_("Environment overflow\n"), log_get_logfd()); - newenvc--; - free (newenvp[newenvc]); - } -diff -up shadow-4.9/libmisc/find_new_gid.c.debug1 shadow-4.9/libmisc/find_new_gid.c ---- shadow-4.9/libmisc/find_new_gid.c.debug1 2022-01-10 10:45:52.191132858 +0100 -+++ shadow-4.9/libmisc/find_new_gid.c 2022-01-10 10:45:52.203132944 +0100 -@@ -38,6 +38,7 @@ - #include "prototypes.h" - #include "groupio.h" - #include "getdef.h" -+#include "shadowlog.h" - - /* - * get_ranges - Get the minimum and maximum ID ranges for the search -@@ -74,10 +75,10 @@ static int get_ranges (bool sys_group, g - - /* Check that the ranges make sense */ - if (*max_id < *min_id) { -- (void) fprintf (shadow_logfd, -+ (void) fprintf (log_get_logfd(), - _("%s: Invalid configuration: SYS_GID_MIN (%lu), " - "GID_MIN (%lu), SYS_GID_MAX (%lu)\n"), -- Prog, (unsigned long) *min_id, -+ log_get_progname(), (unsigned long) *min_id, - getdef_ulong ("GID_MIN", 1000UL), - (unsigned long) *max_id); - return EINVAL; -@@ -104,10 +105,10 @@ static int get_ranges (bool sys_group, g - - /* Check that the ranges make sense */ - if (*max_id < *min_id) { -- (void) fprintf (shadow_logfd, -+ (void) fprintf (log_get_logfd(), - _("%s: Invalid configuration: GID_MIN (%lu), " - "GID_MAX (%lu)\n"), -- Prog, (unsigned long) *min_id, -+ log_get_progname(), (unsigned long) *min_id, - (unsigned long) *max_id); - return EINVAL; - } -@@ -220,10 +221,10 @@ int find_new_gid (bool sys_group, - * more likely to want to stop and address the - * issue. - */ -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: Encountered error attempting to use " - "preferred GID: %s\n"), -- Prog, strerror (result)); -+ log_get_progname(), strerror (result)); - return -1; - } - } -@@ -250,9 +251,9 @@ int find_new_gid (bool sys_group, - /* Create an array to hold all of the discovered GIDs */ - used_gids = malloc (sizeof (bool) * (gid_max +1)); - if (NULL == used_gids) { -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: failed to allocate memory: %s\n"), -- Prog, strerror (errno)); -+ log_get_progname(), strerror (errno)); - return -1; - } - memset (used_gids, false, sizeof (bool) * (gid_max + 1)); -@@ -330,10 +331,10 @@ int find_new_gid (bool sys_group, - * - */ - if (!nospam) { -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: Can't get unique system GID (%s). " - "Suppressing additional messages.\n"), -- Prog, strerror (result)); -+ log_get_progname(), strerror (result)); - SYSLOG ((LOG_ERR, - "Error checking available GIDs: %s", - strerror (result))); -@@ -373,10 +374,10 @@ int find_new_gid (bool sys_group, - * - */ - if (!nospam) { -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: Can't get unique system GID (%s). " - "Suppressing additional messages.\n"), -- Prog, strerror (result)); -+ log_get_progname(), strerror (result)); - SYSLOG ((LOG_ERR, - "Error checking available GIDs: %s", - strerror (result))); -@@ -433,10 +434,10 @@ int find_new_gid (bool sys_group, - * - */ - if (!nospam) { -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: Can't get unique GID (%s). " - "Suppressing additional messages.\n"), -- Prog, strerror (result)); -+ log_get_progname(), strerror (result)); - SYSLOG ((LOG_ERR, - "Error checking available GIDs: %s", - strerror (result))); -@@ -476,10 +477,10 @@ int find_new_gid (bool sys_group, - * - */ - if (!nospam) { -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: Can't get unique GID (%s). " - "Suppressing additional messages.\n"), -- Prog, strerror (result)); -+ log_get_progname(), strerror (result)); - SYSLOG ((LOG_ERR, - "Error checking available GIDs: %s", - strerror (result))); -@@ -495,9 +496,9 @@ int find_new_gid (bool sys_group, - } - - /* The code reached here and found no available IDs in the range */ -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: Can't get unique GID (no more available GIDs)\n"), -- Prog); -+ log_get_progname()); - SYSLOG ((LOG_WARN, "no more available GIDs on the system")); - free (used_gids); - return -1; -diff -up shadow-4.9/libmisc/find_new_sub_gids.c.debug1 shadow-4.9/libmisc/find_new_sub_gids.c ---- shadow-4.9/libmisc/find_new_sub_gids.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/libmisc/find_new_sub_gids.c 2022-01-10 10:45:52.203132944 +0100 -@@ -37,6 +37,7 @@ - #include "prototypes.h" - #include "subordinateio.h" - #include "getdef.h" -+#include "shadowlog.h" - - /* - * find_new_sub_gids - Find a new unused range of GIDs. -@@ -60,18 +61,18 @@ int find_new_sub_gids (gid_t *range_star - count = getdef_ulong ("SUB_GID_COUNT", 65536); - - if (min > max || count >= max || (min + count - 1) > max) { -- (void) fprintf (shadow_logfd, -+ (void) fprintf (log_get_logfd(), - _("%s: Invalid configuration: SUB_GID_MIN (%lu)," - " SUB_GID_MAX (%lu), SUB_GID_COUNT (%lu)\n"), -- Prog, min, max, count); -+ log_get_progname(), min, max, count); - return -1; - } - - start = sub_gid_find_free_range(min, max, count); - if (start == (gid_t)-1) { -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: Can't get unique subordinate GID range\n"), -- Prog); -+ log_get_progname()); - SYSLOG ((LOG_WARN, "no more available subordinate GIDs on the system")); - return -1; - } -diff -up shadow-4.9/libmisc/find_new_sub_uids.c.debug1 shadow-4.9/libmisc/find_new_sub_uids.c ---- shadow-4.9/libmisc/find_new_sub_uids.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/libmisc/find_new_sub_uids.c 2022-01-10 10:45:52.203132944 +0100 -@@ -37,6 +37,7 @@ - #include "prototypes.h" - #include "subordinateio.h" - #include "getdef.h" -+#include "shadowlog.h" - - /* - * find_new_sub_uids - Find a new unused range of UIDs. -@@ -60,18 +61,18 @@ int find_new_sub_uids (uid_t *range_star - count = getdef_ulong ("SUB_UID_COUNT", 65536); - - if (min > max || count >= max || (min + count - 1) > max) { -- (void) fprintf (shadow_logfd, -+ (void) fprintf (log_get_logfd(), - _("%s: Invalid configuration: SUB_UID_MIN (%lu)," - " SUB_UID_MAX (%lu), SUB_UID_COUNT (%lu)\n"), -- Prog, min, max, count); -+ log_get_progname(), min, max, count); - return -1; - } - - start = sub_uid_find_free_range(min, max, count); - if (start == (uid_t)-1) { -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: Can't get unique subordinate UID range\n"), -- Prog); -+ log_get_progname()); - SYSLOG ((LOG_WARN, "no more available subordinate UIDs on the system")); - return -1; - } -diff -up shadow-4.9/libmisc/find_new_uid.c.debug1 shadow-4.9/libmisc/find_new_uid.c ---- shadow-4.9/libmisc/find_new_uid.c.debug1 2022-01-10 10:45:52.191132858 +0100 -+++ shadow-4.9/libmisc/find_new_uid.c 2022-01-10 10:45:52.204132951 +0100 -@@ -38,6 +38,7 @@ - #include "prototypes.h" - #include "pwio.h" - #include "getdef.h" -+#include "shadowlog.h" - - /* - * get_ranges - Get the minimum and maximum ID ranges for the search -@@ -74,10 +75,10 @@ static int get_ranges (bool sys_user, ui - - /* Check that the ranges make sense */ - if (*max_id < *min_id) { -- (void) fprintf (shadow_logfd, -+ (void) fprintf (log_get_logfd(), - _("%s: Invalid configuration: SYS_UID_MIN (%lu), " - "UID_MIN (%lu), SYS_UID_MAX (%lu)\n"), -- Prog, (unsigned long) *min_id, -+ log_get_progname(), (unsigned long) *min_id, - getdef_ulong ("UID_MIN", 1000UL), - (unsigned long) *max_id); - return EINVAL; -@@ -104,10 +105,10 @@ static int get_ranges (bool sys_user, ui - - /* Check that the ranges make sense */ - if (*max_id < *min_id) { -- (void) fprintf (shadow_logfd, -+ (void) fprintf (log_get_logfd(), - _("%s: Invalid configuration: UID_MIN (%lu), " - "UID_MAX (%lu)\n"), -- Prog, (unsigned long) *min_id, -+ log_get_progname(), (unsigned long) *min_id, - (unsigned long) *max_id); - return EINVAL; - } -@@ -220,10 +221,10 @@ int find_new_uid(bool sys_user, - * more likely to want to stop and address the - * issue. - */ -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: Encountered error attempting to use " - "preferred UID: %s\n"), -- Prog, strerror (result)); -+ log_get_progname(), strerror (result)); - return -1; - } - } -@@ -250,9 +251,9 @@ int find_new_uid(bool sys_user, - /* Create an array to hold all of the discovered UIDs */ - used_uids = malloc (sizeof (bool) * (uid_max +1)); - if (NULL == used_uids) { -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: failed to allocate memory: %s\n"), -- Prog, strerror (errno)); -+ log_get_progname(), strerror (errno)); - return -1; - } - memset (used_uids, false, sizeof (bool) * (uid_max + 1)); -@@ -330,10 +331,10 @@ int find_new_uid(bool sys_user, - * - */ - if (!nospam) { -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: Can't get unique system UID (%s). " - "Suppressing additional messages.\n"), -- Prog, strerror (result)); -+ log_get_progname(), strerror (result)); - SYSLOG ((LOG_ERR, - "Error checking available UIDs: %s", - strerror (result))); -@@ -373,10 +374,10 @@ int find_new_uid(bool sys_user, - * - */ - if (!nospam) { -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: Can't get unique system UID (%s). " - "Suppressing additional messages.\n"), -- Prog, strerror (result)); -+ log_get_progname(), strerror (result)); - SYSLOG((LOG_ERR, - "Error checking available UIDs: %s", - strerror (result))); -@@ -433,10 +434,10 @@ int find_new_uid(bool sys_user, - * - */ - if (!nospam) { -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: Can't get unique UID (%s). " - "Suppressing additional messages.\n"), -- Prog, strerror (result)); -+ log_get_progname(), strerror (result)); - SYSLOG ((LOG_ERR, - "Error checking available UIDs: %s", - strerror (result))); -@@ -476,10 +477,10 @@ int find_new_uid(bool sys_user, - * - */ - if (!nospam) { -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: Can't get unique UID (%s). " - "Suppressing additional messages.\n"), -- Prog, strerror (result)); -+ log_get_progname(), strerror (result)); - SYSLOG ((LOG_ERR, - "Error checking available UIDs: %s", - strerror (result))); -@@ -495,9 +496,9 @@ int find_new_uid(bool sys_user, - } - - /* The code reached here and found no available IDs in the range */ -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: Can't get unique UID (no more available UIDs)\n"), -- Prog); -+ log_get_progname()); - SYSLOG ((LOG_WARN, "no more available UIDs on the system")); - free (used_uids); - return -1; -diff -up shadow-4.9/libmisc/gettime.c.debug1 shadow-4.9/libmisc/gettime.c ---- shadow-4.9/libmisc/gettime.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/libmisc/gettime.c 2022-01-10 10:45:52.204132951 +0100 -@@ -36,6 +36,7 @@ - #include - #include "defines.h" - #include "prototypes.h" -+#include "shadowlog.h" - - /* - * gettime() returns the time as the number of seconds since the Epoch -@@ -50,6 +51,7 @@ - char *source_date_epoch; - time_t fallback; - unsigned long long epoch; -+ FILE *shadow_logfd = log_get_logfd(); - - fallback = time (NULL); - source_date_epoch = shadow_getenv ("SOURCE_DATE_EPOCH"); -diff -up shadow-4.9/libmisc/idmapping.c.debug1 shadow-4.9/libmisc/idmapping.c ---- shadow-4.9/libmisc/idmapping.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/libmisc/idmapping.c 2022-01-10 10:45:52.204132951 +0100 -@@ -40,6 +40,7 @@ - #include - #include - #endif -+#include "shadowlog.h" - - struct map_range *get_map_ranges(int ranges, int argc, char **argv) - { -@@ -47,28 +48,28 @@ struct map_range *get_map_ranges(int ran - int idx, argidx; - - if (ranges < 0 || argc < 0) { -- fprintf(shadow_logfd, "%s: error calculating number of arguments\n", Prog); -+ fprintf(log_get_logfd(), "%s: error calculating number of arguments\n", log_get_progname()); - return NULL; - } - - if (ranges != ((argc + 2) / 3)) { -- fprintf(shadow_logfd, "%s: ranges: %u is wrong for argc: %d\n", Prog, ranges, argc); -+ fprintf(log_get_logfd(), "%s: ranges: %u is wrong for argc: %d\n", log_get_progname(), ranges, argc); - return NULL; - } - - if ((ranges * 3) > argc) { -- fprintf(shadow_logfd, "ranges: %u argc: %d\n", -+ fprintf(log_get_logfd(), "ranges: %u argc: %d\n", - ranges, argc); -- fprintf(shadow_logfd, -+ fprintf(log_get_logfd(), - _( "%s: Not enough arguments to form %u mappings\n"), -- Prog, ranges); -+ log_get_progname(), ranges); - return NULL; - } - - mappings = calloc(ranges, sizeof(*mappings)); - if (!mappings) { -- fprintf(shadow_logfd, _( "%s: Memory allocation failure\n"), -- Prog); -+ fprintf(log_get_logfd(), _( "%s: Memory allocation failure\n"), -+ log_get_progname()); - exit(EXIT_FAILURE); - } - -@@ -88,24 +89,24 @@ struct map_range *get_map_ranges(int ran - return NULL; - } - if (ULONG_MAX - mapping->upper <= mapping->count || ULONG_MAX - mapping->lower <= mapping->count) { -- fprintf(shadow_logfd, _( "%s: subuid overflow detected.\n"), Prog); -+ fprintf(log_get_logfd(), _( "%s: subuid overflow detected.\n"), log_get_progname()); - exit(EXIT_FAILURE); - } - if (mapping->upper > UINT_MAX || - mapping->lower > UINT_MAX || - mapping->count > UINT_MAX) { -- fprintf(shadow_logfd, _( "%s: subuid overflow detected.\n"), Prog); -+ fprintf(log_get_logfd(), _( "%s: subuid overflow detected.\n"), log_get_progname()); - exit(EXIT_FAILURE); - } - if (mapping->lower + mapping->count > UINT_MAX || - mapping->upper + mapping->count > UINT_MAX) { -- fprintf(shadow_logfd, _( "%s: subuid overflow detected.\n"), Prog); -+ fprintf(log_get_logfd(), _( "%s: subuid overflow detected.\n"), log_get_progname()); - exit(EXIT_FAILURE); - } - if (mapping->lower + mapping->count < mapping->lower || - mapping->upper + mapping->count < mapping->upper) { - /* this one really shouldn't be possible given previous checks */ -- fprintf(shadow_logfd, _( "%s: subuid overflow detected.\n"), Prog); -+ fprintf(log_get_logfd(), _( "%s: subuid overflow detected.\n"), log_get_progname()); - exit(EXIT_FAILURE); - } - } -@@ -176,19 +177,19 @@ void write_mapping(int proc_dir_fd, int - } else if (strcmp(map_file, "gid_map") == 0) { - cap = CAP_SETGID; - } else { -- fprintf(shadow_logfd, _("%s: Invalid map file %s specified\n"), Prog, map_file); -+ fprintf(log_get_logfd(), _("%s: Invalid map file %s specified\n"), log_get_progname(), map_file); - exit(EXIT_FAILURE); - } - - /* Align setuid- and fscaps-based new{g,u}idmap behavior. */ - if (geteuid() == 0 && geteuid() != ruid) { - if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) { -- fprintf(shadow_logfd, _("%s: Could not prctl(PR_SET_KEEPCAPS)\n"), Prog); -+ fprintf(log_get_logfd(), _("%s: Could not prctl(PR_SET_KEEPCAPS)\n"), log_get_progname()); - exit(EXIT_FAILURE); - } - - if (seteuid(ruid) < 0) { -- fprintf(shadow_logfd, _("%s: Could not seteuid to %d\n"), Prog, ruid); -+ fprintf(log_get_logfd(), _("%s: Could not seteuid to %d\n"), log_get_progname(), ruid); - exit(EXIT_FAILURE); - } - } -@@ -204,7 +205,7 @@ void write_mapping(int proc_dir_fd, int - data[0].effective |= CAP_TO_MASK(CAP_SETFCAP); - data[0].permitted = data[0].effective; - if (capset(&hdr, data) < 0) { -- fprintf(shadow_logfd, _("%s: Could not set caps\n"), Prog); -+ fprintf(log_get_logfd(), _("%s: Could not set caps\n"), log_get_progname()); - exit(EXIT_FAILURE); - } - #endif -@@ -222,7 +223,7 @@ void write_mapping(int proc_dir_fd, int - mapping->lower, - mapping->count); - if ((written <= 0) || (written >= (bufsize - (pos - buf)))) { -- fprintf(shadow_logfd, _("%s: snprintf failed!\n"), Prog); -+ fprintf(log_get_logfd(), _("%s: snprintf failed!\n"), log_get_progname()); - exit(EXIT_FAILURE); - } - pos += written; -@@ -231,13 +232,13 @@ void write_mapping(int proc_dir_fd, int - /* Write the mapping to the mapping file */ - fd = openat(proc_dir_fd, map_file, O_WRONLY); - if (fd < 0) { -- fprintf(shadow_logfd, _("%s: open of %s failed: %s\n"), -- Prog, map_file, strerror(errno)); -+ fprintf(log_get_logfd(), _("%s: open of %s failed: %s\n"), -+ log_get_progname(), map_file, strerror(errno)); - exit(EXIT_FAILURE); - } - if (write(fd, buf, pos - buf) != (pos - buf)) { -- fprintf(shadow_logfd, _("%s: write to %s failed: %s\n"), -- Prog, map_file, strerror(errno)); -+ fprintf(log_get_logfd(), _("%s: write to %s failed: %s\n"), -+ log_get_progname(), map_file, strerror(errno)); - exit(EXIT_FAILURE); - } - close(fd); -diff -up shadow-4.9/libmisc/limits.c.debug1 shadow-4.9/libmisc/limits.c ---- shadow-4.9/libmisc/limits.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/libmisc/limits.c 2022-01-10 10:45:52.204132951 +0100 -@@ -50,6 +50,7 @@ - #include "defines.h" - #include - #include "getdef.h" -+#include "shadowlog.h" - #ifdef HAVE_SYS_RESOURCE_H - #include - #define LIMITS -@@ -548,7 +549,7 @@ void setup_limits (const struct passwd * - #ifdef LIMITS - if (info->pw_uid != 0) { - if ((setup_user_limits (info->pw_name) & LOGIN_ERROR_LOGIN) != 0) { -- (void) fputs (_("Too many logins.\n"), shadow_logfd); -+ (void) fputs (_("Too many logins.\n"), log_get_logfd()); - (void) sleep (2); /* XXX: Should be FAIL_DELAY */ - exit (EXIT_FAILURE); - } -diff -up shadow-4.9/libmisc/pam_pass.c.debug1 shadow-4.9/libmisc/pam_pass.c ---- shadow-4.9/libmisc/pam_pass.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/libmisc/pam_pass.c 2022-01-10 10:45:52.204132951 +0100 -@@ -46,11 +46,13 @@ - #include "defines.h" - #include "pam_defs.h" - #include "prototypes.h" -+#include "shadowlog.h" - - void do_pam_passwd (const char *user, bool silent, bool change_expired) - { - pam_handle_t *pamh = NULL; - int flags = 0, ret; -+ FILE *shadow_logfd = log_get_logfd(); - - if (silent) - flags |= PAM_SILENT; -diff -up shadow-4.9/libmisc/pam_pass_non_interactive.c.debug1 shadow-4.9/libmisc/pam_pass_non_interactive.c ---- shadow-4.9/libmisc/pam_pass_non_interactive.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/libmisc/pam_pass_non_interactive.c 2022-01-10 10:45:52.204132951 +0100 -@@ -38,6 +38,7 @@ - #include - #include - #include "prototypes.h" -+#include "shadowlog.h" - - /*@null@*/ /*@only@*/static const char *non_interactive_password = NULL; - static int ni_conv (int num_msg, -@@ -76,9 +77,9 @@ static int ni_conv (int num_msg, - - switch (msg[count]->msg_style) { - case PAM_PROMPT_ECHO_ON: -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: PAM modules requesting echoing are not supported.\n"), -- Prog); -+ log_get_progname()); - goto failed_conversation; - case PAM_PROMPT_ECHO_OFF: - responses[count].resp = strdup (non_interactive_password); -@@ -88,7 +89,7 @@ static int ni_conv (int num_msg, - break; - case PAM_ERROR_MSG: - if ( (NULL == msg[count]->msg) -- || (fprintf (shadow_logfd, "%s\n", msg[count]->msg) <0)) { -+ || (fprintf (log_get_logfd(), "%s\n", msg[count]->msg) <0)) { - goto failed_conversation; - } - responses[count].resp = NULL; -@@ -101,9 +102,9 @@ static int ni_conv (int num_msg, - responses[count].resp = NULL; - break; - default: -- (void) fprintf (shadow_logfd, -+ (void) fprintf (log_get_logfd(), - _("%s: conversation type %d not supported.\n"), -- Prog, msg[count]->msg_style); -+ log_get_progname(), msg[count]->msg_style); - goto failed_conversation; - } - } -@@ -143,19 +144,19 @@ int do_pam_passwd_non_interactive (const - - ret = pam_start (pam_service, username, &non_interactive_pam_conv, &pamh); - if (ret != PAM_SUCCESS) { -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: (user %s) pam_start failure %d\n"), -- Prog, username, ret); -+ log_get_progname(), username, ret); - return 1; - } - - non_interactive_password = password; - ret = pam_chauthtok (pamh, 0); - if (ret != PAM_SUCCESS) { -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: (user %s) pam_chauthtok() failed, error:\n" - "%s\n"), -- Prog, username, pam_strerror (pamh, ret)); -+ log_get_progname(), username, pam_strerror (pamh, ret)); - } - - (void) pam_end (pamh, PAM_SUCCESS); -diff -up shadow-4.9/libmisc/prefix_flag.c.debug1 shadow-4.9/libmisc/prefix_flag.c ---- shadow-4.9/libmisc/prefix_flag.c.debug1 2022-01-10 10:45:52.201132929 +0100 -+++ shadow-4.9/libmisc/prefix_flag.c 2022-01-10 10:45:52.204132951 +0100 -@@ -48,6 +48,7 @@ - #include "subordinateio.h" - #endif /* ENABLE_SUBIDS */ - #include "getdef.h" -+#include "shadowlog.h" - - static char *passwd_db_file = NULL; - static char *spw_db_file = NULL; -@@ -83,18 +84,18 @@ extern const char* process_prefix_flag ( - && (val = argv[i] + 9)) - || (strcmp (argv[i], short_opt) == 0)) { - if (NULL != prefix) { -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: multiple --prefix options\n"), -- Prog); -+ log_get_progname()); - exit (E_BAD_ARG); - } - - if (val) { - prefix = val; - } else if (i + 1 == argc) { -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: option '%s' requires an argument\n"), -- Prog, argv[i]); -+ log_get_progname(), argv[i]); - exit (E_BAD_ARG); - } else { - prefix = argv[++ i]; -@@ -110,9 +111,9 @@ extern const char* process_prefix_flag ( - /* should we prevent symbolic link from being used as a prefix? */ - - if ( prefix[0] != '/') { -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: prefix must be an absolute path\n"), -- Prog); -+ log_get_progname()); - exit (E_BAD_ARG); - } - size_t len; -diff -up shadow-4.9/libmisc/pwdcheck.c.debug1 shadow-4.9/libmisc/pwdcheck.c ---- shadow-4.9/libmisc/pwdcheck.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/libmisc/pwdcheck.c 2022-01-10 10:45:52.204132951 +0100 -@@ -39,6 +39,7 @@ - #include "prototypes.h" - #include "defines.h" - #include "pwauth.h" -+#include "shadowlog.h" - - void passwd_check (const char *user, const char *passwd, unused const char *progname) - { -@@ -51,7 +52,7 @@ void passwd_check (const char *user, con - if (pw_auth (passwd, user, PW_LOGIN, (char *) 0) != 0) { - SYSLOG ((LOG_WARN, "incorrect password for `%s'", user)); - (void) sleep (1); -- fprintf (shadow_logfd, _("Incorrect password for %s.\n"), user); -+ fprintf (log_get_logfd(), _("Incorrect password for %s.\n"), user); - exit (EXIT_FAILURE); - } - } -diff -up shadow-4.9/libmisc/root_flag.c.debug1 shadow-4.9/libmisc/root_flag.c ---- shadow-4.9/libmisc/root_flag.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/libmisc/root_flag.c 2022-01-10 10:45:52.204132951 +0100 -@@ -38,6 +38,7 @@ - #include "prototypes.h" - /*@-exitarg@*/ - #include "exitcodes.h" -+#include "shadowlog.h" - - static void change_root (const char* newroot); - -@@ -65,18 +66,18 @@ extern void process_root_flag (const cha - && (val = argv[i] + 7)) - || (strcmp (argv[i], short_opt) == 0)) { - if (NULL != newroot) { -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: multiple --root options\n"), -- Prog); -+ log_get_progname()); - exit (E_BAD_ARG); - } - - if (val) { - newroot = val; - } else if (i + 1 == argc) { -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: option '%s' requires an argument\n"), -- Prog, argv[i]); -+ log_get_progname(), argv[i]); - exit (E_BAD_ARG); - } else { - newroot = argv[++ i]; -@@ -94,36 +95,36 @@ static void change_root (const char* new - /* Drop privileges */ - if ( (setregid (getgid (), getgid ()) != 0) - || (setreuid (getuid (), getuid ()) != 0)) { -- fprintf (shadow_logfd, _("%s: failed to drop privileges (%s)\n"), -- Prog, strerror (errno)); -+ fprintf (log_get_logfd(), _("%s: failed to drop privileges (%s)\n"), -+ log_get_progname(), strerror (errno)); - exit (EXIT_FAILURE); - } - - if ('/' != newroot[0]) { -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: invalid chroot path '%s'\n"), -- Prog, newroot); -+ log_get_progname(), newroot); - exit (E_BAD_ARG); - } - - if (access (newroot, F_OK) != 0) { -- fprintf(shadow_logfd, -+ fprintf(log_get_logfd(), - _("%s: cannot access chroot directory %s: %s\n"), -- Prog, newroot, strerror (errno)); -+ log_get_progname(), newroot, strerror (errno)); - exit (E_BAD_ARG); - } - - if (chdir (newroot) != 0) { -- fprintf(shadow_logfd, -+ fprintf(log_get_logfd(), - _("%s: cannot chdir to chroot directory %s: %s\n"), -- Prog, newroot, strerror (errno)); -+ log_get_progname(), newroot, strerror (errno)); - exit (E_BAD_ARG); - } - - if (chroot (newroot) != 0) { -- fprintf(shadow_logfd, -+ fprintf(log_get_logfd(), - _("%s: unable to chroot to directory %s: %s\n"), -- Prog, newroot, strerror (errno)); -+ log_get_progname(), newroot, strerror (errno)); - exit (E_BAD_ARG); - } - } -diff -up shadow-4.9/libmisc/salt.c.debug1 shadow-4.9/libmisc/salt.c ---- shadow-4.9/libmisc/salt.c.debug1 2022-01-10 10:45:52.195132887 +0100 -+++ shadow-4.9/libmisc/salt.c 2022-01-10 10:45:52.204132951 +0100 -@@ -21,6 +21,7 @@ - #include "prototypes.h" - #include "defines.h" - #include "getdef.h" -+#include "shadowlog.h" - - #if (defined CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY && \ - CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY) -@@ -178,7 +179,7 @@ static long read_random_bytes (void) - #endif - - fail: -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("Unable to obtain random bytes.\n")); - exit (1); - -@@ -506,7 +507,7 @@ static /*@observer@*/const char *gensalt - SHA_salt_rounds_to_buf (result, rounds); - #endif /* USE_SHA_CRYPT */ - } else if (0 != strcmp (method, "DES")) { -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("Invalid ENCRYPT_METHOD value: '%s'.\n" - "Defaulting to DES.\n"), - method); -@@ -532,7 +533,7 @@ static /*@observer@*/const char *gensalt - - /* Should not happen, but... */ - if (NULL == retval) { -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("Unable to generate a salt from setting " - "\"%s\", check your settings in " - "ENCRYPT_METHOD and the corresponding " -diff -up shadow-4.9/libmisc/setupenv.c.debug1 shadow-4.9/libmisc/setupenv.c ---- shadow-4.9/libmisc/setupenv.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/libmisc/setupenv.c 2022-01-10 10:45:52.204132951 +0100 -@@ -47,6 +47,7 @@ - #include "defines.h" - #include - #include "getdef.h" -+#include "shadowlog.h" - - #ifndef USE_PAM - static void -@@ -219,7 +220,7 @@ void setup_env (struct passwd *info) - static char temp_pw_dir[] = "/"; - - if (!getdef_bool ("DEFAULT_HOME") || chdir ("/") == -1) { -- fprintf (shadow_logfd, _("Unable to cd to '%s'\n"), -+ fprintf (log_get_logfd(), _("Unable to cd to '%s'\n"), - info->pw_dir); - SYSLOG ((LOG_WARN, - "unable to cd to `%s' for user `%s'\n", -diff -up shadow-4.9/libmisc/user_busy.c.debug1 shadow-4.9/libmisc/user_busy.c ---- shadow-4.9/libmisc/user_busy.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/libmisc/user_busy.c 2022-01-10 10:45:52.204132951 +0100 -@@ -45,6 +45,7 @@ - #ifdef ENABLE_SUBIDS - #include "subordinateio.h" - #endif /* ENABLE_SUBIDS */ -+#include "shadowlog.h" - - #ifdef __linux__ - static int check_status (const char *name, const char *sname, uid_t uid); -@@ -96,9 +97,9 @@ static int user_busy_utmp (const char *n - continue; - } - -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: user %s is currently logged in\n"), -- Prog, name); -+ log_get_progname(), name); - return 1; - } - -@@ -249,9 +250,9 @@ static int user_busy_processes (const ch - #ifdef ENABLE_SUBIDS - sub_uid_close(); - #endif -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: user %s is currently used by process %d\n"), -- Prog, name, pid); -+ log_get_progname(), name, pid); - return 1; - } - -@@ -273,9 +274,9 @@ static int user_busy_processes (const ch - #ifdef ENABLE_SUBIDS - sub_uid_close(); - #endif -- fprintf (shadow_logfd, -+ fprintf (log_get_logfd(), - _("%s: user %s is currently used by process %d\n"), -- Prog, name, pid); -+ log_get_progname(), name, pid); - return 1; - } - } -diff -up shadow-4.9/libmisc/xgetXXbyYY.c.debug1 shadow-4.9/libmisc/xgetXXbyYY.c ---- shadow-4.9/libmisc/xgetXXbyYY.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/libmisc/xgetXXbyYY.c 2022-01-10 10:45:52.204132951 +0100 -@@ -54,6 +54,7 @@ - #include - #include - #include "prototypes.h" -+#include "shadowlog.h" - - #define XFUNCTION_NAME XPREFIX (FUNCTION_NAME) - #define XPREFIX(name) XPREFIX1 (name) -@@ -74,7 +75,7 @@ - - result = malloc(sizeof(LOOKUP_TYPE)); - if (NULL == result) { -- fprintf (shadow_logfd, _("%s: out of memory\n"), -+ fprintf (log_get_logfd(), _("%s: out of memory\n"), - "x" STRINGIZE(FUNCTION_NAME)); - exit (13); - } -@@ -84,7 +85,7 @@ - LOOKUP_TYPE *resbuf = NULL; - buffer = (char *)realloc (buffer, length); - if (NULL == buffer) { -- fprintf (shadow_logfd, _("%s: out of memory\n"), -+ fprintf (log_get_logfd(), _("%s: out of memory\n"), - "x" STRINGIZE(FUNCTION_NAME)); - exit (13); - } -@@ -132,7 +133,7 @@ - if (result) { - result = DUP_FUNCTION(result); - if (NULL == result) { -- fprintf (shadow_logfd, _("%s: out of memory\n"), -+ fprintf (log_get_logfd(), _("%s: out of memory\n"), - "x" STRINGIZE(FUNCTION_NAME)); - exit (13); - } -diff -up shadow-4.9/libmisc/xmalloc.c.debug1 shadow-4.9/libmisc/xmalloc.c ---- shadow-4.9/libmisc/xmalloc.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/libmisc/xmalloc.c 2022-01-10 10:45:52.204132951 +0100 -@@ -47,6 +47,7 @@ - #include - #include "defines.h" - #include "prototypes.h" -+#include "shadowlog.h" - - /*@maynotreturn@*/ /*@only@*//*@out@*//*@notnull@*/char *xmalloc (size_t size) - { -@@ -54,9 +55,9 @@ - - ptr = (char *) malloc (size); - if (NULL == ptr) { -- (void) fprintf (shadow_logfd, -+ (void) fprintf (log_get_logfd(), - _("%s: failed to allocate memory: %s\n"), -- Prog, strerror (errno)); -+ log_get_progname(), strerror (errno)); - exit (13); - } - return ptr; -diff -up shadow-4.9/lib/nscd.c.debug1 shadow-4.9/lib/nscd.c ---- shadow-4.9/lib/nscd.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/lib/nscd.c 2022-01-10 10:45:52.202132937 +0100 -@@ -10,6 +10,7 @@ - #include "defines.h" - #include "prototypes.h" - #include "nscd.h" -+#include "shadowlog_internal.h" - - #define MSG_NSCD_FLUSH_CACHE_FAILED "%s: Failed to flush the nscd cache.\n" - -diff -up shadow-4.9/lib/nss.c.debug1 shadow-4.9/lib/nss.c ---- shadow-4.9/lib/nss.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/lib/nss.c 2022-01-10 10:45:52.202132937 +0100 -@@ -8,6 +8,7 @@ - #include - #include "prototypes.h" - #include "../libsubid/subid.h" -+#include "shadowlog_internal.h" - - #define NSSWITCH "/etc/nsswitch.conf" - -diff -up shadow-4.9/lib/prototypes.h.debug1 shadow-4.9/lib/prototypes.h ---- shadow-4.9/lib/prototypes.h.debug1 2022-01-10 10:45:52.195132887 +0100 -+++ shadow-4.9/lib/prototypes.h 2022-01-10 10:45:52.202132937 +0100 -@@ -59,9 +59,6 @@ - #include "defines.h" - #include "commonio.h" - --extern /*@observer@*/ const char *Prog; /* Program name showed in error messages */ --extern FILE *shadow_logfd; /* file descripter to which error messages are printed */ -- - /* addgrps.c */ - #if defined (HAVE_SETGROUPS) && ! defined (USE_PAM) - extern int add_groups (const char *); -diff -up shadow-4.9/lib/run_part.c.debug1 shadow-4.9/lib/run_part.c ---- shadow-4.9/lib/run_part.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/lib/run_part.c 2022-01-10 10:45:52.202132937 +0100 -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include "shadowlog_internal.h" - - int run_part (char *script_path, char *name, char *action) - { -diff -up shadow-4.9/lib/selinux.c.debug1 shadow-4.9/lib/selinux.c ---- shadow-4.9/lib/selinux.c.debug1 2022-01-10 10:45:52.196132894 +0100 -+++ shadow-4.9/lib/selinux.c 2022-01-10 10:45:52.202132937 +0100 -@@ -38,6 +38,8 @@ - #include - #include "prototypes.h" - -+#include "shadowlog_internal.h" -+ - static bool selinux_checked = false; - static bool selinux_enabled; - static /*@null@*/struct selabel_handle *selabel_hnd = NULL; -diff -up shadow-4.9/lib/semanage.c.debug1 shadow-4.9/lib/semanage.c ---- shadow-4.9/lib/semanage.c.debug1 2022-01-10 10:45:52.196132894 +0100 -+++ shadow-4.9/lib/semanage.c 2022-01-10 10:45:52.202132937 +0100 -@@ -43,6 +43,7 @@ - #include - #include "prototypes.h" - -+#include "shadowlog_internal.h" - - #ifndef DEFAULT_SERANGE - #define DEFAULT_SERANGE "s0" -diff -up shadow-4.9/lib/shadowlog.c.debug1 shadow-4.9/lib/shadowlog.c ---- shadow-4.9/lib/shadowlog.c.debug1 2022-01-10 10:45:52.202132937 +0100 -+++ shadow-4.9/lib/shadowlog.c 2022-01-10 10:45:52.202132937 +0100 -@@ -0,0 +1,28 @@ -+#include "shadowlog.h" -+ -+#include "lib/shadowlog_internal.h" -+ -+void log_set_progname(const char *progname) -+{ -+ Prog = progname; -+} -+ -+const char *log_get_progname(void) -+{ -+ return Prog; -+} -+ -+void log_set_logfd(FILE *fd) -+{ -+ if (NULL != fd) -+ shadow_logfd = fd; -+ else -+ shadow_logfd = stderr; -+} -+ -+FILE *log_get_logfd(void) -+{ -+ if (shadow_logfd != NULL) -+ return shadow_logfd; -+ return stderr; -+} -diff -up shadow-4.9/lib/shadowlog.h.debug1 shadow-4.9/lib/shadowlog.h ---- shadow-4.9/lib/shadowlog.h.debug1 2022-01-10 10:45:52.202132937 +0100 -+++ shadow-4.9/lib/shadowlog.h 2022-01-10 10:45:52.202132937 +0100 -@@ -0,0 +1,41 @@ -+/* -+ * Copyright (c) 2021 , Serge Hallyn -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. The name of the copyright holders or contributors may not be used to -+ * endorse or promote products derived from this software without -+ * specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/* $Id$ */ -+#ifndef _LOG_H -+#define _LOG_H -+#include -+ -+extern void log_set_progname(const char *); -+extern const char *log_get_progname(void); -+extern void log_set_logfd(FILE *fd); -+extern FILE *log_get_logfd(void); -+extern void log_dolog(char *, ...); -+ -+#endif -diff -up shadow-4.9/lib/shadowlog_internal.h.debug1 shadow-4.9/lib/shadowlog_internal.h ---- shadow-4.9/lib/shadowlog_internal.h.debug1 2022-01-10 10:45:52.202132937 +0100 -+++ shadow-4.9/lib/shadowlog_internal.h 2022-01-10 10:45:52.202132937 +0100 -@@ -0,0 +1,2 @@ -+const char *Prog; /* Program name showed in error messages */ -+FILE *shadow_logfd; /* file descripter to which error messages are printed */ -diff -up shadow-4.9/lib/spawn.c.debug1 shadow-4.9/lib/spawn.c ---- shadow-4.9/lib/spawn.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/lib/spawn.c 2022-01-10 10:45:52.202132937 +0100 -@@ -38,6 +38,8 @@ - #include "exitcodes.h" - #include "prototypes.h" - -+#include "shadowlog_internal.h" -+ - int run_command (const char *cmd, const char *argv[], - /*@null@*/const char *envp[], /*@out@*/int *status) - { -diff -up shadow-4.9/lib/sssd.c.debug1 shadow-4.9/lib/sssd.c ---- shadow-4.9/lib/sssd.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/lib/sssd.c 2022-01-10 10:45:52.203132944 +0100 -@@ -11,6 +11,8 @@ - #include "prototypes.h" - #include "sssd.h" - -+#include "shadowlog_internal.h" -+ - #define MSG_SSSD_FLUSH_CACHE_FAILED "%s: Failed to flush the sssd cache." - - int sssd_flush_cache (int dbflags) -diff -up shadow-4.9/libsubid/api.c.debug1 shadow-4.9/libsubid/api.c ---- shadow-4.9/libsubid/api.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/libsubid/api.c 2022-01-10 10:48:14.913151522 +0100 -@@ -38,12 +38,13 @@ - #include "subordinateio.h" - #include "idmapping.h" - #include "subid.h" -+#include "shadowlog.h" - - const char *Prog = "(libsubid)"; --FILE *shadow_logfd; - - bool libsubid_init(const char *progname, FILE * logfd) - { -+ FILE *shadow_logfd; - if (progname) { - progname = strdup(progname); - if (progname) -@@ -53,14 +54,15 @@ bool libsubid_init(const char *progname, - } - - if (logfd) { -- shadow_logfd = logfd; -+ log_set_logfd(logfd); - return true; - } - shadow_logfd = fopen("/dev/null", "w"); - if (!shadow_logfd) { -- shadow_logfd = stderr; -+ log_set_logfd(stderr); - return false; - } -+ log_set_logfd(shadow_logfd); - return true; - } - -diff -up shadow-4.9/lib/tcbfuncs.c.debug1 shadow-4.9/lib/tcbfuncs.c ---- shadow-4.9/lib/tcbfuncs.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/lib/tcbfuncs.c 2022-01-10 10:45:52.203132944 +0100 -@@ -38,6 +38,8 @@ - #include "shadowio.h" - #include "tcbfuncs.h" - -+#include "shadowlog_internal.h" -+ - #define SHADOWTCB_HASH_BY 1000 - #define SHADOWTCB_LOCK_SUFFIX ".lock" - -diff -up shadow-4.9/src/chage.c.debug1 shadow-4.9/src/chage.c ---- shadow-4.9/src/chage.c.debug1 2022-01-10 10:45:52.188132837 +0100 -+++ shadow-4.9/src/chage.c 2022-01-10 10:45:52.205132958 +0100 -@@ -52,6 +52,7 @@ - #include "defines.h" - #include "pwio.h" - #include "shadowio.h" -+#include "shadowlog.h" - #ifdef WITH_TCB - #include "tcbfuncs.h" - #endif -@@ -62,7 +63,6 @@ - * Global variables - */ - const char *Prog; --FILE *shadow_logfd = NULL; - - static bool - dflg = false, /* set last password change date */ -@@ -820,7 +820,8 @@ int main (int argc, char **argv) - * Get the program name so that error messages can use it. - */ - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - - sanitize_env (); - (void) setlocale (LC_ALL, ""); -diff -up shadow-4.9/src/check_subid_range.c.debug1 shadow-4.9/src/check_subid_range.c ---- shadow-4.9/src/check_subid_range.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/src/check_subid_range.c 2022-01-10 10:45:52.205132958 +0100 -@@ -16,9 +16,9 @@ - #include "prototypes.h" - #include "subordinateio.h" - #include "idmapping.h" -+#include "shadowlog.h" - - const char *Prog; --FILE *shadow_logfd = NULL; - - int main(int argc, char **argv) - { -@@ -26,7 +26,8 @@ int main(int argc, char **argv) - unsigned long start, count; - bool check_uids; - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - - if (argc != 5) - exit(1); -diff -up shadow-4.9/src/chfn.c.debug1 shadow-4.9/src/chfn.c ---- shadow-4.9/src/chfn.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/src/chfn.c 2022-01-10 10:45:52.205132958 +0100 -@@ -52,12 +52,12 @@ - #include "pwio.h" - /*@-exitarg@*/ - #include "exitcodes.h" -+#include "shadowlog.h" - - /* - * Global variables. - */ - const char *Prog; --FILE *shadow_logfd = NULL; - static char fullnm[BUFSIZ]; - static char roomno[BUFSIZ]; - static char workph[BUFSIZ]; -@@ -640,7 +640,8 @@ int main (int argc, char **argv) - * prefix to most error messages. - */ - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - - sanitize_env (); - (void) setlocale (LC_ALL, ""); -diff -up shadow-4.9/src/chgpasswd.c.debug1 shadow-4.9/src/chgpasswd.c ---- shadow-4.9/src/chgpasswd.c.debug1 2022-01-10 10:45:52.188132837 +0100 -+++ shadow-4.9/src/chgpasswd.c 2022-01-10 10:45:52.205132958 +0100 -@@ -61,12 +61,12 @@ - #endif - /*@-exitarg@*/ - #include "exitcodes.h" -+#include "shadowlog.h" - - /* - * Global variables - */ - const char *Prog; --FILE *shadow_logfd = NULL; - static bool eflg = false; - static bool md5flg = false; - #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) -@@ -506,7 +506,8 @@ int main (int argc, char **argv) - int line = 0; - - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.9/src/chpasswd.c.debug1 shadow-4.9/src/chpasswd.c ---- shadow-4.9/src/chpasswd.c.debug1 2022-01-10 10:45:52.188132837 +0100 -+++ shadow-4.9/src/chpasswd.c 2022-01-10 10:45:52.205132958 +0100 -@@ -58,12 +58,12 @@ - #include "shadowio.h" - /*@-exitarg@*/ - #include "exitcodes.h" -+#include "shadowlog.h" - - /* - * Global variables - */ - const char *Prog; --FILE *shadow_logfd = NULL; - static bool eflg = false; - static bool md5flg = false; - #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) -@@ -494,7 +494,8 @@ int main (int argc, char **argv) - int line = 0; - - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.9/src/chsh.c.debug1 shadow-4.9/src/chsh.c ---- shadow-4.9/src/chsh.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/src/chsh.c 2022-01-10 10:45:52.205132958 +0100 -@@ -51,6 +51,7 @@ - #endif - /*@-exitarg@*/ - #include "exitcodes.h" -+#include "shadowlog.h" - - #ifndef SHELLS_FILE - #define SHELLS_FILE "/etc/shells" -@@ -59,7 +60,6 @@ - * Global variables - */ - const char *Prog; /* Program name */ --FILE *shadow_logfd = NULL; - static bool amroot; /* Real UID is root */ - static char loginsh[BUFSIZ]; /* Name of new login shell */ - /* command line options */ -@@ -442,7 +442,8 @@ int main (int argc, char **argv) - * most error messages. - */ - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.9/src/expiry.c.debug1 shadow-4.9/src/expiry.c ---- shadow-4.9/src/expiry.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/src/expiry.c 2022-01-10 10:45:52.205132958 +0100 -@@ -43,10 +43,10 @@ - #include "prototypes.h" - /*@-exitarg@*/ - #include "exitcodes.h" -+#include "shadowlog.h" - - /* Global variables */ - const char *Prog; --FILE *shadow_logfd = NULL; - static bool cflg = false; - - /* local function prototypes */ -@@ -145,7 +145,8 @@ int main (int argc, char **argv) - struct spwd *spwd; - - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - - sanitize_env (); - -diff -up shadow-4.9/src/faillog.c.debug1 shadow-4.9/src/faillog.c ---- shadow-4.9/src/faillog.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/src/faillog.c 2022-01-10 10:45:52.205132958 +0100 -@@ -46,6 +46,7 @@ - #include "prototypes.h" - /*@-exitarg@*/ - #include "exitcodes.h" -+#include "shadowlog.h" - - /* local function prototypes */ - static /*@noreturn@*/void usage (int status); -@@ -62,7 +63,6 @@ static void reset (void); - * Global variables - */ - const char *Prog; /* Program name */ --FILE *shadow_logfd = NULL; - static FILE *fail; /* failure file stream */ - static time_t seconds; /* that number of days in seconds */ - static unsigned long umin; /* if uflg and has_umin, only display users with uid >= umin */ -@@ -574,7 +574,8 @@ int main (int argc, char **argv) - * most error messages. - */ - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.9/src/free_subid_range.c.debug1 shadow-4.9/src/free_subid_range.c ---- shadow-4.9/src/free_subid_range.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/src/free_subid_range.c 2022-01-10 10:45:52.205132958 +0100 -@@ -3,11 +3,11 @@ - #include "subid.h" - #include "stdlib.h" - #include "prototypes.h" -+#include "shadowlog.h" - - /* Test program for the subid freeing routine */ - - const char *Prog; --FILE *shadow_logfd = NULL; - - void usage(void) - { -@@ -24,7 +24,8 @@ int main(int argc, char *argv[]) - bool group = false; // get subuids by default - - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - while ((c = getopt(argc, argv, "g")) != EOF) { - switch(c) { - case 'g': group = true; break; -diff -up shadow-4.9/src/get_subid_owners.c.debug1 shadow-4.9/src/get_subid_owners.c ---- shadow-4.9/src/get_subid_owners.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/src/get_subid_owners.c 2022-01-10 10:45:52.205132958 +0100 -@@ -2,9 +2,9 @@ - #include "subid.h" - #include "stdlib.h" - #include "prototypes.h" -+#include "shadowlog.h" - - const char *Prog; --FILE *shadow_logfd = NULL; - - void usage(void) - { -@@ -20,7 +20,8 @@ int main(int argc, char *argv[]) - uid_t *uids; - - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - if (argc < 2) { - usage(); - } -diff -up shadow-4.9/src/getsubids.c.debug1 shadow-4.9/src/getsubids.c ---- shadow-4.9/src/getsubids.c.debug1 2022-01-10 10:45:52.200132922 +0100 -+++ shadow-4.9/src/getsubids.c 2022-01-10 10:45:52.205132958 +0100 -@@ -3,9 +3,9 @@ - #include - #include "subid.h" - #include "prototypes.h" -+#include "shadowlog.h" - - const char *Prog; --FILE *shadow_logfd = NULL; - - void usage(void) - { -@@ -22,7 +22,8 @@ int main(int argc, char *argv[]) - const char *owner; - - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - if (argc < 2) - usage(); - owner = argv[1]; -diff -up shadow-4.9/src/gpasswd.c.debug1 shadow-4.9/src/gpasswd.c ---- shadow-4.9/src/gpasswd.c.debug1 2022-01-10 10:45:52.184132808 +0100 -+++ shadow-4.9/src/gpasswd.c 2022-01-10 10:45:52.205132958 +0100 -@@ -53,12 +53,12 @@ - /*@-exitarg@*/ - #include "exitcodes.h" - -+#include "shadowlog.h" - /* - * Global variables - */ - /* The name of this command, as it is invoked */ - const char *Prog; --FILE *shadow_logfd = NULL; - - #ifdef SHADOWGRP - /* Indicate if shadow groups are enabled on the system -@@ -927,7 +927,8 @@ int main (int argc, char **argv) - */ - bywho = getuid (); - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - - OPENLOG ("gpasswd"); - setbuf (stdout, NULL); -diff -up shadow-4.9/src/groupadd.c.debug1 shadow-4.9/src/groupadd.c ---- shadow-4.9/src/groupadd.c.debug1 2022-01-10 10:45:52.184132808 +0100 -+++ shadow-4.9/src/groupadd.c 2022-01-10 10:45:52.205132958 +0100 -@@ -56,6 +56,7 @@ - #ifdef SHADOWGRP - #include "sgroupio.h" - #endif -+#include "shadowlog.h" - - /* - * exit status values -@@ -72,7 +73,6 @@ - * Global variables - */ - const char *Prog; --FILE *shadow_logfd = NULL; - - static /*@null@*/char *group_name; - static gid_t group_id; -@@ -602,7 +602,8 @@ int main (int argc, char **argv) - * Get my name so that I can use it to report errors. - */ - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.9/src/groupdel.c.debug1 shadow-4.9/src/groupdel.c ---- shadow-4.9/src/groupdel.c.debug1 2022-01-10 10:45:52.185132815 +0100 -+++ shadow-4.9/src/groupdel.c 2022-01-10 10:45:52.205132958 +0100 -@@ -54,11 +54,11 @@ - #ifdef SHADOWGRP - #include "sgroupio.h" - #endif -+#include "shadowlog.h" - /* - * Global variables - */ - const char *Prog; --FILE *shadow_logfd = NULL; - - static char *group_name; - static gid_t group_id = -1; -@@ -379,7 +379,8 @@ int main (int argc, char **argv) - * Get my name so that I can use it to report errors. - */ - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.9/src/groupmems.c.debug1 shadow-4.9/src/groupmems.c ---- shadow-4.9/src/groupmems.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/src/groupmems.c 2022-01-10 10:45:52.206132965 +0100 -@@ -47,6 +47,7 @@ - #ifdef SHADOWGRP - #include "sgroupio.h" - #endif -+#include "shadowlog.h" - - /* Exit Status Values */ - /*@-exitarg@*/ -@@ -65,7 +66,6 @@ - * Global variables - */ - const char *Prog; --FILE *shadow_logfd = NULL; - - static char *adduser = NULL; - static char *deluser = NULL; -@@ -596,7 +596,8 @@ int main (int argc, char **argv) - * Get my name so that I can use it to report errors. - */ - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.9/src/groupmod.c.debug1 shadow-4.9/src/groupmod.c ---- shadow-4.9/src/groupmod.c.debug1 2022-01-10 10:45:52.185132815 +0100 -+++ shadow-4.9/src/groupmod.c 2022-01-10 10:45:52.206132965 +0100 -@@ -56,6 +56,7 @@ - #ifdef SHADOWGRP - #include "sgroupio.h" - #endif -+#include "shadowlog.h" - /* - * exit status values - */ -@@ -76,7 +77,6 @@ - * Global variables - */ - const char *Prog; --FILE *shadow_logfd = NULL; - - #ifdef SHADOWGRP - static bool is_shadow_grp; -@@ -840,7 +840,8 @@ int main (int argc, char **argv) - * Get my name so that I can use it to report errors. - */ - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.9/src/groups.c.debug1 shadow-4.9/src/groups.c ---- shadow-4.9/src/groups.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/src/groups.c 2022-01-10 10:45:52.206132965 +0100 -@@ -39,11 +39,11 @@ - #include - #include "defines.h" - #include "prototypes.h" -+#include "shadowlog.h" - /* - * Global variables - */ - const char *Prog; --FILE *shadow_logfd = NULL; - - /* local function prototypes */ - static void print_groups (const char *member); -@@ -127,7 +127,8 @@ int main (int argc, char **argv) - * Get the program name so that error messages can use it. - */ - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - - if (argc == 1) { - -diff -up shadow-4.9/src/grpck.c.debug1 shadow-4.9/src/grpck.c ---- shadow-4.9/src/grpck.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/src/grpck.c 2022-01-10 10:45:52.206132965 +0100 -@@ -45,6 +45,7 @@ - #include "nscd.h" - #include "sssd.h" - #include "prototypes.h" -+#include "shadowlog.h" - - #ifdef SHADOWGRP - #include "sgroupio.h" -@@ -66,7 +67,6 @@ - * Global variables - */ - const char *Prog; --FILE *shadow_logfd = NULL; - - static const char *grp_file = GROUP_FILE; - static bool use_system_grp_file = true; -@@ -841,7 +841,8 @@ int main (int argc, char **argv) - * Get my name so that I can use it to report errors. - */ - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.9/src/grpconv.c.debug1 shadow-4.9/src/grpconv.c ---- shadow-4.9/src/grpconv.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/src/grpconv.c 2022-01-10 10:45:52.206132965 +0100 -@@ -55,11 +55,11 @@ - #ifdef SHADOWGRP - #include "groupio.h" - #include "sgroupio.h" -+#include "shadowlog.h" - /* - * Global variables - */ - const char *Prog; --FILE *shadow_logfd = NULL; - - static bool gr_locked = false; - static bool sgr_locked = false; -@@ -147,7 +147,8 @@ int main (int argc, char **argv) - struct sgrp sgent; - - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.9/src/grpunconv.c.debug1 shadow-4.9/src/grpunconv.c ---- shadow-4.9/src/grpunconv.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/src/grpunconv.c 2022-01-10 10:45:52.206132965 +0100 -@@ -55,11 +55,11 @@ - #ifdef SHADOWGRP - #include "groupio.h" - #include "sgroupio.h" -+#include "shadowlog.h" - /* - * Global variables - */ - const char *Prog; --FILE *shadow_logfd = NULL; - - static bool gr_locked = false; - static bool sgr_locked = false; -@@ -146,7 +146,8 @@ int main (int argc, char **argv) - const struct sgrp *sg; - - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.9/src/lastlog.c.debug1 shadow-4.9/src/lastlog.c ---- shadow-4.9/src/lastlog.c.debug1 2022-01-10 10:45:52.189132844 +0100 -+++ shadow-4.9/src/lastlog.c 2022-01-10 10:45:52.206132965 +0100 -@@ -50,6 +50,7 @@ - #include "getdef.h" - /*@-exitarg@*/ - #include "exitcodes.h" -+#include "shadowlog.h" - - /* - * Needed for MkLinux DR1/2/2.1 - J. -@@ -62,7 +63,6 @@ - * Global variables - */ - const char *Prog; /* Program name */ --FILE *shadow_logfd = NULL; - static FILE *lastlogfile; /* lastlog file stream */ - static unsigned long umin; /* if uflg and has_umin, only display users with uid >= umin */ - static bool has_umin = false; -@@ -322,7 +322,8 @@ int main (int argc, char **argv) - * most error messages. - */ - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.9/src/login.c.debug1 shadow-4.9/src/login.c ---- shadow-4.9/src/login.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/src/login.c 2022-01-10 10:45:52.206132965 +0100 -@@ -53,6 +53,7 @@ - #include "pwauth.h" - /*@-exitarg@*/ - #include "exitcodes.h" -+#include "shadowlog.h" - - #ifdef USE_PAM - #include "pam_defs.h" -@@ -83,7 +84,6 @@ static pam_handle_t *pamh = NULL; - * Global variables - */ - const char *Prog; --FILE *shadow_logfd = NULL; - - static const char *hostname = ""; - static /*@null@*/ /*@only@*/char *username = NULL; -@@ -578,7 +578,8 @@ int main (int argc, char **argv) - - amroot = (getuid () == 0); - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - - if (geteuid() != 0) { - fprintf (stderr, _("%s: Cannot possibly work without effective root\n"), Prog); -diff -up shadow-4.9/src/logoutd.c.debug1 shadow-4.9/src/logoutd.c ---- shadow-4.9/src/logoutd.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/src/logoutd.c 2022-01-10 10:45:52.206132965 +0100 -@@ -40,11 +40,11 @@ - #include - #include "defines.h" - #include "prototypes.h" -+#include "shadowlog.h" - /* - * Global variables - */ - const char *Prog; --FILE *shadow_logfd = NULL; - - #ifndef DEFAULT_HUP_MESG - #define DEFAULT_HUP_MESG _("login time exceeded\n\n") -@@ -188,7 +188,8 @@ int main (int argc, char **argv) - * Start syslogging everything - */ - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - - OPENLOG ("logoutd"); - -diff -up shadow-4.9/src/newgidmap.c.debug1 shadow-4.9/src/newgidmap.c ---- shadow-4.9/src/newgidmap.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/src/newgidmap.c 2022-01-10 10:45:52.206132965 +0100 -@@ -41,12 +41,12 @@ - #include "subordinateio.h" - #include "getdef.h" - #include "idmapping.h" -+#include "shadowlog.h" - - /* - * Global variables - */ - const char *Prog; --FILE *shadow_logfd = NULL; - - - static bool verify_range(struct passwd *pw, struct map_range *range, bool *allow_setgroups) -@@ -177,7 +177,8 @@ int main(int argc, char **argv) - bool allow_setgroups = false; - - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - - /* - * The valid syntax are -diff -up shadow-4.9/src/newgrp.c.debug1 shadow-4.9/src/newgrp.c ---- shadow-4.9/src/newgrp.c.debug1 2022-01-10 10:45:52.199132915 +0100 -+++ shadow-4.9/src/newgrp.c 2022-01-10 10:45:52.206132965 +0100 -@@ -44,12 +44,12 @@ - #include "prototypes.h" - /*@-exitarg@*/ - #include "exitcodes.h" -+#include "shadowlog.h" - - /* - * Global variables - */ - const char *Prog; --FILE *shadow_logfd = NULL; - - extern char **newenvp; - extern char **environ; -@@ -446,7 +446,8 @@ int main (int argc, char **argv) - * don't need to re-exec anything. -- JWP - */ - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - is_newgrp = (strcmp (Prog, "newgrp") == 0); - OPENLOG (is_newgrp ? "newgrp" : "sg"); - argc--; -diff -up shadow-4.9/src/new_subid_range.c.debug1 shadow-4.9/src/new_subid_range.c ---- shadow-4.9/src/new_subid_range.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/src/new_subid_range.c 2022-01-10 10:45:52.206132965 +0100 -@@ -3,11 +3,11 @@ - #include "subid.h" - #include "stdlib.h" - #include "prototypes.h" -+#include "shadowlog.h" - - /* Test program for the subid creation routine */ - - const char *Prog; --FILE *shadow_logfd = NULL; - - void usage(void) - { -@@ -27,7 +27,8 @@ int main(int argc, char *argv[]) - bool ok; - - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - while ((c = getopt(argc, argv, "gn")) != EOF) { - switch(c) { - case 'n': makenew = true; break; -diff -up shadow-4.9/src/newuidmap.c.debug1 shadow-4.9/src/newuidmap.c ---- shadow-4.9/src/newuidmap.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/src/newuidmap.c 2022-01-10 10:45:52.206132965 +0100 -@@ -41,12 +41,12 @@ - #include "subordinateio.h" - #include "getdef.h" - #include "idmapping.h" -+#include "shadowlog.h" - - /* - * Global variables - */ - const char *Prog; --FILE *shadow_logfd = NULL; - - static bool verify_range(struct passwd *pw, struct map_range *range) - { -@@ -107,7 +107,8 @@ int main(int argc, char **argv) - int written; - - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - - /* - * The valid syntax are -diff -up shadow-4.9/src/newusers.c.debug1 shadow-4.9/src/newusers.c ---- shadow-4.9/src/newusers.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/src/newusers.c 2022-01-10 10:45:52.207132972 +0100 -@@ -70,12 +70,12 @@ - #include "subordinateio.h" - #endif /* ENABLE_SUBIDS */ - #include "chkname.h" -+#include "shadowlog.h" - - /* - * Global variables - */ - const char *Prog; --FILE *shadow_logfd = NULL; - - static bool rflg = false; /* create a system account */ - #ifndef USE_PAM -@@ -1071,7 +1071,8 @@ int main (int argc, char **argv) - #endif /* USE_PAM */ - - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.9/src/passwd.c.debug1 shadow-4.9/src/passwd.c ---- shadow-4.9/src/passwd.c.debug1 2022-01-10 10:45:52.189132844 +0100 -+++ shadow-4.9/src/passwd.c 2022-01-10 10:45:52.207132972 +0100 -@@ -50,6 +50,7 @@ - #include "pwauth.h" - #include "pwio.h" - #include "shadowio.h" -+#include "shadowlog.h" - - /* - * exit status values -@@ -66,7 +67,6 @@ - * Global variables - */ - const char *Prog; /* Program name */ --FILE *shadow_logfd = NULL; - - static char *name; /* The name of user whose password is being changed */ - static char *myname; /* The current user's name */ -@@ -761,7 +761,8 @@ int main (int argc, char **argv) - * most error messages. - */ - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.9/src/pwck.c.debug1 shadow-4.9/src/pwck.c ---- shadow-4.9/src/pwck.c.debug1 2022-01-10 10:45:52.198132908 +0100 -+++ shadow-4.9/src/pwck.c 2022-01-10 10:45:52.207132972 +0100 -@@ -52,6 +52,7 @@ - #ifdef WITH_TCB - #include "tcbfuncs.h" - #endif /* WITH_TCB */ -+#include "shadowlog.h" - - /* - * Exit codes -@@ -70,7 +71,6 @@ - * Global variables - */ - const char *Prog; --FILE *shadow_logfd = NULL; - - static bool use_system_pw_file = true; - static bool use_system_spw_file = true; -@@ -857,7 +857,8 @@ int main (int argc, char **argv) - * Get my name so that I can use it to report errors. - */ - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.9/src/pwconv.c.debug1 shadow-4.9/src/pwconv.c ---- shadow-4.9/src/pwconv.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/src/pwconv.c 2022-01-10 10:45:52.207132972 +0100 -@@ -73,6 +73,7 @@ - #include "shadowio.h" - #include "nscd.h" - #include "sssd.h" -+#include "shadowlog.h" - - /* - * exit status values -@@ -89,7 +90,6 @@ - * Global variables - */ - const char *Prog; --FILE *shadow_logfd = NULL; - - static bool spw_locked = false; - static bool pw_locked = false; -@@ -177,7 +177,8 @@ int main (int argc, char **argv) - struct spwd spent; - - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.9/src/pwunconv.c.debug1 shadow-4.9/src/pwunconv.c ---- shadow-4.9/src/pwunconv.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/src/pwunconv.c 2022-01-10 10:45:52.207132972 +0100 -@@ -48,12 +48,12 @@ - #include "shadowio.h" - /*@-exitarg@*/ - #include "exitcodes.h" -+#include "shadowlog.h" - - /* - * Global variables - */ - const char *Prog; --FILE *shadow_logfd = NULL; - - static bool spw_locked = false; - static bool pw_locked = false; -@@ -138,7 +138,8 @@ int main (int argc, char **argv) - const struct spwd *spwd; - - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.9/src/su.c.debug1 shadow-4.9/src/su.c ---- shadow-4.9/src/su.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/src/su.c 2022-01-10 10:45:52.207132972 +0100 -@@ -77,12 +77,12 @@ - #endif /* USE_PAM */ - /*@-exitarg@*/ - #include "exitcodes.h" -+#include "shadowlog.h" - - /* - * Global variables - */ - const char *Prog; --FILE *shadow_logfd = NULL; - static /*@observer@*/const char *caller_tty = NULL; /* Name of tty SU is run from */ - static bool caller_is_root = false; - static uid_t caller_uid; -@@ -717,7 +717,8 @@ static void save_caller_context (char ** - * most error messages. - */ - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - - caller_uid = getuid (); - caller_is_root = (caller_uid == 0); -diff -up shadow-4.9/src/sulogin.c.debug1 shadow-4.9/src/sulogin.c ---- shadow-4.9/src/sulogin.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/src/sulogin.c 2022-01-10 10:45:52.207132972 +0100 -@@ -45,12 +45,12 @@ - #include "pwauth.h" - /*@-exitarg@*/ - #include "exitcodes.h" -+#include "shadowlog.h" - - /* - * Global variables - */ - const char *Prog; --FILE *shadow_logfd = NULL; - - static char name[BUFSIZ]; - static char pass[BUFSIZ]; -@@ -107,7 +107,8 @@ static RETSIGTYPE catch_signals (unused - #endif - - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); - (void) textdomain (PACKAGE); -diff -up shadow-4.9/src/useradd.c.debug1 shadow-4.9/src/useradd.c ---- shadow-4.9/src/useradd.c.debug1 2022-01-10 10:45:52.197132901 +0100 -+++ shadow-4.9/src/useradd.c 2022-01-10 10:45:52.207132972 +0100 -@@ -78,6 +78,7 @@ - #ifdef WITH_TCB - #include "tcbfuncs.h" - #endif -+#include "shadowlog.h" - - #ifndef SKEL_DIR - #define SKEL_DIR "/etc/skel" -@@ -96,7 +97,6 @@ - * Global variables - */ - const char *Prog; --FILE *shadow_logfd = NULL; - - /* - * These defaults are used if there is no defaults file. -@@ -2359,7 +2359,8 @@ int main (int argc, char **argv) - * Get my name so that I can use it to report errors. - */ - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.9/src/userdel.c.debug1 shadow-4.9/src/userdel.c ---- shadow-4.9/src/userdel.c.debug1 2022-01-10 10:45:52.186132823 +0100 -+++ shadow-4.9/src/userdel.c 2022-01-10 10:45:52.208132979 +0100 -@@ -72,6 +72,7 @@ - #ifdef ENABLE_SUBIDS - #include "subordinateio.h" - #endif /* ENABLE_SUBIDS */ -+#include "shadowlog.h" - - /* - * exit status values -@@ -91,7 +92,6 @@ - * Global variables - */ - const char *Prog; --FILE *shadow_logfd = NULL; - - static char *user_name; - static uid_t user_id; -@@ -944,7 +944,8 @@ int main (int argc, char **argv) - * Get my name so that I can use it to report errors. - */ - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); - (void) textdomain (PACKAGE); -diff -up shadow-4.9/src/usermod.c.debug1 shadow-4.9/src/usermod.c ---- shadow-4.9/src/usermod.c.debug1 2022-01-10 10:45:52.193132872 +0100 -+++ shadow-4.9/src/usermod.c 2022-01-10 10:45:52.208132979 +0100 -@@ -74,6 +74,7 @@ - #ifdef WITH_TCB - #include "tcbfuncs.h" - #endif -+#include "shadowlog.h" - - /* - * exit status values -@@ -105,7 +106,6 @@ - * Global variables - */ - const char *Prog; --FILE *shadow_logfd = NULL; - - static char *user_name; - static char *user_newname; -@@ -2172,7 +2172,8 @@ int main (int argc, char **argv) - * Get my name so that I can use it to report errors. - */ - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); -diff -up shadow-4.9/src/vipw.c.debug1 shadow-4.9/src/vipw.c ---- shadow-4.9/src/vipw.c.debug1 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/src/vipw.c 2022-01-10 10:45:52.208132979 +0100 -@@ -53,6 +53,7 @@ - #include - #include "tcbfuncs.h" - #endif /* WITH_TCB */ -+#include "shadowlog.h" - - #define MSG_WARN_EDIT_OTHER_FILE _( \ - "You have modified %s.\n"\ -@@ -63,7 +64,6 @@ - * Global variables - */ - const char *Prog; --FILE *shadow_logfd = NULL; - - static const char *filename, *fileeditname; - static bool filelocked = false; -@@ -482,7 +482,8 @@ int main (int argc, char **argv) - bool do_vipw; - - Prog = Basename (argv[0]); -- shadow_logfd = stderr; -+ log_set_progname(Prog); -+ log_set_logfd(stderr); - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); diff --git a/shadow-4.9-move-create-home.patch b/shadow-4.9-move-create-home.patch deleted file mode 100644 index 0ed6ea7..0000000 --- a/shadow-4.9-move-create-home.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 09c752f00f9dfc610f66d68be38c9e5be8ca7f15 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Fri, 8 Oct 2021 13:09:59 +0200 -Subject: [PATCH] useradd: create directories after the SELinux user - -Create the home and mail folders after the SELinux user has been set for -the added user. This will allow the folders to be created with the -SELinux user label. - -Signed-off-by: Iker Pedrosa ---- - src/useradd.c | 46 +++++++++++++++++++++++----------------------- - 1 file changed, 23 insertions(+), 23 deletions(-) - -diff --git a/src/useradd.c b/src/useradd.c -index 6269c01c..b463a170 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -2670,27 +2670,12 @@ int main (int argc, char **argv) - - usr_update (); - -- if (mflg) { -- create_home (); -- if (home_added) { -- copy_tree (def_template, prefix_user_home, false, false, -- (uid_t)-1, user_id, (gid_t)-1, user_gid); -- } else { -- fprintf (stderr, -- _("%s: warning: the home directory %s already exists.\n" -- "%s: Not copying any file from skel directory into it.\n"), -- Prog, user_home, Prog); -- } -- -- } -- -- /* Do not create mail directory for system accounts */ -- if (!rflg) { -- create_mail (); -- } -- - close_files (); - -+ nscd_flush_cache ("passwd"); -+ nscd_flush_cache ("group"); -+ sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP); -+ - /* - * tallylog_reset needs to be able to lookup - * a valid existing user name, -@@ -2716,15 +2701,30 @@ int main (int argc, char **argv) - } - #endif /* WITH_SELINUX */ - -+ if (mflg) { -+ create_home (); -+ if (home_added) { -+ copy_tree (def_template, prefix_user_home, false, false, -+ (uid_t)-1, user_id, (gid_t)-1, user_gid); -+ } else { -+ fprintf (stderr, -+ _("%s: warning: the home directory %s already exists.\n" -+ "%s: Not copying any file from skel directory into it.\n"), -+ Prog, user_home, Prog); -+ } -+ -+ } -+ -+ /* Do not create mail directory for system accounts */ -+ if (!rflg) { -+ create_mail (); -+ } -+ - if (run_parts ("/etc/shadow-maint/useradd-post.d", (char*)user_name, - "useradd")) { - exit(1); - } - -- nscd_flush_cache ("passwd"); -- nscd_flush_cache ("group"); -- sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP); -- - return E_SUCCESS; - } - --- -2.31.1 - diff --git a/shadow-4.9-newgrp-fix-segmentation-fault.patch b/shadow-4.9-newgrp-fix-segmentation-fault.patch deleted file mode 100644 index 49332a1..0000000 --- a/shadow-4.9-newgrp-fix-segmentation-fault.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 497e90751bc0d95cc998b0f06305040563903948 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Wed, 10 Nov 2021 12:02:04 +0100 -Subject: [PATCH] newgrp: fix segmentation fault - -Fix segmentation fault in newgrp when xgetspnam() returns a NULL value -that is immediately freed. - -The error was committed in -https://github.com/shadow-maint/shadow/commit/e65cc6aebcb4132fa413f00a905216a5b35b3d57 - -Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2019553 - -Signed-off-by: Iker Pedrosa ---- - src/newgrp.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/newgrp.c b/src/newgrp.c -index 730f47e8..566f1c89 100644 ---- a/src/newgrp.c -+++ b/src/newgrp.c -@@ -163,8 +163,8 @@ static void check_perms (const struct group *grp, - spwd = xgetspnam (pwd->pw_name); - if (NULL != spwd) { - pwd->pw_passwd = xstrdup (spwd->sp_pwdp); -+ spw_free (spwd); - } -- spw_free (spwd); - - if ((pwd->pw_passwd[0] == '\0') && (grp->gr_passwd[0] != '\0')) { - needspasswd = true; --- -2.31.1 - diff --git a/shadow-4.9-newuidmap-libeconf-dependency.patch b/shadow-4.9-newuidmap-libeconf-dependency.patch deleted file mode 100644 index a1907a6..0000000 --- a/shadow-4.9-newuidmap-libeconf-dependency.patch +++ /dev/null @@ -1,15 +0,0 @@ -diff --git a/src/Makefile.am b/src/Makefile.am -index 7c1a3491..6cc873be 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -96,8 +96,8 @@ LIBCRYPT_NOPAM = $(LIBCRYPT) - endif - - chage_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) --newuidmap_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP) -ldl --newgidmap_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP) -ldl -+newuidmap_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP) $(LIBECONF) -ldl -+newgidmap_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP) $(LIBECONF) -ldl - chfn_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF) - chgpasswd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF) - chsh_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF) diff --git a/shadow-4.9-null-tm.patch b/shadow-4.9-null-tm.patch deleted file mode 100644 index 249b27b..0000000 --- a/shadow-4.9-null-tm.patch +++ /dev/null @@ -1,70 +0,0 @@ -Index: shadow-4.5/src/chage.c -=================================================================== ---- shadow-4.5.orig/src/chage.c -+++ shadow-4.5/src/chage.c -@@ -168,6 +168,10 @@ static void date_to_str (char *buf, size - struct tm *tp; - - tp = gmtime (&date); -+ if (tp == NULL) { -+ (void) snprintf (buf, maxsize, "(unknown)"); -+ return; -+ } - #ifdef HAVE_STRFTIME - (void) strftime (buf, maxsize, "%Y-%m-%d", tp); - #else -Index: shadow-4.5/src/lastlog.c -=================================================================== ---- shadow-4.5.orig/src/lastlog.c -+++ shadow-4.5/src/lastlog.c -@@ -158,13 +158,17 @@ static void print_one (/*@null@*/const s - - ll_time = ll.ll_time; - tm = localtime (&ll_time); -+ if (tm == NULL) { -+ cp = "(unknown)"; -+ } else { - #ifdef HAVE_STRFTIME -- strftime (ptime, sizeof (ptime), "%a %b %e %H:%M:%S %z %Y", tm); -- cp = ptime; -+ strftime (ptime, sizeof (ptime), "%a %b %e %H:%M:%S %z %Y", tm); -+ cp = ptime; - #else -- cp = asctime (tm); -- cp[24] = '\0'; -+ cp = asctime (tm); -+ cp[24] = '\0'; - #endif -+ } - - if (ll.ll_time == (time_t) 0) { - cp = _("**Never logged in**\0"); -Index: shadow-4.5/src/passwd.c -=================================================================== ---- shadow-4.5.orig/src/passwd.c -+++ shadow-4.5/src/passwd.c -@@ -455,6 +455,9 @@ static /*@observer@*/const char *date_to - struct tm *tm; - - tm = gmtime (&t); -+ if (tm == NULL) { -+ return "(unknown)"; -+ } - #ifdef HAVE_STRFTIME - (void) strftime (buf, sizeof buf, "%m/%d/%Y", tm); - #else /* !HAVE_STRFTIME */ -Index: shadow-4.5/src/usermod.c -=================================================================== ---- shadow-4.5.orig/src/usermod.c -+++ shadow-4.5/src/usermod.c -@@ -210,6 +210,10 @@ static void date_to_str (/*@unique@*//*@ - } else { - time_t t = (time_t) date; - tp = gmtime (&t); -+ if (tp == NULL) { -+ strncpy (buf, "unknown", maxsize); -+ return; -+ } - #ifdef HAVE_STRFTIME - strftime (buf, maxsize, "%Y-%m-%d", tp); - #else diff --git a/shadow-4.9-pwck-fix-segfault-when-calling-fprintf.patch b/shadow-4.9-pwck-fix-segfault-when-calling-fprintf.patch deleted file mode 100644 index e7761b7..0000000 --- a/shadow-4.9-pwck-fix-segfault-when-calling-fprintf.patch +++ /dev/null @@ -1,30 +0,0 @@ -From d8e54618feea201987c1f3cb402ed50d1d8b604f Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Mon, 15 Nov 2021 12:40:15 +0100 -Subject: [PATCH] pwck: fix segfault when calling fprintf() - -As shadow_logfd variable is not set at the beginning of the program if -something fails and fprintf() is called a segmentation fault happens. - -Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2021339 - -Signed-off-by: Iker Pedrosa ---- - src/pwck.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/pwck.c b/src/pwck.c -index 4248944a..4ce86af2 100644 ---- a/src/pwck.c -+++ b/src/pwck.c -@@ -857,6 +857,7 @@ int main (int argc, char **argv) - * Get my name so that I can use it to report errors. - */ - Prog = Basename (argv[0]); -+ shadow_logfd = stderr; - - (void) setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); --- -2.31.1 - diff --git a/shadow-4.9-rename-prog-to-shadow-progname.patch b/shadow-4.9-rename-prog-to-shadow-progname.patch deleted file mode 100644 index d3a73a3..0000000 --- a/shadow-4.9-rename-prog-to-shadow-progname.patch +++ /dev/null @@ -1,507 +0,0 @@ -diff -up shadow-4.9/lib/commonio.c.debug2 shadow-4.9/lib/commonio.c ---- shadow-4.9/lib/commonio.c.debug2 2022-01-10 10:57:47.535238522 +0100 -+++ shadow-4.9/lib/commonio.c 2022-01-10 10:57:47.544238586 +0100 -@@ -147,7 +147,7 @@ static int do_lock_file (const char *fil - if (log) { - (void) fprintf (shadow_logfd, - "%s: %s: %s\n", -- Prog, file, strerror (errno)); -+ shadow_progname, file, strerror (errno)); - } - return 0; - } -@@ -159,7 +159,7 @@ static int do_lock_file (const char *fil - if (log) { - (void) fprintf (shadow_logfd, - "%s: %s file write error: %s\n", -- Prog, file, strerror (errno)); -+ shadow_progname, file, strerror (errno)); - } - (void) close (fd); - unlink (file); -@@ -169,7 +169,7 @@ static int do_lock_file (const char *fil - if (log) { - (void) fprintf (shadow_logfd, - "%s: %s file sync error: %s\n", -- Prog, file, strerror (errno)); -+ shadow_progname, file, strerror (errno)); - } - (void) close (fd); - unlink (file); -@@ -182,7 +182,7 @@ static int do_lock_file (const char *fil - if ((0==retval) && log) { - (void) fprintf (shadow_logfd, - "%s: %s: lock file already used\n", -- Prog, file); -+ shadow_progname, file); - } - unlink (file); - return retval; -@@ -193,7 +193,7 @@ static int do_lock_file (const char *fil - if (log) { - (void) fprintf (shadow_logfd, - "%s: %s: %s\n", -- Prog, lock, strerror (errno)); -+ shadow_progname, lock, strerror (errno)); - } - unlink (file); - errno = EINVAL; -@@ -205,7 +205,7 @@ static int do_lock_file (const char *fil - if (log) { - (void) fprintf (shadow_logfd, - "%s: existing lock file %s without a PID\n", -- Prog, lock); -+ shadow_progname, lock); - } - unlink (file); - errno = EINVAL; -@@ -216,7 +216,7 @@ static int do_lock_file (const char *fil - if (log) { - (void) fprintf (shadow_logfd, - "%s: existing lock file %s with an invalid PID '%s'\n", -- Prog, lock, buf); -+ shadow_progname, lock, buf); - } - unlink (file); - errno = EINVAL; -@@ -226,7 +226,7 @@ static int do_lock_file (const char *fil - if (log) { - (void) fprintf (shadow_logfd, - "%s: lock %s already used by PID %lu\n", -- Prog, lock, (unsigned long) pid); -+ shadow_progname, lock, (unsigned long) pid); - } - unlink (file); - errno = EEXIST; -@@ -236,7 +236,7 @@ static int do_lock_file (const char *fil - if (log) { - (void) fprintf (shadow_logfd, - "%s: cannot get lock %s: %s\n", -- Prog, lock, strerror (errno)); -+ shadow_progname, lock, strerror (errno)); - } - unlink (file); - return 0; -@@ -248,13 +248,13 @@ static int do_lock_file (const char *fil - if ((0==retval) && log) { - (void) fprintf (shadow_logfd, - "%s: %s: lock file already used\n", -- Prog, file); -+ shadow_progname, file); - } - } else { - if (log) { - (void) fprintf (shadow_logfd, - "%s: cannot get lock %s: %s\n", -- Prog, lock, strerror (errno)); -+ shadow_progname, lock, strerror (errno)); - } - } - -@@ -449,7 +449,7 @@ int commonio_lock (struct commonio_db *d - if (geteuid () != 0) { - (void) fprintf (shadow_logfd, - "%s: Permission denied.\n", -- Prog); -+ shadow_progname); - } - return 0; /* failure */ - } -@@ -484,7 +484,7 @@ int commonio_lock (struct commonio_db *d - /* no unnecessary retries on "permission denied" errors */ - if (geteuid () != 0) { - (void) fprintf (shadow_logfd, "%s: Permission denied.\n", -- Prog); -+ shadow_progname); - return 0; - } - } -diff -up shadow-4.9/lib/nscd.c.debug2 shadow-4.9/lib/nscd.c ---- shadow-4.9/lib/nscd.c.debug2 2022-01-10 10:57:47.537238536 +0100 -+++ shadow-4.9/lib/nscd.c 2022-01-10 10:57:47.544238586 +0100 -@@ -26,7 +26,7 @@ int nscd_flush_cache (const char *servic - - if (run_command (cmd, spawnedArgs, spawnedEnv, &status) != 0) { - /* run_command writes its own more detailed message. */ -- (void) fprintf (shadow_logfd, _(MSG_NSCD_FLUSH_CACHE_FAILED), Prog); -+ (void) fprintf (shadow_logfd, _(MSG_NSCD_FLUSH_CACHE_FAILED), shadow_progname); - return -1; - } - -@@ -34,7 +34,7 @@ int nscd_flush_cache (const char *servic - if (!WIFEXITED (status)) { - (void) fprintf (shadow_logfd, - _("%s: nscd did not terminate normally (signal %d)\n"), -- Prog, WTERMSIG (status)); -+ shadow_progname, WTERMSIG (status)); - return -1; - } else if (code == E_CMD_NOTFOUND) { - /* nscd is not installed, or it is installed but uses an -@@ -45,8 +45,8 @@ int nscd_flush_cache (const char *servic - return 0; - } else if (code != 0) { - (void) fprintf (shadow_logfd, _("%s: nscd exited with status %d\n"), -- Prog, code); -- (void) fprintf (shadow_logfd, _(MSG_NSCD_FLUSH_CACHE_FAILED), Prog); -+ shadow_progname, code); -+ (void) fprintf (shadow_logfd, _(MSG_NSCD_FLUSH_CACHE_FAILED), shadow_progname); - return -1; - } - -diff -up shadow-4.9/lib/selinux.c.debug2 shadow-4.9/lib/selinux.c ---- shadow-4.9/lib/selinux.c.debug2 2022-01-10 10:57:47.538238543 +0100 -+++ shadow-4.9/lib/selinux.c 2022-01-10 10:57:47.544238586 +0100 -@@ -216,7 +216,7 @@ int check_selinux_permit (const char *pe - if (getprevcon_raw (&user_context_raw) != 0) { - fprintf (shadow_logfd, - _("%s: can not get previous SELinux process context: %s\n"), -- Prog, strerror (errno)); -+ shadow_progname, strerror (errno)); - SYSLOG ((LOG_WARN, - "can not get previous SELinux process context: %s", - strerror (errno))); -diff -up shadow-4.9/lib/shadowlog.c.debug2 shadow-4.9/lib/shadowlog.c ---- shadow-4.9/lib/shadowlog.c.debug2 2022-01-10 10:57:47.538238543 +0100 -+++ shadow-4.9/lib/shadowlog.c 2022-01-10 10:57:47.544238586 +0100 -@@ -2,14 +2,17 @@ - - #include "lib/shadowlog_internal.h" - -+const char *shadow_progname; -+FILE *shadow_logfd; -+ - void log_set_progname(const char *progname) - { -- Prog = progname; -+ shadow_progname = progname; - } - - const char *log_get_progname(void) - { -- return Prog; -+ return shadow_progname; - } - - void log_set_logfd(FILE *fd) -diff -up shadow-4.9/lib/shadowlog_internal.h.debug2 shadow-4.9/lib/shadowlog_internal.h ---- shadow-4.9/lib/shadowlog_internal.h.debug2 2022-01-10 10:57:47.538238543 +0100 -+++ shadow-4.9/lib/shadowlog_internal.h 2022-01-10 10:57:47.544238586 +0100 -@@ -1,2 +1,2 @@ --const char *Prog; /* Program name showed in error messages */ --FILE *shadow_logfd; /* file descripter to which error messages are printed */ -+extern const char *shadow_progname; /* Program name showed in error messages */ -+extern FILE *shadow_logfd; /* file descripter to which error messages are printed */ -diff -up shadow-4.9/lib/spawn.c.debug2 shadow-4.9/lib/spawn.c ---- shadow-4.9/lib/spawn.c.debug2 2022-01-10 10:57:47.538238543 +0100 -+++ shadow-4.9/lib/spawn.c 2022-01-10 10:57:47.544238586 +0100 -@@ -60,11 +60,11 @@ int run_command (const char *cmd, const - exit (E_CMD_NOTFOUND); - } - fprintf (shadow_logfd, "%s: cannot execute %s: %s\n", -- Prog, cmd, strerror (errno)); -+ shadow_progname, cmd, strerror (errno)); - exit (E_CMD_NOEXEC); - } else if ((pid_t)-1 == pid) { - fprintf (shadow_logfd, "%s: cannot execute %s: %s\n", -- Prog, cmd, strerror (errno)); -+ shadow_progname, cmd, strerror (errno)); - return -1; - } - -@@ -77,7 +77,7 @@ int run_command (const char *cmd, const - - if ((pid_t)-1 == wpid) { - fprintf (shadow_logfd, "%s: waitpid (status: %d): %s\n", -- Prog, *status, strerror (errno)); -+ shadow_progname, *status, strerror (errno)); - return -1; - } - -diff -up shadow-4.9/lib/sssd.c.debug2 shadow-4.9/lib/sssd.c ---- shadow-4.9/lib/sssd.c.debug2 2022-01-10 10:57:47.538238543 +0100 -+++ shadow-4.9/lib/sssd.c 2022-01-10 10:57:47.544238586 +0100 -@@ -48,22 +48,22 @@ int sssd_flush_cache (int dbflags) - free(sss_cache_args); - if (rv != 0) { - /* run_command writes its own more detailed message. */ -- SYSLOG ((LOG_WARN, MSG_SSSD_FLUSH_CACHE_FAILED, Prog)); -+ SYSLOG ((LOG_WARN, MSG_SSSD_FLUSH_CACHE_FAILED, shadow_progname)); - return -1; - } - - code = WEXITSTATUS (status); - if (!WIFEXITED (status)) { - SYSLOG ((LOG_WARN, "%s: sss_cache did not terminate normally (signal %d)", -- Prog, WTERMSIG (status))); -+ shadow_progname, WTERMSIG (status))); - return -1; - } else if (code == E_CMD_NOTFOUND) { - /* sss_cache is not installed, or it is installed but uses an - interpreter that is missing. Probably the former. */ - return 0; - } else if (code != 0) { -- SYSLOG ((LOG_WARN, "%s: sss_cache exited with status %d", Prog, code)); -- SYSLOG ((LOG_WARN, MSG_SSSD_FLUSH_CACHE_FAILED, Prog)); -+ SYSLOG ((LOG_WARN, "%s: sss_cache exited with status %d", shadow_progname, code)); -+ SYSLOG ((LOG_WARN, MSG_SSSD_FLUSH_CACHE_FAILED, shadow_progname)); - return -1; - } - -diff -up shadow-4.9/lib/tcbfuncs.c.debug2 shadow-4.9/lib/tcbfuncs.c ---- shadow-4.9/lib/tcbfuncs.c.debug2 2022-01-10 10:57:47.538238543 +0100 -+++ shadow-4.9/lib/tcbfuncs.c 2022-01-10 10:59:01.228764507 +0100 -@@ -74,7 +74,7 @@ shadowtcb_status shadowtcb_gain_priv (vo - * to exit soon. - */ - #define OUT_OF_MEMORY do { \ -- fprintf (shadow_logfd, _("%s: out of memory\n"), Prog); \ -+ fprintf (shadow_logfd, _("%s: out of memory\n"), shadow_progname); \ - (void) fflush (shadow_logfd); \ - } while (false) - -@@ -120,7 +120,7 @@ static /*@null@*/ char *shadowtcb_path_r - if (lstat (path, &st) != 0) { - fprintf (shadow_logfd, - _("%s: Cannot stat %s: %s\n"), -- Prog, path, strerror (errno)); -+ shadow_progname, path, strerror (errno)); - free (path); - return NULL; - } -@@ -136,7 +136,7 @@ static /*@null@*/ char *shadowtcb_path_r - if (!S_ISLNK (st.st_mode)) { - fprintf (shadow_logfd, - _("%s: %s is neither a directory, nor a symlink.\n"), -- Prog, path); -+ shadow_progname, path); - free (path); - return NULL; - } -@@ -144,7 +144,7 @@ static /*@null@*/ char *shadowtcb_path_r - if (-1 == ret) { - fprintf (shadow_logfd, - _("%s: Cannot read symbolic link %s: %s\n"), -- Prog, path, strerror (errno)); -+ shadow_progname, path, strerror (errno)); - free (path); - return NULL; - } -@@ -153,7 +153,7 @@ static /*@null@*/ char *shadowtcb_path_r - link[sizeof(link) - 1] = '\0'; - fprintf (shadow_logfd, - _("%s: Suspiciously long symlink: %s\n"), -- Prog, link); -+ shadow_progname, link); - return NULL; - } - link[(size_t)ret] = '\0'; -@@ -211,7 +211,7 @@ static shadowtcb_status mkdir_leading (c - if (stat (TCB_DIR, &st) != 0) { - fprintf (shadow_logfd, - _("%s: Cannot stat %s: %s\n"), -- Prog, TCB_DIR, strerror (errno)); -+ shadow_progname, TCB_DIR, strerror (errno)); - goto out_free_path; - } - while ((ind = strchr (ptr, '/'))) { -@@ -223,19 +223,19 @@ static shadowtcb_status mkdir_leading (c - if ((mkdir (dir, 0700) != 0) && (errno != EEXIST)) { - fprintf (shadow_logfd, - _("%s: Cannot create directory %s: %s\n"), -- Prog, dir, strerror (errno)); -+ shadow_progname, dir, strerror (errno)); - goto out_free_dir; - } - if (chown (dir, 0, st.st_gid) != 0) { - fprintf (shadow_logfd, - _("%s: Cannot change owner of %s: %s\n"), -- Prog, dir, strerror (errno)); -+ shadow_progname, dir, strerror (errno)); - goto out_free_dir; - } - if (chmod (dir, 0711) != 0) { - fprintf (shadow_logfd, - _("%s: Cannot change mode of %s: %s\n"), -- Prog, dir, strerror (errno)); -+ shadow_progname, dir, strerror (errno)); - goto out_free_dir; - } - free (dir); -@@ -265,7 +265,7 @@ static shadowtcb_status unlink_suffs (co - if ((unlink (tmp) != 0) && (errno != ENOENT)) { - fprintf (shadow_logfd, - _("%s: unlink: %s: %s\n"), -- Prog, tmp, strerror (errno)); -+ shadow_progname, tmp, strerror (errno)); - free (tmp); - return SHADOWTCB_FAILURE; - } -@@ -290,7 +290,7 @@ static shadowtcb_status rmdir_leading (c - if (errno != ENOTEMPTY) { - fprintf (shadow_logfd, - _("%s: Cannot remove directory %s: %s\n"), -- Prog, dir, strerror (errno)); -+ shadow_progname, dir, strerror (errno)); - ret = SHADOWTCB_FAILURE; - } - free (dir); -@@ -319,7 +319,7 @@ static shadowtcb_status move_dir (const - if (stat (olddir, &oldmode) != 0) { - fprintf (shadow_logfd, - _("%s: Cannot stat %s: %s\n"), -- Prog, olddir, strerror (errno)); -+ shadow_progname, olddir, strerror (errno)); - goto out_free; - } - old_uid = oldmode.st_uid; -@@ -346,7 +346,7 @@ static shadowtcb_status move_dir (const - if (rename (real_old_dir, real_new_dir) != 0) { - fprintf (shadow_logfd, - _("%s: Cannot rename %s to %s: %s\n"), -- Prog, real_old_dir, real_new_dir, strerror (errno)); -+ shadow_progname, real_old_dir, real_new_dir, strerror (errno)); - goto out_free; - } - if (rmdir_leading (real_old_dir_rel) == SHADOWTCB_FAILURE) { -@@ -355,7 +355,7 @@ static shadowtcb_status move_dir (const - if ((unlink (olddir) != 0) && (errno != ENOENT)) { - fprintf (shadow_logfd, - _("%s: Cannot remove %s: %s\n"), -- Prog, olddir, strerror (errno)); -+ shadow_progname, olddir, strerror (errno)); - goto out_free; - } - if (asprintf (&newdir, TCB_DIR "/%s", user_newname) == -1) { -@@ -369,7 +369,7 @@ static shadowtcb_status move_dir (const - && (symlink (real_new_dir_rel, newdir) != 0)) { - fprintf (shadow_logfd, - _("%s: Cannot create symbolic link %s: %s\n"), -- Prog, real_new_dir_rel, strerror (errno)); -+ shadow_progname, real_new_dir_rel, strerror (errno)); - goto out_free; - } - ret = SHADOWTCB_SUCCESS; -@@ -468,31 +468,31 @@ shadowtcb_status shadowtcb_move (/*@NULL - if (stat (tcbdir, &dirmode) != 0) { - fprintf (shadow_logfd, - _("%s: Cannot stat %s: %s\n"), -- Prog, tcbdir, strerror (errno)); -+ shadow_progname, tcbdir, strerror (errno)); - goto out_free; - } - if (chown (tcbdir, 0, 0) != 0) { - fprintf (shadow_logfd, - _("%s: Cannot change owners of %s: %s\n"), -- Prog, tcbdir, strerror (errno)); -+ shadow_progname, tcbdir, strerror (errno)); - goto out_free; - } - if (chmod (tcbdir, 0700) != 0) { - fprintf (shadow_logfd, - _("%s: Cannot change mode of %s: %s\n"), -- Prog, tcbdir, strerror (errno)); -+ shadow_progname, tcbdir, strerror (errno)); - goto out_free; - } - if (lstat (shadow, &filemode) != 0) { - if (errno != ENOENT) { - fprintf (shadow_logfd, - _("%s: Cannot lstat %s: %s\n"), -- Prog, shadow, strerror (errno)); -+ shadow_progname, shadow, strerror (errno)); - goto out_free; - } - fprintf (shadow_logfd, - _("%s: Warning, user %s has no tcb shadow file.\n"), -- Prog, user_newname); -+ shadow_progname, user_newname); - } else { - if (!S_ISREG (filemode.st_mode) || - filemode.st_nlink != 1) { -@@ -500,19 +500,19 @@ shadowtcb_status shadowtcb_move (/*@NULL - _("%s: Emergency: %s's tcb shadow is not a " - "regular file with st_nlink=1.\n" - "The account is left locked.\n"), -- Prog, user_newname); -+ shadow_progname, user_newname); - goto out_free; - } - if (chown (shadow, user_newid, filemode.st_gid) != 0) { - fprintf (shadow_logfd, - _("%s: Cannot change owner of %s: %s\n"), -- Prog, shadow, strerror (errno)); -+ shadow_progname, shadow, strerror (errno)); - goto out_free; - } - if (chmod (shadow, filemode.st_mode & 07777) != 0) { - fprintf (shadow_logfd, - _("%s: Cannot change mode of %s: %s\n"), -- Prog, shadow, strerror (errno)); -+ shadow_progname, shadow, strerror (errno)); - goto out_free; - } - } -@@ -522,7 +522,7 @@ shadowtcb_status shadowtcb_move (/*@NULL - if (chown (tcbdir, user_newid, dirmode.st_gid) != 0) { - fprintf (shadow_logfd, - _("%s: Cannot change owner of %s: %s\n"), -- Prog, tcbdir, strerror (errno)); -+ shadow_progname, tcbdir, strerror (errno)); - goto out_free; - } - ret = SHADOWTCB_SUCCESS; -@@ -547,7 +547,7 @@ shadowtcb_status shadowtcb_create (const - if (stat (TCB_DIR, &tcbdir_stat) != 0) { - fprintf (shadow_logfd, - _("%s: Cannot stat %s: %s\n"), -- Prog, TCB_DIR, strerror (errno)); -+ shadow_progname, TCB_DIR, strerror (errno)); - return SHADOWTCB_FAILURE; - } - shadowgid = tcbdir_stat.st_gid; -@@ -567,39 +567,39 @@ shadowtcb_status shadowtcb_create (const - if (mkdir (dir, 0700) != 0) { - fprintf (shadow_logfd, - _("%s: mkdir: %s: %s\n"), -- Prog, dir, strerror (errno)); -+ shadow_progname, dir, strerror (errno)); - goto out_free; - } - fd = open (shadow, O_RDWR | O_CREAT | O_TRUNC, 0600); - if (fd < 0) { - fprintf (shadow_logfd, - _("%s: Cannot open %s: %s\n"), -- Prog, shadow, strerror (errno)); -+ shadow_progname, shadow, strerror (errno)); - goto out_free; - } - close (fd); - if (chown (shadow, 0, authgid) != 0) { - fprintf (shadow_logfd, - _("%s: Cannot change owner of %s: %s\n"), -- Prog, shadow, strerror (errno)); -+ shadow_progname, shadow, strerror (errno)); - goto out_free; - } - if (chmod (shadow, (mode_t) ((authgid == shadowgid) ? 0600 : 0640)) != 0) { - fprintf (shadow_logfd, - _("%s: Cannot change mode of %s: %s\n"), -- Prog, shadow, strerror (errno)); -+ shadow_progname, shadow, strerror (errno)); - goto out_free; - } - if (chown (dir, 0, authgid) != 0) { - fprintf (shadow_logfd, - _("%s: Cannot change owner of %s: %s\n"), -- Prog, dir, strerror (errno)); -+ shadow_progname, dir, strerror (errno)); - goto out_free; - } - if (chmod (dir, (mode_t) ((authgid == shadowgid) ? 02700 : 02710)) != 0) { - fprintf (shadow_logfd, - _("%s: Cannot change mode of %s: %s\n"), -- Prog, dir, strerror (errno)); -+ shadow_progname, dir, strerror (errno)); - goto out_free; - } - if ( (shadowtcb_set_user (name) == SHADOWTCB_FAILURE) diff --git a/shadow-4.9-revert-useradd-fix-memleak.patch b/shadow-4.9-revert-useradd-fix-memleak.patch deleted file mode 100644 index e8251f2..0000000 --- a/shadow-4.9-revert-useradd-fix-memleak.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 4624e9fca1b02b64e25e8b2280a0186182ab73ba Mon Sep 17 00:00:00 2001 -From: Serge Hallyn -Date: Sat, 14 Aug 2021 19:37:24 -0500 -Subject: [PATCH] Revert "useradd.c:fix memleaks of grp" - -In some cases, the value which was being freed is not actually -safe to free. - -Closes #394 - -This reverts commit c44b71cec25d60efc51aec9de3abce1f6efbfcf5. ---- - src/useradd.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/src/useradd.c b/src/useradd.c -index f90127cd..0d3f390d 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -413,7 +413,6 @@ static void get_defaults (void) - } else { - def_group = grp->gr_gid; - def_gname = xstrdup (grp->gr_name); -- gr_free(grp); - } - } - --- -2.31.1 - diff --git a/shadow-4.9-semanage-close-the-selabel-handle.patch b/shadow-4.9-semanage-close-the-selabel-handle.patch deleted file mode 100644 index 11a23e4..0000000 --- a/shadow-4.9-semanage-close-the-selabel-handle.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 234af5cf67fc1a3ba99fc246ba65869a3c416545 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Fri, 8 Oct 2021 13:13:13 +0200 -Subject: [PATCH] semanage: close the selabel handle - -Close the selabel handle to update the file_context. This means that the -file_context will be remmaped and used by selabel_lookup() to return -the appropriate context to label the home folder. - -Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1993081 - -Signed-off-by: Iker Pedrosa ---- - lib/prototypes.h | 1 + - lib/selinux.c | 5 +++++ - lib/semanage.c | 1 + - 3 files changed, 7 insertions(+) - -diff --git a/lib/prototypes.h b/lib/prototypes.h -index 1d1586d4..b697e0ec 100644 ---- a/lib/prototypes.h -+++ b/lib/prototypes.h -@@ -392,6 +392,7 @@ extern /*@observer@*/const char *crypt_make_salt (/*@null@*//*@observer@*/const - /* selinux.c */ - #ifdef WITH_SELINUX - extern int set_selinux_file_context (const char *dst_name, mode_t mode); -+extern void reset_selinux_handle (void); - extern int reset_selinux_file_context (void); - extern int check_selinux_permit (const char *perm_name); - #endif -diff --git a/lib/selinux.c b/lib/selinux.c -index c83545f9..b075d4c0 100644 ---- a/lib/selinux.c -+++ b/lib/selinux.c -@@ -50,6 +50,11 @@ static void cleanup(void) - } - } - -+void reset_selinux_handle (void) -+{ -+ cleanup(); -+} -+ - /* - * set_selinux_file_context - Set the security context before any file or - * directory creation. -diff --git a/lib/semanage.c b/lib/semanage.c -index 0d30456a..a5bf9218 100644 ---- a/lib/semanage.c -+++ b/lib/semanage.c -@@ -293,6 +293,7 @@ int set_seuser (const char *login_name, const char *seuser_name) - } - - ret = 0; -+ reset_selinux_handle(); - - done: - semanage_seuser_key_free (key); --- -2.31.1 - diff --git a/shadow-4.9-shadow-progname-default-init.patch b/shadow-4.9-shadow-progname-default-init.patch deleted file mode 100644 index 0c6d616..0000000 --- a/shadow-4.9-shadow-progname-default-init.patch +++ /dev/null @@ -1,39 +0,0 @@ -diff -up shadow-4.9/lib/shadowlog.c.debug3 shadow-4.9/lib/shadowlog.c ---- shadow-4.9/lib/shadowlog.c.debug3 2022-01-10 11:16:31.636261531 +0100 -+++ shadow-4.9/lib/shadowlog.c 2022-01-10 11:16:31.637261538 +0100 -@@ -2,8 +2,8 @@ - - #include "lib/shadowlog_internal.h" - --const char *shadow_progname; --FILE *shadow_logfd; -+const char *shadow_progname = "libshadow"; -+FILE *shadow_logfd = NULL; - - void log_set_progname(const char *progname) - { -diff -up shadow-4.9/libsubid/api.c.debug3 shadow-4.9/libsubid/api.c ---- shadow-4.9/libsubid/api.c.debug3 2022-01-10 11:16:31.637261538 +0100 -+++ shadow-4.9/libsubid/api.c 2022-01-10 11:17:15.431574120 +0100 -@@ -40,17 +40,16 @@ - #include "subid.h" - #include "shadowlog.h" - --const char *Prog = "(libsubid)"; -- - bool libsubid_init(const char *progname, FILE * logfd) - { - FILE *shadow_logfd; - if (progname) { - progname = strdup(progname); -- if (progname) -- Prog = progname; -- else -+ if (!progname) - return false; -+ log_set_progname(progname); -+ } else { -+ log_set_progname("(libsubid)"); - } - - if (logfd) { diff --git a/shadow-4.9-useradd-avoid-generating-empty-subid-range.patch b/shadow-4.9-useradd-avoid-generating-empty-subid-range.patch deleted file mode 100644 index b94fd60..0000000 --- a/shadow-4.9-useradd-avoid-generating-empty-subid-range.patch +++ /dev/null @@ -1,79 +0,0 @@ -diff --git a/src/useradd.c b/src/useradd.c -index baeffb35..9abeea6e 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -142,9 +142,7 @@ static bool is_sub_gid = false; - static bool sub_uid_locked = false; - static bool sub_gid_locked = false; - static uid_t sub_uid_start; /* New subordinate uid range */ --static unsigned long sub_uid_count; - static gid_t sub_gid_start; /* New subordinate gid range */ --static unsigned long sub_gid_count; - #endif /* ENABLE_SUBIDS */ - static bool pw_locked = false; - static bool gr_locked = false; -@@ -234,7 +232,7 @@ static void open_shadow (void); - static void faillog_reset (uid_t); - static void lastlog_reset (uid_t); - static void tallylog_reset (const char *); --static void usr_update (void); -+static void usr_update (unsigned long subuid_count, unsigned long subgid_count); - static void create_home (void); - static void create_mail (void); - static void check_uid_range(int rflg, uid_t user_id); -@@ -2092,7 +2090,7 @@ static void tallylog_reset (const char *user_name) - * usr_update() creates the password file entries for this user - * and will update the group entries if required. - */ --static void usr_update (void) -+static void usr_update (unsigned long subuid_count, unsigned long subgid_count) - { - struct passwd pwent; - struct spwd spent; -@@ -2155,14 +2153,14 @@ static void usr_update (void) - } - #ifdef ENABLE_SUBIDS - if (is_sub_uid && -- (sub_uid_add(user_name, sub_uid_start, sub_uid_count) == 0)) { -+ (sub_uid_add(user_name, sub_uid_start, subuid_count) == 0)) { - fprintf (stderr, - _("%s: failed to prepare the new %s entry\n"), - Prog, sub_uid_dbname ()); - fail_exit (E_SUB_UID_UPDATE); - } - if (is_sub_gid && -- (sub_gid_add(user_name, sub_gid_start, sub_gid_count) == 0)) { -+ (sub_gid_add(user_name, sub_gid_start, subgid_count) == 0)) { - fprintf (stderr, - _("%s: failed to prepare the new %s entry\n"), - Prog, sub_uid_dbname ()); -@@ -2624,16 +2622,16 @@ int main (int argc, char **argv) - } - - #ifdef ENABLE_SUBIDS -- if (is_sub_uid && sub_uid_count != 0) { -- if (find_new_sub_uids(&sub_uid_start, &sub_uid_count) < 0) { -+ if (is_sub_uid && subuid_count != 0) { -+ if (find_new_sub_uids(&sub_uid_start, &subuid_count) < 0) { - fprintf (stderr, - _("%s: can't create subordinate user IDs\n"), - Prog); - fail_exit(E_SUB_UID_UPDATE); - } - } -- if (is_sub_gid && sub_gid_count != 0) { -- if (find_new_sub_gids(&sub_gid_start, &sub_gid_count) < 0) { -+ if (is_sub_gid && subgid_count != 0) { -+ if (find_new_sub_gids(&sub_gid_start, &subgid_count) < 0) { - fprintf (stderr, - _("%s: can't create subordinate group IDs\n"), - Prog); -@@ -2642,7 +2640,7 @@ int main (int argc, char **argv) - } - #endif /* ENABLE_SUBIDS */ - -- usr_update (); -+ usr_update (subuid_count, subgid_count); - - close_files (); - diff --git a/shadow-4.9-useradd-copy-tree-argument.patch b/shadow-4.9-useradd-copy-tree-argument.patch deleted file mode 100644 index f6b9827..0000000 --- a/shadow-4.9-useradd-copy-tree-argument.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/src/useradd.c b/src/useradd.c -index b463a170..f7c97958 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -2704,7 +2704,7 @@ int main (int argc, char **argv) - if (mflg) { - create_home (); - if (home_added) { -- copy_tree (def_template, prefix_user_home, false, false, -+ copy_tree (def_template, prefix_user_home, false, true, - (uid_t)-1, user_id, (gid_t)-1, user_gid); - } else { - fprintf (stderr, diff --git a/shadow-4.9-usermod-allow-all-group-types.patch b/shadow-4.9-usermod-allow-all-group-types.patch deleted file mode 100644 index fada15e..0000000 --- a/shadow-4.9-usermod-allow-all-group-types.patch +++ /dev/null @@ -1,322 +0,0 @@ -From e481437ab9ebe9a8bf8fbaabe986d42b2f765991 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Tue, 3 Aug 2021 08:57:20 +0200 -Subject: [PATCH] usermod: allow all group types with -G option - -The only way of removing a group from the supplementary list is to use --G option, and list all groups that the user is a member of except for -the one that wants to be removed. The problem lies when there's a user -that contains both local and remote groups, and the group to be removed -is a local one. As we need to include the remote group with -G option -the command will fail. - -This reverts commit 140510de9de4771feb3af1d859c09604043a4c9b. This way, -it would be possible to remove the remote groups from the supplementary -list. - -Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1967641 -Resolves: https://github.com/shadow-maint/shadow/issues/338 - -Signed-off-by: Iker Pedrosa ---- - src/usermod.c | 220 ++++++++++++++++++-------------------------------- - 1 file changed, 77 insertions(+), 143 deletions(-) - -diff --git a/src/usermod.c b/src/usermod.c -index 03bb9b9d..a0c03afa 100644 ---- a/src/usermod.c -+++ b/src/usermod.c -@@ -187,7 +187,6 @@ static bool sub_gid_locked = false; - static void date_to_str (/*@unique@*//*@out@*/char *buf, size_t maxsize, - long int date); - static int get_groups (char *); --static struct group * get_local_group (char * grp_name); - static /*@noreturn@*/void usage (int status); - static void new_pwent (struct passwd *); - static void new_spent (struct spwd *); -@@ -201,9 +200,7 @@ static void grp_update (void); - - static void process_flags (int, char **); - static void close_files (void); --static void close_group_files (void); - static void open_files (void); --static void open_group_files (void); - static void usr_update (void); - static void move_home (void); - static void update_lastlog (void); -@@ -260,11 +257,6 @@ static int get_groups (char *list) - return 0; - } - -- /* -- * Open the group files -- */ -- open_group_files (); -- - /* - * So long as there is some data to be converted, strip off each - * name and look it up. A mix of numerical and string values for -@@ -284,7 +276,7 @@ static int get_groups (char *list) - * Names starting with digits are treated as numerical GID - * values, otherwise the string is looked up as is. - */ -- grp = get_local_group (list); -+ grp = prefix_getgr_nam_gid (list); - - /* - * There must be a match, either by GID value or by -@@ -334,8 +326,6 @@ static int get_groups (char *list) - gr_free ((struct group *)grp); - } while (NULL != list); - -- close_group_files (); -- - user_groups[ngroups] = (char *) 0; - - /* -@@ -348,44 +338,6 @@ static int get_groups (char *list) - return 0; - } - --/* -- * get_local_group - checks if a given group name exists locally -- * -- * get_local_group() checks if a given group name exists locally. -- * If the name exists the group information is returned, otherwise NULL is -- * returned. -- */ --static struct group * get_local_group(char * grp_name) --{ -- const struct group *grp; -- struct group *result_grp = NULL; -- long long int gid; -- char *endptr; -- -- gid = strtoll (grp_name, &endptr, 10); -- if ( ('\0' != *grp_name) -- && ('\0' == *endptr) -- && (ERANGE != errno) -- && (gid == (gid_t)gid)) { -- grp = gr_locate_gid ((gid_t) gid); -- } -- else { -- grp = gr_locate(grp_name); -- } -- -- if (grp != NULL) { -- result_grp = __gr_dup (grp); -- if (NULL == result_grp) { -- fprintf (stderr, -- _("%s: Out of memory. Cannot find group '%s'.\n"), -- Prog, grp_name); -- fail_exit (E_GRP_UPDATE); -- } -- } -- -- return result_grp; --} -- - #ifdef ENABLE_SUBIDS - struct ulong_range - { -@@ -1523,7 +1475,50 @@ static void close_files (void) - } - - if (Gflg || lflg) { -- close_group_files (); -+ if (gr_close () == 0) { -+ fprintf (stderr, -+ _("%s: failure while writing changes to %s\n"), -+ Prog, gr_dbname ()); -+ SYSLOG ((LOG_ERR, -+ "failure while writing changes to %s", -+ gr_dbname ())); -+ fail_exit (E_GRP_UPDATE); -+ } -+#ifdef SHADOWGRP -+ if (is_shadow_grp) { -+ if (sgr_close () == 0) { -+ fprintf (stderr, -+ _("%s: failure while writing changes to %s\n"), -+ Prog, sgr_dbname ()); -+ SYSLOG ((LOG_ERR, -+ "failure while writing changes to %s", -+ sgr_dbname ())); -+ fail_exit (E_GRP_UPDATE); -+ } -+ } -+#endif -+#ifdef SHADOWGRP -+ if (is_shadow_grp) { -+ if (sgr_unlock () == 0) { -+ fprintf (stderr, -+ _("%s: failed to unlock %s\n"), -+ Prog, sgr_dbname ()); -+ SYSLOG ((LOG_ERR, -+ "failed to unlock %s", -+ sgr_dbname ())); -+ /* continue */ -+ } -+ } -+#endif -+ if (gr_unlock () == 0) { -+ fprintf (stderr, -+ _("%s: failed to unlock %s\n"), -+ Prog, gr_dbname ()); -+ SYSLOG ((LOG_ERR, -+ "failed to unlock %s", -+ gr_dbname ())); -+ /* continue */ -+ } - } - - if (is_shadow_pwd) { -@@ -1592,60 +1587,6 @@ static void close_files (void) - #endif - } - --/* -- * close_group_files - close all of the files that were opened -- * -- * close_group_files() closes all of the files that were opened related -- * with groups. This causes any modified entries to be written out. -- */ --static void close_group_files (void) --{ -- if (gr_close () == 0) { -- fprintf (stderr, -- _("%s: failure while writing changes to %s\n"), -- Prog, gr_dbname ()); -- SYSLOG ((LOG_ERR, -- "failure while writing changes to %s", -- gr_dbname ())); -- fail_exit (E_GRP_UPDATE); -- } --#ifdef SHADOWGRP -- if (is_shadow_grp) { -- if (sgr_close () == 0) { -- fprintf (stderr, -- _("%s: failure while writing changes to %s\n"), -- Prog, sgr_dbname ()); -- SYSLOG ((LOG_ERR, -- "failure while writing changes to %s", -- sgr_dbname ())); -- fail_exit (E_GRP_UPDATE); -- } -- } --#endif --#ifdef SHADOWGRP -- if (is_shadow_grp) { -- if (sgr_unlock () == 0) { -- fprintf (stderr, -- _("%s: failed to unlock %s\n"), -- Prog, sgr_dbname ()); -- SYSLOG ((LOG_ERR, -- "failed to unlock %s", -- sgr_dbname ())); -- /* continue */ -- } -- } --#endif -- if (gr_unlock () == 0) { -- fprintf (stderr, -- _("%s: failed to unlock %s\n"), -- Prog, gr_dbname ()); -- SYSLOG ((LOG_ERR, -- "failed to unlock %s", -- gr_dbname ())); -- /* continue */ -- } --} -- - /* - * open_files - lock and open the password files - * -@@ -1681,7 +1622,38 @@ static void open_files (void) - } - - if (Gflg || lflg) { -- open_group_files (); -+ /* -+ * Lock and open the group file. This will load all of the -+ * group entries. -+ */ -+ if (gr_lock () == 0) { -+ fprintf (stderr, -+ _("%s: cannot lock %s; try again later.\n"), -+ Prog, gr_dbname ()); -+ fail_exit (E_GRP_UPDATE); -+ } -+ gr_locked = true; -+ if (gr_open (O_CREAT | O_RDWR) == 0) { -+ fprintf (stderr, -+ _("%s: cannot open %s\n"), -+ Prog, gr_dbname ()); -+ fail_exit (E_GRP_UPDATE); -+ } -+#ifdef SHADOWGRP -+ if (is_shadow_grp && (sgr_lock () == 0)) { -+ fprintf (stderr, -+ _("%s: cannot lock %s; try again later.\n"), -+ Prog, sgr_dbname ()); -+ fail_exit (E_GRP_UPDATE); -+ } -+ sgr_locked = true; -+ if (is_shadow_grp && (sgr_open (O_CREAT | O_RDWR) == 0)) { -+ fprintf (stderr, -+ _("%s: cannot open %s\n"), -+ Prog, sgr_dbname ()); -+ fail_exit (E_GRP_UPDATE); -+ } -+#endif - } - #ifdef ENABLE_SUBIDS - if (vflg || Vflg) { -@@ -1717,44 +1689,6 @@ static void open_files (void) - #endif /* ENABLE_SUBIDS */ - } - --/* -- * open_group_files - lock and open the group files -- * -- * open_group_files() loads all of the group entries. -- */ --static void open_group_files (void) --{ -- if (gr_lock () == 0) { -- fprintf (stderr, -- _("%s: cannot lock %s; try again later.\n"), -- Prog, gr_dbname ()); -- fail_exit (E_GRP_UPDATE); -- } -- gr_locked = true; -- if (gr_open (O_CREAT | O_RDWR) == 0) { -- fprintf (stderr, -- _("%s: cannot open %s\n"), -- Prog, gr_dbname ()); -- fail_exit (E_GRP_UPDATE); -- } -- --#ifdef SHADOWGRP -- if (is_shadow_grp && (sgr_lock () == 0)) { -- fprintf (stderr, -- _("%s: cannot lock %s; try again later.\n"), -- Prog, sgr_dbname ()); -- fail_exit (E_GRP_UPDATE); -- } -- sgr_locked = true; -- if (is_shadow_grp && (sgr_open (O_CREAT | O_RDWR) == 0)) { -- fprintf (stderr, -- _("%s: cannot open %s\n"), -- Prog, sgr_dbname ()); -- fail_exit (E_GRP_UPDATE); -- } --#endif --} -- - /* - * usr_update - create the user entries - * --- -2.31.1 - diff --git a/shadow-utils.spec b/shadow-utils.spec index bcbadf8..16ec56c 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,12 +1,12 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils -Version: 4.9 -Release: 10%{?dist} +Version: 4.11.1 +Release: 1%{?dist} Epoch: 2 License: BSD and GPLv2+ URL: https://github.com/shadow-maint/shadow -Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz -Source1: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz.asc +Source0: https://github.com/shadow-maint/shadow/releases/download/v%{version}/shadow-%{version}.tar.xz +Source1: https://github.com/shadow-maint/shadow/releases/download/v%{version}/shadow-%{version}.tar.xz.asc Source2: shadow-utils.useradd Source3: shadow-utils.login.defs Source4: shadow-bsd.txt @@ -18,11 +18,9 @@ Source6: shadow-utils.HOME_MODE.xml ### Patches ### # Misc small changes - most probably non-upstreamable -Patch0: shadow-4.9-redhat.patch +Patch0: shadow-4.11.1-redhat.patch # Be more lenient with acceptable user/group names - non upstreamable Patch1: shadow-4.8-goodname.patch -# https://github.com/shadow-maint/shadow/commit/09c752f00f9dfc610f66d68be38c9e5be8ca7f15 -Patch2: shadow-4.9-move-create-home.patch # SElinux related - upstreamability unknown Patch3: shadow-4.9-default-range.patch # Misc manual page changes - non-upstreamable @@ -32,50 +30,21 @@ Patch5: shadow-4.2.1-date-parsing.patch # Additional error message - could be upstreamed Patch6: shadow-4.6-move-home.patch # Audit message changes - upstreamability unknown -Patch7: shadow-4.9-audit-update.patch +Patch7: shadow-4.11.1-audit-update.patch # Changes related to password unlocking - could be upstreamed Patch8: shadow-4.5-usermod-unlock.patch # Additional SElinux related changes - upstreamability unknown Patch9: shadow-4.8-selinux-perms.patch -# Handle NULL return from *time funcs - could be upstreamed -Patch10: shadow-4.9-null-tm.patch +# Handle NULL return from *time funcs - upstreamable +Patch10: shadow-4.11.1-null-tm.patch # Handle /etc/passwd corruption - could be upstreamed Patch11: shadow-4.8-long-entry.patch # Limit uid/gid allocation to non-zero - could be upstreamed Patch12: shadow-4.6-sysugid-min-limit.patch # Ignore LOGIN_PLAIN_PROMPT in login.defs - upstreamability unknown Patch13: shadow-4.8-ignore-login-prompt.patch -# https://github.com/shadow-maint/shadow/commit/c6847011e8b656adacd9a0d2a78418cad0de34cb -Patch14: shadow-4.9-newuidmap-libeconf-dependency.patch -# https://github.com/shadow-maint/shadow/commit/e481437ab9ebe9a8bf8fbaabe986d42b2f765991 -Patch15: shadow-4.9-usermod-allow-all-group-types.patch -# https://github.com/shadow-maint/shadow/commit/9dd720a28578eef5be8171697aae0906e4c53249 -Patch16: shadow-4.9-useradd-avoid-generating-empty-subid-range.patch -# https://github.com/shadow-maint/shadow/commit/234e8fa7b134d1ebabfdad980a3ae5b63c046c62 -Patch17: shadow-4.9-libmisc-fix-default-value-in-SHA_get_salt_rounds.patch -# https://github.com/shadow-maint/shadow/commit/234af5cf67fc1a3ba99fc246ba65869a3c416545 -Patch18: shadow-4.9-semanage-close-the-selabel-handle.patch -# https://github.com/shadow-maint/shadow/commit/4624e9fca1b02b64e25e8b2280a0186182ab73ba -Patch19: shadow-4.9-revert-useradd-fix-memleak.patch -# https://github.com/shadow-maint/shadow/commit/06eb4e4d76ac7f1ac86e68a89b2dc9be7c7323a2 -Patch20: shadow-4.9-useradd-copy-tree-argument.patch -# https://github.com/shadow-maint/shadow/commit/d8e54618feea201987c1f3cb402ed50d1d8b604f -Patch21: shadow-4.9-pwck-fix-segfault-when-calling-fprintf.patch -# https://github.com/shadow-maint/shadow/commit/497e90751bc0d95cc998b0f06305040563903948 -Patch22: shadow-4.9-newgrp-fix-segmentation-fault.patch -# https://github.com/shadow-maint/shadow/commit/3b6ccf642c6bb2b7db087f09ee563ae9318af734 -Patch23: shadow-4.9-getsubids.patch -# https://github.com/shadow-maint/shadow/commit/a757b458ffb4fb9a40bcbb4f7869449431c67f83 -Patch24: shadow-4.9-groupdel-fix-sigsegv-when-passwd-does-not-exist.patch -# https://github.com/shadow-maint/shadow/commit/79157cbad87f42cdc2068d72e798488572c68bb2 -Patch25: shadow-4.9-make-shadow-logfd-and-prog-not-extern.patch -# https://github.com/shadow-maint/shadow/commit/0e6fe5e728a45baff3977d73e81a27adb6ae30c6 -Patch26: shadow-4.9-rename-prog-to-shadow-progname.patch -# https://github.com/shadow-maint/shadow/commit/2b0bdef6f9a18382e92b0fb6d893c4339123ffac -# https://github.com/shadow-maint/shadow/commit/9750fd681919ed558a9b044248a284d567cddf1a -Patch27: shadow-4.9-shadow-progname-default-init.patch # https://github.com/shadow-maint/shadow/commit/e101219ad71de11da3fdd1b3ec2620fd1a97b92c -Patch28: shadow-4.9-nss-get-shadow-logfd-with-log-get-logfd.patch +Patch14: shadow-4.9-nss-get-shadow-logfd-with-log-get-logfd.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -129,6 +98,7 @@ Utility library that provides a way to manage subid ranges. %package subid-devel Summary: Development package for shadow-utils-subid License: BSD and GPLv2+ +Requires: shadow-utils-subid = %{version}-%{release} %description subid-devel Development files for shadow-utils-subid. @@ -137,7 +107,6 @@ Development files for shadow-utils-subid. %setup -q -n shadow-%{version} %patch0 -p1 -b .redhat %patch1 -p1 -b .goodname -%patch2 -p1 -b .move-create-home %patch3 -p1 -b .default-range %patch4 -p1 -b .manfix %patch5 -p1 -b .date-parsing @@ -149,21 +118,7 @@ Development files for shadow-utils-subid. %patch11 -p1 -b .long-entry %patch12 -p1 -b .sysugid-min-limit %patch13 -p1 -b .login-prompt -%patch14 -p1 -b .newuidmap-libeconf-dependency -%patch15 -p1 -b .usermod-allow-all-group-types -%patch16 -p1 -b .useradd-avoid-generating-empty-subid-range -%patch17 -p1 -b .libmisc-fix-default-value-in-SHA_get_salt_rounds -%patch18 -p1 -b .semanage-close-the-selabel-handle -%patch19 -p1 -b .revert-useradd-fix-memleak -%patch20 -p1 -b .useradd-copy-tree-argument -%patch21 -p1 -b .pwck-fix-segfault-when-calling-fprintf -%patch22 -p1 -b .newgrp-fix-segmentation-fault -%patch23 -p1 -b .getsubids -%patch24 -p1 -b .groupdel-fix-sigsegv-when-passwd-does-not-exist -%patch25 -p1 -b .make-shadow-logfd-and-prog-not-extern -%patch26 -p1 -b .rename-prog-to-shadow-progname -%patch27 -p1 -b .shadow-progname-default-init -%patch28 -p1 -b .nss-get-shadow-logfd-with-log-get-logfd +%patch14 -p1 -b .nss-get-shadow-logfd-with-log-get-logfd iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -275,8 +230,9 @@ echo $(ls) mkdir -p $RPM_BUILD_ROOT/%{includesubiddir} install -m 644 libsubid/subid.h $RPM_BUILD_ROOT/%{includesubiddir}/ -# Remove .la files created by libsubid +# Remove .la and .a files created by libsubid rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la +rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %files -f shadow.lang %doc NEWS doc/HOWTO README @@ -336,6 +292,11 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la %{_libdir}/libsubid.so %changelog +* Tue Jan 25 2022 Iker Pedrosa - 2:4.11.1-1 +- Rebase to version 4.11.1 (#2034038) +- Fix release sources +- Add explicit subid requirement for subid-devel + * Sat Jan 22 2022 Fedora Release Engineering - 2:4.9-10 - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild From a986f4a036f3f055e0b5fcd5bc48ea6415317bcf Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Wed, 26 Jan 2022 09:39:55 +0100 Subject: [PATCH 058/134] Add forgotten sources Signed-off-by: Iker Pedrosa --- .gitignore | 2 ++ sources | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index cc68ade..e368bdf 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,5 @@ shadow-4.1.4.2.tar.bz2 /shadow-4.8.1.tar.xz.asc /shadow-4.9.tar.xz /shadow-4.9.tar.xz.asc +/shadow-4.11.1.tar.xz +/shadow-4.11.1.tar.xz.asc diff --git a/sources b/sources index 803fac0..53a4fb0 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (shadow-4.9.tar.xz) = 254cda49bb14505a7604821e7fa898bf4bf317d648e9ddc881ab80a6860d52053dfffacad6feab87c7d16608c35ed6b6cee99e7757eac930da3a7b31cdcd4b95 -SHA512 (shadow-4.9.tar.xz.asc) = 16c0ff7be263c9d471b05656c9a1d14da8ec9b17544910323ca6ab854126d1a03ece221e0caf610e65a9b1d080b4cd1b8b46973f20e3ae45ea0e5581ce6c90d9 +SHA512 (shadow-4.11.1.tar.xz) = 12fbe4d6ac929ad3c21525ed0f1026b5b678ccec9762f2ec7e611d9c180934def506325f2835fb750dd30af035b592f827ff151cd6e4c805aaaf8e01425c279f +SHA512 (shadow-4.11.1.tar.xz.asc) = 4594189678cc9bcc8831f62a5d42c605b085be4a3b540429d7c800f4304e2e8fe04358547917eb90c1513646fade7c714611bfdc98af7dec5321a3dc3e65c4fd From 5ba2bc90cc868264bfea084504bee28e45ccbb79 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Thu, 10 Feb 2022 17:46:56 +0100 Subject: [PATCH 059/134] Fix explicit subid requirement for subid-devel Signed-off-by: Iker Pedrosa --- shadow-utils.spec | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index 16ec56c..c90978b 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.11.1 -Release: 1%{?dist} +Release: 2%{?dist} Epoch: 2 License: BSD and GPLv2+ URL: https://github.com/shadow-maint/shadow @@ -98,7 +98,7 @@ Utility library that provides a way to manage subid ranges. %package subid-devel Summary: Development package for shadow-utils-subid License: BSD and GPLv2+ -Requires: shadow-utils-subid = %{version}-%{release} +Requires: shadow-utils-subid = %{epoch}:%{version}-%{release} %description subid-devel Development files for shadow-utils-subid. @@ -292,6 +292,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Thu Feb 10 2022 Iker Pedrosa - 2:4.11.1-2 +- Fix explicit subid requirement for subid-devel + * Tue Jan 25 2022 Iker Pedrosa - 2:4.11.1-1 - Rebase to version 4.11.1 (#2034038) - Fix release sources From 71c99ba5b1ae994e34e41111733227798b791f40 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Sat, 23 Jul 2022 08:29:04 +0000 Subject: [PATCH 060/134] Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- shadow-utils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index c90978b..98efee1 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.11.1 -Release: 2%{?dist} +Release: 3%{?dist} Epoch: 2 License: BSD and GPLv2+ URL: https://github.com/shadow-maint/shadow @@ -292,6 +292,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Sat Jul 23 2022 Fedora Release Engineering - 2:4.11.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + * Thu Feb 10 2022 Iker Pedrosa - 2:4.11.1-2 - Fix explicit subid requirement for subid-devel From 97547bc00ae47970bfc9a99209083fff0f3d7931 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Mon, 1 Aug 2022 11:13:56 +0200 Subject: [PATCH 061/134] useradd: modify check ID range for system users Resolves: #2093692 Signed-off-by: Iker Pedrosa --- ...dify-check-ID-range-for-system-users.patch | 40 +++++++++++++++++++ shadow-utils.spec | 8 +++- 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 shadow-4.11.1-useradd-modify-check-ID-range-for-system-users.patch diff --git a/shadow-4.11.1-useradd-modify-check-ID-range-for-system-users.patch b/shadow-4.11.1-useradd-modify-check-ID-range-for-system-users.patch new file mode 100644 index 0000000..dead628 --- /dev/null +++ b/shadow-4.11.1-useradd-modify-check-ID-range-for-system-users.patch @@ -0,0 +1,40 @@ +From f1f1678e13aa3ae49bdb139efaa2c5bc53dcfe92 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Tue, 4 Jan 2022 13:06:00 +0100 +Subject: [PATCH] useradd: modify check ID range for system users + +useradd warns that a system user ID less than SYS_UID_MIN is outside the +expected range, even though that ID has been specifically selected with +the "-u" option. + +In my opinion all the user ID's below SYS_UID_MAX are for the system, +thus I change the condition to take that into account. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2004911 + +Signed-off-by: Iker Pedrosa +--- + src/useradd.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/src/useradd.c b/src/useradd.c +index 34376fa5..4c71c38a 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -2409,11 +2409,9 @@ static void check_uid_range(int rflg, uid_t user_id) + uid_t uid_min ; + uid_t uid_max ; + if (rflg) { +- uid_min = (uid_t)getdef_ulong("SYS_UID_MIN",101UL); + uid_max = (uid_t)getdef_ulong("SYS_UID_MAX",getdef_ulong("UID_MIN",1000UL)-1); +- if (uid_min <= uid_max) { +- if (user_id < uid_min || user_id >uid_max) +- fprintf(stderr, _("%s warning: %s's uid %d outside of the SYS_UID_MIN %d and SYS_UID_MAX %d range.\n"), Prog, user_name, user_id, uid_min, uid_max); ++ if (user_id > uid_max) { ++ fprintf(stderr, _("%s warning: %s's uid %d is greater than SYS_UID_MAX %d\n"), Prog, user_name, user_id, uid_max); + } + }else{ + uid_min = (uid_t)getdef_ulong("UID_MIN", 1000UL); +-- +2.37.1 + diff --git a/shadow-utils.spec b/shadow-utils.spec index 98efee1..660f777 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.11.1 -Release: 3%{?dist} +Release: 4%{?dist} Epoch: 2 License: BSD and GPLv2+ URL: https://github.com/shadow-maint/shadow @@ -45,6 +45,8 @@ Patch12: shadow-4.6-sysugid-min-limit.patch Patch13: shadow-4.8-ignore-login-prompt.patch # https://github.com/shadow-maint/shadow/commit/e101219ad71de11da3fdd1b3ec2620fd1a97b92c Patch14: shadow-4.9-nss-get-shadow-logfd-with-log-get-logfd.patch +# https://github.com/shadow-maint/shadow/commit/f1f1678e13aa3ae49bdb139efaa2c5bc53dcfe92 +Patch15: shadow-4.11.1-useradd-modify-check-ID-range-for-system-users.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -119,6 +121,7 @@ Development files for shadow-utils-subid. %patch12 -p1 -b .sysugid-min-limit %patch13 -p1 -b .login-prompt %patch14 -p1 -b .nss-get-shadow-logfd-with-log-get-logfd +%patch15 -p1 -b .useradd-modify-check-ID-range-for-system-users iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -292,6 +295,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Mon Aug 1 2022 Iker Pedrosa - 2:4.11.1-4 +- useradd: modify check ID range for system users. Resolves: #2093692 + * Sat Jul 23 2022 Fedora Release Engineering - 2:4.11.1-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild From cd421e05aeb4f13565d980dc0a45f664dfd0ec09 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Tue, 23 Aug 2022 09:25:47 +0200 Subject: [PATCH 062/134] Rebase to version 4.12.3 Resolves: #2117809 Signed-off-by: Iker Pedrosa --- .gitignore | 2 + ...dify-check-ID-range-for-system-users.patch | 40 ---------------- ...name.patch => shadow-4.12.3-goodname.patch | 28 +++++------ ...ry.patch => shadow-4.12.3-long-entry.patch | 48 +++++++++---------- ...redhat.patch => shadow-4.12.3-redhat.patch | 23 ++++----- ...patch => shadow-4.12.3-selinux-perms.patch | 34 ++++++------- ...-get-shadow-logfd-with-log-get-logfd.patch | 48 ------------------- shadow-utils.spec | 21 ++++---- sources | 4 +- 9 files changed, 78 insertions(+), 170 deletions(-) delete mode 100644 shadow-4.11.1-useradd-modify-check-ID-range-for-system-users.patch rename shadow-4.8-goodname.patch => shadow-4.12.3-goodname.patch (77%) rename shadow-4.8-long-entry.patch => shadow-4.12.3-long-entry.patch (54%) rename shadow-4.11.1-redhat.patch => shadow-4.12.3-redhat.patch (53%) rename shadow-4.8-selinux-perms.patch => shadow-4.12.3-selinux-perms.patch (84%) delete mode 100644 shadow-4.9-nss-get-shadow-logfd-with-log-get-logfd.patch diff --git a/.gitignore b/.gitignore index e368bdf..7113c48 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,5 @@ shadow-4.1.4.2.tar.bz2 /shadow-4.9.tar.xz.asc /shadow-4.11.1.tar.xz /shadow-4.11.1.tar.xz.asc +/shadow-4.12.3.tar.xz +/shadow-4.12.3.tar.xz.asc diff --git a/shadow-4.11.1-useradd-modify-check-ID-range-for-system-users.patch b/shadow-4.11.1-useradd-modify-check-ID-range-for-system-users.patch deleted file mode 100644 index dead628..0000000 --- a/shadow-4.11.1-useradd-modify-check-ID-range-for-system-users.patch +++ /dev/null @@ -1,40 +0,0 @@ -From f1f1678e13aa3ae49bdb139efaa2c5bc53dcfe92 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Tue, 4 Jan 2022 13:06:00 +0100 -Subject: [PATCH] useradd: modify check ID range for system users - -useradd warns that a system user ID less than SYS_UID_MIN is outside the -expected range, even though that ID has been specifically selected with -the "-u" option. - -In my opinion all the user ID's below SYS_UID_MAX are for the system, -thus I change the condition to take that into account. - -Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2004911 - -Signed-off-by: Iker Pedrosa ---- - src/useradd.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/src/useradd.c b/src/useradd.c -index 34376fa5..4c71c38a 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -2409,11 +2409,9 @@ static void check_uid_range(int rflg, uid_t user_id) - uid_t uid_min ; - uid_t uid_max ; - if (rflg) { -- uid_min = (uid_t)getdef_ulong("SYS_UID_MIN",101UL); - uid_max = (uid_t)getdef_ulong("SYS_UID_MAX",getdef_ulong("UID_MIN",1000UL)-1); -- if (uid_min <= uid_max) { -- if (user_id < uid_min || user_id >uid_max) -- fprintf(stderr, _("%s warning: %s's uid %d outside of the SYS_UID_MIN %d and SYS_UID_MAX %d range.\n"), Prog, user_name, user_id, uid_min, uid_max); -+ if (user_id > uid_max) { -+ fprintf(stderr, _("%s warning: %s's uid %d is greater than SYS_UID_MAX %d\n"), Prog, user_name, user_id, uid_max); - } - }else{ - uid_min = (uid_t)getdef_ulong("UID_MIN", 1000UL); --- -2.37.1 - diff --git a/shadow-4.8-goodname.patch b/shadow-4.12.3-goodname.patch similarity index 77% rename from shadow-4.8-goodname.patch rename to shadow-4.12.3-goodname.patch index f3c18d5..2376674 100644 --- a/shadow-4.8-goodname.patch +++ b/shadow-4.12.3-goodname.patch @@ -1,7 +1,7 @@ -diff -up shadow-4.8/libmisc/chkname.c.goodname shadow-4.8/libmisc/chkname.c ---- shadow-4.8/libmisc/chkname.c.goodname 2020-01-13 09:44:41.968507996 +0100 -+++ shadow-4.8/libmisc/chkname.c 2020-01-13 09:46:27.863727732 +0100 -@@ -55,26 +55,44 @@ static bool is_valid_name (const char *n +diff -up shadow-4.12.3/libmisc/chkname.c.goodname shadow-4.12.3/libmisc/chkname.c +--- shadow-4.12.3/libmisc/chkname.c.goodname 2022-06-19 16:16:48.000000000 +0200 ++++ shadow-4.12.3/libmisc/chkname.c 2022-08-22 16:00:27.646087971 +0200 +@@ -32,26 +32,44 @@ static bool is_valid_name (const char *n } /* @@ -56,12 +56,12 @@ diff -up shadow-4.8/libmisc/chkname.c.goodname shadow-4.8/libmisc/chkname.c } bool is_valid_user_name (const char *name) -diff -up shadow-4.8/man/groupadd.8.xml.goodname shadow-4.8/man/groupadd.8.xml ---- shadow-4.8/man/groupadd.8.xml.goodname 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8/man/groupadd.8.xml 2020-01-13 09:44:41.968507996 +0100 -@@ -273,10 +273,12 @@ - - CAVEATS +diff -up shadow-4.12.3/man/groupadd.8.xml.goodname shadow-4.12.3/man/groupadd.8.xml +--- shadow-4.12.3/man/groupadd.8.xml.goodname 2022-08-22 16:00:27.646087971 +0200 ++++ shadow-4.12.3/man/groupadd.8.xml 2022-08-22 16:01:59.301779733 +0200 +@@ -64,10 +64,12 @@ + files as needed. + - Groupnames must start with a lower case letter or an underscore, - followed by lower case letters, digits, underscores, or dashes. @@ -76,10 +76,10 @@ diff -up shadow-4.8/man/groupadd.8.xml.goodname shadow-4.8/man/groupadd.8.xml Groupnames may only be up to &GROUP_NAME_MAX_LENGTH; characters long. -diff -up shadow-4.8/man/useradd.8.xml.goodname shadow-4.8/man/useradd.8.xml ---- shadow-4.8/man/useradd.8.xml.goodname 2019-10-05 03:23:58.000000000 +0200 -+++ shadow-4.8/man/useradd.8.xml 2020-01-13 09:44:41.968507996 +0100 -@@ -661,10 +661,14 @@ +diff -up shadow-4.12.3/man/useradd.8.xml.goodname shadow-4.12.3/man/useradd.8.xml +--- shadow-4.12.3/man/useradd.8.xml.goodname 2022-08-22 14:46:57.000000000 +0200 ++++ shadow-4.12.3/man/useradd.8.xml 2022-08-22 16:00:27.646087971 +0200 +@@ -692,10 +692,14 @@ diff --git a/shadow-4.8-long-entry.patch b/shadow-4.12.3-long-entry.patch similarity index 54% rename from shadow-4.8-long-entry.patch rename to shadow-4.12.3-long-entry.patch index 64d9636..9dc5ef2 100644 --- a/shadow-4.8-long-entry.patch +++ b/shadow-4.12.3-long-entry.patch @@ -1,7 +1,7 @@ -diff -up shadow-4.8/lib/defines.h.long-entry shadow-4.8/lib/defines.h ---- shadow-4.8/lib/defines.h.long-entry 2020-01-13 10:29:45.288957339 +0100 -+++ shadow-4.8/lib/defines.h 2020-01-13 10:30:47.482902954 +0100 -@@ -388,6 +388,9 @@ extern char *strerror (); +diff -up shadow-4.12.3/lib/defines.h.long-entry shadow-4.12.3/lib/defines.h +--- shadow-4.12.3/lib/defines.h.long-entry 2022-08-18 23:51:37.000000000 +0200 ++++ shadow-4.12.3/lib/defines.h 2022-08-22 16:12:27.412522768 +0200 +@@ -335,6 +335,9 @@ extern char *strerror (); # endif #endif @@ -11,10 +11,10 @@ diff -up shadow-4.8/lib/defines.h.long-entry shadow-4.8/lib/defines.h #ifdef HAVE_SECURE_GETENV # define shadow_getenv(name) secure_getenv(name) # else -diff -up shadow-4.8/lib/pwio.c.long-entry shadow-4.8/lib/pwio.c ---- shadow-4.8/lib/pwio.c.long-entry 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8/lib/pwio.c 2020-01-13 10:29:45.288957339 +0100 -@@ -79,7 +79,10 @@ static int passwd_put (const void *ent, +diff -up shadow-4.12.3/lib/pwio.c.long-entry shadow-4.12.3/lib/pwio.c +--- shadow-4.12.3/lib/pwio.c.long-entry 2022-06-19 16:16:48.000000000 +0200 ++++ shadow-4.12.3/lib/pwio.c 2022-08-22 16:12:27.412522768 +0200 +@@ -56,7 +56,10 @@ static int passwd_put (const void *ent, || (pw->pw_gid == (gid_t)-1) || (valid_field (pw->pw_gecos, ":\n") == -1) || (valid_field (pw->pw_dir, ":\n") == -1) @@ -26,19 +26,19 @@ diff -up shadow-4.8/lib/pwio.c.long-entry shadow-4.8/lib/pwio.c return -1; } -diff -up shadow-4.8/lib/sgetpwent.c.long-entry shadow-4.8/lib/sgetpwent.c ---- shadow-4.8/lib/sgetpwent.c.long-entry 2019-10-05 03:23:58.000000000 +0200 -+++ shadow-4.8/lib/sgetpwent.c 2020-01-13 10:29:45.288957339 +0100 -@@ -57,7 +57,7 @@ +diff -up shadow-4.12.3/lib/sgetpwent.c.long-entry shadow-4.12.3/lib/sgetpwent.c +--- shadow-4.12.3/lib/sgetpwent.c.long-entry 2022-08-09 00:30:40.000000000 +0200 ++++ shadow-4.12.3/lib/sgetpwent.c 2022-08-22 16:14:10.955309200 +0200 +@@ -34,7 +34,7 @@ struct passwd *sgetpwent (const char *buf) { static struct passwd pwent; - static char pwdbuf[1024]; + static char pwdbuf[PASSWD_ENTRY_MAX_LENGTH]; - register int i; - register char *cp; + int i; + char *cp; char *fields[NFIELDS]; -@@ -67,8 +67,10 @@ struct passwd *sgetpwent (const char *bu +@@ -44,8 +44,10 @@ struct passwd *sgetpwent (const char *bu * the password structure remain valid. */ @@ -50,10 +50,10 @@ diff -up shadow-4.8/lib/sgetpwent.c.long-entry shadow-4.8/lib/sgetpwent.c strcpy (pwdbuf, buf); /* -diff -up shadow-4.8/lib/sgetspent.c.long-entry shadow-4.8/lib/sgetspent.c ---- shadow-4.8/lib/sgetspent.c.long-entry 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8/lib/sgetspent.c 2020-01-13 10:29:45.289957322 +0100 -@@ -48,7 +48,7 @@ +diff -up shadow-4.12.3/lib/sgetspent.c.long-entry shadow-4.12.3/lib/sgetspent.c +--- shadow-4.12.3/lib/sgetspent.c.long-entry 2022-06-19 16:16:54.000000000 +0200 ++++ shadow-4.12.3/lib/sgetspent.c 2022-08-22 16:12:27.413522776 +0200 +@@ -25,7 +25,7 @@ */ struct spwd *sgetspent (const char *string) { @@ -62,7 +62,7 @@ diff -up shadow-4.8/lib/sgetspent.c.long-entry shadow-4.8/lib/sgetspent.c static struct spwd spwd; char *fields[FIELDS]; char *cp; -@@ -61,6 +61,7 @@ struct spwd *sgetspent (const char *stri +@@ -37,6 +37,7 @@ struct spwd *sgetspent (const char *stri */ if (strlen (string) >= sizeof spwbuf) { @@ -70,10 +70,10 @@ diff -up shadow-4.8/lib/sgetspent.c.long-entry shadow-4.8/lib/sgetspent.c return 0; /* fail if too long */ } strcpy (spwbuf, string); -diff -up shadow-4.8/lib/shadowio.c.long-entry shadow-4.8/lib/shadowio.c ---- shadow-4.8/lib/shadowio.c.long-entry 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8/lib/shadowio.c 2020-01-13 10:29:45.289957322 +0100 -@@ -79,7 +79,9 @@ static int shadow_put (const void *ent, +diff -up shadow-4.12.3/lib/shadowio.c.long-entry shadow-4.12.3/lib/shadowio.c +--- shadow-4.12.3/lib/shadowio.c.long-entry 2022-06-19 16:16:48.000000000 +0200 ++++ shadow-4.12.3/lib/shadowio.c 2022-08-22 16:12:27.413522776 +0200 +@@ -56,7 +56,9 @@ static int shadow_put (const void *ent, if ( (NULL == sp) || (valid_field (sp->sp_namp, ":\n") == -1) diff --git a/shadow-4.11.1-redhat.patch b/shadow-4.12.3-redhat.patch similarity index 53% rename from shadow-4.11.1-redhat.patch rename to shadow-4.12.3-redhat.patch index e5e6c60..48c591d 100644 --- a/shadow-4.11.1-redhat.patch +++ b/shadow-4.12.3-redhat.patch @@ -1,6 +1,6 @@ -diff -up shadow-4.11.1/src/useradd.c.redhat shadow-4.11.1/src/useradd.c ---- shadow-4.11.1/src/useradd.c.redhat 2022-01-03 01:46:53.000000000 +0100 -+++ shadow-4.11.1/src/useradd.c 2022-01-03 14:53:12.988484829 +0100 +diff -up shadow-4.12.3/src/useradd.c.redhat shadow-4.12.3/src/useradd.c +--- shadow-4.12.3/src/useradd.c.redhat 2022-08-06 18:22:45.000000000 +0200 ++++ shadow-4.12.3/src/useradd.c 2022-08-22 15:57:19.034664441 +0200 @@ -82,7 +82,7 @@ const char *Prog; static gid_t def_group = 1000; static const char *def_gname = "other"; @@ -19,19 +19,16 @@ diff -up shadow-4.11.1/src/useradd.c.redhat shadow-4.11.1/src/useradd.c static uid_t user_id; static gid_t user_gid; static const char *user_comment = ""; -@@ -1219,9 +1219,9 @@ static void process_flags (int argc, cha +@@ -1227,7 +1227,7 @@ static void process_flags (int argc, cha + {NULL, 0, NULL, '\0'} }; while ((c = getopt_long (argc, argv, +- "b:c:d:De:f:g:G:hk:K:lmMNop:rR:P:s:u:U" ++ "b:c:d:De:f:g:G:hk:K:lmMnNop:rR:P:s:u:U" #ifdef WITH_SELINUX -- "b:c:d:De:f:g:G:hk:K:lmMNop:rR:P:s:u:UZ:", -+ "b:c:d:De:f:g:G:hk:K:lmMnNop:rR:P:s:u:UZ:", - #else /* !WITH_SELINUX */ -- "b:c:d:De:f:g:G:hk:K:lmMNop:rR:P:s:u:U", -+ "b:c:d:De:f:g:G:hk:K:lmMnNop:rR:P:s:u:U", - #endif /* !WITH_SELINUX */ - long_options, NULL)) != -1) { - switch (c) { -@@ -1378,6 +1378,7 @@ static void process_flags (int argc, cha + "Z:" + #endif /* WITH_SELINUX */ +@@ -1395,6 +1395,7 @@ static void process_flags (int argc, cha case 'M': Mflg = true; break; diff --git a/shadow-4.8-selinux-perms.patch b/shadow-4.12.3-selinux-perms.patch similarity index 84% rename from shadow-4.8-selinux-perms.patch rename to shadow-4.12.3-selinux-perms.patch index dfb32ec..f396455 100644 --- a/shadow-4.8-selinux-perms.patch +++ b/shadow-4.12.3-selinux-perms.patch @@ -1,7 +1,7 @@ -diff -up shadow-4.8/src/chgpasswd.c.selinux-perms shadow-4.8/src/chgpasswd.c ---- shadow-4.8/src/chgpasswd.c.selinux-perms 2019-12-01 18:02:43.000000000 +0100 -+++ shadow-4.8/src/chgpasswd.c 2020-01-13 10:21:44.558107260 +0100 -@@ -39,6 +39,13 @@ +diff -up shadow-4.12.3/src/chgpasswd.c.selinux-perms shadow-4.12.3/src/chgpasswd.c +--- shadow-4.12.3/src/chgpasswd.c.selinux-perms 2022-06-19 16:16:48.000000000 +0200 ++++ shadow-4.12.3/src/chgpasswd.c 2022-08-22 16:09:02.006970030 +0200 +@@ -16,6 +16,13 @@ #include #include #include @@ -15,7 +15,7 @@ diff -up shadow-4.8/src/chgpasswd.c.selinux-perms shadow-4.8/src/chgpasswd.c #ifdef ACCT_TOOLS_SETUID #ifdef USE_PAM #include "pam_defs.h" -@@ -80,6 +87,9 @@ static bool sgr_locked = false; +@@ -61,6 +68,9 @@ static bool sgr_locked = false; #endif static bool gr_locked = false; @@ -25,7 +25,7 @@ diff -up shadow-4.8/src/chgpasswd.c.selinux-perms shadow-4.8/src/chgpasswd.c /* local function prototypes */ static void fail_exit (int code); static /*@noreturn@*/void usage (int status); -@@ -334,6 +344,63 @@ static void check_perms (void) +@@ -318,6 +328,63 @@ static void check_perms (void) #endif /* ACCT_TOOLS_SETUID */ } @@ -89,7 +89,7 @@ diff -up shadow-4.8/src/chgpasswd.c.selinux-perms shadow-4.8/src/chgpasswd.c /* * open_files - lock and open the group databases */ -@@ -427,6 +494,7 @@ int main (int argc, char **argv) +@@ -411,6 +478,7 @@ int main (int argc, char **argv) const struct group *gr; struct group newgr; @@ -97,7 +97,7 @@ diff -up shadow-4.8/src/chgpasswd.c.selinux-perms shadow-4.8/src/chgpasswd.c int errors = 0; int line = 0; -@@ -436,12 +504,37 @@ int main (int argc, char **argv) +@@ -422,12 +490,37 @@ int main (int argc, char **argv) (void) bindtextdomain (PACKAGE, LOCALEDIR); (void) textdomain (PACKAGE); @@ -135,10 +135,10 @@ diff -up shadow-4.8/src/chgpasswd.c.selinux-perms shadow-4.8/src/chgpasswd.c check_perms (); #ifdef SHADOWGRP -diff -up shadow-4.8/src/chpasswd.c.selinux-perms shadow-4.8/src/chpasswd.c ---- shadow-4.8/src/chpasswd.c.selinux-perms 2019-12-01 18:02:43.000000000 +0100 -+++ shadow-4.8/src/chpasswd.c 2020-01-13 10:21:44.558107260 +0100 -@@ -39,6 +39,13 @@ +diff -up shadow-4.12.3/src/chpasswd.c.selinux-perms shadow-4.12.3/src/chpasswd.c +--- shadow-4.12.3/src/chpasswd.c.selinux-perms 2022-06-19 16:16:48.000000000 +0200 ++++ shadow-4.12.3/src/chpasswd.c 2022-08-22 16:10:56.702835681 +0200 +@@ -16,6 +16,13 @@ #include #include #include @@ -152,7 +152,7 @@ diff -up shadow-4.8/src/chpasswd.c.selinux-perms shadow-4.8/src/chpasswd.c #ifdef USE_PAM #include "pam_defs.h" #endif /* USE_PAM */ -@@ -332,6 +339,63 @@ static void check_perms (void) +@@ -318,6 +325,63 @@ static void check_perms (void) #endif /* USE_PAM */ } @@ -216,7 +216,7 @@ diff -up shadow-4.8/src/chpasswd.c.selinux-perms shadow-4.8/src/chpasswd.c /* * open_files - lock and open the password databases */ -@@ -428,6 +492,10 @@ int main (int argc, char **argv) +@@ -450,6 +514,10 @@ int main (int argc, char **argv) (void) bindtextdomain (PACKAGE, LOCALEDIR); (void) textdomain (PACKAGE); @@ -224,10 +224,10 @@ diff -up shadow-4.8/src/chpasswd.c.selinux-perms shadow-4.8/src/chpasswd.c + selinux_check_root (); +#endif + - process_root_flag ("-R", argc, argv); - process_flags (argc, argv); -@@ -440,6 +508,10 @@ int main (int argc, char **argv) + + salt = get_salt(); +@@ -463,6 +531,10 @@ int main (int argc, char **argv) OPENLOG ("chpasswd"); diff --git a/shadow-4.9-nss-get-shadow-logfd-with-log-get-logfd.patch b/shadow-4.9-nss-get-shadow-logfd-with-log-get-logfd.patch deleted file mode 100644 index 4d8e792..0000000 --- a/shadow-4.9-nss-get-shadow-logfd-with-log-get-logfd.patch +++ /dev/null @@ -1,48 +0,0 @@ -From e101219ad71de11da3fdd1b3ec2620fd1a97b92c Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Mon, 10 Jan 2022 15:30:28 +0100 -Subject: [PATCH] nss: get shadow_logfd with log_get_logfd() - -If /etc/nsswitch.conf doesn't exist podman crashes because shadow_logfd -is NULL. In order to avoid that load the log file descriptor with the -log_get_logfd() helper function. - -Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2038811 - -Signed-off-by: Iker Pedrosa ---- - lib/nss.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/lib/nss.c b/lib/nss.c -index 02742902..06fa48e5 100644 ---- a/lib/nss.c -+++ b/lib/nss.c -@@ -9,6 +9,7 @@ - #include "prototypes.h" - #include "../libsubid/subid.h" - #include "shadowlog_internal.h" -+#include "shadowlog.h" - - #define NSSWITCH "/etc/nsswitch.conf" - -@@ -42,6 +43,7 @@ void nss_init(const char *nsswitch_path) { - FILE *nssfp = NULL; - char *line = NULL, *p, *token, *saveptr; - size_t len = 0; -+ FILE *shadow_logfd = log_get_logfd(); - - if (atomic_flag_test_and_set(&nss_init_started)) { - // Another thread has started nss_init, wait for it to complete -@@ -57,7 +59,7 @@ void nss_init(const char *nsswitch_path) { - // subid: files - nssfp = fopen(nsswitch_path, "r"); - if (!nssfp) { -- fprintf(shadow_logfd, "Failed opening %s: %m", nsswitch_path); -+ fprintf(shadow_logfd, "Failed opening %s: %m\n", nsswitch_path); - atomic_store(&nss_init_completed, true); - return; - } --- -2.34.1 - diff --git a/shadow-utils.spec b/shadow-utils.spec index 660f777..69a2aa8 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils -Version: 4.11.1 -Release: 4%{?dist} +Version: 4.12.3 +Release: 1%{?dist} Epoch: 2 License: BSD and GPLv2+ URL: https://github.com/shadow-maint/shadow @@ -18,9 +18,9 @@ Source6: shadow-utils.HOME_MODE.xml ### Patches ### # Misc small changes - most probably non-upstreamable -Patch0: shadow-4.11.1-redhat.patch +Patch0: shadow-4.12.3-redhat.patch # Be more lenient with acceptable user/group names - non upstreamable -Patch1: shadow-4.8-goodname.patch +Patch1: shadow-4.12.3-goodname.patch # SElinux related - upstreamability unknown Patch3: shadow-4.9-default-range.patch # Misc manual page changes - non-upstreamable @@ -34,19 +34,15 @@ Patch7: shadow-4.11.1-audit-update.patch # Changes related to password unlocking - could be upstreamed Patch8: shadow-4.5-usermod-unlock.patch # Additional SElinux related changes - upstreamability unknown -Patch9: shadow-4.8-selinux-perms.patch +Patch9: shadow-4.12.3-selinux-perms.patch # Handle NULL return from *time funcs - upstreamable Patch10: shadow-4.11.1-null-tm.patch # Handle /etc/passwd corruption - could be upstreamed -Patch11: shadow-4.8-long-entry.patch +Patch11: shadow-4.12.3-long-entry.patch # Limit uid/gid allocation to non-zero - could be upstreamed Patch12: shadow-4.6-sysugid-min-limit.patch # Ignore LOGIN_PLAIN_PROMPT in login.defs - upstreamability unknown Patch13: shadow-4.8-ignore-login-prompt.patch -# https://github.com/shadow-maint/shadow/commit/e101219ad71de11da3fdd1b3ec2620fd1a97b92c -Patch14: shadow-4.9-nss-get-shadow-logfd-with-log-get-logfd.patch -# https://github.com/shadow-maint/shadow/commit/f1f1678e13aa3ae49bdb139efaa2c5bc53dcfe92 -Patch15: shadow-4.11.1-useradd-modify-check-ID-range-for-system-users.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -120,8 +116,6 @@ Development files for shadow-utils-subid. %patch11 -p1 -b .long-entry %patch12 -p1 -b .sysugid-min-limit %patch13 -p1 -b .login-prompt -%patch14 -p1 -b .nss-get-shadow-logfd-with-log-get-logfd -%patch15 -p1 -b .useradd-modify-check-ID-range-for-system-users iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -295,6 +289,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Mon Aug 22 2022 Iker Pedrosa - 2:4.12.3-1 +- Rebase to version 4.12.3. Resolves: #2117809 + * Mon Aug 1 2022 Iker Pedrosa - 2:4.11.1-4 - useradd: modify check ID range for system users. Resolves: #2093692 diff --git a/sources b/sources index 53a4fb0..d1e0ebd 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (shadow-4.11.1.tar.xz) = 12fbe4d6ac929ad3c21525ed0f1026b5b678ccec9762f2ec7e611d9c180934def506325f2835fb750dd30af035b592f827ff151cd6e4c805aaaf8e01425c279f -SHA512 (shadow-4.11.1.tar.xz.asc) = 4594189678cc9bcc8831f62a5d42c605b085be4a3b540429d7c800f4304e2e8fe04358547917eb90c1513646fade7c714611bfdc98af7dec5321a3dc3e65c4fd +SHA512 (shadow-4.12.3.tar.xz) = 0529889258f54e7634762dc154aa680d55f8c5f1654afadd1b7431cfbb890a3b1ba27c7ff4b7c45986e4ee2289946db2e420b23ed13e4e5b15800a1fb3a013bc +SHA512 (shadow-4.12.3.tar.xz.asc) = d3f294d86c0e2174c88809810a801737c01cd01f9cadbe7b1ae382b2745d86e2e30c0718fa6489c2abb65500ed94c8ac1961d05243b5a1800c966384c69281c9 From d491f14619d851b66e1da1dbc2cd492f87b0d28e Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Fri, 9 Sep 2022 15:04:49 +0200 Subject: [PATCH 063/134] useradd: Do not reset non-existent data in {last,fail}log Signed-off-by: Iker Pedrosa --- ...2.3-useradd-stop-last-fail-log-reset.patch | 42 +++++++++++++++++++ shadow-utils.spec | 10 ++++- 2 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 shadow-4.12.3-useradd-stop-last-fail-log-reset.patch diff --git a/shadow-4.12.3-useradd-stop-last-fail-log-reset.patch b/shadow-4.12.3-useradd-stop-last-fail-log-reset.patch new file mode 100644 index 0000000..8662672 --- /dev/null +++ b/shadow-4.12.3-useradd-stop-last-fail-log-reset.patch @@ -0,0 +1,42 @@ +From ebf9b232b012725d2be5e750876c7336cf1c37fd Mon Sep 17 00:00:00 2001 +From: David Kalnischkies +Date: Wed, 24 Aug 2022 13:21:01 +0200 +Subject: [PATCH] useradd: Do not reset non-existent data in {last,fail}log + +useradd does not create the files if they don't exist, but if they exist +it will reset user data even if the data did not exist before creating +a hole and an explicitly zero'd data point resulting (especially for +high UIDs) in a lot of zeros ending up in containers and tarballs. +--- + src/useradd.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/useradd.c b/src/useradd.c +index 6eaeb533..39a744ee 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -1996,8 +1996,9 @@ static void faillog_reset (uid_t uid) + struct faillog fl; + int fd; + off_t offset_uid = (off_t) (sizeof fl) * uid; ++ struct stat st; + +- if (access (FAILLOG_FILE, F_OK) != 0) { ++ if (stat (FAILLOG_FILE, &st) != 0 || st.st_size <= offset_uid) { + return; + } + +@@ -2033,8 +2034,9 @@ static void lastlog_reset (uid_t uid) + int fd; + off_t offset_uid = (off_t) (sizeof ll) * uid; + uid_t max_uid; ++ struct stat st; + +- if (access (LASTLOG_FILE, F_OK) != 0) { ++ if (stat (LASTLOG_FILE, &st) != 0 || st.st_size <= offset_uid) { + return; + } + +-- +2.37.3 + diff --git a/shadow-utils.spec b/shadow-utils.spec index 69a2aa8..bdc0515 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.12.3 -Release: 1%{?dist} +Release: 2%{?dist} Epoch: 2 License: BSD and GPLv2+ URL: https://github.com/shadow-maint/shadow @@ -19,7 +19,7 @@ Source6: shadow-utils.HOME_MODE.xml ### Patches ### # Misc small changes - most probably non-upstreamable Patch0: shadow-4.12.3-redhat.patch -# Be more lenient with acceptable user/group names - non upstreamable +# https://github.com/shadow-maint/shadow/commit/cfc981df2afc615e3792b918e9ee49e631b0a3a9 Patch1: shadow-4.12.3-goodname.patch # SElinux related - upstreamability unknown Patch3: shadow-4.9-default-range.patch @@ -43,6 +43,8 @@ Patch11: shadow-4.12.3-long-entry.patch Patch12: shadow-4.6-sysugid-min-limit.patch # Ignore LOGIN_PLAIN_PROMPT in login.defs - upstreamability unknown Patch13: shadow-4.8-ignore-login-prompt.patch +# https://github.com/shadow-maint/shadow/commit/ebf9b232b012725d2be5e750876c7336cf1c37fd +Patch14: shadow-4.12.3-useradd-stop-last-fail-log-reset.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -116,6 +118,7 @@ Development files for shadow-utils-subid. %patch11 -p1 -b .long-entry %patch12 -p1 -b .sysugid-min-limit %patch13 -p1 -b .login-prompt +%patch14 -p1 -b .useradd-stop-last-fail-log-reset iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -289,6 +292,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Fri Sep 9 2022 Iker Pedrosa - 2:4.12.3-2 +- useradd: Do not reset non-existent data in {last,fail}log + * Mon Aug 22 2022 Iker Pedrosa - 2:4.12.3-1 - Rebase to version 4.12.3. Resolves: #2117809 From 47d965b5dcba59291e90261ccd9f3e6436b0691d Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Wed, 5 Oct 2022 13:04:29 +0200 Subject: [PATCH 064/134] chage: Fix regression in print_date Resolves: #2129336 Signed-off-by: Iker Pedrosa --- ...w-4.12.3-chage-print-date-regression.patch | 32 +++++++++++++++++++ shadow-utils.spec | 8 ++++- 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 shadow-4.12.3-chage-print-date-regression.patch diff --git a/shadow-4.12.3-chage-print-date-regression.patch b/shadow-4.12.3-chage-print-date-regression.patch new file mode 100644 index 0000000..7f9f225 --- /dev/null +++ b/shadow-4.12.3-chage-print-date-regression.patch @@ -0,0 +1,32 @@ +From e503fd574b7dbf6b21b1168e20938f0922807916 Mon Sep 17 00:00:00 2001 +From: Xiami <1927254+Xiami2012@users.noreply.github.com> +Date: Wed, 5 Oct 2022 18:11:28 +0800 +Subject: [PATCH] chage: Fix regression in print_date + +Introduced by c6c8130db4319613a91dd07bbb845f6c33c5f79f + +After removing snprintf, the format string should get unescaped once. + +Fixes #564 + +Reporter and patch author: DerMouse (github.com/DerMouse) +--- + src/chage.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/chage.c b/src/chage.c +index 8cf67794..01570d72 100644 +--- a/src/chage.c ++++ b/src/chage.c +@@ -228,7 +228,7 @@ static void print_date (time_t date) + if (NULL == tp) { + (void) printf ("time_t: %lu\n", (unsigned long)date); + } else { +- (void) strftime (buf, sizeof buf, iflg ? "%%Y-%%m-%%d" : "%%b %%d, %%Y", tp); ++ (void) strftime (buf, sizeof buf, iflg ? "%Y-%m-%d" : "%b %d, %Y", tp); + (void) puts (buf); + } + } +-- +2.37.3 + diff --git a/shadow-utils.spec b/shadow-utils.spec index bdc0515..c9c1c89 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.12.3 -Release: 2%{?dist} +Release: 3%{?dist} Epoch: 2 License: BSD and GPLv2+ URL: https://github.com/shadow-maint/shadow @@ -45,6 +45,8 @@ Patch12: shadow-4.6-sysugid-min-limit.patch Patch13: shadow-4.8-ignore-login-prompt.patch # https://github.com/shadow-maint/shadow/commit/ebf9b232b012725d2be5e750876c7336cf1c37fd Patch14: shadow-4.12.3-useradd-stop-last-fail-log-reset.patch +# https://github.com/shadow-maint/shadow/commit/e503fd574b7dbf6b21b1168e20938f0922807916 +Patch15: shadow-4.12.3-chage-print-date-regression.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -119,6 +121,7 @@ Development files for shadow-utils-subid. %patch12 -p1 -b .sysugid-min-limit %patch13 -p1 -b .login-prompt %patch14 -p1 -b .useradd-stop-last-fail-log-reset +%patch15 -p1 -b .chage-print-date-regression iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -292,6 +295,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Wed Oct 5 2022 Iker Pedrosa - 2:4.12.3-3 +- chage: Fix regression in print_date. Resolves: #2129336 + * Fri Sep 9 2022 Iker Pedrosa - 2:4.12.3-2 - useradd: Do not reset non-existent data in {last,fail}log From d3e12503afcd822a8dcd98a174813d1a70a585e6 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Wed, 9 Nov 2022 10:12:41 +0100 Subject: [PATCH 065/134] - Rebase to version 4.13 - SPDX license migration Signed-off-by: Iker Pedrosa --- .gitignore | 2 + shadow-4.11.1-null-tm.patch | 22 ---- ...w-4.12.3-chage-print-date-regression.patch | 32 ------ shadow-4.12.3-goodname.patch | 100 ------------------ shadow-4.12.3-long-entry.patch | 86 --------------- ...2.3-useradd-stop-last-fail-log-reset.patch | 42 -------- shadow-4.13-default-range.patch | 35 ++++++ shadow-4.6-move-home.patch | 15 --- shadow-4.6-sysugid-min-limit.patch | 34 ------ shadow-4.8-ignore-login-prompt.patch | 11 -- shadow-4.9-default-range.patch | 35 ------ shadow-utils.spec | 58 ++++------ sources | 4 +- 13 files changed, 58 insertions(+), 418 deletions(-) delete mode 100644 shadow-4.11.1-null-tm.patch delete mode 100644 shadow-4.12.3-chage-print-date-regression.patch delete mode 100644 shadow-4.12.3-goodname.patch delete mode 100644 shadow-4.12.3-long-entry.patch delete mode 100644 shadow-4.12.3-useradd-stop-last-fail-log-reset.patch create mode 100644 shadow-4.13-default-range.patch delete mode 100644 shadow-4.6-move-home.patch delete mode 100644 shadow-4.6-sysugid-min-limit.patch delete mode 100644 shadow-4.8-ignore-login-prompt.patch delete mode 100644 shadow-4.9-default-range.patch diff --git a/.gitignore b/.gitignore index 7113c48..44cb6ed 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,5 @@ shadow-4.1.4.2.tar.bz2 /shadow-4.11.1.tar.xz.asc /shadow-4.12.3.tar.xz /shadow-4.12.3.tar.xz.asc +/shadow-4.13.tar.xz +/shadow-4.13.tar.xz.asc diff --git a/shadow-4.11.1-null-tm.patch b/shadow-4.11.1-null-tm.patch deleted file mode 100644 index b8d5fc8..0000000 --- a/shadow-4.11.1-null-tm.patch +++ /dev/null @@ -1,22 +0,0 @@ -diff -up shadow-4.11.1/src/chage.c.null-tm shadow-4.11.1/src/chage.c -diff -up shadow-4.11.1/src/lastlog.c.null-tm shadow-4.11.1/src/lastlog.c ---- shadow-4.11.1/src/lastlog.c.null-tm 2022-01-03 15:31:56.348555620 +0100 -+++ shadow-4.11.1/src/lastlog.c 2022-01-03 15:38:41.262229024 +0100 -@@ -151,9 +151,12 @@ static void print_one (/*@null@*/const s - - ll_time = ll.ll_time; - tm = localtime (&ll_time); -- strftime (ptime, sizeof (ptime), "%a %b %e %H:%M:%S %z %Y", tm); -- cp = ptime; -- -+ if (tm == NULL) { -+ cp = "(unknown)"; -+ } else { -+ strftime (ptime, sizeof (ptime), "%a %b %e %H:%M:%S %z %Y", tm); -+ cp = ptime; -+ } - if (ll.ll_time == (time_t) 0) { - cp = _("**Never logged in**\0"); - } -diff -up shadow-4.11.1/src/passwd.c.null-tm shadow-4.11.1/src/passwd.c -diff -up shadow-4.11.1/src/usermod.c.null-tm shadow-4.11.1/src/usermod.c diff --git a/shadow-4.12.3-chage-print-date-regression.patch b/shadow-4.12.3-chage-print-date-regression.patch deleted file mode 100644 index 7f9f225..0000000 --- a/shadow-4.12.3-chage-print-date-regression.patch +++ /dev/null @@ -1,32 +0,0 @@ -From e503fd574b7dbf6b21b1168e20938f0922807916 Mon Sep 17 00:00:00 2001 -From: Xiami <1927254+Xiami2012@users.noreply.github.com> -Date: Wed, 5 Oct 2022 18:11:28 +0800 -Subject: [PATCH] chage: Fix regression in print_date - -Introduced by c6c8130db4319613a91dd07bbb845f6c33c5f79f - -After removing snprintf, the format string should get unescaped once. - -Fixes #564 - -Reporter and patch author: DerMouse (github.com/DerMouse) ---- - src/chage.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/chage.c b/src/chage.c -index 8cf67794..01570d72 100644 ---- a/src/chage.c -+++ b/src/chage.c -@@ -228,7 +228,7 @@ static void print_date (time_t date) - if (NULL == tp) { - (void) printf ("time_t: %lu\n", (unsigned long)date); - } else { -- (void) strftime (buf, sizeof buf, iflg ? "%%Y-%%m-%%d" : "%%b %%d, %%Y", tp); -+ (void) strftime (buf, sizeof buf, iflg ? "%Y-%m-%d" : "%b %d, %Y", tp); - (void) puts (buf); - } - } --- -2.37.3 - diff --git a/shadow-4.12.3-goodname.patch b/shadow-4.12.3-goodname.patch deleted file mode 100644 index 2376674..0000000 --- a/shadow-4.12.3-goodname.patch +++ /dev/null @@ -1,100 +0,0 @@ -diff -up shadow-4.12.3/libmisc/chkname.c.goodname shadow-4.12.3/libmisc/chkname.c ---- shadow-4.12.3/libmisc/chkname.c.goodname 2022-06-19 16:16:48.000000000 +0200 -+++ shadow-4.12.3/libmisc/chkname.c 2022-08-22 16:00:27.646087971 +0200 -@@ -32,26 +32,44 @@ static bool is_valid_name (const char *n - } - - /* -- * User/group names must match [a-z_][a-z0-9_-]*[$] -- */ -+ * User/group names must match gnu e-regex: -+ * [a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,30}[a-zA-Z0-9_.$-]? -+ * -+ * as a non-POSIX, extension, allow "$" as the last char for -+ * sake of Samba 3.x "add machine script" -+ * -+ * Also do not allow fully numeric names or just "." or "..". -+ */ -+ int numeric; - -- if (('\0' == *name) || -- !((('a' <= *name) && ('z' >= *name)) || ('_' == *name))) { -+ if ('\0' == *name || -+ ('.' == *name && (('.' == name[1] && '\0' == name[2]) || -+ '\0' == name[1])) || -+ !((*name >= 'a' && *name <= 'z') || -+ (*name >= 'A' && *name <= 'Z') || -+ (*name >= '0' && *name <= '9') || -+ *name == '_' || -+ *name == '.')) { - return false; - } - -+ numeric = isdigit(*name); -+ - while ('\0' != *++name) { -- if (!(( ('a' <= *name) && ('z' >= *name) ) || -- ( ('0' <= *name) && ('9' >= *name) ) || -- ('_' == *name) || -- ('-' == *name) || -- ( ('$' == *name) && ('\0' == *(name + 1)) ) -+ if (!((*name >= 'a' && *name <= 'z') || -+ (*name >= 'A' && *name <= 'Z') || -+ (*name >= '0' && *name <= '9') || -+ *name == '_' || -+ *name == '.' || -+ *name == '-' || -+ (*name == '$' && name[1] == '\0') - )) { - return false; - } -+ numeric &= isdigit(*name); - } - -- return true; -+ return !numeric; - } - - bool is_valid_user_name (const char *name) -diff -up shadow-4.12.3/man/groupadd.8.xml.goodname shadow-4.12.3/man/groupadd.8.xml ---- shadow-4.12.3/man/groupadd.8.xml.goodname 2022-08-22 16:00:27.646087971 +0200 -+++ shadow-4.12.3/man/groupadd.8.xml 2022-08-22 16:01:59.301779733 +0200 -@@ -64,10 +64,12 @@ - files as needed. - - -- Groupnames must start with a lower case letter or an underscore, -- followed by lower case letters, digits, underscores, or dashes. -- They can end with a dollar sign. -- In regular expression terms: [a-z_][a-z0-9_-]*[$]? -+ Groupnames may contain only lower and upper case letters, digits, -+ underscores, or dashes. They can end with a dollar sign. -+ -+ Dashes are not allowed at the beginning of the groupname. -+ Fully numeric groupnames and groupnames . or .. are -+ also disallowed. - - - Groupnames may only be up to &GROUP_NAME_MAX_LENGTH; characters long. -diff -up shadow-4.12.3/man/useradd.8.xml.goodname shadow-4.12.3/man/useradd.8.xml ---- shadow-4.12.3/man/useradd.8.xml.goodname 2022-08-22 14:46:57.000000000 +0200 -+++ shadow-4.12.3/man/useradd.8.xml 2022-08-22 16:00:27.646087971 +0200 -@@ -692,10 +692,14 @@ - - - -- Usernames must start with a lower case letter or an underscore, -- followed by lower case letters, digits, underscores, or dashes. -- They can end with a dollar sign. -- In regular expression terms: [a-z_][a-z0-9_-]*[$]? -+ Usernames may contain only lower and upper case letters, digits, -+ underscores, or dashes. They can end with a dollar sign. -+ -+ Dashes are not allowed at the beginning of the username. -+ Fully numeric usernames and usernames . or .. are -+ also disallowed. It is not recommended to use usernames beginning -+ with . character as their home directories will be hidden in -+ the ls output. - - - Usernames may only be up to 32 characters long. diff --git a/shadow-4.12.3-long-entry.patch b/shadow-4.12.3-long-entry.patch deleted file mode 100644 index 9dc5ef2..0000000 --- a/shadow-4.12.3-long-entry.patch +++ /dev/null @@ -1,86 +0,0 @@ -diff -up shadow-4.12.3/lib/defines.h.long-entry shadow-4.12.3/lib/defines.h ---- shadow-4.12.3/lib/defines.h.long-entry 2022-08-18 23:51:37.000000000 +0200 -+++ shadow-4.12.3/lib/defines.h 2022-08-22 16:12:27.412522768 +0200 -@@ -335,6 +335,9 @@ extern char *strerror (); - # endif - #endif - -+/* Maximum length of passwd entry */ -+#define PASSWD_ENTRY_MAX_LENGTH 32768 -+ - #ifdef HAVE_SECURE_GETENV - # define shadow_getenv(name) secure_getenv(name) - # else -diff -up shadow-4.12.3/lib/pwio.c.long-entry shadow-4.12.3/lib/pwio.c ---- shadow-4.12.3/lib/pwio.c.long-entry 2022-06-19 16:16:48.000000000 +0200 -+++ shadow-4.12.3/lib/pwio.c 2022-08-22 16:12:27.412522768 +0200 -@@ -56,7 +56,10 @@ static int passwd_put (const void *ent, - || (pw->pw_gid == (gid_t)-1) - || (valid_field (pw->pw_gecos, ":\n") == -1) - || (valid_field (pw->pw_dir, ":\n") == -1) -- || (valid_field (pw->pw_shell, ":\n") == -1)) { -+ || (valid_field (pw->pw_shell, ":\n") == -1) -+ || (strlen (pw->pw_name) + strlen (pw->pw_passwd) + -+ strlen (pw->pw_gecos) + strlen (pw->pw_dir) + -+ strlen (pw->pw_shell) + 100 > PASSWD_ENTRY_MAX_LENGTH)) { - return -1; - } - -diff -up shadow-4.12.3/lib/sgetpwent.c.long-entry shadow-4.12.3/lib/sgetpwent.c ---- shadow-4.12.3/lib/sgetpwent.c.long-entry 2022-08-09 00:30:40.000000000 +0200 -+++ shadow-4.12.3/lib/sgetpwent.c 2022-08-22 16:14:10.955309200 +0200 -@@ -34,7 +34,7 @@ - struct passwd *sgetpwent (const char *buf) - { - static struct passwd pwent; -- static char pwdbuf[1024]; -+ static char pwdbuf[PASSWD_ENTRY_MAX_LENGTH]; - int i; - char *cp; - char *fields[NFIELDS]; -@@ -44,8 +44,10 @@ struct passwd *sgetpwent (const char *bu - * the password structure remain valid. - */ - -- if (strlen (buf) >= sizeof pwdbuf) -+ if (strlen (buf) >= sizeof pwdbuf) { -+ fprintf (stderr, "Too long passwd entry encountered, file corruption?\n"); - return 0; /* fail if too long */ -+ } - strcpy (pwdbuf, buf); - - /* -diff -up shadow-4.12.3/lib/sgetspent.c.long-entry shadow-4.12.3/lib/sgetspent.c ---- shadow-4.12.3/lib/sgetspent.c.long-entry 2022-06-19 16:16:54.000000000 +0200 -+++ shadow-4.12.3/lib/sgetspent.c 2022-08-22 16:12:27.413522776 +0200 -@@ -25,7 +25,7 @@ - */ - struct spwd *sgetspent (const char *string) - { -- static char spwbuf[1024]; -+ static char spwbuf[PASSWD_ENTRY_MAX_LENGTH]; - static struct spwd spwd; - char *fields[FIELDS]; - char *cp; -@@ -37,6 +37,7 @@ struct spwd *sgetspent (const char *stri - */ - - if (strlen (string) >= sizeof spwbuf) { -+ fprintf (stderr, "Too long shadow entry encountered, file corruption?\n"); - return 0; /* fail if too long */ - } - strcpy (spwbuf, string); -diff -up shadow-4.12.3/lib/shadowio.c.long-entry shadow-4.12.3/lib/shadowio.c ---- shadow-4.12.3/lib/shadowio.c.long-entry 2022-06-19 16:16:48.000000000 +0200 -+++ shadow-4.12.3/lib/shadowio.c 2022-08-22 16:12:27.413522776 +0200 -@@ -56,7 +56,9 @@ static int shadow_put (const void *ent, - - if ( (NULL == sp) - || (valid_field (sp->sp_namp, ":\n") == -1) -- || (valid_field (sp->sp_pwdp, ":\n") == -1)) { -+ || (valid_field (sp->sp_pwdp, ":\n") == -1) -+ || (strlen (sp->sp_namp) + strlen (sp->sp_pwdp) + -+ 1000 > PASSWD_ENTRY_MAX_LENGTH)) { - return -1; - } - diff --git a/shadow-4.12.3-useradd-stop-last-fail-log-reset.patch b/shadow-4.12.3-useradd-stop-last-fail-log-reset.patch deleted file mode 100644 index 8662672..0000000 --- a/shadow-4.12.3-useradd-stop-last-fail-log-reset.patch +++ /dev/null @@ -1,42 +0,0 @@ -From ebf9b232b012725d2be5e750876c7336cf1c37fd Mon Sep 17 00:00:00 2001 -From: David Kalnischkies -Date: Wed, 24 Aug 2022 13:21:01 +0200 -Subject: [PATCH] useradd: Do not reset non-existent data in {last,fail}log - -useradd does not create the files if they don't exist, but if they exist -it will reset user data even if the data did not exist before creating -a hole and an explicitly zero'd data point resulting (especially for -high UIDs) in a lot of zeros ending up in containers and tarballs. ---- - src/useradd.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/src/useradd.c b/src/useradd.c -index 6eaeb533..39a744ee 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -1996,8 +1996,9 @@ static void faillog_reset (uid_t uid) - struct faillog fl; - int fd; - off_t offset_uid = (off_t) (sizeof fl) * uid; -+ struct stat st; - -- if (access (FAILLOG_FILE, F_OK) != 0) { -+ if (stat (FAILLOG_FILE, &st) != 0 || st.st_size <= offset_uid) { - return; - } - -@@ -2033,8 +2034,9 @@ static void lastlog_reset (uid_t uid) - int fd; - off_t offset_uid = (off_t) (sizeof ll) * uid; - uid_t max_uid; -+ struct stat st; - -- if (access (LASTLOG_FILE, F_OK) != 0) { -+ if (stat (LASTLOG_FILE, &st) != 0 || st.st_size <= offset_uid) { - return; - } - --- -2.37.3 - diff --git a/shadow-4.13-default-range.patch b/shadow-4.13-default-range.patch new file mode 100644 index 0000000..f199b39 --- /dev/null +++ b/shadow-4.13-default-range.patch @@ -0,0 +1,35 @@ +diff -up shadow-4.13/lib/semanage.c.default-range shadow-4.13/lib/semanage.c +--- shadow-4.13/lib/semanage.c.default-range 2022-11-09 09:37:11.955314964 +0100 ++++ shadow-4.13/lib/semanage.c 2022-11-09 09:47:59.130645564 +0100 +@@ -122,6 +122,7 @@ static int semanage_user_mod (semanage_h + goto done; + } + ++#if 0 + if (semanage_mls_enabled(handle)) { + ret = semanage_seuser_set_mlsrange (handle, seuser, DEFAULT_SERANGE); + if (ret != 0) { +@@ -131,6 +132,7 @@ static int semanage_user_mod (semanage_h + goto done; + } + } ++#endif + + ret = semanage_seuser_set_sename (handle, seuser, seuser_name); + if (ret != 0) { +@@ -181,6 +183,7 @@ static int semanage_user_add (semanage_h + goto done; + } + ++#if 0 + if (semanage_mls_enabled(handle)) { + ret = semanage_seuser_set_mlsrange (handle, seuser, DEFAULT_SERANGE); + if (ret != 0) { +@@ -190,6 +193,7 @@ static int semanage_user_add (semanage_h + goto done; + } + } ++#endif + + ret = semanage_seuser_set_sename (handle, seuser, seuser_name); + if (ret != 0) { diff --git a/shadow-4.6-move-home.patch b/shadow-4.6-move-home.patch deleted file mode 100644 index cff9561..0000000 --- a/shadow-4.6-move-home.patch +++ /dev/null @@ -1,15 +0,0 @@ -diff -up shadow-4.6/src/usermod.c.move-home shadow-4.6/src/usermod.c ---- shadow-4.6/src/usermod.c.move-home 2018-05-28 14:59:05.594076665 +0200 -+++ shadow-4.6/src/usermod.c 2018-05-28 15:00:28.479837392 +0200 -@@ -1845,6 +1845,11 @@ static void move_home (void) - Prog, prefix_user_home, prefix_user_newhome); - fail_exit (E_HOMEDIR); - } -+ } else { -+ fprintf (stderr, -+ _("%s: The previous home directory (%s) does " -+ "not exist or is inaccessible. Move cannot be completed.\n"), -+ Prog, prefix_user_home); - } - } - diff --git a/shadow-4.6-sysugid-min-limit.patch b/shadow-4.6-sysugid-min-limit.patch deleted file mode 100644 index 4cea6ef..0000000 --- a/shadow-4.6-sysugid-min-limit.patch +++ /dev/null @@ -1,34 +0,0 @@ -diff -up shadow-4.6/libmisc/find_new_gid.c.min-limit shadow-4.6/libmisc/find_new_gid.c ---- shadow-4.6/libmisc/find_new_gid.c.min-limit 2018-04-29 18:42:37.000000001 +0200 -+++ shadow-4.6/libmisc/find_new_gid.c 2018-11-06 10:51:20.554963292 +0100 -@@ -82,6 +82,13 @@ static int get_ranges (bool sys_group, g - (unsigned long) *max_id); - return EINVAL; - } -+ /* -+ * Zero is reserved for root and the allocation algorithm does not -+ * work right with it. -+ */ -+ if (*min_id == 0) { -+ *min_id = (gid_t) 1; -+ } - } else { - /* Non-system groups */ - -diff -up shadow-4.6/libmisc/find_new_uid.c.min-limit shadow-4.6/libmisc/find_new_uid.c ---- shadow-4.6/libmisc/find_new_uid.c.min-limit 2018-04-29 18:42:37.000000001 +0200 -+++ shadow-4.6/libmisc/find_new_uid.c 2018-11-06 10:51:39.341399569 +0100 -@@ -82,6 +82,13 @@ static int get_ranges (bool sys_user, ui - (unsigned long) *max_id); - return EINVAL; - } -+ /* -+ * Zero is reserved for root and the allocation algorithm does not -+ * work right with it. -+ */ -+ if (*min_id == 0) { -+ *min_id = (uid_t) 1; -+ } - } else { - /* Non-system users */ - diff --git a/shadow-4.8-ignore-login-prompt.patch b/shadow-4.8-ignore-login-prompt.patch deleted file mode 100644 index c93aae7..0000000 --- a/shadow-4.8-ignore-login-prompt.patch +++ /dev/null @@ -1,11 +0,0 @@ -diff -up shadow-4.8/lib/getdef.c.login-prompt shadow-4.8/lib/getdef.c ---- shadow-4.8/lib/getdef.c.login-prompt 2020-01-13 10:38:44.852796681 +0100 -+++ shadow-4.8/lib/getdef.c 2020-01-13 10:39:54.472612511 +0100 -@@ -98,6 +98,7 @@ static struct itemdef def_table[] = { - {"LASTLOG_UID_MAX", NULL}, - {"LOGIN_RETRIES", NULL}, - {"LOGIN_TIMEOUT", NULL}, -+ {"LOGIN_PLAIN_PROMPT", NULL}, - {"LOG_OK_LOGINS", NULL}, - {"LOG_UNKFAIL_ENAB", NULL}, - {"MAIL_DIR", NULL}, diff --git a/shadow-4.9-default-range.patch b/shadow-4.9-default-range.patch deleted file mode 100644 index f6e0427..0000000 --- a/shadow-4.9-default-range.patch +++ /dev/null @@ -1,35 +0,0 @@ -diff -up shadow-4.9/lib/semanage.c.default-range shadow-4.9/lib/semanage.c ---- shadow-4.9/lib/semanage.c.default-range 2021-07-22 23:55:35.000000000 +0200 -+++ shadow-4.9/lib/semanage.c 2021-08-02 12:43:16.822817392 +0200 -@@ -143,6 +143,7 @@ static int semanage_user_mod (semanage_h - goto done; - } - -+#if 0 - ret = semanage_seuser_set_mlsrange (handle, seuser, DEFAULT_SERANGE); - if (ret != 0) { - fprintf (shadow_logfd, -@@ -150,6 +151,7 @@ static int semanage_user_mod (semanage_h - ret = 1; - goto done; - } -+#endif - - ret = semanage_seuser_set_sename (handle, seuser, seuser_name); - if (ret != 0) { -@@ -200,6 +202,7 @@ static int semanage_user_add (semanage_h - goto done; - } - -+#if 0 - ret = semanage_seuser_set_mlsrange (handle, seuser, DEFAULT_SERANGE); - if (ret != 0) { - fprintf (shadow_logfd, -@@ -208,6 +211,7 @@ static int semanage_user_add (semanage_h - ret = 1; - goto done; - } -+#endif - - ret = semanage_seuser_set_sename (handle, seuser, seuser_name); - if (ret != 0) { diff --git a/shadow-utils.spec b/shadow-utils.spec index c9c1c89..da2d3bd 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,9 +1,9 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils -Version: 4.12.3 -Release: 3%{?dist} +Version: 4.13 +Release: 1%{?dist} Epoch: 2 -License: BSD and GPLv2+ +License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow Source0: https://github.com/shadow-maint/shadow/releases/download/v%{version}/shadow-%{version}.tar.xz Source1: https://github.com/shadow-maint/shadow/releases/download/v%{version}/shadow-%{version}.tar.xz.asc @@ -19,34 +19,18 @@ Source6: shadow-utils.HOME_MODE.xml ### Patches ### # Misc small changes - most probably non-upstreamable Patch0: shadow-4.12.3-redhat.patch -# https://github.com/shadow-maint/shadow/commit/cfc981df2afc615e3792b918e9ee49e631b0a3a9 -Patch1: shadow-4.12.3-goodname.patch # SElinux related - upstreamability unknown -Patch3: shadow-4.9-default-range.patch +Patch1: shadow-4.13-default-range.patch # Misc manual page changes - non-upstreamable -Patch4: shadow-4.9-manfix.patch +Patch2: shadow-4.9-manfix.patch # Date parsing improvement - could be upstreamed -Patch5: shadow-4.2.1-date-parsing.patch -# Additional error message - could be upstreamed -Patch6: shadow-4.6-move-home.patch +Patch3: shadow-4.2.1-date-parsing.patch # Audit message changes - upstreamability unknown -Patch7: shadow-4.11.1-audit-update.patch +Patch4: shadow-4.11.1-audit-update.patch # Changes related to password unlocking - could be upstreamed -Patch8: shadow-4.5-usermod-unlock.patch +Patch5: shadow-4.5-usermod-unlock.patch # Additional SElinux related changes - upstreamability unknown -Patch9: shadow-4.12.3-selinux-perms.patch -# Handle NULL return from *time funcs - upstreamable -Patch10: shadow-4.11.1-null-tm.patch -# Handle /etc/passwd corruption - could be upstreamed -Patch11: shadow-4.12.3-long-entry.patch -# Limit uid/gid allocation to non-zero - could be upstreamed -Patch12: shadow-4.6-sysugid-min-limit.patch -# Ignore LOGIN_PLAIN_PROMPT in login.defs - upstreamability unknown -Patch13: shadow-4.8-ignore-login-prompt.patch -# https://github.com/shadow-maint/shadow/commit/ebf9b232b012725d2be5e750876c7336cf1c37fd -Patch14: shadow-4.12.3-useradd-stop-last-fail-log-reset.patch -# https://github.com/shadow-maint/shadow/commit/e503fd574b7dbf6b21b1168e20938f0922807916 -Patch15: shadow-4.12.3-chage-print-date-regression.patch +Patch6: shadow-4.12.3-selinux-perms.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -108,20 +92,12 @@ Development files for shadow-utils-subid. %prep %setup -q -n shadow-%{version} %patch0 -p1 -b .redhat -%patch1 -p1 -b .goodname -%patch3 -p1 -b .default-range -%patch4 -p1 -b .manfix -%patch5 -p1 -b .date-parsing -%patch6 -p1 -b .move-home -%patch7 -p1 -b .audit-update -%patch8 -p1 -b .unlock -%patch9 -p1 -b .selinux-perms -%patch10 -p1 -b .null-tm -%patch11 -p1 -b .long-entry -%patch12 -p1 -b .sysugid-min-limit -%patch13 -p1 -b .login-prompt -%patch14 -p1 -b .useradd-stop-last-fail-log-reset -%patch15 -p1 -b .chage-print-date-regression +%patch1 -p1 -b .default-range +%patch2 -p1 -b .manfix +%patch3 -p1 -b .date-parsing +%patch4 -p1 -b .audit-update +%patch5 -p1 -b .unlock +%patch6 -p1 -b .selinux-perms iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -295,6 +271,10 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Wed Nov 9 2022 Iker Pedrosa - 2:4.13-1 +- Rebase to version 4.13 +- SPDX license migration + * Wed Oct 5 2022 Iker Pedrosa - 2:4.12.3-3 - chage: Fix regression in print_date. Resolves: #2129336 diff --git a/sources b/sources index d1e0ebd..40bac31 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (shadow-4.12.3.tar.xz) = 0529889258f54e7634762dc154aa680d55f8c5f1654afadd1b7431cfbb890a3b1ba27c7ff4b7c45986e4ee2289946db2e420b23ed13e4e5b15800a1fb3a013bc -SHA512 (shadow-4.12.3.tar.xz.asc) = d3f294d86c0e2174c88809810a801737c01cd01f9cadbe7b1ae382b2745d86e2e30c0718fa6489c2abb65500ed94c8ac1961d05243b5a1800c966384c69281c9 +SHA512 (shadow-4.13.tar.xz) = 2949a728c3312bef13d23138d6b79caf402781b1cb179e33b5be546c1790971ec20778d0e9cd3dbe09691d928ffcbe88e60da42fab58c69a90d5ebe5e3e2ab8e +SHA512 (shadow-4.13.tar.xz.asc) = f8549c4e699c65721d53946d61b6127712572f7ad9ee13018ef3a25307002992aa727471c948d1bb22dcddf112715bed387d28f436123f30e153ae6bc0cd3648 From bb5dc8ec04d089507c26f58974b056ae1aa334ca Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Mon, 21 Nov 2022 11:55:57 +0100 Subject: [PATCH 066/134] Fix gshadow configure check (switching to glibc implementation) Related to: --- shadow-utils-configure-gshadow.patch | 20 ++++++++++++++++++++ shadow-utils.spec | 7 ++++++- 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 shadow-utils-configure-gshadow.patch diff --git a/shadow-utils-configure-gshadow.patch b/shadow-utils-configure-gshadow.patch new file mode 100644 index 0000000..a983ce0 --- /dev/null +++ b/shadow-utils-configure-gshadow.patch @@ -0,0 +1,20 @@ +The missing #include causes the configure check to fail +spuriously, resulting in HAVE_SHADOWGRP not being defined. + +Submitted upstream: + +diff --git a/configure.ac b/configure.ac +index 924254a0c8171802..6c7d9839979e037d 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -116,6 +116,10 @@ if test "$ac_cv_header_shadow_h" = "yes"; then + ac_cv_libc_shadowgrp, + AC_RUN_IFELSE([AC_LANG_SOURCE([ + #include ++ #ifdef HAVE_GSHADOW_H ++ #include ++ #endif ++ int + main() + { + struct sgrp *sg = sgetsgent("test:x::"); diff --git a/shadow-utils.spec b/shadow-utils.spec index da2d3bd..0953cbc 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.13 -Release: 1%{?dist} +Release: 2%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -31,6 +31,7 @@ Patch4: shadow-4.11.1-audit-update.patch Patch5: shadow-4.5-usermod-unlock.patch # Additional SElinux related changes - upstreamability unknown Patch6: shadow-4.12.3-selinux-perms.patch +Patch7: shadow-utils-configure-gshadow.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -98,6 +99,7 @@ Development files for shadow-utils-subid. %patch4 -p1 -b .audit-update %patch5 -p1 -b .unlock %patch6 -p1 -b .selinux-perms +%patch7 -p1 iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -271,6 +273,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Mon Nov 21 2022 Florian Weimer - 2:4.13-2 +- Fix gshadow configure check (switching to glibc implementation) + * Wed Nov 9 2022 Iker Pedrosa - 2:4.13-1 - Rebase to version 4.13 - SPDX license migration From 8779239933ce3516955e1d54368399509f66e0cc Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Wed, 23 Nov 2022 15:57:56 +0100 Subject: [PATCH 067/134] Change SUB_UID_MIN and SUB_GID_MIN to 524288 Resolves: #2144558 Signed-off-by: Iker Pedrosa --- shadow-utils.login.defs | 4 ++-- shadow-utils.spec | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/shadow-utils.login.defs b/shadow-utils.login.defs index a6c34a1..c0295b1 100644 --- a/shadow-utils.login.defs +++ b/shadow-utils.login.defs @@ -147,7 +147,7 @@ UID_MAX 60000 SYS_UID_MIN 201 SYS_UID_MAX 999 # Extra per user uids -SUB_UID_MIN 100000 +SUB_UID_MIN 524288 SUB_UID_MAX 600100000 SUB_UID_COUNT 65536 @@ -160,7 +160,7 @@ GID_MAX 60000 SYS_GID_MIN 201 SYS_GID_MAX 999 # Extra per user group ids -SUB_GID_MIN 100000 +SUB_GID_MIN 524288 SUB_GID_MAX 600100000 SUB_GID_COUNT 65536 diff --git a/shadow-utils.spec b/shadow-utils.spec index 0953cbc..85bf8a2 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.13 -Release: 2%{?dist} +Release: 3%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -273,6 +273,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Wed Nov 23 2022 Iker Pedrosa - 2:4.13-3 +- Change SUB_UID_MIN and SUB_GID_MIN to 524288. Resolves: #2144558 + * Mon Nov 21 2022 Florian Weimer - 2:4.13-2 - Fix gshadow configure check (switching to glibc implementation) From f7089c062fe967a79f962385229781d1fa0d1fc5 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Sat, 21 Jan 2023 03:07:17 +0000 Subject: [PATCH 068/134] Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- shadow-utils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index 85bf8a2..74e1c42 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.13 -Release: 3%{?dist} +Release: 4%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -273,6 +273,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Sat Jan 21 2023 Fedora Release Engineering - 2:4.13-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + * Wed Nov 23 2022 Iker Pedrosa - 2:4.13-3 - Change SUB_UID_MIN and SUB_GID_MIN to 524288. Resolves: #2144558 From c0c2ea7769d5e6faf56f62dfa08df7d799c6c341 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Thu, 2 Mar 2023 14:36:39 +0100 Subject: [PATCH 069/134] newuidmap and newgidmap: support passing pid as fd Resolves: #2174752 Signed-off-by: Iker Pedrosa --- ...3-newidmap-support-passing-pid-as-fd.patch | 441 ++++++++++++++++++ shadow-utils.spec | 14 +- 2 files changed, 453 insertions(+), 2 deletions(-) create mode 100644 shadow-4.13-newidmap-support-passing-pid-as-fd.patch diff --git a/shadow-4.13-newidmap-support-passing-pid-as-fd.patch b/shadow-4.13-newidmap-support-passing-pid-as-fd.patch new file mode 100644 index 0000000..37e0d41 --- /dev/null +++ b/shadow-4.13-newidmap-support-passing-pid-as-fd.patch @@ -0,0 +1,441 @@ +From 6974df39a708abf8bafbdfa2b7827e0f70f874cb Mon Sep 17 00:00:00 2001 +From: Serge Hallyn +Date: Mon, 6 Feb 2023 22:49:42 -0600 +Subject: [PATCH] newuidmap and newgidmap: support passing pid as fd + +Closes #635 + +newuidmap and newgidmap currently take an integner pid as +the first argument, determining the process id on which to +act. Accept also "fd:N", where N must be an open file +descriptor to the /proc/pid directory for the process to +act upon. This way, if you + +exec 10 +--- + lib/get_pid.c | 51 +++++++++++++++++++++++++++++++++++++++++++++ + lib/prototypes.h | 2 ++ + man/newgidmap.1.xml | 11 ++++++++++ + man/newuidmap.1.xml | 11 ++++++++++ + src/newgidmap.c | 41 ++++++++++++++---------------------- + src/newuidmap.c | 40 +++++++++++++---------------------- + 6 files changed, 106 insertions(+), 50 deletions(-) + +diff --git a/lib/get_pid.c b/lib/get_pid.c +index 10184bf0..ab91d158 100644 +--- a/lib/get_pid.c ++++ b/lib/get_pid.c +@@ -10,6 +10,9 @@ + + #include "prototypes.h" + #include "defines.h" ++#include ++#include ++#include + + int get_pid (const char *pidstr, pid_t *pid) + { +@@ -29,3 +32,51 @@ int get_pid (const char *pidstr, pid_t *pid) + return 1; + } + ++/* ++ * If use passed in fd:4 as an argument, then return the ++ * value '4', the fd to use. ++ */ ++int get_pidfd_from_fd(const char *pidfdstr) ++{ ++ long long int val; ++ char *endptr; ++ ++ errno = 0; ++ val = strtoll (pidfdstr, &endptr, 10); ++ if ( ('\0' == *pidfdstr) ++ || ('\0' != *endptr) ++ || (ERANGE == errno) ++ || (/*@+longintegral@*/val != (pid_t)val)/*@=longintegral@*/) { ++ return 0; ++ } ++ ++ return (int)val; ++} ++ ++int open_pidfd(const char *pidstr) ++{ ++ int proc_dir_fd; ++ int written; ++ char proc_dir_name[32]; ++ pid_t target; ++ ++ if (get_pid(pidstr, &target) == 0) ++ return -ENOENT; ++ ++ /* max string length is 6 + 10 + 1 + 1 = 18, allocate 32 bytes */ ++ written = snprintf(proc_dir_name, sizeof(proc_dir_name), "/proc/%u/", ++ target); ++ if ((written <= 0) || ((size_t)written >= sizeof(proc_dir_name))) { ++ fprintf(stderr, "snprintf of proc path failed for %u: %s\n", ++ target, strerror(errno)); ++ return -EINVAL; ++ } ++ ++ proc_dir_fd = open(proc_dir_name, O_DIRECTORY); ++ if (proc_dir_fd < 0) { ++ fprintf(stderr, _("Could not open proc directory for target %u: %s\n"), ++ target, strerror(errno)); ++ return -EINVAL; ++ } ++ return proc_dir_fd; ++} +diff --git a/lib/prototypes.h b/lib/prototypes.h +index 400d5b97..21df6f61 100644 +--- a/lib/prototypes.h ++++ b/lib/prototypes.h +@@ -160,6 +160,8 @@ extern int getlong (const char *numstr, /*@out@*/long int *result); + + /* get_pid.c */ + extern int get_pid (const char *pidstr, pid_t *pid); ++extern int get_pidfd_from_fd(const char *pidfdstr); ++extern int open_pidfd(const char *pidstr); + + /* getrange */ + extern int getrange (const char *range, +diff --git a/man/newgidmap.1.xml b/man/newgidmap.1.xml +index e4ebc69e..9b7683eb 100644 +--- a/man/newgidmap.1.xml ++++ b/man/newgidmap.1.xml +@@ -116,6 +116,17 @@ + + Note that newgidmap may be used only once for a given process. + ++ ++ Instead of an integer process id, the first argument may be ++ specified as fd:N, where the integer N ++ is the file descriptor number for the calling process's opened ++ file for /proc/[pid[. In this case, ++ newgidmap will use ++ openat2 ++ to open the gid_map file under that ++ directory, avoiding a TOCTTOU in case the process exits and ++ the pid is immediately reused. ++ + + + +diff --git a/man/newuidmap.1.xml b/man/newuidmap.1.xml +index f5cb5b48..ca917a77 100644 +--- a/man/newuidmap.1.xml ++++ b/man/newuidmap.1.xml +@@ -116,6 +116,17 @@ + + Note that newuidmap may be used only once for a given process. + ++ ++ Instead of an integer process id, the first argument may be ++ specified as fd:N, where the integer N ++ is the file descriptor number for the calling process's opened ++ file for /proc/[pid[. In this case, ++ newuidmap will use ++ openat2 ++ to open the uid_map file under that ++ directory, avoiding a TOCTTOU in case the process exits and ++ the pid is immediately reused. ++ + + + +diff --git a/src/newgidmap.c b/src/newgidmap.c +index 01d0fe90..d6d29725 100644 +--- a/src/newgidmap.c ++++ b/src/newgidmap.c +@@ -69,7 +69,7 @@ static void verify_ranges(struct passwd *pw, int ranges, + + static void usage(void) + { +- fprintf(stderr, _("usage: %s [ ] ... \n"), Prog); ++ fprintf(stderr, _("usage: %s [] [ ] ... \n"), Prog); + exit(EXIT_FAILURE); + } + +@@ -143,15 +143,12 @@ out: + */ + int main(int argc, char **argv) + { +- char proc_dir_name[32]; + char *target_str; +- pid_t target; + int proc_dir_fd; + int ranges; + struct map_range *mappings; + struct stat st; + struct passwd *pw; +- int written; + bool allow_setgroups = false; + + Prog = Basename (argv[0]); +@@ -168,25 +165,19 @@ int main(int argc, char **argv) + /* Find the process that needs its user namespace + * gid mapping set. + */ +- target_str = argv[1]; +- if (!get_pid(target_str, &target)) +- usage(); + +- /* max string length is 6 + 10 + 1 + 1 = 18, allocate 32 bytes */ +- written = snprintf(proc_dir_name, sizeof(proc_dir_name), "/proc/%u/", +- target); +- if ((written <= 0) || (written >= sizeof(proc_dir_name))) { +- fprintf(stderr, "%s: snprintf of proc path failed: %s\n", +- Prog, strerror(errno)); +- } +- +- proc_dir_fd = open(proc_dir_name, O_DIRECTORY); +- if (proc_dir_fd < 0) { +- fprintf(stderr, _("%s: Could not open proc directory for target %u\n"), +- Prog, target); +- return EXIT_FAILURE; ++ target_str = argv[1]; ++ if (strlen(target_str) > 3 && strncmp(target_str, "fd:", 3) == 0) { ++ /* the user passed in a /proc/pid fd for the process */ ++ target_str = &target_str[3]; ++ proc_dir_fd = get_pidfd_from_fd(target_str); ++ if (proc_dir_fd < 0) ++ usage(); ++ } else { ++ proc_dir_fd = open_pidfd(target_str); ++ if (proc_dir_fd < 0) ++ usage(); + } +- + /* Who am i? */ + pw = get_my_pwent (); + if (NULL == pw) { +@@ -200,8 +191,8 @@ int main(int argc, char **argv) + + /* Get the effective uid and effective gid of the target process */ + if (fstat(proc_dir_fd, &st) < 0) { +- fprintf(stderr, _("%s: Could not stat directory for target %u\n"), +- Prog, target); ++ fprintf(stderr, _("%s: Could not stat directory for process\n"), ++ Prog); + return EXIT_FAILURE; + } + +@@ -213,8 +204,8 @@ int main(int argc, char **argv) + (!getdef_bool("GRANT_AUX_GROUP_SUBIDS") && (getgid() != pw->pw_gid)) || + (pw->pw_uid != st.st_uid) || + (getgid() != st.st_gid)) { +- fprintf(stderr, _( "%s: Target %u is owned by a different user: uid:%lu pw_uid:%lu st_uid:%lu, gid:%lu pw_gid:%lu st_gid:%lu\n" ), +- Prog, target, ++ fprintf(stderr, _( "%s: Target process is owned by a different user: uid:%lu pw_uid:%lu st_uid:%lu, gid:%lu pw_gid:%lu st_gid:%lu\n" ), ++ Prog, + (unsigned long int)getuid(), (unsigned long int)pw->pw_uid, (unsigned long int)st.st_uid, + (unsigned long int)getgid(), (unsigned long int)pw->pw_gid, (unsigned long int)st.st_gid); + return EXIT_FAILURE; +diff --git a/src/newuidmap.c b/src/newuidmap.c +index e8798409..e99655c9 100644 +--- a/src/newuidmap.c ++++ b/src/newuidmap.c +@@ -64,7 +64,7 @@ static void verify_ranges(struct passwd *pw, int ranges, + + static void usage(void) + { +- fprintf(stderr, _("usage: %s [ ] ... \n"), Prog); ++ fprintf(stderr, _("usage: %s [|fd:] [ ] ... \n"), Prog); + exit(EXIT_FAILURE); + } + +@@ -73,15 +73,12 @@ static void usage(void) + */ + int main(int argc, char **argv) + { +- char proc_dir_name[32]; + char *target_str; +- pid_t target; + int proc_dir_fd; + int ranges; + struct map_range *mappings; + struct stat st; + struct passwd *pw; +- int written; + + Prog = Basename (argv[0]); + log_set_progname(Prog); +@@ -94,26 +91,20 @@ int main(int argc, char **argv) + if (argc < 2) + usage(); + ++ target_str = argv[1]; + /* Find the process that needs its user namespace + * uid mapping set. + */ +- target_str = argv[1]; +- if (!get_pid(target_str, &target)) +- usage(); +- +- /* max string length is 6 + 10 + 1 + 1 = 18, allocate 32 bytes */ +- written = snprintf(proc_dir_name, sizeof(proc_dir_name), "/proc/%u/", +- target); +- if ((written <= 0) || (written >= sizeof(proc_dir_name))) { +- fprintf(stderr, "%s: snprintf of proc path failed: %s\n", +- Prog, strerror(errno)); +- } +- +- proc_dir_fd = open(proc_dir_name, O_DIRECTORY); +- if (proc_dir_fd < 0) { +- fprintf(stderr, _("%s: Could not open proc directory for target %u\n"), +- Prog, target); +- return EXIT_FAILURE; ++ if (strlen(target_str) > 3 && strncmp(target_str, "fd:", 3) == 0) { ++ /* the user passed in a /proc/pid fd for the process */ ++ target_str = &target_str[3]; ++ proc_dir_fd = get_pidfd_from_fd(target_str); ++ if (proc_dir_fd < 0) ++ usage(); ++ } else { ++ proc_dir_fd = open_pidfd(target_str); ++ if (proc_dir_fd < 0) ++ usage(); + } + + /* Who am i? */ +@@ -129,8 +120,7 @@ int main(int argc, char **argv) + + /* Get the effective uid and effective gid of the target process */ + if (fstat(proc_dir_fd, &st) < 0) { +- fprintf(stderr, _("%s: Could not stat directory for target %u\n"), +- Prog, target); ++ fprintf(stderr, _("%s: Could not stat directory for target process\n"), Prog); + return EXIT_FAILURE; + } + +@@ -142,8 +132,8 @@ int main(int argc, char **argv) + (!getdef_bool("GRANT_AUX_GROUP_SUBIDS") && (getgid() != pw->pw_gid)) || + (pw->pw_uid != st.st_uid) || + (getgid() != st.st_gid)) { +- fprintf(stderr, _( "%s: Target process %u is owned by a different user: uid:%lu pw_uid:%lu st_uid:%lu, gid:%lu pw_gid:%lu st_gid:%lu\n" ), +- Prog, target, ++ fprintf(stderr, _( "%s: Target process is owned by a different user: uid:%lu pw_uid:%lu st_uid:%lu, gid:%lu pw_gid:%lu st_gid:%lu\n" ), ++ Prog, + (unsigned long int)getuid(), (unsigned long int)pw->pw_uid, (unsigned long int)st.st_uid, + (unsigned long int)getgid(), (unsigned long int)pw->pw_gid, (unsigned long int)st.st_gid); + return EXIT_FAILURE; +-- +2.39.2 + +From 7ff33fae6f9cd79c0e012671c37a172e9a681d0b Mon Sep 17 00:00:00 2001 +From: Serge Hallyn +Date: Fri, 24 Feb 2023 13:52:32 -0600 +Subject: [PATCH] get_pidfd_from_fd: return -1 on error, not 0 + +Fixes: 6974df39a: newuidmap and newgidmap: support passing pid as fd +Signed-off-by: Serge Hallyn +--- + lib/get_pid.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/lib/get_pid.c b/lib/get_pid.c +index ab91d158..5b6d9da4 100644 +--- a/lib/get_pid.c ++++ b/lib/get_pid.c +@@ -35,6 +35,7 @@ int get_pid (const char *pidstr, pid_t *pid) + /* + * If use passed in fd:4 as an argument, then return the + * value '4', the fd to use. ++ * On error, return -1. + */ + int get_pidfd_from_fd(const char *pidfdstr) + { +@@ -47,7 +48,7 @@ int get_pidfd_from_fd(const char *pidfdstr) + || ('\0' != *endptr) + || (ERANGE == errno) + || (/*@+longintegral@*/val != (pid_t)val)/*@=longintegral@*/) { +- return 0; ++ return -1; + } + + return (int)val; +-- +2.39.2 + +From 05e2adf509ba0e3779dae66a276b86927a8e1e0e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Vin=C3=ADcius=20dos=20Santos=20Oliveira?= + +Date: Fri, 24 Feb 2023 18:06:02 -0300 +Subject: [PATCH] Validate fds created by the user + +write_mapping() will do the following: + +openat(proc_dir_fd, map_file, O_WRONLY); + +An attacker could create a directory containing a symlink named +"uid_map" pointing to any file owned by root, and thus allow him to +overwrite any root-owned file. +--- + lib/get_pid.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/lib/get_pid.c b/lib/get_pid.c +index 5b6d9da4..8e5e6014 100644 +--- a/lib/get_pid.c ++++ b/lib/get_pid.c +@@ -41,6 +41,8 @@ int get_pidfd_from_fd(const char *pidfdstr) + { + long long int val; + char *endptr; ++ struct stat st; ++ dev_t proc_st_dev, proc_st_rdev; + + errno = 0; + val = strtoll (pidfdstr, &endptr, 10); +@@ -51,6 +53,21 @@ int get_pidfd_from_fd(const char *pidfdstr) + return -1; + } + ++ if (stat("/proc/self/uid_map", &st) < 0) { ++ return -1; ++ } ++ ++ proc_st_dev = st.st_dev; ++ proc_st_rdev = st.st_rdev; ++ ++ if (fstat(val, &st) < 0) { ++ return -1; ++ } ++ ++ if (st.st_dev != proc_st_dev || st.st_rdev != proc_st_rdev) { ++ return -1; ++ } ++ + return (int)val; + } + +-- +2.39.2 + diff --git a/shadow-utils.spec b/shadow-utils.spec index 74e1c42..0ec578b 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.13 -Release: 4%{?dist} +Release: 5%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -25,13 +25,19 @@ Patch1: shadow-4.13-default-range.patch Patch2: shadow-4.9-manfix.patch # Date parsing improvement - could be upstreamed Patch3: shadow-4.2.1-date-parsing.patch -# Audit message changes - upstreamability unknown +# Audit message changes - partially upstreamed +# https://github.com/shadow-maint/shadow/commit/37412f505ed0bc5c9e3f04b2266b40f8f6fc310f Patch4: shadow-4.11.1-audit-update.patch # Changes related to password unlocking - could be upstreamed Patch5: shadow-4.5-usermod-unlock.patch # Additional SElinux related changes - upstreamability unknown Patch6: shadow-4.12.3-selinux-perms.patch +# https://github.com/shadow-maint/shadow/commit/a281f241b592aec636d1b93a99e764499d68c7ef Patch7: shadow-utils-configure-gshadow.patch +# https://github.com/shadow-maint/shadow/commit/6974df39a708abf8bafbdfa2b7827e0f70f874cb +# https://github.com/shadow-maint/shadow/commit/7ff33fae6f9cd79c0e012671c37a172e9a681d0b +# https://github.com/shadow-maint/shadow/commit/05e2adf509ba0e3779dae66a276b86927a8e1e0e +Patch8: shadow-4.13-newidmap-support-passing-pid-as-fd.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -100,6 +106,7 @@ Development files for shadow-utils-subid. %patch5 -p1 -b .unlock %patch6 -p1 -b .selinux-perms %patch7 -p1 +%patch8 -p1 -b .newidmap-pid-fd iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -273,6 +280,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Thu Mar 2 2023 Iker Pedrosa - 2:4.13-5 +- newuidmap and newgidmap: support passing pid as fd. Resolves: #2174752 + * Sat Jan 21 2023 Fedora Release Engineering - 2:4.13-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild From fd05b1cb1a183db7af622b34c9cf7c3994808475 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Mon, 6 Mar 2023 12:05:17 +0100 Subject: [PATCH 070/134] Add build dependencies Add libbsd-devel and libeconf-devel as build dependencies Signed-off-by: Iker Pedrosa --- shadow-utils.spec | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index 0ec578b..438e9ca 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.13 -Release: 5%{?dist} +Release: 6%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -57,6 +57,8 @@ BuildRequires: gettext-devel BuildRequires: itstool BuildRequires: libacl-devel BuildRequires: libattr-devel +BuildRequires: libbsd-devel +BuildRequires: libeconf-devel BuildRequires: libselinux-devel >= 1.25.2-1 BuildRequires: libsemanage-devel BuildRequires: libtool @@ -280,6 +282,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Mon Mar 6 2023 Iker Pedrosa - 2:4.13-6 +- Add libbsd-devel and libeconf-devel as build dependencies + * Thu Mar 2 2023 Iker Pedrosa - 2:4.13-5 - newuidmap and newgidmap: support passing pid as fd. Resolves: #2174752 From 14b1f3518c8e3837f868b719c1f7d3ebb6db62e6 Mon Sep 17 00:00:00 2001 From: Yaakov Selkowitz Date: Tue, 6 Jun 2023 19:30:55 -0400 Subject: [PATCH 071/134] Remove unused libbsd-devel dependency libbsd is unwanted in RHEL, but the resulting binaries show no dependency on libbsd anyway. --- shadow-utils.spec | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index 438e9ca..d164957 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.13 -Release: 6%{?dist} +Release: 7%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -57,7 +57,6 @@ BuildRequires: gettext-devel BuildRequires: itstool BuildRequires: libacl-devel BuildRequires: libattr-devel -BuildRequires: libbsd-devel BuildRequires: libeconf-devel BuildRequires: libselinux-devel >= 1.25.2-1 BuildRequires: libsemanage-devel @@ -282,6 +281,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Tue Jun 06 2023 Yaakov Selkowitz - 2:4.13-7 +- Remove unused libbsd-devel dependency + * Mon Mar 6 2023 Iker Pedrosa - 2:4.13-6 - Add libbsd-devel and libeconf-devel as build dependencies From 874ece902889ef407a933f712ef550f31b822135 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Sat, 22 Jul 2023 01:31:45 +0000 Subject: [PATCH 072/134] Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- shadow-utils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index d164957..419b8d0 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.13 -Release: 7%{?dist} +Release: 8%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -281,6 +281,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Sat Jul 22 2023 Fedora Release Engineering - 2:4.13-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + * Tue Jun 06 2023 Yaakov Selkowitz - 2:4.13-7 - Remove unused libbsd-devel dependency From 5cab3439c8ffe4e07ec09aa9acf5112348e80a0c Mon Sep 17 00:00:00 2001 From: Petr Lautrbach Date: Wed, 2 Aug 2023 16:33:21 +0200 Subject: [PATCH 073/134] Use %autosetup instead of obsoleted %patchX macros Also use -S git instead of suffixes, see https://rpm-software-management.github.io/rpm/manual/autosetup.html Fixes: RPM build warnings: %patchN is deprecated (9 usages found), use %patch N (or %patch -P N) Signed-off-by: Petr Lautrbach --- shadow-utils.spec | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index 419b8d0..8ee19af 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -54,6 +54,7 @@ BuildRequires: docbook-style-xsl BuildRequires: flex BuildRequires: gcc BuildRequires: gettext-devel +BuildRequires: git BuildRequires: itstool BuildRequires: libacl-devel BuildRequires: libattr-devel @@ -98,16 +99,7 @@ Requires: shadow-utils-subid = %{epoch}:%{version}-%{release} Development files for shadow-utils-subid. %prep -%setup -q -n shadow-%{version} -%patch0 -p1 -b .redhat -%patch1 -p1 -b .default-range -%patch2 -p1 -b .manfix -%patch3 -p1 -b .date-parsing -%patch4 -p1 -b .audit-update -%patch5 -p1 -b .unlock -%patch6 -p1 -b .selinux-perms -%patch7 -p1 -%patch8 -p1 -b .newidmap-pid-fd +%autosetup -p 1 -S git -n shadow-%{version} iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO From 799aaaa5088cde64c65f2897d9c335c52e4de0bc Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Wed, 16 Aug 2023 10:55:53 +0200 Subject: [PATCH 074/134] Rebase to version 4.14.0 Resolves: #2229000 Signed-off-by: Iker Pedrosa --- .gitignore | 2 + shadow-4.12.3-redhat.patch | 38 - shadow-4.12.3-selinux-perms.patch | 240 ----- shadow-4.13-default-range.patch | 35 - ....patch => shadow-4.14.0-audit-update.patch | 970 +++++++----------- ...manfix.patch => shadow-4.14.0-manfix.patch | 2 +- shadow-4.5-usermod-unlock.patch | 64 -- shadow-utils.spec | 33 +- sources | 4 +- 9 files changed, 381 insertions(+), 1007 deletions(-) delete mode 100644 shadow-4.12.3-redhat.patch delete mode 100644 shadow-4.12.3-selinux-perms.patch delete mode 100644 shadow-4.13-default-range.patch rename shadow-4.11.1-audit-update.patch => shadow-4.14.0-audit-update.patch (66%) rename shadow-4.9-manfix.patch => shadow-4.14.0-manfix.patch (99%) delete mode 100644 shadow-4.5-usermod-unlock.patch diff --git a/.gitignore b/.gitignore index 44cb6ed..422ed12 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,5 @@ shadow-4.1.4.2.tar.bz2 /shadow-4.12.3.tar.xz.asc /shadow-4.13.tar.xz /shadow-4.13.tar.xz.asc +/shadow-4.14.0.tar.xz +/shadow-4.14.0.tar.xz.asc diff --git a/shadow-4.12.3-redhat.patch b/shadow-4.12.3-redhat.patch deleted file mode 100644 index 48c591d..0000000 --- a/shadow-4.12.3-redhat.patch +++ /dev/null @@ -1,38 +0,0 @@ -diff -up shadow-4.12.3/src/useradd.c.redhat shadow-4.12.3/src/useradd.c ---- shadow-4.12.3/src/useradd.c.redhat 2022-08-06 18:22:45.000000000 +0200 -+++ shadow-4.12.3/src/useradd.c 2022-08-22 15:57:19.034664441 +0200 -@@ -82,7 +82,7 @@ const char *Prog; - static gid_t def_group = 1000; - static const char *def_gname = "other"; - static const char *def_home = "/home"; --static const char *def_shell = "/bin/bash"; -+static const char *def_shell = "/sbin/nologin"; - static const char *def_template = SKEL_DIR; - static const char *def_create_mail_spool = "yes"; - static const char *def_log_init = "yes"; -@@ -93,7 +93,7 @@ static const char *def_expire = ""; - #define VALID(s) (strcspn (s, ":\n") == strlen (s)) - - static const char *user_name = ""; --static const char *user_pass = "!"; -+static const char *user_pass = "!!"; - static uid_t user_id; - static gid_t user_gid; - static const char *user_comment = ""; -@@ -1227,7 +1227,7 @@ static void process_flags (int argc, cha - {NULL, 0, NULL, '\0'} - }; - while ((c = getopt_long (argc, argv, -- "b:c:d:De:f:g:G:hk:K:lmMNop:rR:P:s:u:U" -+ "b:c:d:De:f:g:G:hk:K:lmMnNop:rR:P:s:u:U" - #ifdef WITH_SELINUX - "Z:" - #endif /* WITH_SELINUX */ -@@ -1395,6 +1395,7 @@ static void process_flags (int argc, cha - case 'M': - Mflg = true; - break; -+ case 'n': - case 'N': - Nflg = true; - break; diff --git a/shadow-4.12.3-selinux-perms.patch b/shadow-4.12.3-selinux-perms.patch deleted file mode 100644 index f396455..0000000 --- a/shadow-4.12.3-selinux-perms.patch +++ /dev/null @@ -1,240 +0,0 @@ -diff -up shadow-4.12.3/src/chgpasswd.c.selinux-perms shadow-4.12.3/src/chgpasswd.c ---- shadow-4.12.3/src/chgpasswd.c.selinux-perms 2022-06-19 16:16:48.000000000 +0200 -+++ shadow-4.12.3/src/chgpasswd.c 2022-08-22 16:09:02.006970030 +0200 -@@ -16,6 +16,13 @@ - #include - #include - #include -+#ifdef WITH_SELINUX -+#include -+#include -+#endif -+#ifdef WITH_LIBAUDIT -+#include -+#endif - #ifdef ACCT_TOOLS_SETUID - #ifdef USE_PAM - #include "pam_defs.h" -@@ -61,6 +68,9 @@ static bool sgr_locked = false; - #endif - static bool gr_locked = false; - -+/* The name of the caller */ -+static char *myname = NULL; -+ - /* local function prototypes */ - static void fail_exit (int code); - static /*@noreturn@*/void usage (int status); -@@ -318,6 +328,63 @@ static void check_perms (void) - #endif /* ACCT_TOOLS_SETUID */ - } - -+#ifdef WITH_SELINUX -+static int -+log_callback (int type, const char *fmt, ...) -+{ -+ int audit_fd; -+ va_list ap; -+ -+ va_start(ap, fmt); -+#ifdef WITH_AUDIT -+ audit_fd = audit_open(); -+ -+ if (audit_fd >= 0) { -+ char *buf; -+ -+ if (vasprintf (&buf, fmt, ap) < 0) -+ goto ret; -+ audit_log_user_avc_message(audit_fd, AUDIT_USER_AVC, buf, NULL, NULL, -+ NULL, 0); -+ audit_close(audit_fd); -+ free(buf); -+ goto ret; -+ } -+ -+#endif -+ vsyslog (LOG_USER | LOG_INFO, fmt, ap); -+ret: -+ va_end(ap); -+ return 0; -+} -+ -+static void -+selinux_check_root (void) -+{ -+ int status = -1; -+ security_context_t user_context; -+ union selinux_callback old_callback; -+ -+ if (is_selinux_enabled() < 1) -+ return; -+ -+ old_callback = selinux_get_callback(SELINUX_CB_LOG); -+ /* setup callbacks */ -+ selinux_set_callback(SELINUX_CB_LOG, (union selinux_callback) &log_callback); -+ if ((status = getprevcon(&user_context)) < 0) { -+ selinux_set_callback(SELINUX_CB_LOG, old_callback); -+ exit(1); -+ } -+ -+ status = selinux_check_access(user_context, user_context, "passwd", "passwd", NULL); -+ -+ selinux_set_callback(SELINUX_CB_LOG, old_callback); -+ freecon(user_context); -+ if (status != 0 && security_getenforce() != 0) -+ exit(1); -+} -+#endif -+ - /* - * open_files - lock and open the group databases - */ -@@ -411,6 +478,7 @@ int main (int argc, char **argv) - - const struct group *gr; - struct group newgr; -+ struct passwd *pw = NULL; - int errors = 0; - int line = 0; - -@@ -422,12 +490,37 @@ int main (int argc, char **argv) - (void) bindtextdomain (PACKAGE, LOCALEDIR); - (void) textdomain (PACKAGE); - -+#ifdef WITH_SELINUX -+ selinux_check_root (); -+#endif -+ - process_root_flag ("-R", argc, argv); - - process_flags (argc, argv); - - OPENLOG ("chgpasswd"); - -+#ifdef WITH_AUDIT -+ audit_help_open (); -+#endif -+ -+ /* -+ * Determine the name of the user that invoked this command. This -+ * is really hit or miss because there are so many ways that command -+ * can be executed and so many ways to trip up the routines that -+ * report the user name. -+ */ -+ pw = get_my_pwent (); -+ if (NULL == pw) { -+ fprintf (stderr, _("%s: Cannot determine your user name.\n"), -+ Prog); -+ SYSLOG ((LOG_WARN, -+ "Cannot determine the user name of the caller (UID %lu)", -+ (unsigned long) getuid ())); -+ exit (E_NOPERM); -+ } -+ myname = xstrdup (pw->pw_name); -+ - check_perms (); - - #ifdef SHADOWGRP -diff -up shadow-4.12.3/src/chpasswd.c.selinux-perms shadow-4.12.3/src/chpasswd.c ---- shadow-4.12.3/src/chpasswd.c.selinux-perms 2022-06-19 16:16:48.000000000 +0200 -+++ shadow-4.12.3/src/chpasswd.c 2022-08-22 16:10:56.702835681 +0200 -@@ -16,6 +16,13 @@ - #include - #include - #include -+#ifdef WITH_SELINUX -+#include -+#include -+#endif -+#ifdef WITH_LIBAUDIT -+#include -+#endif - #ifdef USE_PAM - #include "pam_defs.h" - #endif /* USE_PAM */ -@@ -318,6 +325,63 @@ static void check_perms (void) - #endif /* USE_PAM */ - } - -+#ifdef WITH_SELINUX -+static int -+log_callback (int type, const char *fmt, ...) -+{ -+ int audit_fd; -+ va_list ap; -+ -+ va_start(ap, fmt); -+#ifdef WITH_AUDIT -+ audit_fd = audit_open(); -+ -+ if (audit_fd >= 0) { -+ char *buf; -+ -+ if (vasprintf (&buf, fmt, ap) < 0) -+ goto ret; -+ audit_log_user_avc_message(audit_fd, AUDIT_USER_AVC, buf, NULL, NULL, -+ NULL, 0); -+ audit_close(audit_fd); -+ free(buf); -+ goto ret; -+ } -+ -+#endif -+ vsyslog (LOG_USER | LOG_INFO, fmt, ap); -+ret: -+ va_end(ap); -+ return 0; -+} -+ -+static void -+selinux_check_root (void) -+{ -+ int status = -1; -+ security_context_t user_context; -+ union selinux_callback old_callback; -+ -+ if (is_selinux_enabled() < 1) -+ return; -+ -+ old_callback = selinux_get_callback(SELINUX_CB_LOG); -+ /* setup callbacks */ -+ selinux_set_callback(SELINUX_CB_LOG, (union selinux_callback) &log_callback); -+ if ((status = getprevcon(&user_context)) < 0) { -+ selinux_set_callback(SELINUX_CB_LOG, old_callback); -+ exit(1); -+ } -+ -+ status = selinux_check_access(user_context, user_context, "passwd", "passwd", NULL); -+ -+ selinux_set_callback(SELINUX_CB_LOG, old_callback); -+ freecon(user_context); -+ if (status != 0 && security_getenforce() != 0) -+ exit(1); -+} -+#endif -+ - /* - * open_files - lock and open the password databases - */ -@@ -450,6 +514,10 @@ int main (int argc, char **argv) - (void) bindtextdomain (PACKAGE, LOCALEDIR); - (void) textdomain (PACKAGE); - -+#ifdef WITH_SELINUX -+ selinux_check_root (); -+#endif -+ - process_flags (argc, argv); - - salt = get_salt(); -@@ -463,6 +531,10 @@ int main (int argc, char **argv) - - OPENLOG ("chpasswd"); - -+#ifdef WITH_AUDIT -+ audit_help_open (); -+#endif -+ - check_perms (); - - #ifdef USE_PAM diff --git a/shadow-4.13-default-range.patch b/shadow-4.13-default-range.patch deleted file mode 100644 index f199b39..0000000 --- a/shadow-4.13-default-range.patch +++ /dev/null @@ -1,35 +0,0 @@ -diff -up shadow-4.13/lib/semanage.c.default-range shadow-4.13/lib/semanage.c ---- shadow-4.13/lib/semanage.c.default-range 2022-11-09 09:37:11.955314964 +0100 -+++ shadow-4.13/lib/semanage.c 2022-11-09 09:47:59.130645564 +0100 -@@ -122,6 +122,7 @@ static int semanage_user_mod (semanage_h - goto done; - } - -+#if 0 - if (semanage_mls_enabled(handle)) { - ret = semanage_seuser_set_mlsrange (handle, seuser, DEFAULT_SERANGE); - if (ret != 0) { -@@ -131,6 +132,7 @@ static int semanage_user_mod (semanage_h - goto done; - } - } -+#endif - - ret = semanage_seuser_set_sename (handle, seuser, seuser_name); - if (ret != 0) { -@@ -181,6 +183,7 @@ static int semanage_user_add (semanage_h - goto done; - } - -+#if 0 - if (semanage_mls_enabled(handle)) { - ret = semanage_seuser_set_mlsrange (handle, seuser, DEFAULT_SERANGE); - if (ret != 0) { -@@ -190,6 +193,7 @@ static int semanage_user_add (semanage_h - goto done; - } - } -+#endif - - ret = semanage_seuser_set_sename (handle, seuser, seuser_name); - if (ret != 0) { diff --git a/shadow-4.11.1-audit-update.patch b/shadow-4.14.0-audit-update.patch similarity index 66% rename from shadow-4.11.1-audit-update.patch rename to shadow-4.14.0-audit-update.patch index 65acae0..0ff7dae 100644 --- a/shadow-4.11.1-audit-update.patch +++ b/shadow-4.14.0-audit-update.patch @@ -1,6 +1,6 @@ -diff -up shadow-4.11.1/libmisc/audit_help.c.audit-update shadow-4.11.1/libmisc/audit_help.c ---- shadow-4.11.1/libmisc/audit_help.c.audit-update 2022-01-03 01:46:53.000000000 +0100 -+++ shadow-4.11.1/libmisc/audit_help.c 2022-01-03 15:15:38.946046192 +0100 +diff -up shadow-4.14.0/libmisc/audit_help.c.audit-update shadow-4.14.0/libmisc/audit_help.c +--- shadow-4.14.0/libmisc/audit_help.c.audit-update 2023-05-26 04:56:11.000000000 +0200 ++++ shadow-4.14.0/libmisc/audit_help.c 2023-08-04 09:30:25.206963536 +0200 @@ -46,7 +46,7 @@ void audit_help_open (void) * This function will log a message to the audit system using a predefined * message format. Parameter usage is as follows: @@ -50,9 +50,9 @@ diff -up shadow-4.11.1/libmisc/audit_help.c.audit-update shadow-4.11.1/libmisc/a void audit_logger_message (const char *message, shadow_audit_result result) { if (audit_fd < 0) { -diff -up shadow-4.11.1/libmisc/cleanup_group.c.audit-update shadow-4.11.1/libmisc/cleanup_group.c ---- shadow-4.11.1/libmisc/cleanup_group.c.audit-update 2022-01-03 14:57:01.777006776 +0100 -+++ shadow-4.11.1/libmisc/cleanup_group.c 2022-01-03 15:22:27.438770608 +0100 +diff -up shadow-4.14.0/libmisc/cleanup_group.c.audit-update shadow-4.14.0/libmisc/cleanup_group.c +--- shadow-4.14.0/libmisc/cleanup_group.c.audit-update 2023-05-26 04:56:11.000000000 +0200 ++++ shadow-4.14.0/libmisc/cleanup_group.c 2023-08-04 09:30:25.207963539 +0200 @@ -61,7 +61,7 @@ void cleanup_report_mod_group (void *cle gr_dbname (), info->action)); @@ -131,9 +131,9 @@ diff -up shadow-4.11.1/libmisc/cleanup_group.c.audit-update shadow-4.11.1/libmis SHADOW_AUDIT_FAILURE); #endif } -diff -up shadow-4.11.1/libmisc/cleanup_user.c.audit-update shadow-4.11.1/libmisc/cleanup_user.c ---- shadow-4.11.1/libmisc/cleanup_user.c.audit-update 2022-01-03 14:57:01.777006776 +0100 -+++ shadow-4.11.1/libmisc/cleanup_user.c 2022-01-03 15:21:22.593338130 +0100 +diff -up shadow-4.14.0/libmisc/cleanup_user.c.audit-update shadow-4.14.0/libmisc/cleanup_user.c +--- shadow-4.14.0/libmisc/cleanup_user.c.audit-update 2023-05-26 04:56:11.000000000 +0200 ++++ shadow-4.14.0/libmisc/cleanup_user.c 2023-08-04 09:30:25.207963539 +0200 @@ -43,7 +43,7 @@ void cleanup_report_mod_passwd (void *cl pw_dbname (), info->action)); @@ -181,10 +181,10 @@ diff -up shadow-4.11.1/libmisc/cleanup_user.c.audit-update shadow-4.11.1/libmisc SHADOW_AUDIT_FAILURE); #endif } -diff -up shadow-4.11.1/lib/prototypes.h.audit-update shadow-4.11.1/lib/prototypes.h ---- shadow-4.11.1/lib/prototypes.h.audit-update 2022-01-03 01:46:53.000000000 +0100 -+++ shadow-4.11.1/lib/prototypes.h 2022-01-03 14:57:01.777006776 +0100 -@@ -197,12 +197,21 @@ extern int audit_fd; +diff -up shadow-4.14.0/lib/prototypes.h.audit-update shadow-4.14.0/lib/prototypes.h +--- shadow-4.14.0/lib/prototypes.h.audit-update 2023-08-03 18:28:35.000000000 +0200 ++++ shadow-4.14.0/lib/prototypes.h 2023-08-04 09:30:25.207963539 +0200 +@@ -202,12 +202,21 @@ extern int audit_fd; extern void audit_help_open (void); /* Use AUDIT_NO_ID when a name is provided to audit_logger instead of an ID */ #define AUDIT_NO_ID ((unsigned int) -1) @@ -206,100 +206,91 @@ diff -up shadow-4.11.1/lib/prototypes.h.audit-update shadow-4.11.1/lib/prototype void audit_logger_message (const char *message, shadow_audit_result result); #endif -diff -up shadow-4.11.1/src/chage.c.audit-update shadow-4.11.1/src/chage.c ---- shadow-4.11.1/src/chage.c.audit-update 2022-01-03 01:46:53.000000000 +0100 -+++ shadow-4.11.1/src/chage.c 2022-01-03 14:57:01.777006776 +0100 -@@ -100,9 +100,10 @@ static /*@noreturn@*/void fail_exit (int +diff -up shadow-4.14.0/src/chage.c.audit-update shadow-4.14.0/src/chage.c +--- shadow-4.14.0/src/chage.c.audit-update 2023-08-04 09:30:25.207963539 +0200 ++++ shadow-4.14.0/src/chage.c 2023-08-04 09:31:12.237080212 +0200 +@@ -106,8 +106,8 @@ fail_exit (int code) #ifdef WITH_AUDIT if (E_SUCCESS != code) { - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "change age", -- user_name, (unsigned int) user_uid, 0); +- "change age", user_name, user_uid, 0); + audit_logger (AUDIT_USER_MGMT, Prog, -+ "change-age", -+ user_name, (unsigned int) user_uid, -+ SHADOW_AUDIT_FAILURE); ++ "change-age", user_name, user_uid, SHADOW_AUDIT_FAILURE); } #endif -@@ -837,11 +838,7 @@ int main (int argc, char **argv) +@@ -841,10 +841,7 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: Permission denied.\n"), Prog); fail_exit (E_NOPERM); } -#ifdef WITH_AUDIT - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "display aging info", -- user_name, (unsigned int) user_uid, 1); +- "display aging info", user_name, user_uid, 1); -#endif + /* Displaying fields is not of interest to audit */ list_fields (); fail_exit (E_SUCCESS); } -@@ -860,41 +857,43 @@ int main (int argc, char **argv) +@@ -863,39 +860,39 @@ int main (int argc, char **argv) } #ifdef WITH_AUDIT else { - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, - "change all aging information", -- user_name, (unsigned int) user_uid, 1); +- user_name, user_uid, 1); + audit_logger (AUDIT_USER_MGMT, Prog, + "change-all-aging-information", -+ user_name, (unsigned int) user_uid, -+ SHADOW_AUDIT_SUCCESS); ++ user_name, user_uid, SHADOW_AUDIT_SUCCESS); } #endif } else { #ifdef WITH_AUDIT if (Mflg) { - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "change max age", -- user_name, (unsigned int) user_uid, 1); +- "change max age", user_name, user_uid, 1); + audit_logger (AUDIT_USER_MGMT, Prog, -+ "change-max-age", -+ user_name, (unsigned int) user_uid, -+ SHADOW_AUDIT_SUCCESS); ++ "change-max-age", user_name, user_uid, SHADOW_AUDIT_SUCCESS); } if (mflg) { - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "change min age", +- "change min age", user_name, user_uid, 1); + audit_logger (AUDIT_USER_MGMT, Prog, -+ "change-min-age", - user_name, (unsigned int) user_uid, 1); ++ "change-min-age", user_name, user_uid, 1); } if (dflg) { - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, - "change last change date", + audit_logger (AUDIT_USER_MGMT, Prog, + "change-last-change-date", - user_name, (unsigned int) user_uid, 1); + user_name, user_uid, 1); } if (Wflg) { - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, - "change passwd warning", + audit_logger (AUDIT_USER_MGMT, Prog, + "change-passwd-warning", - user_name, (unsigned int) user_uid, 1); + user_name, user_uid, 1); } if (Iflg) { - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, - "change inactive days", + audit_logger (AUDIT_USER_MGMT, Prog, + "change-inactive-days", - user_name, (unsigned int) user_uid, 1); + user_name, user_uid, 1); } if (Eflg) { - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, - "change passwd expiration", + audit_logger (AUDIT_USER_MGMT, Prog, + "change-passwd-expiration", - user_name, (unsigned int) user_uid, 1); + user_name, user_uid, 1); } #endif -diff -up shadow-4.11.1/src/gpasswd.c.audit-update shadow-4.11.1/src/gpasswd.c ---- shadow-4.11.1/src/gpasswd.c.audit-update 2022-01-03 01:46:53.000000000 +0100 -+++ shadow-4.11.1/src/gpasswd.c 2022-01-03 14:57:01.778006782 +0100 -@@ -116,7 +116,7 @@ static void usage (int status) +diff -up shadow-4.14.0/src/gpasswd.c.audit-update shadow-4.14.0/src/gpasswd.c +--- shadow-4.14.0/src/gpasswd.c.audit-update 2023-06-11 03:35:50.000000000 +0200 ++++ shadow-4.14.0/src/gpasswd.c 2023-08-04 09:30:25.207963539 +0200 +@@ -118,7 +118,7 @@ static void usage (int status) (void) fputs (_(" -d, --delete USER remove USER from GROUP\n"), usageout); (void) fputs (_(" -h, --help display this help message and exit\n"), usageout); (void) fputs (_(" -Q, --root CHROOT_DIR directory to chroot into\n"), usageout); @@ -308,7 +299,7 @@ diff -up shadow-4.11.1/src/gpasswd.c.audit-update shadow-4.11.1/src/gpasswd.c (void) fputs (_(" -R, --restrict restrict access to GROUP to its members\n"), usageout); (void) fputs (_(" -M, --members USER,... set the list of members of GROUP\n"), usageout); #ifdef SHADOWGRP -@@ -375,21 +375,14 @@ static void open_files (void) +@@ -377,21 +377,14 @@ static void open_files (void) static void log_gpasswd_failure (const char *suffix) { @@ -333,7 +324,7 @@ diff -up shadow-4.11.1/src/gpasswd.c.audit-update shadow-4.11.1/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } else if (dflg) { -@@ -397,13 +390,9 @@ static void log_gpasswd_failure (const c +@@ -399,13 +392,9 @@ static void log_gpasswd_failure (const c "%s failed to remove user %s from group %s%s", myname, user, group, suffix)); #ifdef WITH_AUDIT @@ -350,7 +341,7 @@ diff -up shadow-4.11.1/src/gpasswd.c.audit-update shadow-4.11.1/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } else if (rflg) { -@@ -411,13 +400,9 @@ static void log_gpasswd_failure (const c +@@ -413,13 +402,9 @@ static void log_gpasswd_failure (const c "%s failed to remove password of group %s%s", myname, group, suffix)); #ifdef WITH_AUDIT @@ -367,7 +358,7 @@ diff -up shadow-4.11.1/src/gpasswd.c.audit-update shadow-4.11.1/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } else if (Rflg) { -@@ -425,13 +410,9 @@ static void log_gpasswd_failure (const c +@@ -427,13 +412,9 @@ static void log_gpasswd_failure (const c "%s failed to restrict access to group %s%s", myname, group, suffix)); #ifdef WITH_AUDIT @@ -384,7 +375,7 @@ diff -up shadow-4.11.1/src/gpasswd.c.audit-update shadow-4.11.1/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } else if (Aflg || Mflg) { -@@ -441,13 +422,9 @@ static void log_gpasswd_failure (const c +@@ -443,13 +424,9 @@ static void log_gpasswd_failure (const c "%s failed to set the administrators of group %s to %s%s", myname, group, admins, suffix)); #ifdef WITH_AUDIT @@ -401,7 +392,7 @@ diff -up shadow-4.11.1/src/gpasswd.c.audit-update shadow-4.11.1/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } -@@ -457,13 +434,9 @@ static void log_gpasswd_failure (const c +@@ -459,13 +436,9 @@ static void log_gpasswd_failure (const c "%s failed to set the members of group %s to %s%s", myname, group, members, suffix)); #ifdef WITH_AUDIT @@ -418,7 +409,7 @@ diff -up shadow-4.11.1/src/gpasswd.c.audit-update shadow-4.11.1/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } -@@ -472,13 +445,9 @@ static void log_gpasswd_failure (const c +@@ -474,13 +447,9 @@ static void log_gpasswd_failure (const c "%s failed to change password of group %s%s", myname, group, suffix)); #ifdef WITH_AUDIT @@ -435,7 +426,7 @@ diff -up shadow-4.11.1/src/gpasswd.c.audit-update shadow-4.11.1/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } -@@ -509,21 +478,14 @@ static void log_gpasswd_failure_gshadow +@@ -511,21 +480,14 @@ static void log_gpasswd_failure_gshadow static void log_gpasswd_success (const char *suffix) { @@ -460,7 +451,7 @@ diff -up shadow-4.11.1/src/gpasswd.c.audit-update shadow-4.11.1/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } else if (dflg) { -@@ -531,13 +493,9 @@ static void log_gpasswd_success (const c +@@ -533,13 +495,9 @@ static void log_gpasswd_success (const c "user %s removed by %s from group %s%s", user, myname, group, suffix)); #ifdef WITH_AUDIT @@ -477,7 +468,7 @@ diff -up shadow-4.11.1/src/gpasswd.c.audit-update shadow-4.11.1/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } else if (rflg) { -@@ -545,13 +503,9 @@ static void log_gpasswd_success (const c +@@ -547,13 +505,9 @@ static void log_gpasswd_success (const c "password of group %s removed by %s%s", group, myname, suffix)); #ifdef WITH_AUDIT @@ -494,7 +485,7 @@ diff -up shadow-4.11.1/src/gpasswd.c.audit-update shadow-4.11.1/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } else if (Rflg) { -@@ -559,13 +513,9 @@ static void log_gpasswd_success (const c +@@ -561,13 +515,9 @@ static void log_gpasswd_success (const c "access to group %s restricted by %s%s", group, myname, suffix)); #ifdef WITH_AUDIT @@ -511,7 +502,7 @@ diff -up shadow-4.11.1/src/gpasswd.c.audit-update shadow-4.11.1/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } else if (Aflg || Mflg) { -@@ -575,13 +525,9 @@ static void log_gpasswd_success (const c +@@ -577,13 +527,9 @@ static void log_gpasswd_success (const c "administrators of group %s set by %s to %s%s", group, myname, admins, suffix)); #ifdef WITH_AUDIT @@ -528,7 +519,7 @@ diff -up shadow-4.11.1/src/gpasswd.c.audit-update shadow-4.11.1/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } -@@ -591,13 +537,9 @@ static void log_gpasswd_success (const c +@@ -593,13 +539,9 @@ static void log_gpasswd_success (const c "members of group %s set by %s to %s%s", group, myname, members, suffix)); #ifdef WITH_AUDIT @@ -545,7 +536,7 @@ diff -up shadow-4.11.1/src/gpasswd.c.audit-update shadow-4.11.1/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } -@@ -606,13 +548,9 @@ static void log_gpasswd_success (const c +@@ -608,13 +550,9 @@ static void log_gpasswd_success (const c "password of group %s changed by %s%s", group, myname, suffix)); #ifdef WITH_AUDIT @@ -562,10 +553,10 @@ diff -up shadow-4.11.1/src/gpasswd.c.audit-update shadow-4.11.1/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } -diff -up shadow-4.11.1/src/groupadd.c.audit-update shadow-4.11.1/src/groupadd.c ---- shadow-4.11.1/src/groupadd.c.audit-update 2022-01-03 01:46:53.000000000 +0100 -+++ shadow-4.11.1/src/groupadd.c 2022-01-03 14:57:01.778006782 +0100 -@@ -111,6 +111,15 @@ static /*@noreturn@*/void usage (int sta +diff -up shadow-4.14.0/src/groupadd.c.audit-update shadow-4.14.0/src/groupadd.c +--- shadow-4.14.0/src/groupadd.c.audit-update 2023-05-26 04:56:11.000000000 +0200 ++++ shadow-4.14.0/src/groupadd.c 2023-08-04 09:34:34.125581046 +0200 +@@ -114,6 +114,15 @@ usage (int status) exit (status); } @@ -581,7 +572,7 @@ diff -up shadow-4.11.1/src/groupadd.c.audit-update shadow-4.11.1/src/groupadd.c /* * new_grent - initialize the values in a group file entry * -@@ -207,7 +216,7 @@ static void grp_update (void) +@@ -210,7 +219,7 @@ static void grp_update (void) fprintf (stderr, _("%s: failed to prepare the new %s entry '%s'\n"), Prog, gr_dbname (), grp.gr_name); @@ -590,7 +581,7 @@ diff -up shadow-4.11.1/src/groupadd.c.audit-update shadow-4.11.1/src/groupadd.c } #ifdef SHADOWGRP /* -@@ -217,7 +226,7 @@ static void grp_update (void) +@@ -220,7 +229,7 @@ static void grp_update (void) fprintf (stderr, _("%s: failed to prepare the new %s entry '%s'\n"), Prog, sgr_dbname (), sgrp.sg_name); @@ -599,7 +590,7 @@ diff -up shadow-4.11.1/src/groupadd.c.audit-update shadow-4.11.1/src/groupadd.c } #endif /* SHADOWGRP */ } -@@ -241,7 +250,7 @@ static void check_new_name (void) +@@ -244,7 +253,7 @@ static void check_new_name (void) fprintf (stderr, _("%s: '%s' is not a valid group name\n"), Prog, group_name); @@ -608,7 +599,7 @@ diff -up shadow-4.11.1/src/groupadd.c.audit-update shadow-4.11.1/src/groupadd.c } /* -@@ -257,11 +266,11 @@ static void close_files (void) +@@ -260,11 +269,11 @@ static void close_files (void) fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, gr_dbname ()); @@ -619,10 +610,10 @@ diff -up shadow-4.11.1/src/groupadd.c.audit-update shadow-4.11.1/src/groupadd.c audit_logger (AUDIT_ADD_GROUP, Prog, - "adding group to /etc/group", + "add-group", - group_name, (unsigned int) group_id, - SHADOW_AUDIT_SUCCESS); + group_name, group_id, SHADOW_AUDIT_SUCCESS); #endif -@@ -279,11 +288,11 @@ static void close_files (void) + SYSLOG ((LOG_INFO, "group added to %s: name=%s, GID=%u", +@@ -281,11 +290,11 @@ static void close_files (void) fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sgr_dbname ()); @@ -634,23 +625,21 @@ diff -up shadow-4.11.1/src/groupadd.c.audit-update shadow-4.11.1/src/groupadd.c - "adding group to /etc/gshadow", + audit_logger (AUDIT_GRP_MGMT, Prog, + "add-shadow-group", - group_name, (unsigned int) group_id, - SHADOW_AUDIT_SUCCESS); + group_name, group_id, SHADOW_AUDIT_SUCCESS); #endif -@@ -297,12 +306,6 @@ static void close_files (void) + SYSLOG ((LOG_INFO, "group added to %s: name=%s", +@@ -298,10 +307,6 @@ static void close_files (void) #endif /* SHADOWGRP */ /* Report success at the system level */ -#ifdef WITH_AUDIT - audit_logger (AUDIT_ADD_GROUP, Prog, -- "", -- group_name, (unsigned int) group_id, -- SHADOW_AUDIT_SUCCESS); +- "", group_name, group_id, SHADOW_AUDIT_SUCCESS); -#endif SYSLOG ((LOG_INFO, "new group: name=%s, GID=%u", group_name, (unsigned int) group_id)); del_cleanup (cleanup_report_add_group); -@@ -320,7 +323,7 @@ static void open_files (void) +@@ -319,7 +324,7 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, gr_dbname ()); @@ -659,7 +648,7 @@ diff -up shadow-4.11.1/src/groupadd.c.audit-update shadow-4.11.1/src/groupadd.c } add_cleanup (cleanup_unlock_group, NULL); -@@ -330,7 +333,7 @@ static void open_files (void) +@@ -329,7 +334,7 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, sgr_dbname ()); @@ -668,7 +657,7 @@ diff -up shadow-4.11.1/src/groupadd.c.audit-update shadow-4.11.1/src/groupadd.c } add_cleanup (cleanup_unlock_gshadow, NULL); } -@@ -346,7 +349,7 @@ static void open_files (void) +@@ -345,7 +350,7 @@ static void open_files (void) if (gr_open (O_CREAT | O_RDWR) == 0) { fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ()); SYSLOG ((LOG_WARN, "cannot open %s", gr_dbname ())); @@ -677,7 +666,7 @@ diff -up shadow-4.11.1/src/groupadd.c.audit-update shadow-4.11.1/src/groupadd.c } #ifdef SHADOWGRP -@@ -356,7 +359,7 @@ static void open_files (void) +@@ -355,7 +360,7 @@ static void open_files (void) _("%s: cannot open %s\n"), Prog, sgr_dbname ()); SYSLOG ((LOG_WARN, "cannot open %s", sgr_dbname ())); @@ -686,7 +675,7 @@ diff -up shadow-4.11.1/src/groupadd.c.audit-update shadow-4.11.1/src/groupadd.c } } #endif /* SHADOWGRP */ -@@ -493,7 +496,7 @@ static void check_flags (void) +@@ -492,7 +497,7 @@ static void check_flags (void) fprintf (stderr, _("%s: group '%s' already exists\n"), Prog, group_name); @@ -695,7 +684,7 @@ diff -up shadow-4.11.1/src/groupadd.c.audit-update shadow-4.11.1/src/groupadd.c } if (gflg && (prefix_getgrgid (group_id) != NULL)) { -@@ -512,7 +515,7 @@ static void check_flags (void) +@@ -511,7 +516,7 @@ static void check_flags (void) fprintf (stderr, _("%s: GID '%lu' already exists\n"), Prog, (unsigned long int) group_id); @@ -704,7 +693,7 @@ diff -up shadow-4.11.1/src/groupadd.c.audit-update shadow-4.11.1/src/groupadd.c } } } -@@ -540,7 +543,7 @@ static void check_perms (void) +@@ -539,7 +544,7 @@ static void check_perms (void) fprintf (stderr, _("%s: Cannot determine your user name.\n"), Prog); @@ -713,7 +702,7 @@ diff -up shadow-4.11.1/src/groupadd.c.audit-update shadow-4.11.1/src/groupadd.c } retval = pam_start ("groupadd", pampw->pw_name, &conv, &pamh); -@@ -560,7 +563,7 @@ static void check_perms (void) +@@ -559,7 +564,7 @@ static void check_perms (void) if (NULL != pamh) { (void) pam_end (pamh, retval); } @@ -722,7 +711,7 @@ diff -up shadow-4.11.1/src/groupadd.c.audit-update shadow-4.11.1/src/groupadd.c } (void) pam_end (pamh, retval); #endif /* USE_PAM */ -@@ -595,7 +598,7 @@ int main (int argc, char **argv) +@@ -594,7 +599,7 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: Cannot setup cleanup service.\n"), Prog); @@ -731,7 +720,7 @@ diff -up shadow-4.11.1/src/groupadd.c.audit-update shadow-4.11.1/src/groupadd.c } /* -@@ -617,7 +620,7 @@ int main (int argc, char **argv) +@@ -621,7 +626,7 @@ int main (int argc, char **argv) if (!gflg) { if (find_new_gid (rflg, &group_id, NULL) < 0) { @@ -740,10 +729,10 @@ diff -up shadow-4.11.1/src/groupadd.c.audit-update shadow-4.11.1/src/groupadd.c } } -diff -up shadow-4.11.1/src/groupdel.c.audit-update shadow-4.11.1/src/groupdel.c ---- shadow-4.11.1/src/groupdel.c.audit-update 2022-01-03 01:46:53.000000000 +0100 -+++ shadow-4.11.1/src/groupdel.c 2022-01-03 14:57:01.778006782 +0100 -@@ -84,6 +84,15 @@ static /*@noreturn@*/void usage (int sta +diff -up shadow-4.14.0/src/groupdel.c.audit-update shadow-4.14.0/src/groupdel.c +--- shadow-4.14.0/src/groupdel.c.audit-update 2023-05-26 04:56:11.000000000 +0200 ++++ shadow-4.14.0/src/groupdel.c 2023-08-04 09:36:42.778900250 +0200 +@@ -87,6 +87,15 @@ usage (int status) exit (status); } @@ -759,7 +748,7 @@ diff -up shadow-4.11.1/src/groupdel.c.audit-update shadow-4.11.1/src/groupdel.c /* * grp_update - update group file entries * -@@ -110,7 +119,7 @@ static void grp_update (void) +@@ -113,7 +122,7 @@ static void grp_update (void) fprintf (stderr, _("%s: cannot remove entry '%s' from %s\n"), Prog, group_name, gr_dbname ()); @@ -768,7 +757,7 @@ diff -up shadow-4.11.1/src/groupdel.c.audit-update shadow-4.11.1/src/groupdel.c } #ifdef SHADOWGRP -@@ -122,7 +131,7 @@ static void grp_update (void) +@@ -125,7 +134,7 @@ static void grp_update (void) fprintf (stderr, _("%s: cannot remove entry '%s' from %s\n"), Prog, group_name, sgr_dbname ()); @@ -777,7 +766,7 @@ diff -up shadow-4.11.1/src/groupdel.c.audit-update shadow-4.11.1/src/groupdel.c } } #endif /* SHADOWGRP */ -@@ -141,12 +150,12 @@ static void close_files (void) +@@ -144,12 +153,12 @@ static void close_files (void) fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, gr_dbname ()); @@ -789,10 +778,10 @@ diff -up shadow-4.11.1/src/groupdel.c.audit-update shadow-4.11.1/src/groupdel.c audit_logger (AUDIT_DEL_GROUP, Prog, - "removing group from /etc/group", + "delete-group", - group_name, (unsigned int) group_id, - SHADOW_AUDIT_SUCCESS); + group_name, group_id, SHADOW_AUDIT_SUCCESS); #endif -@@ -166,12 +175,12 @@ static void close_files (void) + SYSLOG ((LOG_INFO, +@@ -168,12 +177,12 @@ static void close_files (void) fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sgr_dbname ()); @@ -805,24 +794,22 @@ diff -up shadow-4.11.1/src/groupdel.c.audit-update shadow-4.11.1/src/groupdel.c - "removing group from /etc/gshadow", + audit_logger (AUDIT_GRP_MGMT, Prog, + "delete-shadow-group", - group_name, (unsigned int) group_id, - SHADOW_AUDIT_SUCCESS); + group_name, group_id, SHADOW_AUDIT_SUCCESS); #endif -@@ -185,13 +194,6 @@ static void close_files (void) + SYSLOG ((LOG_INFO, +@@ -186,11 +195,6 @@ static void close_files (void) } #endif /* SHADOWGRP */ - /* Report success at the system level */ -#ifdef WITH_AUDIT - audit_logger (AUDIT_DEL_GROUP, Prog, -- "", -- group_name, (unsigned int) group_id, -- SHADOW_AUDIT_SUCCESS); +- "", group_name, group_id, SHADOW_AUDIT_SUCCESS); -#endif SYSLOG ((LOG_INFO, "group '%s' removed\n", group_name)); del_cleanup (cleanup_report_del_group); } -@@ -208,7 +210,7 @@ static void open_files (void) +@@ -207,7 +211,7 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, gr_dbname ()); @@ -831,7 +818,7 @@ diff -up shadow-4.11.1/src/groupdel.c.audit-update shadow-4.11.1/src/groupdel.c } add_cleanup (cleanup_unlock_group, NULL); #ifdef SHADOWGRP -@@ -217,7 +219,7 @@ static void open_files (void) +@@ -216,7 +220,7 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, sgr_dbname ()); @@ -840,7 +827,7 @@ diff -up shadow-4.11.1/src/groupdel.c.audit-update shadow-4.11.1/src/groupdel.c } add_cleanup (cleanup_unlock_gshadow, NULL); } -@@ -235,7 +237,7 @@ static void open_files (void) +@@ -234,7 +238,7 @@ static void open_files (void) _("%s: cannot open %s\n"), Prog, gr_dbname ()); SYSLOG ((LOG_WARN, "cannot open %s", gr_dbname ())); @@ -849,7 +836,7 @@ diff -up shadow-4.11.1/src/groupdel.c.audit-update shadow-4.11.1/src/groupdel.c } #ifdef SHADOWGRP if (is_shadow_grp) { -@@ -244,7 +246,7 @@ static void open_files (void) +@@ -243,7 +247,7 @@ static void open_files (void) _("%s: cannot open %s\n"), Prog, sgr_dbname ()); SYSLOG ((LOG_WARN, "cannot open %s", sgr_dbname ())); @@ -858,7 +845,7 @@ diff -up shadow-4.11.1/src/groupdel.c.audit-update shadow-4.11.1/src/groupdel.c } } #endif /* SHADOWGRP */ -@@ -285,7 +287,7 @@ static void group_busy (gid_t gid) +@@ -284,7 +288,7 @@ static void group_busy (gid_t gid) fprintf (stderr, _("%s: cannot remove the primary group of user '%s'\n"), Prog, pwd->pw_name); @@ -867,7 +854,7 @@ diff -up shadow-4.11.1/src/groupdel.c.audit-update shadow-4.11.1/src/groupdel.c } /* -@@ -373,7 +375,7 @@ int main (int argc, char **argv) +@@ -372,7 +376,7 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: Cannot setup cleanup service.\n"), Prog); @@ -876,7 +863,7 @@ diff -up shadow-4.11.1/src/groupdel.c.audit-update shadow-4.11.1/src/groupdel.c } process_flags (argc, argv); -@@ -387,7 +389,7 @@ int main (int argc, char **argv) +@@ -386,7 +390,7 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: Cannot determine your user name.\n"), Prog); @@ -885,7 +872,7 @@ diff -up shadow-4.11.1/src/groupdel.c.audit-update shadow-4.11.1/src/groupdel.c } retval = pam_start ("groupdel", pampw->pw_name, &conv, &pamh); -@@ -408,7 +410,7 @@ int main (int argc, char **argv) +@@ -407,7 +411,7 @@ int main (int argc, char **argv) if (NULL != pamh) { (void) pam_end (pamh, retval); } @@ -894,7 +881,7 @@ diff -up shadow-4.11.1/src/groupdel.c.audit-update shadow-4.11.1/src/groupdel.c } (void) pam_end (pamh, retval); #endif /* USE_PAM */ -@@ -428,7 +430,7 @@ int main (int argc, char **argv) +@@ -427,7 +431,7 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: group '%s' does not exist\n"), Prog, group_name); @@ -903,7 +890,7 @@ diff -up shadow-4.11.1/src/groupdel.c.audit-update shadow-4.11.1/src/groupdel.c } group_id = grp->gr_gid; -@@ -452,7 +454,7 @@ int main (int argc, char **argv) +@@ -451,7 +455,7 @@ int main (int argc, char **argv) _("%s: %s is the NIS master\n"), Prog, nis_master); } @@ -912,10 +899,10 @@ diff -up shadow-4.11.1/src/groupdel.c.audit-update shadow-4.11.1/src/groupdel.c } #endif -diff -up shadow-4.11.1/src/groupmod.c.audit-update shadow-4.11.1/src/groupmod.c ---- shadow-4.11.1/src/groupmod.c.audit-update 2022-01-03 01:46:53.000000000 +0100 -+++ shadow-4.11.1/src/groupmod.c 2022-01-03 14:57:01.778006782 +0100 -@@ -468,7 +468,7 @@ static void close_files (void) +diff -up shadow-4.14.0/src/groupmod.c.audit-update shadow-4.14.0/src/groupmod.c +--- shadow-4.14.0/src/groupmod.c.audit-update 2023-06-10 02:02:29.000000000 +0200 ++++ shadow-4.14.0/src/groupmod.c 2023-08-04 09:30:25.208963541 +0200 +@@ -473,7 +473,7 @@ static void close_files (void) exit (E_GRP_UPDATE); } #ifdef WITH_AUDIT @@ -924,7 +911,7 @@ diff -up shadow-4.11.1/src/groupmod.c.audit-update shadow-4.11.1/src/groupmod.c info_group.audit_msg, group_name, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); -@@ -491,7 +491,14 @@ static void close_files (void) +@@ -496,7 +496,14 @@ static void close_files (void) exit (E_GRP_UPDATE); } #ifdef WITH_AUDIT @@ -940,7 +927,7 @@ diff -up shadow-4.11.1/src/groupmod.c.audit-update shadow-4.11.1/src/groupmod.c info_gshadow.audit_msg, group_name, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); -@@ -514,7 +521,7 @@ static void close_files (void) +@@ -519,7 +526,7 @@ static void close_files (void) exit (E_GRP_UPDATE); } #ifdef WITH_AUDIT @@ -949,7 +936,7 @@ diff -up shadow-4.11.1/src/groupmod.c.audit-update shadow-4.11.1/src/groupmod.c info_passwd.audit_msg, group_name, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); -@@ -529,8 +536,8 @@ static void close_files (void) +@@ -534,8 +541,8 @@ static void close_files (void) } #ifdef WITH_AUDIT @@ -960,168 +947,10 @@ diff -up shadow-4.11.1/src/groupmod.c.audit-update shadow-4.11.1/src/groupmod.c group_name, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); #endif -@@ -542,6 +549,8 @@ static void close_files (void) - */ - static void prepare_failure_reports (void) - { -+ char *nv_pair, nv[64]; -+ - info_group.name = group_name; - #ifdef SHADOWGRP - info_gshadow.name = group_name; -@@ -554,76 +563,109 @@ static void prepare_failure_reports (voi - #endif - info_passwd.audit_msg = xmalloc (512); - -- (void) snprintf (info_group.audit_msg, 511, -- "changing %s; ", gr_dbname ()); -+ info_group.action = xmalloc (512); - #ifdef SHADOWGRP -- (void) snprintf (info_gshadow.audit_msg, 511, -- "changing %s; ", sgr_dbname ()); -+ info_gshadow.action = xmalloc (512); - #endif -- (void) snprintf (info_passwd.audit_msg, 511, -- "changing %s; ", pw_dbname ()); -+ info_passwd.action = xmalloc (512); - -- info_group.action = info_group.audit_msg -- + strlen (info_group.audit_msg); -+ (void) snprintf (info_group.audit_msg, 511, -+ "changing-group"); - #ifdef SHADOWGRP -- info_gshadow.action = info_gshadow.audit_msg -- + strlen (info_gshadow.audit_msg); -+ (void) snprintf (info_gshadow.audit_msg, 511, -+ "changing-shadow-group"); - #endif -- info_passwd.action = info_passwd.audit_msg -- + strlen (info_passwd.audit_msg); -+ (void) snprintf (info_passwd.audit_msg, 511, -+ "changing-group-passwd"); - -+ nv_pair = audit_encode_nv_string(" grp", group_name, -+ strlen(group_name)); -+ if(nv_pair) { -+ strncat(info_group.audit_msg, nv_pair, -+ 511 - strlen(info_group.audit_msg)); -+#ifdef SHADOWGRP -+ strncat(info_gshadow.audit_msg, nv_pair, -+ 511 - strlen(info_gshadow.audit_msg)); -+#endif -+ strncat(info_passwd.audit_msg, nv_pair, -+ 511 - strlen(info_passwd.audit_msg)); -+ free(nv_pair); -+ } -+ snprintf(nv, sizeof(nv), " gid=%lu", (unsigned long)group_id); -+ strncat(info_group.audit_msg, nv, 511 - strlen(info_group.audit_msg)); -+ strncat(info_passwd.audit_msg, nv, 511 - strlen(info_passwd.audit_msg)); -+ - (void) snprintf (info_group.action, -- 511 - strlen (info_group.audit_msg), -+ 511, - "group %s/%lu", - group_name, (unsigned long int) group_id); - #ifdef SHADOWGRP - (void) snprintf (info_gshadow.action, -- 511 - strlen (info_group.audit_msg), -+ 511, - "group %s", group_name); - #endif - (void) snprintf (info_passwd.action, -- 511 - strlen (info_group.audit_msg), -+ 511, - "group %s/%lu", - group_name, (unsigned long int) group_id); - - if (nflg) { -+ nv_pair = audit_encode_nv_string(" new_group", group_newname, -+ strlen(group_newname)); -+ strncat(info_group.audit_msg, nv_pair, -+ 511 - strlen(info_group.audit_msg)); - strncat (info_group.action, ", new name: ", -- 511 - strlen (info_group.audit_msg)); -+ 511 - strlen (info_group.action)); - strncat (info_group.action, group_newname, -- 511 - strlen (info_group.audit_msg)); -+ 511 - strlen (info_group.action)); - - #ifdef SHADOWGRP -+ strncat(info_gshadow.audit_msg, nv_pair, -+ 511 - strlen(info_gshadow.audit_msg)); - strncat (info_gshadow.action, ", new name: ", -- 511 - strlen (info_gshadow.audit_msg)); -+ 511 - strlen (info_gshadow.action)); - strncat (info_gshadow.action, group_newname, -- 511 - strlen (info_gshadow.audit_msg)); -+ 511 - strlen (info_gshadow.action)); - #endif - -+ strncat(info_passwd.audit_msg, nv_pair, -+ 511 - strlen(info_passwd.audit_msg)); - strncat (info_passwd.action, ", new name: ", -- 511 - strlen (info_passwd.audit_msg)); -+ 511 - strlen (info_passwd.action)); - strncat (info_passwd.action, group_newname, -- 511 - strlen (info_passwd.audit_msg)); -+ 511 - strlen (info_passwd.action)); -+ free(nv_pair); - } - if (pflg) { -+ strncat(info_passwd.audit_msg, "op=change-password", -+ 511 - strlen (info_passwd.action)); -+ -+ /* Note: audit doesn't want this value recorded */ - strncat (info_group.action, ", new password", -- 511 - strlen (info_group.audit_msg)); -+ 511 - strlen (info_group.action)); - - #ifdef SHADOWGRP - strncat (info_gshadow.action, ", new password", -- 511 - strlen (info_gshadow.audit_msg)); -+ 511 - strlen (info_gshadow.action)); - #endif - } - if (gflg) { -+ snprintf(nv, sizeof(nv), " new_gid=%lu", (unsigned long)group_newid); -+ strncat(info_group.audit_msg, nv, -+ 511 - strlen(info_group.audit_msg)); -+ strncat(info_passwd.audit_msg, nv, -+ 511 - strlen(info_passwd.audit_msg)); -+ - strncat (info_group.action, ", new gid: ", -- 511 - strlen (info_group.audit_msg)); -+ 511 - strlen (info_group.action)); - (void) snprintf (info_group.action+strlen (info_group.action), -- 511 - strlen (info_group.audit_msg), -+ 511 - strlen (info_group.action), - "%lu", (unsigned long int) group_newid); - - strncat (info_passwd.action, ", new gid: ", -- 511 - strlen (info_passwd.audit_msg)); -+ 511 - strlen (info_passwd.action)); - (void) snprintf (info_passwd.action+strlen (info_passwd.action), -- 511 - strlen (info_passwd.audit_msg), -+ 511 - strlen (info_passwd.action), - "%lu", (unsigned long int) group_newid); - } - info_group.audit_msg[511] = '\0'; -@@ -631,6 +673,11 @@ static void prepare_failure_reports (voi - info_gshadow.audit_msg[511] = '\0'; - #endif - info_passwd.audit_msg[511] = '\0'; -+ info_group.action[511] = '\0'; -+#ifdef SHADOWGRP -+ info_gshadow.action[511] = '\0'; -+#endif -+ info_passwd.action[511] = '\0'; - - // FIXME: add a system cleanup - add_cleanup (cleanup_report_mod_group, &info_group); -diff -up shadow-4.11.1/src/newgrp.c.audit-update shadow-4.11.1/src/newgrp.c ---- shadow-4.11.1/src/newgrp.c.audit-update 2022-01-03 01:46:53.000000000 +0100 -+++ shadow-4.11.1/src/newgrp.c 2022-01-03 15:25:39.407050922 +0100 -@@ -185,11 +185,12 @@ static void check_perms (const struct gr +diff -up shadow-4.14.0/src/newgrp.c.audit-update shadow-4.14.0/src/newgrp.c +--- shadow-4.14.0/src/newgrp.c.audit-update 2023-08-04 09:30:25.208963541 +0200 ++++ shadow-4.14.0/src/newgrp.c 2023-08-04 09:51:28.354208322 +0200 +@@ -186,10 +186,10 @@ static void check_perms (const struct gr strcmp (cpasswd, grp->gr_passwd) != 0) { #ifdef WITH_AUDIT snprintf (audit_buf, sizeof(audit_buf), @@ -1129,14 +958,12 @@ diff -up shadow-4.11.1/src/newgrp.c.audit-update shadow-4.11.1/src/newgrp.c + "authentication new_gid=%lu", (unsigned long) grp->gr_gid); audit_logger (AUDIT_GRP_AUTH, Prog, - audit_buf, NULL, -- (unsigned int) getuid (), 0); -+ (unsigned int) getuid (), -+ SHADOW_AUDIT_FAILURE); +- audit_buf, NULL, getuid (), 0); ++ audit_buf, NULL, getuid (), SHADOW_AUDIT_FAILURE); #endif SYSLOG ((LOG_INFO, "Invalid password for group '%s' from '%s'", -@@ -200,11 +201,12 @@ static void check_perms (const struct gr +@@ -200,10 +200,10 @@ static void check_perms (const struct gr } #ifdef WITH_AUDIT snprintf (audit_buf, sizeof(audit_buf), @@ -1144,14 +971,12 @@ diff -up shadow-4.11.1/src/newgrp.c.audit-update shadow-4.11.1/src/newgrp.c + "authentication new_gid=%lu", (unsigned long) grp->gr_gid); audit_logger (AUDIT_GRP_AUTH, Prog, - audit_buf, NULL, -- (unsigned int) getuid (), 1); -+ (unsigned int) getuid (), -+ SHADOW_AUDIT_SUCCESS); +- audit_buf, NULL, getuid (), 1); ++ audit_buf, NULL, getuid (), SHADOW_AUDIT_SUCCESS); #endif } -@@ -215,19 +217,6 @@ failure: +@@ -214,17 +214,6 @@ failure: * harm. -- JWP */ closelog (); @@ -1160,18 +985,16 @@ diff -up shadow-4.11.1/src/newgrp.c.audit-update shadow-4.11.1/src/newgrp.c - snprintf (audit_buf, sizeof(audit_buf), - "changing new-group=%s", groupname); - audit_logger (AUDIT_CHGRP_ID, Prog, -- audit_buf, NULL, -- (unsigned int) getuid (), 0); +- audit_buf, NULL, getuid (), 0); - } else { - audit_logger (AUDIT_CHGRP_ID, Prog, -- "changing", NULL, -- (unsigned int) getuid (), 0); +- "changing", NULL, getuid (), 0); - } -#endif exit (EXIT_FAILURE); } -@@ -299,15 +288,27 @@ static void syslog_sg (const char *name, +@@ -298,13 +287,23 @@ static void syslog_sg (const char *name, is_newgrp ? "newgrp" : "sg", strerror (errno)); #ifdef WITH_AUDIT if (group) { @@ -1190,29 +1013,25 @@ diff -up shadow-4.11.1/src/newgrp.c.audit-update shadow-4.11.1/src/newgrp.c + group); + } audit_logger (AUDIT_CHGRP_ID, Prog, - audit_buf, NULL, -- (unsigned int) getuid (), 0); -+ (unsigned int) getuid (), -+ SHADOW_AUDIT_FAILURE); +- audit_buf, NULL, getuid (), 0); ++ audit_buf, NULL, getuid (), SHADOW_AUDIT_FAILURE); } else { audit_logger (AUDIT_CHGRP_ID, Prog, - "changing", NULL, -- (unsigned int) getuid (), 0); -+ (unsigned int) getuid (), -+ SHADOW_AUDIT_FAILURE); +- "changing", NULL, getuid (), 0); ++ "changing", NULL, getuid (), SHADOW_AUDIT_FAILURE); } #endif exit (EXIT_FAILURE); -@@ -438,7 +439,7 @@ int main (int argc, char **argv) +@@ -440,7 +439,7 @@ int main (int argc, char **argv) + Prog); #ifdef WITH_AUDIT audit_logger (AUDIT_CHGRP_ID, Prog, - "changing", NULL, -- (unsigned int) getuid (), 0); -+ (unsigned int) getuid (), SHADOW_AUDIT_FAILURE); +- "changing", NULL, getuid (), 0); ++ "changing", NULL, getuid (), SHADOW_AUDIT_FAILURE); #endif SYSLOG ((LOG_WARN, "Cannot determine the user name of the caller (UID %lu)", (unsigned long) getuid ())); -@@ -554,15 +555,26 @@ int main (int argc, char **argv) +@@ -556,13 +555,22 @@ int main (int argc, char **argv) perror ("getgroups"); #ifdef WITH_AUDIT if (group) { @@ -1230,59 +1049,52 @@ diff -up shadow-4.11.1/src/newgrp.c.audit-update shadow-4.11.1/src/newgrp.c + "changing new_group=\"%s\"", group); + } audit_logger (AUDIT_CHGRP_ID, Prog, - audit_buf, NULL, -- (unsigned int) getuid (), 0); -+ (unsigned int) getuid (), -+ SHADOW_AUDIT_FAILURE); +- audit_buf, NULL, getuid (), 0); ++ audit_buf, NULL, getuid (), SHADOW_AUDIT_FAILURE); } else { audit_logger (AUDIT_CHGRP_ID, Prog, - "changing", NULL, -- (unsigned int) getuid (), 0); -+ (unsigned int) getuid (), -+ SHADOW_AUDIT_FAILURE); +- "changing", NULL, getuid (), 0); ++ "changing", NULL, getuid (), SHADOW_AUDIT_FAILURE); } #endif exit (EXIT_FAILURE); -@@ -719,10 +731,10 @@ int main (int argc, char **argv) +@@ -717,9 +725,9 @@ int main (int argc, char **argv) perror ("setgid"); #ifdef WITH_AUDIT snprintf (audit_buf, sizeof(audit_buf), - "changing new-gid=%lu", (unsigned long) gid); + "changing new_gid=%lu", (unsigned long) gid); audit_logger (AUDIT_CHGRP_ID, Prog, - audit_buf, NULL, -- (unsigned int) getuid (), 0); -+ (unsigned int) getuid (), SHADOW_AUDIT_FAILURE); +- audit_buf, NULL, getuid (), 0); ++ audit_buf, NULL, getuid (), SHADOW_AUDIT_FAILURE); #endif exit (EXIT_FAILURE); } -@@ -731,10 +743,10 @@ int main (int argc, char **argv) +@@ -728,9 +736,9 @@ int main (int argc, char **argv) perror ("setuid"); #ifdef WITH_AUDIT snprintf (audit_buf, sizeof(audit_buf), - "changing new-gid=%lu", (unsigned long) gid); + "changing new_gid=%lu", (unsigned long) gid); audit_logger (AUDIT_CHGRP_ID, Prog, - audit_buf, NULL, -- (unsigned int) getuid (), 0); -+ (unsigned int) getuid (), SHADOW_AUDIT_FAILURE); +- audit_buf, NULL, getuid (), 0); ++ audit_buf, NULL, getuid (), SHADOW_AUDIT_FAILURE); #endif exit (EXIT_FAILURE); } -@@ -748,10 +760,10 @@ int main (int argc, char **argv) - execl (SHELL, "sh", "-c", command, (char *) 0); +@@ -744,9 +752,9 @@ int main (int argc, char **argv) + execl (SHELL, "sh", "-c", command, (char *) NULL); #ifdef WITH_AUDIT snprintf (audit_buf, sizeof(audit_buf), - "changing new-gid=%lu", (unsigned long) gid); + "changing new_gid=%lu", (unsigned long) gid); audit_logger (AUDIT_CHGRP_ID, Prog, - audit_buf, NULL, -- (unsigned int) getuid (), 0); -+ (unsigned int) getuid (), SHADOW_AUDIT_FAILURE); +- audit_buf, NULL, getuid (), 0); ++ audit_buf, NULL, getuid (), SHADOW_AUDIT_FAILURE); #endif perror (SHELL); exit ((errno == ENOENT) ? E_CMD_NOTFOUND : E_CMD_NOEXEC); -@@ -815,11 +827,11 @@ int main (int argc, char **argv) +@@ -810,10 +818,10 @@ int main (int argc, char **argv) } #ifdef WITH_AUDIT @@ -1290,13 +1102,12 @@ diff -up shadow-4.11.1/src/newgrp.c.audit-update shadow-4.11.1/src/newgrp.c + snprintf (audit_buf, sizeof(audit_buf), "changing new_gid=%lu", (unsigned long) gid); audit_logger (AUDIT_CHGRP_ID, Prog, - audit_buf, NULL, -- (unsigned int) getuid (), 1); -+ (unsigned int) getuid (), SHADOW_AUDIT_SUCCESS); +- audit_buf, NULL, getuid (), 1); ++ audit_buf, NULL, getuid (), SHADOW_AUDIT_SUCCESS); #endif /* * Exec the login shell and go away. We are trying to get back to -@@ -843,15 +855,24 @@ int main (int argc, char **argv) +@@ -837,13 +845,22 @@ int main (int argc, char **argv) closelog (); #ifdef WITH_AUDIT if (NULL != group) { @@ -1314,112 +1125,91 @@ diff -up shadow-4.11.1/src/newgrp.c.audit-update shadow-4.11.1/src/newgrp.c + "changing new_group=\"%s\"", group); + } audit_logger (AUDIT_CHGRP_ID, Prog, - audit_buf, NULL, -- (unsigned int) getuid (), 0); -+ (unsigned int) getuid (), SHADOW_AUDIT_FAILURE); +- audit_buf, NULL, getuid (), 0); ++ audit_buf, NULL, getuid (), SHADOW_AUDIT_FAILURE); } else { audit_logger (AUDIT_CHGRP_ID, Prog, - "changing", NULL, -- (unsigned int) getuid (), 0); -+ (unsigned int) getuid (), SHADOW_AUDIT_FAILURE); +- "changing", NULL, getuid (), 0); ++ "changing", NULL, getuid (), SHADOW_AUDIT_FAILURE); } #endif exit (EXIT_FAILURE); -diff -up shadow-4.11.1/src/useradd.c.audit-update shadow-4.11.1/src/useradd.c ---- shadow-4.11.1/src/useradd.c.audit-update 2022-01-03 14:57:01.772006744 +0100 -+++ shadow-4.11.1/src/useradd.c 2022-01-03 14:57:01.787006838 +0100 -@@ -222,6 +222,8 @@ static void check_uid_range(int rflg, ui +diff -up shadow-4.14.0/src/useradd.c.audit-update shadow-4.14.0/src/useradd.c +--- shadow-4.14.0/src/useradd.c.audit-update 2023-07-30 12:38:39.000000000 +0200 ++++ shadow-4.14.0/src/useradd.c 2023-08-04 10:02:18.851935396 +0200 +@@ -240,6 +240,8 @@ static void check_uid_range(int rflg, ui */ static void fail_exit (int code) { + int type; + - if (home_added) { - if (rmdir (prefix_user_home) != 0) { - fprintf (stderr, -@@ -235,12 +237,6 @@ static void fail_exit (int code) - if (spw_unlock () == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + if (home_added && rmdir(prefix_user_home) != 0) { + fprintf(stderr, + _("%s: %s was created, but could not be removed\n"), +@@ -250,38 +252,22 @@ static void fail_exit (int code) + if (spw_locked && spw_unlock() == 0) { + fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname()); + SYSLOG((LOG_ERR, "failed to unlock %s", spw_dbname())); -#ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_USER, Prog, -- "unlocking shadow file", -- user_name, AUDIT_NO_ID, -- SHADOW_AUDIT_FAILURE); +- audit_logger(AUDIT_ADD_USER, Prog, "unlocking shadow file", +- user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); -#endif - /* continue */ - } + /* continue */ } -@@ -248,12 +244,6 @@ static void fail_exit (int code) - if (pw_unlock () == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + if (pw_locked && pw_unlock() == 0) { + fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname()); + SYSLOG((LOG_ERR, "failed to unlock %s", pw_dbname())); -#ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_USER, Prog, -- "unlocking passwd file", -- user_name, AUDIT_NO_ID, -- SHADOW_AUDIT_FAILURE); +- audit_logger(AUDIT_ADD_USER, Prog, "unlocking passwd file", +- user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); -#endif - /* continue */ - } + /* continue */ } -@@ -261,12 +251,6 @@ static void fail_exit (int code) - if (gr_unlock () == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + if (gr_locked && gr_unlock() == 0) { + fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname()); + SYSLOG((LOG_ERR, "failed to unlock %s", gr_dbname())); -#ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_USER, Prog, -- "unlocking group file", -- user_name, AUDIT_NO_ID, -- SHADOW_AUDIT_FAILURE); +- audit_logger(AUDIT_ADD_USER, Prog, "unlocking group file", +- user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); -#endif - /* continue */ - } + /* continue */ } -@@ -275,12 +259,6 @@ static void fail_exit (int code) - if (sgr_unlock () == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); --#ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_USER, Prog, -- "unlocking gshadow file", -- user_name, AUDIT_NO_ID, -- SHADOW_AUDIT_FAILURE); --#endif - /* continue */ - } + #ifdef SHADOWGRP + if (sgr_locked && sgr_unlock() == 0) { + fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname()); + SYSLOG((LOG_ERR, "failed to unlock %s", sgr_dbname())); +-# ifdef WITH_AUDIT +- audit_logger(AUDIT_ADD_USER, Prog, "unlocking gshadow file", +- user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); +-# endif + /* continue */ } -@@ -290,12 +268,6 @@ static void fail_exit (int code) - if (sub_uid_unlock () == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); --#ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_USER, Prog, -- "unlocking subordinate user file", -- user_name, AUDIT_NO_ID, -- SHADOW_AUDIT_FAILURE); --#endif - /* continue */ - } + #endif +@@ -289,27 +275,23 @@ static void fail_exit (int code) + if (sub_uid_locked && sub_uid_unlock() == 0) { + fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname()); + SYSLOG((LOG_ERR, "failed to unlock %s", sub_uid_dbname())); +-# ifdef WITH_AUDIT +- audit_logger(AUDIT_ADD_USER, Prog, +- "unlocking subordinate user file", +- user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); +-# endif + /* continue */ } -@@ -303,20 +275,19 @@ static void fail_exit (int code) - if (sub_gid_unlock () == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); --#ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_USER, Prog, -- "unlocking subordinate group file", -- user_name, AUDIT_NO_ID, -- SHADOW_AUDIT_FAILURE); --#endif - /* continue */ - } + if (sub_gid_locked && sub_gid_unlock() == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname())); +-# ifdef WITH_AUDIT +- audit_logger(AUDIT_ADD_USER, Prog, +- "unlocking subordinate group file", +- user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); +-# endif + /* continue */ } - #endif /* ENABLE_SUBIDS */ + #endif /* ENABLE_SUBIDS */ #ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_USER, Prog, -- "adding user", +- audit_logger(AUDIT_ADD_USER, Prog, "adding user", + if (code == E_PW_UPDATE || code >= E_GRP_UPDATE) + type = AUDIT_USER_MGMT; + else @@ -1427,10 +1217,10 @@ diff -up shadow-4.11.1/src/useradd.c.audit-update shadow-4.11.1/src/useradd.c + + audit_logger (type, Prog, + "add-user", - user_name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); + user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -719,7 +690,7 @@ static int set_defaults (void) + SYSLOG((LOG_INFO, "failed adding user '%s', exit code: %d", user_name, code)); +@@ -759,7 +741,7 @@ static int set_defaults (void) } #ifdef WITH_AUDIT audit_logger (AUDIT_USYS_CONFIG, Prog, @@ -1439,7 +1229,7 @@ diff -up shadow-4.11.1/src/useradd.c.audit-update shadow-4.11.1/src/useradd.c NULL, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); #endif -@@ -1050,12 +1021,6 @@ static void grp_update (void) +@@ -1096,12 +1078,6 @@ static void grp_update (void) _("%s: Out of memory. Cannot update %s.\n"), Prog, gr_dbname ()); SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", gr_dbname (), user_name)); @@ -1452,7 +1242,7 @@ diff -up shadow-4.11.1/src/useradd.c.audit-update shadow-4.11.1/src/useradd.c fail_exit (E_GRP_UPDATE); /* XXX */ } -@@ -1069,18 +1034,12 @@ static void grp_update (void) +@@ -1115,18 +1091,12 @@ static void grp_update (void) _("%s: failed to prepare the new %s entry '%s'\n"), Prog, gr_dbname (), ngrp->gr_name); SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", gr_dbname (), user_name)); @@ -1474,7 +1264,7 @@ diff -up shadow-4.11.1/src/useradd.c.audit-update shadow-4.11.1/src/useradd.c SHADOW_AUDIT_SUCCESS); #endif SYSLOG ((LOG_INFO, -@@ -1125,12 +1084,6 @@ static void grp_update (void) +@@ -1171,12 +1141,6 @@ static void grp_update (void) _("%s: Out of memory. Cannot update %s.\n"), Prog, sgr_dbname ()); SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", sgr_dbname (), user_name)); @@ -1487,7 +1277,7 @@ diff -up shadow-4.11.1/src/useradd.c.audit-update shadow-4.11.1/src/useradd.c fail_exit (E_GRP_UPDATE); /* XXX */ } -@@ -1144,18 +1097,13 @@ static void grp_update (void) +@@ -1190,18 +1154,13 @@ static void grp_update (void) _("%s: failed to prepare the new %s entry '%s'\n"), Prog, sgr_dbname (), nsgrp->sg_name); SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", sgr_dbname (), user_name)); @@ -1510,7 +1300,7 @@ diff -up shadow-4.11.1/src/useradd.c.audit-update shadow-4.11.1/src/useradd.c SHADOW_AUDIT_SUCCESS); #endif SYSLOG ((LOG_INFO, -@@ -1528,7 +1476,7 @@ static void process_flags (int argc, cha +@@ -1596,7 +1555,7 @@ static void process_flags (int argc, cha Prog, user_name); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1519,7 +1309,7 @@ diff -up shadow-4.11.1/src/useradd.c.audit-update shadow-4.11.1/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1637,7 +1585,7 @@ static void close_files (void) +@@ -1705,7 +1664,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1528,7 +1318,7 @@ diff -up shadow-4.11.1/src/useradd.c.audit-update shadow-4.11.1/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1650,7 +1598,7 @@ static void close_files (void) +@@ -1718,7 +1677,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1537,7 +1327,7 @@ diff -up shadow-4.11.1/src/useradd.c.audit-update shadow-4.11.1/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1667,7 +1615,7 @@ static void close_files (void) +@@ -1735,7 +1694,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1546,7 +1336,7 @@ diff -up shadow-4.11.1/src/useradd.c.audit-update shadow-4.11.1/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1681,7 +1629,7 @@ static void close_files (void) +@@ -1749,7 +1708,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1555,7 +1345,7 @@ diff -up shadow-4.11.1/src/useradd.c.audit-update shadow-4.11.1/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1942,7 +1890,7 @@ static void grp_add (void) +@@ -2012,7 +1971,7 @@ static void grp_add (void) Prog, gr_dbname (), grp.gr_name); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_GROUP, Prog, @@ -1564,7 +1354,7 @@ diff -up shadow-4.11.1/src/useradd.c.audit-update shadow-4.11.1/src/useradd.c grp.gr_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1958,7 +1906,7 @@ static void grp_add (void) +@@ -2028,7 +1987,7 @@ static void grp_add (void) Prog, sgr_dbname (), sgrp.sg_name); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_GROUP, Prog, @@ -1573,7 +1363,7 @@ diff -up shadow-4.11.1/src/useradd.c.audit-update shadow-4.11.1/src/useradd.c grp.gr_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1968,7 +1916,7 @@ static void grp_add (void) +@@ -2038,7 +1997,7 @@ static void grp_add (void) SYSLOG ((LOG_INFO, "new group: name=%s, GID=%u", user_name, user_gid)); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_GROUP, Prog, @@ -1582,61 +1372,48 @@ diff -up shadow-4.11.1/src/useradd.c.audit-update shadow-4.11.1/src/useradd.c grp.gr_name, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); #endif -@@ -2161,12 +2109,6 @@ static void usr_update (unsigned long su +@@ -2240,11 +2199,6 @@ static void usr_update (unsigned long su fprintf (stderr, _("%s: failed to prepare the new %s entry '%s'\n"), Prog, spw_dbname (), spent.sp_namp); -#ifdef WITH_AUDIT - audit_logger (AUDIT_ADD_USER, Prog, - "adding shadow password", -- user_name, (unsigned int) user_id, -- SHADOW_AUDIT_FAILURE); +- user_name, user_id, SHADOW_AUDIT_FAILURE); -#endif fail_exit (E_PW_UPDATE); } #ifdef ENABLE_SUBIDS -@@ -2187,9 +2129,14 @@ static void usr_update (unsigned long su - #endif /* ENABLE_SUBIDS */ - - #ifdef WITH_AUDIT -+ /* -+ * Even though we have the ID of the user, we won't send it now -+ * because its not written to disk yet. After close_files it is -+ * and we can use the real ID thereafter. -+ */ +@@ -2271,7 +2225,7 @@ static void usr_update (unsigned long su + * and we can use the real ID thereafter. + */ audit_logger (AUDIT_ADD_USER, Prog, - "adding user", -- user_name, (unsigned int) user_id, + "add-user", -+ user_name, AUDIT_NO_ID, + user_name, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); #endif - /* -@@ -2279,12 +2226,6 @@ static void create_home (void) - fprintf (stderr, - _("%s: cannot create directory %s\n"), - Prog, path); +@@ -2365,10 +2319,6 @@ static void create_home (void) + if (mkdir(path, 0) != 0) { + fprintf(stderr, _("%s: cannot create directory %s\n"), + Prog, path); -#ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_USER, Prog, -- "adding home directory", -- user_name, (unsigned int) user_id, -- SHADOW_AUDIT_FAILURE); +- audit_logger(AUDIT_ADD_USER, Prog, "adding home directory", +- user_name, user_id, SHADOW_AUDIT_FAILURE); -#endif - fail_exit (E_HOMEDIR); + fail_exit(E_HOMEDIR); } - if (chown (path, 0, 0) < 0) { -@@ -2311,8 +2252,8 @@ static void create_home (void) - } - home_added = true; + if (chown(path, 0, 0) < 0) { +@@ -2393,7 +2343,7 @@ static void create_home (void) + } + home_added = true; #ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_USER, Prog, -- "adding home directory", -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "add-home-dir", - user_name, (unsigned int) user_id, - SHADOW_AUDIT_SUCCESS); +- audit_logger(AUDIT_ADD_USER, Prog, "adding home directory", ++ audit_logger(AUDIT_USER_MGMT, Prog, "add-home-dir", + user_name, user_id, SHADOW_AUDIT_SUCCESS); #endif -@@ -2552,12 +2493,6 @@ int main (int argc, char **argv) + #ifdef WITH_SELINUX +@@ -2637,12 +2587,6 @@ int main (int argc, char **argv) */ if (prefix_getpwnam (user_name) != NULL) { /* local, no need for xgetpwnam */ fprintf (stderr, _("%s: user '%s' already exists\n"), Prog, user_name); @@ -1649,7 +1426,7 @@ diff -up shadow-4.11.1/src/useradd.c.audit-update shadow-4.11.1/src/useradd.c fail_exit (E_NAME_IN_USE); } -@@ -2573,12 +2508,6 @@ int main (int argc, char **argv) +@@ -2658,12 +2602,6 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: group %s exists - if you want to add this user to that group, use -g.\n"), Prog, user_name); @@ -1662,62 +1439,61 @@ diff -up shadow-4.11.1/src/useradd.c.audit-update shadow-4.11.1/src/useradd.c fail_exit (E_NAME_IN_USE); } } -@@ -2608,12 +2537,6 @@ int main (int argc, char **argv) +@@ -2693,12 +2631,6 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: UID %lu is not unique\n"), Prog, (unsigned long) user_id); -#ifdef WITH_AUDIT - audit_logger (AUDIT_ADD_USER, Prog, - "adding user", -- user_name, (unsigned int) user_id, +- user_name, user_id, - SHADOW_AUDIT_FAILURE); -#endif fail_exit (E_UID_IN_USE); } } -@@ -2688,9 +2611,10 @@ int main (int argc, char **argv) +@@ -2773,9 +2705,9 @@ int main (int argc, char **argv) _("%s: warning: the user name %s to %s SELinux user mapping failed.\n"), Prog, user_name, user_selinux); #ifdef WITH_AUDIT - audit_logger (AUDIT_ADD_USER, Prog, - "adding SELinux user mapping", -- user_name, (unsigned int) user_id, 0); +- user_name, user_id, 0); + audit_logger (AUDIT_ROLE_ASSIGN, Prog, + "add-selinux-user-mapping", -+ user_name, (unsigned int) user_id, -+ SHADOW_AUDIT_FAILURE); ++ user_name, user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ fail_exit (E_SE_UPDATE); } -diff -up shadow-4.11.1/src/userdel.c.audit-update shadow-4.11.1/src/userdel.c ---- shadow-4.11.1/src/userdel.c.audit-update 2022-01-03 01:46:53.000000000 +0100 -+++ shadow-4.11.1/src/userdel.c 2022-01-03 14:57:01.787006838 +0100 -@@ -202,9 +202,9 @@ static void update_groups (void) +diff -up shadow-4.14.0/src/userdel.c.audit-update shadow-4.14.0/src/userdel.c +--- shadow-4.14.0/src/userdel.c.audit-update 2023-06-10 02:02:29.000000000 +0200 ++++ shadow-4.14.0/src/userdel.c 2023-08-04 10:26:18.225695416 +0200 +@@ -204,9 +204,9 @@ static void update_groups (void) * Update the DBM group file with the new entry as well. */ #ifdef WITH_AUDIT - audit_logger (AUDIT_DEL_USER, Prog, - "deleting user from group", -- user_name, (unsigned int) user_id, +- user_name, user_id, SHADOW_AUDIT_SUCCESS); + audit_logger_with_group (AUDIT_USER_MGMT, Prog, + "deleting-user-from-group", -+ user_name, (unsigned int) user_id, ngrp->gr_name, - SHADOW_AUDIT_SUCCESS); ++ user_name, user_id, ngrp->gr_name, SHADOW_AUDIT_SUCCESS); #endif /* WITH_AUDIT */ SYSLOG ((LOG_INFO, "delete '%s' from group '%s'\n", -@@ -264,9 +264,9 @@ static void update_groups (void) + user_name, ngrp->gr_name)); +@@ -265,9 +265,9 @@ static void update_groups (void) exit (E_GRP_UPDATE); } #ifdef WITH_AUDIT - audit_logger (AUDIT_DEL_USER, Prog, - "deleting user from shadow group", -- user_name, (unsigned int) user_id, +- user_name, user_id, SHADOW_AUDIT_SUCCESS); + audit_logger_with_group (AUDIT_USER_MGMT, Prog, + "deleting-user-from-shadow-group", -+ user_name, (unsigned int) user_id, nsgrp->sg_name, - SHADOW_AUDIT_SUCCESS); ++ user_name, user_id, nsgrp->sg_name, SHADOW_AUDIT_SUCCESS); #endif /* WITH_AUDIT */ SYSLOG ((LOG_INFO, "delete '%s' from shadow group '%s'\n", + user_name, nsgrp->sg_name)); @@ -343,9 +343,9 @@ static void remove_usergroup (void) } @@ -1750,18 +1526,17 @@ diff -up shadow-4.11.1/src/userdel.c.audit-update shadow-4.11.1/src/userdel.c audit_logger (AUDIT_DEL_USER, Prog, - "deleting user", + "delete-user", - user_name, (unsigned int) user_id, - SHADOW_AUDIT_FAILURE); + user_name, user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -545,24 +545,12 @@ static void open_files (void) + +@@ -544,22 +544,12 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, pw_dbname ()); -#ifdef WITH_AUDIT - audit_logger (AUDIT_DEL_USER, Prog, - "locking password file", -- user_name, (unsigned int) user_id, -- SHADOW_AUDIT_FAILURE); +- user_name, user_id, SHADOW_AUDIT_FAILURE); -#endif /* WITH_AUDIT */ fail_exit (E_PW_UPDATE); } @@ -1772,47 +1547,43 @@ diff -up shadow-4.11.1/src/userdel.c.audit-update shadow-4.11.1/src/userdel.c -#ifdef WITH_AUDIT - audit_logger (AUDIT_DEL_USER, Prog, - "opening password file", -- user_name, (unsigned int) user_id, -- SHADOW_AUDIT_FAILURE); +- user_name, user_id, SHADOW_AUDIT_FAILURE); -#endif /* WITH_AUDIT */ fail_exit (E_PW_UPDATE); } if (is_shadow_pwd) { -@@ -570,12 +558,6 @@ static void open_files (void) +@@ -567,11 +557,6 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, spw_dbname ()); -#ifdef WITH_AUDIT - audit_logger (AUDIT_DEL_USER, Prog, - "locking shadow password file", -- user_name, (unsigned int) user_id, -- SHADOW_AUDIT_FAILURE); +- user_name, user_id, SHADOW_AUDIT_FAILURE); -#endif /* WITH_AUDIT */ fail_exit (E_PW_UPDATE); } spw_locked = true; -@@ -583,12 +565,6 @@ static void open_files (void) +@@ -579,11 +564,6 @@ static void open_files (void) fprintf (stderr, _("%s: cannot open %s\n"), Prog, spw_dbname ()); -#ifdef WITH_AUDIT - audit_logger (AUDIT_DEL_USER, Prog, - "opening shadow password file", -- user_name, (unsigned int) user_id, -- SHADOW_AUDIT_FAILURE); +- user_name, user_id, SHADOW_AUDIT_FAILURE); -#endif /* WITH_AUDIT */ fail_exit (E_PW_UPDATE); } } -@@ -596,23 +572,11 @@ static void open_files (void) +@@ -591,21 +571,11 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, gr_dbname ()); -#ifdef WITH_AUDIT - audit_logger (AUDIT_DEL_USER, Prog, - "locking group file", -- user_name, (unsigned int) user_id, -- SHADOW_AUDIT_FAILURE); +- user_name, user_id, SHADOW_AUDIT_FAILURE); -#endif /* WITH_AUDIT */ fail_exit (E_GRP_UPDATE); } @@ -1822,21 +1593,19 @@ diff -up shadow-4.11.1/src/userdel.c.audit-update shadow-4.11.1/src/userdel.c -#ifdef WITH_AUDIT - audit_logger (AUDIT_DEL_USER, Prog, - "opening group file", -- user_name, (unsigned int) user_id, -- SHADOW_AUDIT_FAILURE); +- user_name, user_id, SHADOW_AUDIT_FAILURE); -#endif /* WITH_AUDIT */ fail_exit (E_GRP_UPDATE); } #ifdef SHADOWGRP -@@ -621,24 +585,12 @@ static void open_files (void) +@@ -614,22 +584,12 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, sgr_dbname ()); -#ifdef WITH_AUDIT - audit_logger (AUDIT_DEL_USER, Prog, - "locking shadow group file", -- user_name, (unsigned int) user_id, -- SHADOW_AUDIT_FAILURE); +- user_name, user_id, SHADOW_AUDIT_FAILURE); -#endif /* WITH_AUDIT */ fail_exit (E_GRP_UPDATE); } @@ -1847,21 +1616,19 @@ diff -up shadow-4.11.1/src/userdel.c.audit-update shadow-4.11.1/src/userdel.c -#ifdef WITH_AUDIT - audit_logger (AUDIT_DEL_USER, Prog, - "opening shadow group file", -- user_name, (unsigned int) user_id, -- SHADOW_AUDIT_FAILURE); +- user_name, user_id, SHADOW_AUDIT_FAILURE); -#endif /* WITH_AUDIT */ fail_exit (E_GRP_UPDATE); } } -@@ -649,24 +601,12 @@ static void open_files (void) +@@ -640,22 +600,12 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, sub_uid_dbname ()); -#ifdef WITH_AUDIT - audit_logger (AUDIT_DEL_USER, Prog, - "locking subordinate user file", -- user_name, (unsigned int) user_id, -- SHADOW_AUDIT_FAILURE); +- user_name, user_id, SHADOW_AUDIT_FAILURE); -#endif /* WITH_AUDIT */ fail_exit (E_SUB_UID_UPDATE); } @@ -1872,21 +1639,19 @@ diff -up shadow-4.11.1/src/userdel.c.audit-update shadow-4.11.1/src/userdel.c -#ifdef WITH_AUDIT - audit_logger (AUDIT_DEL_USER, Prog, - "opening subordinate user file", -- user_name, (unsigned int) user_id, -- SHADOW_AUDIT_FAILURE); +- user_name, user_id, SHADOW_AUDIT_FAILURE); -#endif /* WITH_AUDIT */ fail_exit (E_SUB_UID_UPDATE); } } -@@ -675,24 +615,12 @@ static void open_files (void) +@@ -664,22 +614,12 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, sub_gid_dbname ()); -#ifdef WITH_AUDIT - audit_logger (AUDIT_DEL_USER, Prog, - "locking subordinate group file", -- user_name, (unsigned int) user_id, -- SHADOW_AUDIT_FAILURE); +- user_name, user_id, SHADOW_AUDIT_FAILURE); -#endif /* WITH_AUDIT */ fail_exit (E_SUB_GID_UPDATE); } @@ -1897,40 +1662,39 @@ diff -up shadow-4.11.1/src/userdel.c.audit-update shadow-4.11.1/src/userdel.c -#ifdef WITH_AUDIT - audit_logger (AUDIT_DEL_USER, Prog, - "opening subordinate group file", -- user_name, (unsigned int) user_id, -- SHADOW_AUDIT_FAILURE); +- user_name, user_id, SHADOW_AUDIT_FAILURE); -#endif /* WITH_AUDIT */ fail_exit (E_SUB_GID_UPDATE); } } -@@ -737,7 +665,7 @@ static void update_user (void) +@@ -724,7 +664,7 @@ static void update_user (void) #endif /* ENABLE_SUBIDS */ #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, - "deleting user entries", + "delete-user", - user_name, (unsigned int) user_id, - SHADOW_AUDIT_SUCCESS); + user_name, user_id, SHADOW_AUDIT_SUCCESS); #endif /* WITH_AUDIT */ -@@ -845,7 +773,7 @@ static int remove_mailbox (void) + SYSLOG ((LOG_INFO, "delete user '%s'\n", user_name)); +@@ -831,7 +771,7 @@ static int remove_mailbox (void) SYSLOG ((LOG_ERR, "Cannot remove %s: %s", mailfile, strerror (errno))); #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, - "deleting mail file", + "delete-mail-file", - user_name, (unsigned int) user_id, - SHADOW_AUDIT_FAILURE); + user_name, user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -862,7 +790,7 @@ static int remove_mailbox (void) + free(mailfile); +@@ -847,7 +787,7 @@ static int remove_mailbox (void) SYSLOG ((LOG_ERR, "Cannot remove %s: %s", mailfile, strerror (errno))); #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, - "deleting mail file", + "delete-mail-file", - user_name, (unsigned int) user_id, - SHADOW_AUDIT_FAILURE); + user_name, user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -872,8 +800,8 @@ static int remove_mailbox (void) + errors = 1; +@@ -856,8 +796,8 @@ static int remove_mailbox (void) #ifdef WITH_AUDIT else { @@ -1938,28 +1702,28 @@ diff -up shadow-4.11.1/src/userdel.c.audit-update shadow-4.11.1/src/userdel.c - "deleting mail file", + audit_logger (AUDIT_USER_MGMT, Prog, + "delete-mail-file", - user_name, (unsigned int) user_id, - SHADOW_AUDIT_SUCCESS); + user_name, user_id, SHADOW_AUDIT_SUCCESS); } -@@ -891,7 +819,7 @@ static int remove_mailbox (void) + #endif /* WITH_AUDIT */ +@@ -874,7 +814,7 @@ static int remove_mailbox (void) mailfile, strerror (errno))); #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, - "deleting mail file", + "delete-mail-file", - user_name, (unsigned int) user_id, - SHADOW_AUDIT_FAILURE); + user_name, user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -908,7 +836,7 @@ static int remove_mailbox (void) + free(mailfile); +@@ -890,7 +830,7 @@ static int remove_mailbox (void) SYSLOG ((LOG_ERR, "Cannot remove %s: %s", mailfile, strerror (errno))); #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, - "deleting mail file", + "delete-mail-file", - user_name, (unsigned int) user_id, - SHADOW_AUDIT_FAILURE); + user_name, user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -918,8 +846,8 @@ static int remove_mailbox (void) + errors = 1; +@@ -899,8 +839,8 @@ static int remove_mailbox (void) #ifdef WITH_AUDIT else { @@ -1967,10 +1731,10 @@ diff -up shadow-4.11.1/src/userdel.c.audit-update shadow-4.11.1/src/userdel.c - "deleting mail file", + audit_logger (AUDIT_USER_MGMT, Prog, + "delete-mail-file", - user_name, (unsigned int) user_id, - SHADOW_AUDIT_SUCCESS); + user_name, user_id, SHADOW_AUDIT_SUCCESS); } -@@ -1138,7 +1066,7 @@ int main (int argc, char **argv) + #endif /* WITH_AUDIT */ +@@ -1118,7 +1058,7 @@ int main (int argc, char **argv) Prog, user_name); #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, @@ -1979,7 +1743,7 @@ diff -up shadow-4.11.1/src/userdel.c.audit-update shadow-4.11.1/src/userdel.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -1194,7 +1122,7 @@ int main (int argc, char **argv) +@@ -1174,7 +1114,7 @@ int main (int argc, char **argv) if (!fflg) { #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, @@ -1988,7 +1752,7 @@ diff -up shadow-4.11.1/src/userdel.c.audit-update shadow-4.11.1/src/userdel.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -1288,8 +1216,8 @@ int main (int argc, char **argv) +@@ -1268,8 +1208,8 @@ int main (int argc, char **argv) #ifdef WITH_AUDIT else { @@ -1996,10 +1760,10 @@ diff -up shadow-4.11.1/src/userdel.c.audit-update shadow-4.11.1/src/userdel.c - "deleting home directory", + audit_logger (AUDIT_USER_MGMT, Prog, + "deleting-home-directory", - user_name, (unsigned int) user_id, - SHADOW_AUDIT_SUCCESS); + user_name, user_id, SHADOW_AUDIT_SUCCESS); } -@@ -1298,7 +1226,7 @@ int main (int argc, char **argv) + #endif /* WITH_AUDIT */ +@@ -1277,7 +1217,7 @@ int main (int argc, char **argv) #ifdef WITH_AUDIT if (0 != errors) { audit_logger (AUDIT_DEL_USER, Prog, @@ -2008,7 +1772,7 @@ diff -up shadow-4.11.1/src/userdel.c.audit-update shadow-4.11.1/src/userdel.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); } -@@ -1311,8 +1239,8 @@ int main (int argc, char **argv) +@@ -1290,8 +1230,8 @@ int main (int argc, char **argv) _("%s: warning: the user name %s to SELinux user mapping removal failed.\n"), Prog, user_name); #ifdef WITH_AUDIT @@ -2016,66 +1780,61 @@ diff -up shadow-4.11.1/src/userdel.c.audit-update shadow-4.11.1/src/userdel.c - "removing SELinux user mapping", + audit_logger (AUDIT_ROLE_REMOVE, Prog, + "delete-selinux-user-mapping", - user_name, (unsigned int) user_id, - SHADOW_AUDIT_FAILURE); + user_name, user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -diff -up shadow-4.11.1/src/usermod.c.audit-update shadow-4.11.1/src/usermod.c ---- shadow-4.11.1/src/usermod.c.audit-update 2022-01-03 14:57:01.776006769 +0100 -+++ shadow-4.11.1/src/usermod.c 2022-01-03 15:28:16.959101706 +0100 -@@ -417,8 +417,8 @@ static char *new_pw_passwd (char *pw_pas + fail_exit (E_SE_UPDATE); +diff -up shadow-4.14.0/src/usermod.c.audit-update shadow-4.14.0/src/usermod.c +--- shadow-4.14.0/src/usermod.c.audit-update 2023-07-30 12:38:39.000000000 +0200 ++++ shadow-4.14.0/src/usermod.c 2023-08-04 10:33:04.601749324 +0200 +@@ -427,7 +427,7 @@ static char *new_pw_passwd (char *pw_pas #ifdef WITH_AUDIT audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "updating passwd", -- user_newname, (unsigned int) user_newid, 0); -+ "updating-password", -+ user_newname, (unsigned int) user_newid, 1); +- "updating passwd", user_newname, user_newid, 0); ++ "updating-passwd", user_newname, user_newid, 1); #endif SYSLOG ((LOG_INFO, "lock user '%s' password", user_newname)); strcpy (buf, "!"); -@@ -437,8 +437,8 @@ static char *new_pw_passwd (char *pw_pas +@@ -444,14 +444,14 @@ static char *new_pw_passwd (char *pw_pas #ifdef WITH_AUDIT audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "updating password", -- user_newname, (unsigned int) user_newid, 0); -+ "updating-password", -+ user_newname, (unsigned int) user_newid, 1); +- "updating password", user_newname, user_newid, 0); ++ "updating-password", user_newname, user_newid, 1); #endif SYSLOG ((LOG_INFO, "unlock user '%s' password", user_newname)); - s = pw_pass; -@@ -449,7 +449,7 @@ static char *new_pw_passwd (char *pw_pas + memmove(pw_pass, pw_pass + 1, strlen(pw_pass)); } else if (pflg) { #ifdef WITH_AUDIT audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "changing password", -+ "updating-password", - user_newname, (unsigned int) user_newid, 1); +- "changing password", user_newname, user_newid, 1); ++ "updating-password", user_newname, user_newid, 1); #endif SYSLOG ((LOG_INFO, "change user '%s' password", user_newname)); -@@ -478,8 +478,8 @@ static void new_pwent (struct passwd *pw + pw_pass = xstrdup (user_pass); +@@ -479,8 +479,8 @@ static void new_pwent (struct passwd *pw fail_exit (E_NAME_IN_USE); } #ifdef WITH_AUDIT - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "changing name", +- "changing name", user_newname, user_newid, 1); + audit_logger (AUDIT_USER_MGMT, Prog, -+ "changing-name", - user_newname, (unsigned int) user_newid, 1); ++ "changing-name", user_newname, user_newid, 1); #endif SYSLOG ((LOG_INFO, + "change user name '%s' to '%s'", @@ -499,8 +499,8 @@ static void new_pwent (struct passwd *pw if (uflg) { #ifdef WITH_AUDIT - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "changing uid", +- "changing uid", user_newname, user_newid, 1); + audit_logger (AUDIT_USER_MGMT, Prog, -+ "changing-uid", - user_newname, (unsigned int) user_newid, 1); ++ "changing-uid", user_newname, user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -510,8 +510,8 @@ static void new_pwent (struct passwd *pw + "change user '%s' UID from '%d' to '%d'", +@@ -509,8 +509,8 @@ static void new_pwent (struct passwd *pw } if (gflg) { #ifdef WITH_AUDIT @@ -2083,21 +1842,20 @@ diff -up shadow-4.11.1/src/usermod.c.audit-update shadow-4.11.1/src/usermod.c - "changing primary group", + audit_logger (AUDIT_USER_MGMT, Prog, + "changing-primary-group", - user_newname, (unsigned int) user_newid, 1); + user_newname, user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -521,8 +521,8 @@ static void new_pwent (struct passwd *pw +@@ -520,16 +520,16 @@ static void new_pwent (struct passwd *pw } if (cflg) { #ifdef WITH_AUDIT - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "changing comment", +- "changing comment", user_newname, user_newid, 1); + audit_logger (AUDIT_USER_MGMT, Prog, -+ "changing-comment", - user_newname, (unsigned int) user_newid, 1); ++ "changing-comment", user_newname, user_newid, 1); #endif pwent->pw_gecos = user_newcomment; -@@ -530,8 +530,8 @@ static void new_pwent (struct passwd *pw + } if (dflg) { #ifdef WITH_AUDIT @@ -2105,10 +1863,10 @@ diff -up shadow-4.11.1/src/usermod.c.audit-update shadow-4.11.1/src/usermod.c - "changing home directory", + audit_logger (AUDIT_USER_MGMT, Prog, + "changing-home-dir", - user_newname, (unsigned int) user_newid, 1); + user_newname, user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -547,8 +547,8 @@ static void new_pwent (struct passwd *pw +@@ -545,8 +545,8 @@ static void new_pwent (struct passwd *pw } if (sflg) { #ifdef WITH_AUDIT @@ -2116,10 +1874,10 @@ diff -up shadow-4.11.1/src/usermod.c.audit-update shadow-4.11.1/src/usermod.c - "changing user shell", + audit_logger (AUDIT_USER_MGMT, Prog, + "changing-shell", - user_newname, (unsigned int) user_newid, 1); + user_newname, user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -578,8 +578,8 @@ static void new_spent (struct spwd *spen +@@ -576,8 +576,8 @@ static void new_spent (struct spwd *spen if (fflg) { #ifdef WITH_AUDIT @@ -2127,10 +1885,10 @@ diff -up shadow-4.11.1/src/usermod.c.audit-update shadow-4.11.1/src/usermod.c - "changing inactive days", + audit_logger (AUDIT_USER_MGMT, Prog, + "changing-inactive-days", - user_newname, (unsigned int) user_newid, 1); + user_newname, user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -593,8 +593,8 @@ static void new_spent (struct spwd *spen +@@ -591,8 +591,8 @@ static void new_spent (struct spwd *spen date_to_str (sizeof(new_exp), new_exp, user_newexpire * DAY); date_to_str (sizeof(old_exp), old_exp, user_expire * DAY); #ifdef WITH_AUDIT @@ -2138,10 +1896,10 @@ diff -up shadow-4.11.1/src/usermod.c.audit-update shadow-4.11.1/src/usermod.c - "changing expiration date", + audit_logger (AUDIT_USER_MGMT, Prog, + "changing-expiration-date", - user_newname, (unsigned int) user_newid, 1); + user_newname, user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -677,9 +677,9 @@ static /*@noreturn@*/void fail_exit (int +@@ -677,9 +677,9 @@ fail_exit (int code) #endif /* ENABLE_SUBIDS */ #ifdef WITH_AUDIT @@ -2256,7 +2014,7 @@ diff -up shadow-4.11.1/src/usermod.c.audit-update shadow-4.11.1/src/usermod.c #endif SYSLOG ((LOG_INFO, "add '%s' to shadow group '%s'", user_newname, nsgrp->sg_name)); -@@ -1817,8 +1828,8 @@ static void move_home (void) +@@ -1830,8 +1841,8 @@ static void move_home (void) #ifdef WITH_AUDIT if (uflg || gflg) { @@ -2264,10 +2022,10 @@ diff -up shadow-4.11.1/src/usermod.c.audit-update shadow-4.11.1/src/usermod.c - "changing home directory owner", + audit_logger (AUDIT_USER_MGMT, Prog, + "updating-home-dir-owner", - user_newname, (unsigned int) user_newid, 1); + user_newname, user_newid, 1); } #endif -@@ -1836,8 +1847,8 @@ static void move_home (void) +@@ -1849,8 +1860,8 @@ static void move_home (void) fail_exit (E_HOMEDIR); } #ifdef WITH_AUDIT @@ -2275,10 +2033,10 @@ diff -up shadow-4.11.1/src/usermod.c.audit-update shadow-4.11.1/src/usermod.c - "moving home directory", + audit_logger (AUDIT_USER_MGMT, Prog, + "moving-home-dir", - user_newname, (unsigned int) user_newid, - 1); + user_newname, user_newid, 1); #endif -@@ -1865,9 +1876,9 @@ static void move_home (void) + return; +@@ -1877,9 +1888,9 @@ static void move_home (void) Prog, prefix_user_home); } #ifdef WITH_AUDIT @@ -2288,9 +2046,9 @@ diff -up shadow-4.11.1/src/usermod.c.audit-update shadow-4.11.1/src/usermod.c - "moving home directory", + "moving-home-dir", user_newname, - (unsigned int) user_newid, + user_newid, 1); -@@ -2085,8 +2096,8 @@ static void move_mailbox (void) +@@ -2100,8 +2111,8 @@ static void move_mailbox (void) } #ifdef WITH_AUDIT else { @@ -2298,10 +2056,10 @@ diff -up shadow-4.11.1/src/usermod.c.audit-update shadow-4.11.1/src/usermod.c - "changing mail file owner", + audit_logger (AUDIT_USER_MGMT, Prog, + "updating-mail-file-owner", - user_newname, (unsigned int) user_newid, 1); + user_newname, user_newid, 1); } #endif -@@ -2112,8 +2123,8 @@ static void move_mailbox (void) +@@ -2129,8 +2140,8 @@ static void move_mailbox (void) } #ifdef WITH_AUDIT else { @@ -2309,10 +2067,10 @@ diff -up shadow-4.11.1/src/usermod.c.audit-update shadow-4.11.1/src/usermod.c - "changing mail file name", + audit_logger (AUDIT_USER_MGMT, Prog, + "updating-mail-file-name", - user_newname, (unsigned int) user_newid, 1); + user_newname, user_newid, 1); } - #endif -@@ -2310,8 +2321,8 @@ int main (int argc, char **argv) + +@@ -2331,8 +2342,8 @@ int main (int argc, char **argv) _("%s: warning: the user name %s to %s SELinux user mapping failed.\n"), Prog, user_name, user_selinux); #ifdef WITH_AUDIT @@ -2320,10 +2078,10 @@ diff -up shadow-4.11.1/src/usermod.c.audit-update shadow-4.11.1/src/usermod.c - "modifying User mapping ", + audit_logger (AUDIT_ROLE_ASSIGN, Prog, + "changing-selinux-user-mapping ", - user_name, (unsigned int) user_id, + user_name, user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -2323,8 +2334,8 @@ int main (int argc, char **argv) +@@ -2344,8 +2355,8 @@ int main (int argc, char **argv) _("%s: warning: the user name %s to SELinux user mapping removal failed.\n"), Prog, user_name); #ifdef WITH_AUDIT @@ -2331,10 +2089,10 @@ diff -up shadow-4.11.1/src/usermod.c.audit-update shadow-4.11.1/src/usermod.c - "removing SELinux user mapping", + audit_logger (AUDIT_ROLE_REMOVE, Prog, + "delete-selinux-user-mapping", - user_name, (unsigned int) user_id, + user_name, user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -2365,8 +2376,8 @@ int main (int argc, char **argv) +@@ -2388,8 +2399,8 @@ int main (int argc, char **argv) */ #ifdef WITH_AUDIT if (uflg || gflg) { @@ -2342,6 +2100,6 @@ diff -up shadow-4.11.1/src/usermod.c.audit-update shadow-4.11.1/src/usermod.c - "changing home directory owner", + audit_logger (AUDIT_USER_MGMT, Prog, + "updating-home-dir-owner", - user_newname, (unsigned int) user_newid, 1); + user_newname, user_newid, 1); } #endif diff --git a/shadow-4.9-manfix.patch b/shadow-4.14.0-manfix.patch similarity index 99% rename from shadow-4.9-manfix.patch rename to shadow-4.14.0-manfix.patch index 46cba1a..70f030e 100644 --- a/shadow-4.9-manfix.patch +++ b/shadow-4.14.0-manfix.patch @@ -19,7 +19,7 @@ diff -up shadow-4.8.1/man/groupmems.8.xml.manfix shadow-4.8.1/man/groupmems.8.xm - - $ groupadd -r groups - $ chmod 2710 groupmems -- $ chown root.groups groupmems +- $ chown root:groups groupmems - $ groupmems -g groups -a gk4 - diff --git a/shadow-4.5-usermod-unlock.patch b/shadow-4.5-usermod-unlock.patch deleted file mode 100644 index e2d70b5..0000000 --- a/shadow-4.5-usermod-unlock.patch +++ /dev/null @@ -1,64 +0,0 @@ -Index: shadow-4.5/src/usermod.c -=================================================================== ---- shadow-4.5.orig/src/usermod.c -+++ shadow-4.5/src/usermod.c -@@ -455,14 +455,17 @@ static char *new_pw_passwd (char *pw_pas - strcat (buf, pw_pass); - pw_pass = buf; - } else if (Uflg && pw_pass[0] == '!') { -- char *s; -+ char *s = pw_pass; - -- if (pw_pass[1] == '\0') { -+ while ('!' == *s) -+ ++s; -+ -+ if (*s == '\0') { - fprintf (stderr, - _("%s: unlocking the user's password would result in a passwordless account.\n" - "You should set a password with usermod -p to unlock this user's password.\n"), - Prog); -- return pw_pass; -+ return NULL; - } - - #ifdef WITH_AUDIT -@@ -471,12 +474,15 @@ static char *new_pw_passwd (char *pw_pas - user_newname, (unsigned int) user_newid, 1); - #endif - SYSLOG ((LOG_INFO, "unlock user '%s' password", user_newname)); -- s = pw_pass; -- while ('\0' != *s) { -- *s = *(s + 1); -- s++; -- } -+ memmove (pw_pass, s, strlen (s) + 1); - } else if (pflg) { -+ if (strchr (user_pass, ':') != NULL) { -+ fprintf (stderr, -+ _("%s: The password field cannot contain a colon character.\n"), -+ Prog); -+ return NULL; -+ -+ } - #ifdef WITH_AUDIT - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, - "updating-password", -@@ -525,6 +531,8 @@ static void new_pwent (struct passwd *pw - if ( (!is_shadow_pwd) - || (strcmp (pwent->pw_passwd, SHADOW_PASSWD_STRING) != 0)) { - pwent->pw_passwd = new_pw_passwd (pwent->pw_passwd); -+ if (pwent->pw_passwd == NULL) -+ fail_exit (E_PW_UPDATE); - } - - if (uflg) { -@@ -639,6 +647,8 @@ static void new_spent (struct spwd *spen - * + aging has been requested - */ - spent->sp_pwdp = new_pw_passwd (spent->sp_pwdp); -+ if (spent->sp_pwdp == NULL) -+ fail_exit(E_PW_UPDATE); - - if (pflg) { - spent->sp_lstchg = (long) gettime () / SCALE; diff --git a/shadow-utils.spec b/shadow-utils.spec index 8ee19af..74f4ec6 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils -Version: 4.13 -Release: 8%{?dist} +Version: 4.14.0 +Release: 1%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -17,27 +17,12 @@ Source6: shadow-utils.HOME_MODE.xml %global includesubiddir %{_includedir}/shadow ### Patches ### -# Misc small changes - most probably non-upstreamable -Patch0: shadow-4.12.3-redhat.patch -# SElinux related - upstreamability unknown -Patch1: shadow-4.13-default-range.patch # Misc manual page changes - non-upstreamable -Patch2: shadow-4.9-manfix.patch +Patch0: shadow-4.14.0-manfix.patch # Date parsing improvement - could be upstreamed -Patch3: shadow-4.2.1-date-parsing.patch +Patch1: shadow-4.2.1-date-parsing.patch # Audit message changes - partially upstreamed -# https://github.com/shadow-maint/shadow/commit/37412f505ed0bc5c9e3f04b2266b40f8f6fc310f -Patch4: shadow-4.11.1-audit-update.patch -# Changes related to password unlocking - could be upstreamed -Patch5: shadow-4.5-usermod-unlock.patch -# Additional SElinux related changes - upstreamability unknown -Patch6: shadow-4.12.3-selinux-perms.patch -# https://github.com/shadow-maint/shadow/commit/a281f241b592aec636d1b93a99e764499d68c7ef -Patch7: shadow-utils-configure-gshadow.patch -# https://github.com/shadow-maint/shadow/commit/6974df39a708abf8bafbdfa2b7827e0f70f874cb -# https://github.com/shadow-maint/shadow/commit/7ff33fae6f9cd79c0e012671c37a172e9a681d0b -# https://github.com/shadow-maint/shadow/commit/05e2adf509ba0e3779dae66a276b86927a8e1e0e -Patch8: shadow-4.13-newidmap-support-passing-pid-as-fd.patch +Patch2: shadow-4.14.0-audit-update.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -129,10 +114,13 @@ autoreconf --with-bcrypt \ --with-yescrypt \ --with-selinux \ + --without-libbsd \ --without-libcrack \ --without-libpam \ --enable-shared \ - --with-group-name-max-length=32 + --with-group-name-max-length=32 \ + --enable-lastlog \ + --enable-logind=no %make_build %install @@ -273,6 +261,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Wed Aug 16 2023 Iker Pedrosa - 2:4.14.0-1 +- Rebase to version 4.14.0. Resolves: #2229000 + * Sat Jul 22 2023 Fedora Release Engineering - 2:4.13-8 - Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild diff --git a/sources b/sources index 40bac31..1ec1caa 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (shadow-4.13.tar.xz) = 2949a728c3312bef13d23138d6b79caf402781b1cb179e33b5be546c1790971ec20778d0e9cd3dbe09691d928ffcbe88e60da42fab58c69a90d5ebe5e3e2ab8e -SHA512 (shadow-4.13.tar.xz.asc) = f8549c4e699c65721d53946d61b6127712572f7ad9ee13018ef3a25307002992aa727471c948d1bb22dcddf112715bed387d28f436123f30e153ae6bc0cd3648 +SHA512 (shadow-4.14.0.tar.xz) = ff960481d576f9db5a9f10becc4e1a74c03de484ecfdcd7f1ea735fded683d7ba0f9cd895dc6a431b77e5a633752273178b1bcda4cefaa5adbf0f143c9a0c86f +SHA512 (shadow-4.14.0.tar.xz.asc) = d011a732d73b4b066ca8d204c0420303f925c87efc7655feb5c5f60b619d67da450e220ee44f6c86929ae79cbd4343136fe9c20d25b39fa0a228a48e57636309 From b2b4416387c3424380e5efcaa20e1a100406b8e1 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Tue, 3 Oct 2023 09:59:47 +0200 Subject: [PATCH 075/134] useradd: Set proper SELinux labels for def_usrtemplate Signed-off-by: Iker Pedrosa --- ...seradd-def-usrtemplate-selinux-label.patch | 28 +++++++++++++++++++ shadow-utils.spec | 7 ++++- 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 shadow-4.14.0-useradd-def-usrtemplate-selinux-label.patch diff --git a/shadow-4.14.0-useradd-def-usrtemplate-selinux-label.patch b/shadow-4.14.0-useradd-def-usrtemplate-selinux-label.patch new file mode 100644 index 0000000..97b709a --- /dev/null +++ b/shadow-4.14.0-useradd-def-usrtemplate-selinux-label.patch @@ -0,0 +1,28 @@ +From 48aa12af31c0b72872b411857d03a518a4200a3d Mon Sep 17 00:00:00 2001 +From: Johannes Segitz +Date: Tue, 26 Sep 2023 15:14:14 +0200 +Subject: [PATCH] useradd: Set proper SELinux labels for def_usrtemplate + +Fixes: 74c17c716 ("Add support for skeleton files from /usr/etc/skel") + +Signed-off-by: Johannes Segitz +--- + src/useradd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/useradd.c b/src/useradd.c +index 76a4d649..fe62a051 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -2788,7 +2788,7 @@ int main (int argc, char **argv) + if (home_added) { + copy_tree (def_template, prefix_user_home, false, true, + (uid_t)-1, user_id, (gid_t)-1, user_gid); +- copy_tree (def_usrtemplate, prefix_user_home, false, false, ++ copy_tree (def_usrtemplate, prefix_user_home, false, true, + (uid_t)-1, user_id, (gid_t)-1, user_gid); + } else { + fprintf (stderr, +-- +2.41.0 + diff --git a/shadow-utils.spec b/shadow-utils.spec index 74f4ec6..49a7819 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.14.0 -Release: 1%{?dist} +Release: 2%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -23,6 +23,8 @@ Patch0: shadow-4.14.0-manfix.patch Patch1: shadow-4.2.1-date-parsing.patch # Audit message changes - partially upstreamed Patch2: shadow-4.14.0-audit-update.patch +# https://github.com/shadow-maint/shadow/pull/812 +Patch3: shadow-4.14.0-useradd-def-usrtemplate-selinux-label.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -261,6 +263,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Tue Oct 3 2023 Iker Pedrosa - 2:4.14.0-2 +- useradd: Set proper SELinux labels for def_usrtemplate + * Wed Aug 16 2023 Iker Pedrosa - 2:4.14.0-1 - Rebase to version 4.14.0. Resolves: #2229000 From d5da1a5785e9955df3119cffb836dbc191ad0d49 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Sat, 27 Jan 2024 02:49:28 +0000 Subject: [PATCH 076/134] Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild --- shadow-utils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index 49a7819..22ecf32 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.14.0 -Release: 2%{?dist} +Release: 3%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -263,6 +263,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Sat Jan 27 2024 Fedora Release Engineering - 2:4.14.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + * Tue Oct 3 2023 Iker Pedrosa - 2:4.14.0-2 - useradd: Set proper SELinux labels for def_usrtemplate From 1820858d26f633482d3679d1c97324e25e3c1df8 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Fri, 26 Jan 2024 10:32:23 +0100 Subject: [PATCH 077/134] Disable SSSD support Resolves: #2253182 Signed-off-by: Iker Pedrosa --- shadow-utils.spec | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index 22ecf32..633f1fe 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.14.0 -Release: 3%{?dist} +Release: 4%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -119,6 +119,7 @@ autoreconf --without-libbsd \ --without-libcrack \ --without-libpam \ + --without-sssd \ --enable-shared \ --with-group-name-max-length=32 \ --enable-lastlog \ @@ -263,6 +264,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Mon Jan 29 2024 Iker Pedrosa - 2:4.14.0-4 +- Disable SSSD support. Resolves: #2253182 + * Sat Jan 27 2024 Fedora Release Engineering - 2:4.14.0-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild From 91360f25a8c8b810d59bec2803a2477a2647c775 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Mon, 27 Nov 2023 11:51:16 +0100 Subject: [PATCH 078/134] passwd: Provide binary from this package Provide binary from this package. Enable libpam and disable account-tools-setuid. Provide passwd PAM service file. Finally, provide --stdin option in passwd. Resolves: #2233275 Signed-off-by: Iker Pedrosa --- passwd.pamd | 5 + shadow-4.14.0-account-tools-setuid.patch | 383 +++++++++++++++++++++++ shadow-4.14.0-passwd-stdin.patch | 288 +++++++++++++++++ shadow-4.14.0-remove-libcrack.patch | 306 ++++++++++++++++++ shadow-utils.login.defs | 20 +- shadow-utils.spec | 34 +- 6 files changed, 1026 insertions(+), 10 deletions(-) create mode 100644 passwd.pamd create mode 100644 shadow-4.14.0-account-tools-setuid.patch create mode 100644 shadow-4.14.0-passwd-stdin.patch create mode 100644 shadow-4.14.0-remove-libcrack.patch diff --git a/passwd.pamd b/passwd.pamd new file mode 100644 index 0000000..fd03d03 --- /dev/null +++ b/passwd.pamd @@ -0,0 +1,5 @@ +#%PAM-1.0 +# This tool only uses the password stack. +password substack system-auth +-password optional pam_gnome_keyring.so use_authtok +password substack postlogin diff --git a/shadow-4.14.0-account-tools-setuid.patch b/shadow-4.14.0-account-tools-setuid.patch new file mode 100644 index 0000000..17d8918 --- /dev/null +++ b/shadow-4.14.0-account-tools-setuid.patch @@ -0,0 +1,383 @@ +diff --git a/src/chpasswd.c b/src/chpasswd.c +index 3a4bd4fe..246e4176 100644 +--- a/src/chpasswd.c ++++ b/src/chpasswd.c +@@ -443,9 +443,11 @@ int main (int argc, char **argv) + char *cp; + const char *salt; + ++#ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + bool use_pam = true; + #endif /* USE_PAM */ ++#endif /* ACCT_TOOLS_SETUID */ + + int errors = 0; + int line = 0; +@@ -470,19 +472,23 @@ int main (int argc, char **argv) + process_root_flag ("-R", argc, argv); + prefix = process_prefix_flag ("-P", argc, argv); + ++#ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + if (md5flg || eflg || cflg || prefix[0]) { + use_pam = false; + } + #endif /* USE_PAM */ ++#endif /* ACCT_TOOLS_SETUID */ + + OPENLOG ("chpasswd"); + + check_perms (); + ++#ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + if (!use_pam) + #endif /* USE_PAM */ ++#endif /* ACCT_TOOLS_SETUID */ + { + is_shadow_pwd = spw_file_present (); + +@@ -544,6 +550,7 @@ int main (int argc, char **argv) + } + newpwd = cp; + ++#ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + if (use_pam) { + if (do_pam_passwd_non_interactive ("chpasswd", name, newpwd) != 0) { +@@ -554,6 +561,7 @@ int main (int argc, char **argv) + } + } else + #endif /* USE_PAM */ ++#endif /* ACCT_TOOLS_SETUID */ + { + const struct spwd *sp; + struct spwd newsp; +@@ -673,9 +681,11 @@ int main (int argc, char **argv) + * password database. + */ + if (0 != errors) { ++#ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + if (!use_pam) + #endif /* USE_PAM */ ++#endif /* ACCT_TOOLS_SETUID */ + { + fprintf (stderr, + _("%s: error detected, changes ignored\n"), +@@ -684,9 +694,11 @@ int main (int argc, char **argv) + fail_exit (1); + } + ++#ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + if (!use_pam) + #endif /* USE_PAM */ ++#endif /* ACCT_TOOLS_SETUID */ + { + /* Save the changes */ + close_files (); +diff --git a/src/groupmems.c b/src/groupmems.c +index 63a1601c..73f7310e 100644 +--- a/src/groupmems.c ++++ b/src/groupmems.c +@@ -14,9 +14,11 @@ + #include + #include + #include ++#ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + #include "pam_defs.h" + #endif /* USE_PAM */ ++#endif /* ACCT_TOOLS_SETUID */ + #include + + #include "alloc.h" +@@ -430,6 +432,7 @@ static void process_flags (int argc, char **argv) + static void check_perms (void) + { + if (!list) { ++#ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + pam_handle_t *pamh = NULL; + int retval; +@@ -463,7 +466,8 @@ static void check_perms (void) + fail_exit (1); + } + (void) pam_end (pamh, retval); +-#endif ++#endif /* USE_PAM */ ++#endif /* ACCT_TOOLS_SETUID */ + } + } + +diff --git a/src/newusers.c b/src/newusers.c +index 09e14a48..96b60de2 100644 +--- a/src/newusers.c ++++ b/src/newusers.c +@@ -59,6 +59,7 @@ + const char *Prog; + + static bool rflg = false; /* create a system account */ ++#ifndef ACCT_TOOLS_SETUID + #ifndef USE_PAM + static /*@null@*//*@observer@*/char *crypt_method = NULL; + #define cflg (NULL != crypt_method) +@@ -75,6 +76,7 @@ static long bcrypt_rounds = 13; + static long yescrypt_cost = 5; + #endif /* USE_YESCRYPT */ + #endif /* !USE_PAM */ ++#endif /* !ACCT_TOOLS_SETUID */ + + static bool is_shadow; + #ifdef SHADOWGRP +@@ -97,9 +99,11 @@ NORETURN static void fail_exit (int); + static int add_group (const char *, const char *, gid_t *, gid_t); + static int get_user_id (const char *, uid_t *); + static int add_user (const char *, uid_t, gid_t); ++#ifndef ACCT_TOOLS_SETUID + #ifndef USE_PAM + static int update_passwd (struct passwd *, const char *); + #endif /* !USE_PAM */ ++#endif /* !ACCT_TOOLS_SETUID */ + static int add_passwd (struct passwd *, const char *); + static void process_flags (int argc, char **argv); + static void check_flags (void); +@@ -121,6 +125,7 @@ static void usage (int status) + "Options:\n"), + Prog); + (void) fputs (_(" -b, --badname allow bad names\n"), usageout); ++#ifndef ACCT_TOOLS_SETUID + #ifndef USE_PAM + (void) fprintf (usageout, + _(" -c, --crypt-method METHOD the crypt method (one of %s)\n"), +@@ -136,9 +141,11 @@ static void usage (int status) + #endif + ); + #endif /* !USE_PAM */ ++#endif /* !ACCT_TOOLS_SETUID */ + (void) fputs (_(" -h, --help display this help message and exit\n"), usageout); + (void) fputs (_(" -r, --system create system accounts\n"), usageout); + (void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout); ++#ifndef ACCT_TOOLS_SETUID + #ifndef USE_PAM + #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) + (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT\n" +@@ -146,6 +153,7 @@ static void usage (int status) + usageout); + #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ + #endif /* !USE_PAM */ ++#endif /* !ACCT_TOOLS_SETUID */ + (void) fputs ("\n", usageout); + + exit (status); +@@ -405,6 +413,7 @@ static int add_user (const char *name, uid_t uid, gid_t gid) + return (pw_update (&pwent) == 0) ? -1 : 0; + } + ++#ifndef ACCT_TOOLS_SETUID + #ifndef USE_PAM + /* + * update_passwd - update the password in the passwd entry +@@ -457,6 +466,7 @@ static int update_passwd (struct passwd *pwd, const char *password) + return 0; + } + #endif /* !USE_PAM */ ++#endif /* !ACCT_TOOLS_SETUID */ + + /* + * add_passwd - add or update the encrypted password +@@ -465,10 +475,13 @@ static int add_passwd (struct passwd *pwd, const char *password) + { + const struct spwd *sp; + struct spwd spent; ++#ifndef ACCT_TOOLS_SETUID + #ifndef USE_PAM + char *cp; + #endif /* !USE_PAM */ ++#endif /* !ACCT_TOOLS_SETUID */ + ++#ifndef ACCT_TOOLS_SETUID + #ifndef USE_PAM + void *crypt_arg = NULL; + if (NULL != crypt_method) { +@@ -505,13 +518,14 @@ static int add_passwd (struct passwd *pwd, const char *password) + return update_passwd (pwd, password); + } + #endif /* USE_PAM */ ++#endif /* !ACCT_TOOLS_SETUID */ + + /* + * Do the first and easiest shadow file case. The user already + * exists in the shadow password file. + */ + sp = spw_locate (pwd->pw_name); +-#ifndef USE_PAM ++#if !defined(ACCT_TOOLS_SETUID) && !defined(USE_PAM) + if (NULL != sp) { + spent = *sp; + if ( (NULL != crypt_method) +@@ -547,7 +561,7 @@ static int add_passwd (struct passwd *pwd, const char *password) + if (strcmp (pwd->pw_passwd, "x") != 0) { + return update_passwd (pwd, password); + } +-#else /* USE_PAM */ ++#else /* !ACCT_TOOLS_SETUID && !USE_PAM */ + /* + * If there is already a shadow entry, do not touch it. + * If there is already a passwd entry with a password, do not +@@ -558,14 +572,14 @@ static int add_passwd (struct passwd *pwd, const char *password) + || (strcmp (pwd->pw_passwd, "x") != 0)) { + return 0; + } +-#endif /* USE_PAM */ ++#endif /* !ACCT_TOOLS_SETUID && !USE_PAM */ + + /* + * Now the really hard case - I need to create an entirely new + * shadow password file entry. + */ + spent.sp_namp = pwd->pw_name; +-#ifndef USE_PAM ++#if !defined(ACCT_TOOLS_SETUID) && !defined(USE_PAM) + if ((crypt_method != NULL) && (0 == strcmp(crypt_method, "NONE"))) { + spent.sp_pwdp = (char *)password; + } else { +@@ -610,35 +624,41 @@ static int add_passwd (struct passwd *pwd, const char *password) + static void process_flags (int argc, char **argv) + { + int c; ++#ifndef ACCT_TOOLS_SETUID + #ifndef USE_PAM + #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) + int bad_s; + #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ + #endif /* !USE_PAM */ ++#endif /* !ACCT_TOOLS_SETUID */ + static struct option long_options[] = { + {"badname", no_argument, NULL, 'b'}, ++#ifndef ACCT_TOOLS_SETUID + #ifndef USE_PAM + {"crypt-method", required_argument, NULL, 'c'}, + #endif /* !USE_PAM */ ++#endif /* !ACCT_TOOLS_SETUID */ + {"help", no_argument, NULL, 'h'}, + {"system", no_argument, NULL, 'r'}, + {"root", required_argument, NULL, 'R'}, ++#ifndef ACCT_TOOLS_SETUID + #ifndef USE_PAM + #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) + {"sha-rounds", required_argument, NULL, 's'}, + #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ + #endif /* !USE_PAM */ ++#endif /* !ACCT_TOOLS_SETUID */ + {NULL, 0, NULL, '\0'} + }; + + while ((c = getopt_long (argc, argv, +-#ifndef USE_PAM ++#if !defined(ACCT_TOOLS_SETUID) && !defined(USE_PAM) + #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) + "c:bhrs:", + #else /* !USE_SHA_CRYPT && !USE_BCRYPT && !USE_YESCRYPT */ + "c:bhr", + #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ +-#else /* USE_PAM */ ++#else /* !ACCT_TOOLS_SETUID && !USE_PAM */ + "bhr", + #endif + long_options, NULL)) != -1) { +@@ -646,11 +666,13 @@ static void process_flags (int argc, char **argv) + case 'b': + allow_bad_names = true; + break; ++#ifndef ACCT_TOOLS_SETUID + #ifndef USE_PAM + case 'c': + crypt_method = optarg; + break; + #endif /* !USE_PAM */ ++#endif /* !ACCT_TOOLS_SETUID */ + case 'h': + usage (EXIT_SUCCESS); + break; +@@ -659,6 +681,7 @@ static void process_flags (int argc, char **argv) + break; + case 'R': /* no-op, handled in process_root_flag () */ + break; ++#ifndef ACCT_TOOLS_SETUID + #ifndef USE_PAM + #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) + case 's': +@@ -698,6 +721,7 @@ static void process_flags (int argc, char **argv) + break; + #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ + #endif /* !USE_PAM */ ++#endif /* !ACCT_TOOLS_SETUID */ + default: + usage (EXIT_FAILURE); + break; +@@ -730,6 +754,7 @@ static void process_flags (int argc, char **argv) + */ + static void check_flags (void) + { ++#ifndef ACCT_TOOLS_SETUID + #ifndef USE_PAM + #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) + if (sflg && !cflg) { +@@ -762,6 +787,7 @@ static void check_flags (void) + } + } + #endif /* !USE_PAM */ ++#endif /* !ACCT_TOOLS_SETUID */ + } + + /* +@@ -1052,12 +1078,14 @@ int main (int argc, char **argv) + int line = 0; + uid_t uid; + gid_t gid; ++#ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + int *lines = NULL; + char **usernames = NULL; + char **passwords = NULL; + unsigned int nusers = 0; + #endif /* USE_PAM */ ++#endif /* ACCT_TOOLS_SETUID */ + + Prog = Basename (argv[0]); + log_set_progname(Prog); +@@ -1196,6 +1224,7 @@ int main (int argc, char **argv) + } + newpw = *pw; + ++#ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + /* keep the list of user/password for later update by PAM */ + nusers++; +@@ -1212,6 +1241,7 @@ int main (int argc, char **argv) + usernames[nusers-1] = strdup (fields[0]); + passwords[nusers-1] = strdup (fields[1]); + #endif /* USE_PAM */ ++#endif /* ACCT_TOOLS_SETUID */ + if (add_passwd (&newpw, fields[1]) != 0) { + fprintf (stderr, + _("%s: line %d: can't update password\n"), +@@ -1328,6 +1358,7 @@ int main (int argc, char **argv) + nscd_flush_cache ("group"); + sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP); + ++#ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + unsigned int i; + /* Now update the passwords using PAM */ +@@ -1340,6 +1371,7 @@ int main (int argc, char **argv) + } + } + #endif /* USE_PAM */ ++#endif /* ACCT_TOOLS_SETUID */ + + exit (EXIT_SUCCESS); + } diff --git a/shadow-4.14.0-passwd-stdin.patch b/shadow-4.14.0-passwd-stdin.patch new file mode 100644 index 0000000..2603350 --- /dev/null +++ b/shadow-4.14.0-passwd-stdin.patch @@ -0,0 +1,288 @@ +diff -up shadow-4.14.0/libmisc/agetpass.c.orig shadow-4.14.0/libmisc/agetpass.c +--- shadow-4.14.0/libmisc/agetpass.c.orig 2024-01-24 20:06:20.557577853 +0100 ++++ shadow-4.14.0/libmisc/agetpass.c 2024-01-24 21:21:06.379445080 +0100 +@@ -32,6 +32,7 @@ + * SYNOPSIS + * [[gnu::malloc(erase_pass)]] + * char *agetpass(const char *prompt); ++ * char *agetpass_stdin(); + * + * void erase_pass(char *pass); + * +@@ -64,6 +65,10 @@ + * erased by calling erase_pass(), to avoid possibly leaking the + * password. + * ++ * agetpass_stdin() ++ * This function is the same as previous one (agetpass). Just the ++ * password is read from stdin and terminal is not required. ++ * + * erase_pass() + * This function first clears the password, by calling + * explicit_bzero(3) (or an equivalent call), and then frees the +@@ -92,8 +97,8 @@ + */ + + +-char * +-agetpass(const char *prompt) ++static char * ++agetpass_internal(const char *prompt, int flags) + { + char *pass; + size_t len; +@@ -110,7 +115,7 @@ agetpass(const char *prompt) + if (pass == NULL) + return NULL; + +- if (readpassphrase(prompt, pass, PASS_MAX + 2, RPP_REQUIRE_TTY) == NULL) ++ if (readpassphrase(prompt, pass, PASS_MAX + 2, flags) == NULL) + goto fail; + + len = strlen(pass); +@@ -126,6 +131,17 @@ fail: + return NULL; + } + ++char * ++agetpass(const char *prompt) ++{ ++ return agetpass_internal(prompt, RPP_REQUIRE_TTY); ++} ++ ++char * ++agetpass_stdin() ++{ ++ return agetpass_internal(NULL, RPP_STDIN); ++} + + void + erase_pass(char *pass) +diff -up shadow-4.14.0/lib/prototypes.h.orig shadow-4.14.0/lib/prototypes.h +--- shadow-4.14.0/lib/prototypes.h.orig 2024-01-24 22:06:18.786184942 +0100 ++++ shadow-4.14.0/lib/prototypes.h 2024-01-24 20:19:45.299231059 +0100 +@@ -47,6 +47,7 @@ extern int expire (const struct passwd * + extern void erase_pass(char *pass); + ATTR_MALLOC(erase_pass) + extern char *agetpass(const char *prompt); ++extern char *agetpass_stdin(); + + /* isexpired.c */ + extern int isexpired (const struct passwd *, /*@null@*/const struct spwd *); +diff -up shadow-4.14.0/man/passwd.1.xml.orig shadow-4.14.0/man/passwd.1.xml +--- shadow-4.14.0/man/passwd.1.xml.orig 2024-01-24 20:33:31.438972506 +0100 ++++ shadow-4.14.0/man/passwd.1.xml 2024-01-29 17:36:31.082495245 +0100 +@@ -341,6 +341,17 @@ + + + ++ ++ ++ , ++ ++ ++ ++ This option is used to indicate that passwd should read the new password from standard ++ input, which can be a pipe. ++ ++ ++ + + + +diff -up shadow-4.14.0/src/passwd.c.orig shadow-4.14.0/src/passwd.c +--- shadow-4.14.0/src/passwd.c.orig 2024-01-24 13:57:15.714549266 +0100 ++++ shadow-4.14.0/src/passwd.c 2024-01-29 17:33:59.421508534 +0100 +@@ -65,7 +65,8 @@ static bool + Sflg = false, /* -S - show password status */ + uflg = false, /* -u - unlock the user's password */ + wflg = false, /* -w - set warning days */ +- xflg = false; /* -x - set maximum days */ ++ xflg = false, /* -x - set maximum days */ ++ sflg = false; /* -s - read passwd from stdin */ + + /* + * set to 1 if there are any flags which require root privileges, +@@ -156,6 +157,7 @@ usage (int status) + (void) fputs (_(" -w, --warndays WARN_DAYS set expiration warning days to WARN_DAYS\n"), usageout); + (void) fputs (_(" -x, --maxdays MAX_DAYS set maximum number of days before password\n" + " change to MAX_DAYS\n"), usageout); ++ (void) fputs (_(" -s, --stdin read new token from stdin\n"), usageout); + (void) fputs ("\n", usageout); + exit (status); + } +@@ -275,7 +277,7 @@ static int new_password (const struct pa + pass_max_len = getdef_num ("PASS_MAX_LEN", 8); + } + } +- if (!qflg) { ++ if (!qflg && !sflg) { + if (pass_max_len == -1) { + (void) printf (_( + "Enter the new password (minimum of %d characters)\n" +@@ -289,55 +291,67 @@ static int new_password (const struct pa + } + } + +- warned = false; +- for (i = getdef_num ("PASS_CHANGE_TRIES", 5); i > 0; i--) { +- cp = agetpass (_("New password: ")); ++ if (sflg) { ++ /* ++ * root is setting the passphrase from stdin ++ */ ++ cp = agetpass_stdin (); + if (NULL == cp) { +- memzero (orig, sizeof orig); +- memzero (pass, sizeof pass); + return -1; + } +- if (warned && (strcmp (pass, cp) != 0)) { +- warned = false; +- } + STRFCPY (pass, cp); + erase_pass (cp); ++ } else { ++ warned = false; ++ for (i = getdef_num ("PASS_CHANGE_TRIES", 5); i > 0; i--) { ++ cp = agetpass (_("New password: ")); ++ if (NULL == cp) { ++ memzero (orig, sizeof orig); ++ memzero (pass, sizeof pass); ++ return -1; ++ } ++ if (warned && (strcmp (pass, cp) != 0)) { ++ warned = false; ++ } ++ STRFCPY (pass, cp); ++ erase_pass (cp); + +- if (!amroot && !obscure(orig, pass, pw)) { +- (void) puts (_("Try again.")); +- continue; +- } ++ if (!amroot && !obscure(orig, pass, pw)) { ++ (void) puts (_("Try again.")); ++ continue; ++ } + +- /* +- * If enabled, warn about weak passwords even if you are +- * root (enter this password again to use it anyway). +- * --marekm +- */ +- if (amroot && !warned && getdef_bool ("PASS_ALWAYS_WARN") +- && !obscure(orig, pass, pw)) { +- (void) puts (_("\nWarning: weak password (enter it again to use it anyway).")); +- warned = true; +- continue; ++ /* ++ * If enabled, warn about weak passwords even if you are ++ * root (enter this password again to use it anyway). ++ * --marekm ++ */ ++ if (amroot && !warned && getdef_bool ("PASS_ALWAYS_WARN") ++ && !obscure(orig, pass, pw)) { ++ (void) puts (_("\nWarning: weak password (enter it again to use it anyway).")); ++ warned = true; ++ continue; ++ } ++ cp = agetpass (_("Re-enter new password: ")); ++ if (NULL == cp) { ++ memzero (orig, sizeof orig); ++ memzero (pass, sizeof pass); ++ return -1; ++ } ++ if (strcmp (cp, pass) != 0) { ++ erase_pass (cp); ++ (void) fputs (_("They don't match; try again.\n"), stderr); ++ } else { ++ erase_pass (cp); ++ break; ++ } + } +- cp = agetpass (_("Re-enter new password: ")); +- if (NULL == cp) { +- memzero (orig, sizeof orig); ++ memzero (orig, sizeof orig); ++ ++ if (i == 0) { + memzero (pass, sizeof pass); + return -1; + } +- if (strcmp (cp, pass) != 0) { +- erase_pass (cp); +- (void) fputs (_("They don't match; try again.\n"), stderr); +- } else { +- erase_pass (cp); +- break; +- } +- } +- memzero (orig, sizeof orig); +- +- if (i == 0) { +- memzero (pass, sizeof pass); +- return -1; + } + + /* +@@ -714,6 +728,7 @@ static void update_shadow (void) + * -u unlock the password of the named account (*) + * -w # set sp_warn to # days (*) + * -x # set sp_max to # days (*) ++ * -s read password from stdin + * + * (*) requires root permission to execute. + * +@@ -781,10 +796,11 @@ int main (int argc, char **argv) + {"unlock", no_argument, NULL, 'u'}, + {"warndays", required_argument, NULL, 'w'}, + {"maxdays", required_argument, NULL, 'x'}, ++ {"stdin", no_argument, NULL, 's'}, + {NULL, 0, NULL, '\0'} + }; + +- while ((c = getopt_long (argc, argv, "adehi:kln:qr:R:P:Suw:x:", ++ while ((c = getopt_long (argc, argv, "adehi:kln:qr:R:P:Suw:x:s", + long_options, NULL)) != -1) { + switch (c) { + case 'a': +@@ -877,6 +893,15 @@ int main (int argc, char **argv) + xflg = true; + anyflag = true; + break; ++ case 's': ++ if (!amroot) { ++ (void) fprintf (stderr, ++ _("%s: only root can use --stdin/-s option\n"), ++ Prog); ++ usage (E_BAD_ARG); ++ } ++ sflg = true; ++ break; + default: + usage (E_BAD_ARG); + } +@@ -1068,7 +1093,16 @@ int main (int argc, char **argv) + * Don't set the real UID for PAM... + */ + if (!anyflag && use_pam) { +- do_pam_passwd (name, qflg, kflg); ++ if (sflg) { ++ cp = agetpass_stdin (); ++ if (cp == NULL) { ++ exit (E_FAILURE); ++ } ++ do_pam_passwd_non_interactive ("passwd", name, cp); ++ erase_pass (cp); ++ } else { ++ do_pam_passwd (name, qflg, kflg); ++ } + exit (E_SUCCESS); + } + #endif /* USE_PAM */ +@@ -1102,4 +1136,3 @@ int main (int argc, char **argv) + + return E_SUCCESS; + } +- diff --git a/shadow-4.14.0-remove-libcrack.patch b/shadow-4.14.0-remove-libcrack.patch new file mode 100644 index 0000000..4dc1328 --- /dev/null +++ b/shadow-4.14.0-remove-libcrack.patch @@ -0,0 +1,306 @@ +From 43b4e5a6c41f5c43cad18810f9229e40e8c4a57e Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Mon, 30 Oct 2023 12:53:37 +0100 +Subject: [PATCH 1/2] Remove FascistHistory() and FascistHistoryPw() calls + +These functions don't seem to exist anymore. I can't find them in +Debian, nor in a web search. They probably were functions from an +ancient implementation of cracklib that doesn't exist anymore. + +$ git remote -v +origin git@github.com:cracklib/cracklib.git (fetch) +origin git@github.com:cracklib/cracklib.git (push) +$ grep -rni fascisthistory +$ git log --grep FascistHistory +$ git log -S FascistHistory + +Closes: +Cc: Mike Frysinger +Acked-by: Michael Vetter +Signed-off-by: Alejandro Colomar +--- + configure.ac | 4 ---- + libmisc/obscure.c | 8 -------- + src/passwd.c | 33 ++------------------------------- + 3 files changed, 2 insertions(+), 43 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 2c8cca3f..5c8c7764 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -526,10 +526,6 @@ if test "$with_libcrack" = "yes"; then + echo "checking cracklib flavour, don't be surprised by the results" + AC_CHECK_LIB(crack, FascistCheck, + [LIBCRACK=-lcrack AC_DEFINE(HAVE_LIBCRACK, 1, [Defined if you have libcrack.])]) +- AC_CHECK_LIB(crack, FascistHistory, +- AC_DEFINE(HAVE_LIBCRACK_HIST, 1, [Defined if you have the ts&szs cracklib.])) +- AC_CHECK_LIB(crack, FascistHistoryPw, +- AC_DEFINE(HAVE_LIBCRACK_PW, 1, [Defined if it includes *Pw functions.])) + fi + + if test "$with_btrfs" != "no"; then +diff --git a/libmisc/obscure.c b/libmisc/obscure.c +index ccffb71d..4070d4e4 100644 +--- a/libmisc/obscure.c ++++ b/libmisc/obscure.c +@@ -100,11 +100,7 @@ static /*@observer@*//*@null@*/const char *password_check ( + #ifdef HAVE_LIBCRACK + char *dictpath; + +-#ifdef HAVE_LIBCRACK_PW +- char *FascistCheckPw (); +-#else + char *FascistCheck (); +-#endif + #endif + + if (strcmp (new, old) == 0) { +@@ -133,11 +129,7 @@ static /*@observer@*//*@null@*/const char *password_check ( + + dictpath = getdef_str ("CRACKLIB_DICTPATH"); + if (NULL != dictpath) { +-#ifdef HAVE_LIBCRACK_PW +- msg = FascistCheckPw (new, dictpath, pwdp); +-#else + msg = FascistCheck (new, dictpath); +-#endif + } + #endif + } +diff --git a/src/passwd.c b/src/passwd.c +index 67608619..a4f49320 100644 +--- a/src/passwd.c ++++ b/src/passwd.c +@@ -114,7 +114,6 @@ static bool do_update_pwd = false; + /* local function prototypes */ + NORETURN static void usage (int); + +-static bool reuse (const char *, const struct passwd *); + static int new_password (const struct passwd *); + + static void check_password (const struct passwd *, const struct spwd *); +@@ -163,27 +162,6 @@ usage (int status) + exit (status); + } + +-static bool reuse (const char *pass, const struct passwd *pw) +-{ +-#ifdef HAVE_LIBCRACK_HIST +- const char *reason; +- +-#ifdef HAVE_LIBCRACK_PW +- const char *FascistHistoryPw (const char *, const struct passwd *); +- +- reason = FascistHistory (pass, pw); +-#else /* !HAVE_LIBCRACK_PW */ +- const char *FascistHistory (const char *, int); +- +- reason = FascistHistory (pass, pw->pw_uid); +-#endif /* !HAVE_LIBCRACK_PW */ +- if (NULL != reason) { +- (void) printf (_("Bad password: %s. "), reason); +- return true; +- } +-#endif /* HAVE_LIBCRACK_HIST */ +- return false; +-} + + /* + * new_password - validate old password and replace with new (both old and +@@ -202,10 +180,6 @@ static int new_password (const struct passwd *pw) + int pass_max_len = -1; + const char *method; + +-#ifdef HAVE_LIBCRACK_HIST +- int HistUpdate (const char *, const char *); +-#endif /* HAVE_LIBCRACK_HIST */ +- + /* + * Authenticate the user. The user will be prompted for their own + * password. +@@ -306,7 +280,7 @@ static int new_password (const struct passwd *pw) + STRFCPY (pass, cp); + erase_pass (cp); + +- if (!amroot && (!obscure (orig, pass, pw) || reuse (pass, pw))) { ++ if (!amroot && !obscure(orig, pass, pw)) { + (void) puts (_("Try again.")); + continue; + } +@@ -317,7 +291,7 @@ static int new_password (const struct passwd *pw) + * --marekm + */ + if (amroot && !warned && getdef_bool ("PASS_ALWAYS_WARN") +- && (!obscure (orig, pass, pw) || reuse (pass, pw))) { ++ && !obscure(orig, pass, pw)) { + (void) puts (_("\nWarning: weak password (enter it again to use it anyway).")); + warned = true; + continue; +@@ -357,9 +331,6 @@ static int new_password (const struct passwd *pw) + return -1; + } + +-#ifdef HAVE_LIBCRACK_HIST +- HistUpdate (pw->pw_name, crypt_passwd); +-#endif /* HAVE_LIBCRACK_HIST */ + STRFCPY (crypt_passwd, cp); + return 0; + } +-- +2.43.0 + + +From 45f34ee8c196a98397504cb7ed8576b6f1825cf9 Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Mon, 30 Oct 2023 13:31:42 +0100 +Subject: [PATCH 2/2] Remove libcrack support + +Signed-off-by: Alejandro Colomar +--- + configure.ac | 11 ----------- + etc/login.defs | 5 ----- + lib/getdef.c | 1 - + libmisc/obscure.c | 22 ---------------------- + libsubid/Makefile.am | 1 - + src/Makefile.am | 2 +- + 7 files changed, 2 insertions(+), 42 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 5c8c7764..c2b0a1a5 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -243,9 +243,6 @@ AC_ARG_WITH(skey, + AC_ARG_WITH(tcb, + [AS_HELP_STRING([--with-tcb], [use tcb support (incomplete) @<:@default=yes if found@:>@])], + [with_tcb=$withval], [with_tcb=maybe]) +-AC_ARG_WITH(libcrack, +- [AS_HELP_STRING([--with-libcrack], [use libcrack @<:@default=no@:>@])], +- [with_libcrack=$withval], [with_libcrack=no]) + AC_ARG_WITH(sha-crypt, + [AS_HELP_STRING([--with-sha-crypt], [allow the SHA256 and SHA512 password encryption algorithms @<:@default=yes@:>@])], + [with_sha_crypt=$withval], [with_sha_crypt=yes]) +@@ -521,13 +518,6 @@ if test "$with_audit" != "no"; then + fi + fi + +-AC_SUBST(LIBCRACK) +-if test "$with_libcrack" = "yes"; then +- echo "checking cracklib flavour, don't be surprised by the results" +- AC_CHECK_LIB(crack, FascistCheck, +- [LIBCRACK=-lcrack AC_DEFINE(HAVE_LIBCRACK, 1, [Defined if you have libcrack.])]) +-fi +- + if test "$with_btrfs" != "no"; then + AC_CHECK_HEADERS([sys/statfs.h linux/magic.h linux/btrfs_tree.h], \ + [btrfs_headers="yes"], [btrfs_headers="no"]) +@@ -768,7 +758,6 @@ echo + echo "shadow will be compiled with the following features:" + echo + echo " auditing support: $with_audit" +-echo " CrackLib support: $with_libcrack" + echo " PAM support: $with_libpam" + if test "$with_libpam" = "yes"; then + echo " suid account management tools: $enable_acct_tools_setuid" +diff --git a/etc/login.defs b/etc/login.defs +index 114dbcd9..33622c29 100644 +--- a/etc/login.defs ++++ b/etc/login.defs +@@ -227,11 +227,6 @@ PASS_WARN_AGE 7 + # + SU_WHEEL_ONLY no + +-# +-# If compiled with cracklib support, sets the path to the dictionaries +-# +-CRACKLIB_DICTPATH /var/cache/cracklib/cracklib_dict +- + # + # Min/max values for automatic uid selection in useradd(8) + # +diff --git a/lib/getdef.c b/lib/getdef.c +index 977660c2..d64e6343 100644 +--- a/lib/getdef.c ++++ b/lib/getdef.c +@@ -39,7 +39,6 @@ struct itemdef { + #define PAMDEFS \ + {"CHFN_AUTH", NULL}, \ + {"CHSH_AUTH", NULL}, \ +- {"CRACKLIB_DICTPATH", NULL}, \ + {"ENV_HZ", NULL}, \ + {"ENVIRON_FILE", NULL}, \ + {"ENV_TZ", NULL}, \ +diff --git a/libmisc/obscure.c b/libmisc/obscure.c +index 4070d4e4..2aece68b 100644 +--- a/libmisc/obscure.c ++++ b/libmisc/obscure.c +@@ -12,11 +12,6 @@ + #ident "$Id$" + + +-/* +- * This version of obscure.c contains modifications to support "cracklib" +- * by Alec Muffet (alec.muffett@uk.sun.com). You must obtain the Cracklib +- * library source code for this function to operate. +- */ + #include + #include + +@@ -97,12 +92,6 @@ static /*@observer@*//*@null@*/const char *password_check ( + const char *msg = NULL; + char *oldmono, *newmono, *wrapped; + +-#ifdef HAVE_LIBCRACK +- char *dictpath; +- +- char *FascistCheck (); +-#endif +- + if (strcmp (new, old) == 0) { + return _("no change"); + } +@@ -121,17 +110,6 @@ static /*@observer@*//*@null@*/const char *password_check ( + msg = _("too similar"); + } else if (strstr (wrapped, newmono) != NULL) { + msg = _("rotated"); +- } else { +-#ifdef HAVE_LIBCRACK +- /* +- * Invoke Alec Muffett's cracklib routines. +- */ +- +- dictpath = getdef_str ("CRACKLIB_DICTPATH"); +- if (NULL != dictpath) { +- msg = FascistCheck (new, dictpath); +- } +-#endif + } + strzero (newmono); + strzero (oldmono); +diff --git a/libsubid/Makefile.am b/libsubid/Makefile.am +index 5ba0ab35..b6488e77 100644 +--- a/libsubid/Makefile.am ++++ b/libsubid/Makefile.am +@@ -8,7 +8,6 @@ MISCLIBS = \ + $(LIBAUDIT) \ + $(LIBSELINUX) \ + $(LIBSEMANAGE) \ +- $(LIBCRACK) \ + $(LIBCRYPT_NOPAM) \ + $(LIBSKEY) \ + $(LIBMD) \ +diff --git a/src/Makefile.am b/src/Makefile.am +index fcfee9d2..b6cb09ef 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -123,7 +123,7 @@ login_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(L + newgrp_LDADD = $(LDADD) $(LIBAUDIT) $(LIBCRYPT) $(LIBECONF) + newusers_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF) -ldl + nologin_LDADD = +-passwd_LDADD = $(LDADD) $(LIBPAM) $(LIBCRACK) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBECONF) -ldl ++passwd_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBECONF) -ldl + pwck_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) + pwconv_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) + pwunconv_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) +-- +2.43.0 + diff --git a/shadow-utils.login.defs b/shadow-utils.login.defs index c0295b1..e84c7ab 100644 --- a/shadow-utils.login.defs +++ b/shadow-utils.login.defs @@ -130,10 +130,9 @@ HOME_MODE 0700 # PASS_MAX_DAYS 99999 PASS_MIN_DAYS 0 +PASS_MIN_LEN 8 PASS_WARN_AGE 7 -# Currently PASS_MIN_LEN is not supported - # Currently SU_WHEEL_ONLY is not supported # Currently CRACKLIB_DICTPATH is not supported @@ -174,11 +173,22 @@ SUB_GID_COUNT 65536 # #LOGIN_TIMEOUT 60 -# Currently PASS_CHANGE_TRIES is not supported +# +# Maximum number of attempts to change password if rejected (too easy) +# +PASS_CHANGE_TRIES 5 -# Currently PASS_ALWAYS_WARN is not supported +# +# Warn about weak passwords (but still allow them) if you are root. +# +PASS_ALWAYS_WARN yes -# Currently PASS_MAX_LEN is not supported +# +# Number of significant characters in the password for crypt(). +# Default is 8, don't change unless your crypt() is better. +# Ignored if MD5_CRYPT_ENAB set to "yes". +# +#PASS_MAX_LEN 8 # Currently CHFN_AUTH is not supported diff --git a/shadow-utils.spec b/shadow-utils.spec index 633f1fe..416cfa1 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.14.0 -Release: 4%{?dist} +Release: 5%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -12,6 +12,7 @@ Source3: shadow-utils.login.defs Source4: shadow-bsd.txt Source5: https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt Source6: shadow-utils.HOME_MODE.xml +Source7: passwd.pamd ### Globals ### %global includesubiddir %{_includedir}/shadow @@ -25,10 +26,18 @@ Patch1: shadow-4.2.1-date-parsing.patch Patch2: shadow-4.14.0-audit-update.patch # https://github.com/shadow-maint/shadow/pull/812 Patch3: shadow-4.14.0-useradd-def-usrtemplate-selinux-label.patch +# Probably non-upstreamable +Patch4: shadow-4.14.0-account-tools-setuid.patch +# https://github.com/shadow-maint/shadow/commit/43b4e5a6c41f5c43cad18810f9229e40e8c4a57e +# https://github.com/shadow-maint/shadow/commit/45f34ee8c196a98397504cb7ed8576b6f1825cf9 +Patch5: shadow-4.14.0-remove-libcrack.patch +# https://github.com/shadow-maint/shadow/pull/927 +Patch6: shadow-4.14.0-passwd-stdin.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 Requires: libselinux >= 1.25.2-1 +Requires: pam-libs Requires: setup ### Build Dependencies ### @@ -51,9 +60,12 @@ BuildRequires: libsemanage-devel BuildRequires: libtool BuildRequires: libxslt BuildRequires: make +BuildRequires: pam-devel ### Provides ### Provides: shadow = %{epoch}:%{version}-%{release} +Provides: passwd = 0.80-18 +Obsoletes: passwd <= 0.80-19 %description The shadow-utils package includes the necessary programs for @@ -112,6 +124,7 @@ autoreconf --enable-shadowgrp \ --enable-man \ --with-audit \ + --with-libpam \ --with-sha-crypt \ --with-bcrypt \ --with-yescrypt \ @@ -123,7 +136,8 @@ autoreconf --enable-shared \ --with-group-name-max-length=32 \ --enable-lastlog \ - --enable-logind=no + --enable-logind=no \ + --disable-account-tools-setuid %make_build %install @@ -131,6 +145,8 @@ autoreconf install -d -m 755 $RPM_BUILD_ROOT%{_sysconfdir}/default install -p -c -m 0644 %{SOURCE3} $RPM_BUILD_ROOT%{_sysconfdir}/login.defs install -p -c -m 0600 %{SOURCE2} $RPM_BUILD_ROOT%{_sysconfdir}/default/useradd +install -d -m 755 $RPM_BUILD_ROOT%{_pam_confdir} +install -m 644 %{SOURCE7} $RPM_BUILD_ROOT%{_pam_confdir}/passwd ln -s useradd $RPM_BUILD_ROOT%{_sbindir}/adduser @@ -145,7 +161,6 @@ rm $RPM_BUILD_ROOT%{_bindir}/chsh rm $RPM_BUILD_ROOT%{_bindir}/expiry rm $RPM_BUILD_ROOT%{_bindir}/groups rm $RPM_BUILD_ROOT%{_bindir}/login -rm $RPM_BUILD_ROOT%{_bindir}/passwd rm $RPM_BUILD_ROOT%{_bindir}/su rm $RPM_BUILD_ROOT%{_bindir}/faillog rm $RPM_BUILD_ROOT%{_sysconfdir}/login.access @@ -162,8 +177,6 @@ rm $RPM_BUILD_ROOT%{_mandir}/man1/groups.* rm $RPM_BUILD_ROOT%{_mandir}/*/man1/groups.* rm $RPM_BUILD_ROOT%{_mandir}/man1/login.* rm $RPM_BUILD_ROOT%{_mandir}/*/man1/login.* -rm $RPM_BUILD_ROOT%{_mandir}/man1/passwd.* -rm $RPM_BUILD_ROOT%{_mandir}/*/man1/passwd.* rm $RPM_BUILD_ROOT%{_mandir}/man1/su.* rm $RPM_BUILD_ROOT%{_mandir}/*/man1/su.* rm $RPM_BUILD_ROOT%{_mandir}/man5/limits.* @@ -187,6 +200,8 @@ rm $RPM_BUILD_ROOT%{_mandir}/*/man5/faillog.* rm $RPM_BUILD_ROOT%{_mandir}/man8/faillog.* rm $RPM_BUILD_ROOT%{_mandir}/*/man8/faillog.* +# Remove PAM service files we don't use. + find $RPM_BUILD_ROOT%{_mandir} -depth -type d -empty -delete %find_lang shadow for dir in $(ls -1d $RPM_BUILD_ROOT%{_mandir}/{??,??_??}) ; do @@ -211,6 +226,7 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %license gpl-2.0.txt shadow-bsd.txt %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/login.defs %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/default/useradd +%config(noreplace) %{_pam_confdir}/passwd %{_bindir}/sg %attr(4755,root,root) %{_bindir}/chage %attr(4755,root,root) %{_bindir}/gpasswd @@ -218,6 +234,7 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %attr(4755,root,root) %{_bindir}/newgrp %attr(0755,root,root) %caps(cap_setgid=ep) %{_bindir}/newgidmap %attr(0755,root,root) %caps(cap_setuid=ep) %{_bindir}/newuidmap +%attr(4755,root,root) %{_bindir}/passwd %{_sbindir}/adduser %attr(0755,root,root) %{_sbindir}/user* %attr(0755,root,root) %{_sbindir}/group* @@ -235,6 +252,7 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_mandir}/man1/newgrp.1* %{_mandir}/man1/newgidmap.1* %{_mandir}/man1/newuidmap.1* +%{_mandir}/man1/passwd.* %{_mandir}/man3/shadow.3* %{_mandir}/man5/shadow.5* %{_mandir}/man5/login.defs.5* @@ -264,6 +282,12 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Thu Feb 1 2024 Iker Pedrosa - 2:4.14.0-5 +- passwd: Provide binary from this package. Enable libpam and + disable account-tools-setuid. Provide passwd PAM service file. + Resolves: #2233275 +- passwd: provide --stdin option + * Mon Jan 29 2024 Iker Pedrosa - 2:4.14.0-4 - Disable SSSD support. Resolves: #2253182 From 07607754dfff84049249e3d0a474b5ec203d6e01 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Mon, 12 Feb 2024 15:57:19 +0100 Subject: [PATCH 079/134] Build linking `libpam` Signed-off-by: Iker Pedrosa --- shadow-utils.spec | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index 416cfa1..6b705cd 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.14.0 -Release: 5%{?dist} +Release: 6%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -131,7 +131,6 @@ autoreconf --with-selinux \ --without-libbsd \ --without-libcrack \ - --without-libpam \ --without-sssd \ --enable-shared \ --with-group-name-max-length=32 \ @@ -163,8 +162,6 @@ rm $RPM_BUILD_ROOT%{_bindir}/groups rm $RPM_BUILD_ROOT%{_bindir}/login rm $RPM_BUILD_ROOT%{_bindir}/su rm $RPM_BUILD_ROOT%{_bindir}/faillog -rm $RPM_BUILD_ROOT%{_sysconfdir}/login.access -rm $RPM_BUILD_ROOT%{_sysconfdir}/limits rm $RPM_BUILD_ROOT%{_sbindir}/logoutd rm $RPM_BUILD_ROOT%{_sbindir}/nologin rm $RPM_BUILD_ROOT%{_mandir}/man1/chfn.* @@ -179,14 +176,8 @@ rm $RPM_BUILD_ROOT%{_mandir}/man1/login.* rm $RPM_BUILD_ROOT%{_mandir}/*/man1/login.* rm $RPM_BUILD_ROOT%{_mandir}/man1/su.* rm $RPM_BUILD_ROOT%{_mandir}/*/man1/su.* -rm $RPM_BUILD_ROOT%{_mandir}/man5/limits.* -rm $RPM_BUILD_ROOT%{_mandir}/*/man5/limits.* -rm $RPM_BUILD_ROOT%{_mandir}/man5/login.access.* -rm $RPM_BUILD_ROOT%{_mandir}/*/man5/login.access.* rm $RPM_BUILD_ROOT%{_mandir}/man5/passwd.* rm $RPM_BUILD_ROOT%{_mandir}/*/man5/passwd.* -rm $RPM_BUILD_ROOT%{_mandir}/man5/porttime.* -rm $RPM_BUILD_ROOT%{_mandir}/*/man5/porttime.* rm $RPM_BUILD_ROOT%{_mandir}/man5/suauth.* rm $RPM_BUILD_ROOT%{_mandir}/*/man5/suauth.* rm $RPM_BUILD_ROOT%{_mandir}/man8/logoutd.* @@ -201,6 +192,11 @@ rm $RPM_BUILD_ROOT%{_mandir}/man8/faillog.* rm $RPM_BUILD_ROOT%{_mandir}/*/man8/faillog.* # Remove PAM service files we don't use. +rm $RPM_BUILD_ROOT%{_pam_confdir}/chfn +rm $RPM_BUILD_ROOT%{_pam_confdir}/chsh +rm $RPM_BUILD_ROOT%{_pam_confdir}/groupmems +rm $RPM_BUILD_ROOT%{_pam_confdir}/login +rm $RPM_BUILD_ROOT%{_pam_confdir}/su find $RPM_BUILD_ROOT%{_mandir} -depth -type d -empty -delete %find_lang shadow @@ -282,6 +278,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Mon Feb 12 2024 Iker Pedrosa - 2:4.14.0-6 +- Build linking `libpam` + * Thu Feb 1 2024 Iker Pedrosa - 2:4.14.0-5 - passwd: Provide binary from this package. Enable libpam and disable account-tools-setuid. Provide passwd PAM service file. From fb4d9302930511096134f042c54aaa360a7af8e2 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Mon, 19 Feb 2024 10:56:01 +0100 Subject: [PATCH 080/134] Rebase to version 4.15.0rc2 Signed-off-by: Iker Pedrosa --- .gitignore | 2 + shadow-4.14.0-passwd-stdin.patch | 288 ---------- shadow-4.14.0-remove-libcrack.patch | 306 ---------- ...seradd-def-usrtemplate-selinux-label.patch | 28 - ....patch => shadow-4.15.0-audit-update.patch | 523 ++++++++---------- ....patch => shadow-4.15.0-date-parsing.patch | 6 +- ...manfix.patch => shadow-4.15.0-manfix.patch | 54 +- shadow-utils.spec | 26 +- sources | 4 +- 9 files changed, 277 insertions(+), 960 deletions(-) delete mode 100644 shadow-4.14.0-passwd-stdin.patch delete mode 100644 shadow-4.14.0-remove-libcrack.patch delete mode 100644 shadow-4.14.0-useradd-def-usrtemplate-selinux-label.patch rename shadow-4.14.0-audit-update.patch => shadow-4.15.0-audit-update.patch (80%) rename shadow-4.2.1-date-parsing.patch => shadow-4.15.0-date-parsing.patch (93%) rename shadow-4.14.0-manfix.patch => shadow-4.15.0-manfix.patch (76%) diff --git a/.gitignore b/.gitignore index 422ed12..8b8ecf6 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,5 @@ shadow-4.1.4.2.tar.bz2 /shadow-4.13.tar.xz.asc /shadow-4.14.0.tar.xz /shadow-4.14.0.tar.xz.asc +/shadow-4.15.0rc2.tar.xz +/shadow-4.15.0rc2.tar.xz.asc diff --git a/shadow-4.14.0-passwd-stdin.patch b/shadow-4.14.0-passwd-stdin.patch deleted file mode 100644 index 2603350..0000000 --- a/shadow-4.14.0-passwd-stdin.patch +++ /dev/null @@ -1,288 +0,0 @@ -diff -up shadow-4.14.0/libmisc/agetpass.c.orig shadow-4.14.0/libmisc/agetpass.c ---- shadow-4.14.0/libmisc/agetpass.c.orig 2024-01-24 20:06:20.557577853 +0100 -+++ shadow-4.14.0/libmisc/agetpass.c 2024-01-24 21:21:06.379445080 +0100 -@@ -32,6 +32,7 @@ - * SYNOPSIS - * [[gnu::malloc(erase_pass)]] - * char *agetpass(const char *prompt); -+ * char *agetpass_stdin(); - * - * void erase_pass(char *pass); - * -@@ -64,6 +65,10 @@ - * erased by calling erase_pass(), to avoid possibly leaking the - * password. - * -+ * agetpass_stdin() -+ * This function is the same as previous one (agetpass). Just the -+ * password is read from stdin and terminal is not required. -+ * - * erase_pass() - * This function first clears the password, by calling - * explicit_bzero(3) (or an equivalent call), and then frees the -@@ -92,8 +97,8 @@ - */ - - --char * --agetpass(const char *prompt) -+static char * -+agetpass_internal(const char *prompt, int flags) - { - char *pass; - size_t len; -@@ -110,7 +115,7 @@ agetpass(const char *prompt) - if (pass == NULL) - return NULL; - -- if (readpassphrase(prompt, pass, PASS_MAX + 2, RPP_REQUIRE_TTY) == NULL) -+ if (readpassphrase(prompt, pass, PASS_MAX + 2, flags) == NULL) - goto fail; - - len = strlen(pass); -@@ -126,6 +131,17 @@ fail: - return NULL; - } - -+char * -+agetpass(const char *prompt) -+{ -+ return agetpass_internal(prompt, RPP_REQUIRE_TTY); -+} -+ -+char * -+agetpass_stdin() -+{ -+ return agetpass_internal(NULL, RPP_STDIN); -+} - - void - erase_pass(char *pass) -diff -up shadow-4.14.0/lib/prototypes.h.orig shadow-4.14.0/lib/prototypes.h ---- shadow-4.14.0/lib/prototypes.h.orig 2024-01-24 22:06:18.786184942 +0100 -+++ shadow-4.14.0/lib/prototypes.h 2024-01-24 20:19:45.299231059 +0100 -@@ -47,6 +47,7 @@ extern int expire (const struct passwd * - extern void erase_pass(char *pass); - ATTR_MALLOC(erase_pass) - extern char *agetpass(const char *prompt); -+extern char *agetpass_stdin(); - - /* isexpired.c */ - extern int isexpired (const struct passwd *, /*@null@*/const struct spwd *); -diff -up shadow-4.14.0/man/passwd.1.xml.orig shadow-4.14.0/man/passwd.1.xml ---- shadow-4.14.0/man/passwd.1.xml.orig 2024-01-24 20:33:31.438972506 +0100 -+++ shadow-4.14.0/man/passwd.1.xml 2024-01-29 17:36:31.082495245 +0100 -@@ -341,6 +341,17 @@ - - - -+ -+ -+ , -+ -+ -+ -+ This option is used to indicate that passwd should read the new password from standard -+ input, which can be a pipe. -+ -+ -+ - - - -diff -up shadow-4.14.0/src/passwd.c.orig shadow-4.14.0/src/passwd.c ---- shadow-4.14.0/src/passwd.c.orig 2024-01-24 13:57:15.714549266 +0100 -+++ shadow-4.14.0/src/passwd.c 2024-01-29 17:33:59.421508534 +0100 -@@ -65,7 +65,8 @@ static bool - Sflg = false, /* -S - show password status */ - uflg = false, /* -u - unlock the user's password */ - wflg = false, /* -w - set warning days */ -- xflg = false; /* -x - set maximum days */ -+ xflg = false, /* -x - set maximum days */ -+ sflg = false; /* -s - read passwd from stdin */ - - /* - * set to 1 if there are any flags which require root privileges, -@@ -156,6 +157,7 @@ usage (int status) - (void) fputs (_(" -w, --warndays WARN_DAYS set expiration warning days to WARN_DAYS\n"), usageout); - (void) fputs (_(" -x, --maxdays MAX_DAYS set maximum number of days before password\n" - " change to MAX_DAYS\n"), usageout); -+ (void) fputs (_(" -s, --stdin read new token from stdin\n"), usageout); - (void) fputs ("\n", usageout); - exit (status); - } -@@ -275,7 +277,7 @@ static int new_password (const struct pa - pass_max_len = getdef_num ("PASS_MAX_LEN", 8); - } - } -- if (!qflg) { -+ if (!qflg && !sflg) { - if (pass_max_len == -1) { - (void) printf (_( - "Enter the new password (minimum of %d characters)\n" -@@ -289,55 +291,67 @@ static int new_password (const struct pa - } - } - -- warned = false; -- for (i = getdef_num ("PASS_CHANGE_TRIES", 5); i > 0; i--) { -- cp = agetpass (_("New password: ")); -+ if (sflg) { -+ /* -+ * root is setting the passphrase from stdin -+ */ -+ cp = agetpass_stdin (); - if (NULL == cp) { -- memzero (orig, sizeof orig); -- memzero (pass, sizeof pass); - return -1; - } -- if (warned && (strcmp (pass, cp) != 0)) { -- warned = false; -- } - STRFCPY (pass, cp); - erase_pass (cp); -+ } else { -+ warned = false; -+ for (i = getdef_num ("PASS_CHANGE_TRIES", 5); i > 0; i--) { -+ cp = agetpass (_("New password: ")); -+ if (NULL == cp) { -+ memzero (orig, sizeof orig); -+ memzero (pass, sizeof pass); -+ return -1; -+ } -+ if (warned && (strcmp (pass, cp) != 0)) { -+ warned = false; -+ } -+ STRFCPY (pass, cp); -+ erase_pass (cp); - -- if (!amroot && !obscure(orig, pass, pw)) { -- (void) puts (_("Try again.")); -- continue; -- } -+ if (!amroot && !obscure(orig, pass, pw)) { -+ (void) puts (_("Try again.")); -+ continue; -+ } - -- /* -- * If enabled, warn about weak passwords even if you are -- * root (enter this password again to use it anyway). -- * --marekm -- */ -- if (amroot && !warned && getdef_bool ("PASS_ALWAYS_WARN") -- && !obscure(orig, pass, pw)) { -- (void) puts (_("\nWarning: weak password (enter it again to use it anyway).")); -- warned = true; -- continue; -+ /* -+ * If enabled, warn about weak passwords even if you are -+ * root (enter this password again to use it anyway). -+ * --marekm -+ */ -+ if (amroot && !warned && getdef_bool ("PASS_ALWAYS_WARN") -+ && !obscure(orig, pass, pw)) { -+ (void) puts (_("\nWarning: weak password (enter it again to use it anyway).")); -+ warned = true; -+ continue; -+ } -+ cp = agetpass (_("Re-enter new password: ")); -+ if (NULL == cp) { -+ memzero (orig, sizeof orig); -+ memzero (pass, sizeof pass); -+ return -1; -+ } -+ if (strcmp (cp, pass) != 0) { -+ erase_pass (cp); -+ (void) fputs (_("They don't match; try again.\n"), stderr); -+ } else { -+ erase_pass (cp); -+ break; -+ } - } -- cp = agetpass (_("Re-enter new password: ")); -- if (NULL == cp) { -- memzero (orig, sizeof orig); -+ memzero (orig, sizeof orig); -+ -+ if (i == 0) { - memzero (pass, sizeof pass); - return -1; - } -- if (strcmp (cp, pass) != 0) { -- erase_pass (cp); -- (void) fputs (_("They don't match; try again.\n"), stderr); -- } else { -- erase_pass (cp); -- break; -- } -- } -- memzero (orig, sizeof orig); -- -- if (i == 0) { -- memzero (pass, sizeof pass); -- return -1; - } - - /* -@@ -714,6 +728,7 @@ static void update_shadow (void) - * -u unlock the password of the named account (*) - * -w # set sp_warn to # days (*) - * -x # set sp_max to # days (*) -+ * -s read password from stdin - * - * (*) requires root permission to execute. - * -@@ -781,10 +796,11 @@ int main (int argc, char **argv) - {"unlock", no_argument, NULL, 'u'}, - {"warndays", required_argument, NULL, 'w'}, - {"maxdays", required_argument, NULL, 'x'}, -+ {"stdin", no_argument, NULL, 's'}, - {NULL, 0, NULL, '\0'} - }; - -- while ((c = getopt_long (argc, argv, "adehi:kln:qr:R:P:Suw:x:", -+ while ((c = getopt_long (argc, argv, "adehi:kln:qr:R:P:Suw:x:s", - long_options, NULL)) != -1) { - switch (c) { - case 'a': -@@ -877,6 +893,15 @@ int main (int argc, char **argv) - xflg = true; - anyflag = true; - break; -+ case 's': -+ if (!amroot) { -+ (void) fprintf (stderr, -+ _("%s: only root can use --stdin/-s option\n"), -+ Prog); -+ usage (E_BAD_ARG); -+ } -+ sflg = true; -+ break; - default: - usage (E_BAD_ARG); - } -@@ -1068,7 +1093,16 @@ int main (int argc, char **argv) - * Don't set the real UID for PAM... - */ - if (!anyflag && use_pam) { -- do_pam_passwd (name, qflg, kflg); -+ if (sflg) { -+ cp = agetpass_stdin (); -+ if (cp == NULL) { -+ exit (E_FAILURE); -+ } -+ do_pam_passwd_non_interactive ("passwd", name, cp); -+ erase_pass (cp); -+ } else { -+ do_pam_passwd (name, qflg, kflg); -+ } - exit (E_SUCCESS); - } - #endif /* USE_PAM */ -@@ -1102,4 +1136,3 @@ int main (int argc, char **argv) - - return E_SUCCESS; - } -- diff --git a/shadow-4.14.0-remove-libcrack.patch b/shadow-4.14.0-remove-libcrack.patch deleted file mode 100644 index 4dc1328..0000000 --- a/shadow-4.14.0-remove-libcrack.patch +++ /dev/null @@ -1,306 +0,0 @@ -From 43b4e5a6c41f5c43cad18810f9229e40e8c4a57e Mon Sep 17 00:00:00 2001 -From: Alejandro Colomar -Date: Mon, 30 Oct 2023 12:53:37 +0100 -Subject: [PATCH 1/2] Remove FascistHistory() and FascistHistoryPw() calls - -These functions don't seem to exist anymore. I can't find them in -Debian, nor in a web search. They probably were functions from an -ancient implementation of cracklib that doesn't exist anymore. - -$ git remote -v -origin git@github.com:cracklib/cracklib.git (fetch) -origin git@github.com:cracklib/cracklib.git (push) -$ grep -rni fascisthistory -$ git log --grep FascistHistory -$ git log -S FascistHistory - -Closes: -Cc: Mike Frysinger -Acked-by: Michael Vetter -Signed-off-by: Alejandro Colomar ---- - configure.ac | 4 ---- - libmisc/obscure.c | 8 -------- - src/passwd.c | 33 ++------------------------------- - 3 files changed, 2 insertions(+), 43 deletions(-) - -diff --git a/configure.ac b/configure.ac -index 2c8cca3f..5c8c7764 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -526,10 +526,6 @@ if test "$with_libcrack" = "yes"; then - echo "checking cracklib flavour, don't be surprised by the results" - AC_CHECK_LIB(crack, FascistCheck, - [LIBCRACK=-lcrack AC_DEFINE(HAVE_LIBCRACK, 1, [Defined if you have libcrack.])]) -- AC_CHECK_LIB(crack, FascistHistory, -- AC_DEFINE(HAVE_LIBCRACK_HIST, 1, [Defined if you have the ts&szs cracklib.])) -- AC_CHECK_LIB(crack, FascistHistoryPw, -- AC_DEFINE(HAVE_LIBCRACK_PW, 1, [Defined if it includes *Pw functions.])) - fi - - if test "$with_btrfs" != "no"; then -diff --git a/libmisc/obscure.c b/libmisc/obscure.c -index ccffb71d..4070d4e4 100644 ---- a/libmisc/obscure.c -+++ b/libmisc/obscure.c -@@ -100,11 +100,7 @@ static /*@observer@*//*@null@*/const char *password_check ( - #ifdef HAVE_LIBCRACK - char *dictpath; - --#ifdef HAVE_LIBCRACK_PW -- char *FascistCheckPw (); --#else - char *FascistCheck (); --#endif - #endif - - if (strcmp (new, old) == 0) { -@@ -133,11 +129,7 @@ static /*@observer@*//*@null@*/const char *password_check ( - - dictpath = getdef_str ("CRACKLIB_DICTPATH"); - if (NULL != dictpath) { --#ifdef HAVE_LIBCRACK_PW -- msg = FascistCheckPw (new, dictpath, pwdp); --#else - msg = FascistCheck (new, dictpath); --#endif - } - #endif - } -diff --git a/src/passwd.c b/src/passwd.c -index 67608619..a4f49320 100644 ---- a/src/passwd.c -+++ b/src/passwd.c -@@ -114,7 +114,6 @@ static bool do_update_pwd = false; - /* local function prototypes */ - NORETURN static void usage (int); - --static bool reuse (const char *, const struct passwd *); - static int new_password (const struct passwd *); - - static void check_password (const struct passwd *, const struct spwd *); -@@ -163,27 +162,6 @@ usage (int status) - exit (status); - } - --static bool reuse (const char *pass, const struct passwd *pw) --{ --#ifdef HAVE_LIBCRACK_HIST -- const char *reason; -- --#ifdef HAVE_LIBCRACK_PW -- const char *FascistHistoryPw (const char *, const struct passwd *); -- -- reason = FascistHistory (pass, pw); --#else /* !HAVE_LIBCRACK_PW */ -- const char *FascistHistory (const char *, int); -- -- reason = FascistHistory (pass, pw->pw_uid); --#endif /* !HAVE_LIBCRACK_PW */ -- if (NULL != reason) { -- (void) printf (_("Bad password: %s. "), reason); -- return true; -- } --#endif /* HAVE_LIBCRACK_HIST */ -- return false; --} - - /* - * new_password - validate old password and replace with new (both old and -@@ -202,10 +180,6 @@ static int new_password (const struct passwd *pw) - int pass_max_len = -1; - const char *method; - --#ifdef HAVE_LIBCRACK_HIST -- int HistUpdate (const char *, const char *); --#endif /* HAVE_LIBCRACK_HIST */ -- - /* - * Authenticate the user. The user will be prompted for their own - * password. -@@ -306,7 +280,7 @@ static int new_password (const struct passwd *pw) - STRFCPY (pass, cp); - erase_pass (cp); - -- if (!amroot && (!obscure (orig, pass, pw) || reuse (pass, pw))) { -+ if (!amroot && !obscure(orig, pass, pw)) { - (void) puts (_("Try again.")); - continue; - } -@@ -317,7 +291,7 @@ static int new_password (const struct passwd *pw) - * --marekm - */ - if (amroot && !warned && getdef_bool ("PASS_ALWAYS_WARN") -- && (!obscure (orig, pass, pw) || reuse (pass, pw))) { -+ && !obscure(orig, pass, pw)) { - (void) puts (_("\nWarning: weak password (enter it again to use it anyway).")); - warned = true; - continue; -@@ -357,9 +331,6 @@ static int new_password (const struct passwd *pw) - return -1; - } - --#ifdef HAVE_LIBCRACK_HIST -- HistUpdate (pw->pw_name, crypt_passwd); --#endif /* HAVE_LIBCRACK_HIST */ - STRFCPY (crypt_passwd, cp); - return 0; - } --- -2.43.0 - - -From 45f34ee8c196a98397504cb7ed8576b6f1825cf9 Mon Sep 17 00:00:00 2001 -From: Alejandro Colomar -Date: Mon, 30 Oct 2023 13:31:42 +0100 -Subject: [PATCH 2/2] Remove libcrack support - -Signed-off-by: Alejandro Colomar ---- - configure.ac | 11 ----------- - etc/login.defs | 5 ----- - lib/getdef.c | 1 - - libmisc/obscure.c | 22 ---------------------- - libsubid/Makefile.am | 1 - - src/Makefile.am | 2 +- - 7 files changed, 2 insertions(+), 42 deletions(-) - -diff --git a/configure.ac b/configure.ac -index 5c8c7764..c2b0a1a5 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -243,9 +243,6 @@ AC_ARG_WITH(skey, - AC_ARG_WITH(tcb, - [AS_HELP_STRING([--with-tcb], [use tcb support (incomplete) @<:@default=yes if found@:>@])], - [with_tcb=$withval], [with_tcb=maybe]) --AC_ARG_WITH(libcrack, -- [AS_HELP_STRING([--with-libcrack], [use libcrack @<:@default=no@:>@])], -- [with_libcrack=$withval], [with_libcrack=no]) - AC_ARG_WITH(sha-crypt, - [AS_HELP_STRING([--with-sha-crypt], [allow the SHA256 and SHA512 password encryption algorithms @<:@default=yes@:>@])], - [with_sha_crypt=$withval], [with_sha_crypt=yes]) -@@ -521,13 +518,6 @@ if test "$with_audit" != "no"; then - fi - fi - --AC_SUBST(LIBCRACK) --if test "$with_libcrack" = "yes"; then -- echo "checking cracklib flavour, don't be surprised by the results" -- AC_CHECK_LIB(crack, FascistCheck, -- [LIBCRACK=-lcrack AC_DEFINE(HAVE_LIBCRACK, 1, [Defined if you have libcrack.])]) --fi -- - if test "$with_btrfs" != "no"; then - AC_CHECK_HEADERS([sys/statfs.h linux/magic.h linux/btrfs_tree.h], \ - [btrfs_headers="yes"], [btrfs_headers="no"]) -@@ -768,7 +758,6 @@ echo - echo "shadow will be compiled with the following features:" - echo - echo " auditing support: $with_audit" --echo " CrackLib support: $with_libcrack" - echo " PAM support: $with_libpam" - if test "$with_libpam" = "yes"; then - echo " suid account management tools: $enable_acct_tools_setuid" -diff --git a/etc/login.defs b/etc/login.defs -index 114dbcd9..33622c29 100644 ---- a/etc/login.defs -+++ b/etc/login.defs -@@ -227,11 +227,6 @@ PASS_WARN_AGE 7 - # - SU_WHEEL_ONLY no - --# --# If compiled with cracklib support, sets the path to the dictionaries --# --CRACKLIB_DICTPATH /var/cache/cracklib/cracklib_dict -- - # - # Min/max values for automatic uid selection in useradd(8) - # -diff --git a/lib/getdef.c b/lib/getdef.c -index 977660c2..d64e6343 100644 ---- a/lib/getdef.c -+++ b/lib/getdef.c -@@ -39,7 +39,6 @@ struct itemdef { - #define PAMDEFS \ - {"CHFN_AUTH", NULL}, \ - {"CHSH_AUTH", NULL}, \ -- {"CRACKLIB_DICTPATH", NULL}, \ - {"ENV_HZ", NULL}, \ - {"ENVIRON_FILE", NULL}, \ - {"ENV_TZ", NULL}, \ -diff --git a/libmisc/obscure.c b/libmisc/obscure.c -index 4070d4e4..2aece68b 100644 ---- a/libmisc/obscure.c -+++ b/libmisc/obscure.c -@@ -12,11 +12,6 @@ - #ident "$Id$" - - --/* -- * This version of obscure.c contains modifications to support "cracklib" -- * by Alec Muffet (alec.muffett@uk.sun.com). You must obtain the Cracklib -- * library source code for this function to operate. -- */ - #include - #include - -@@ -97,12 +92,6 @@ static /*@observer@*//*@null@*/const char *password_check ( - const char *msg = NULL; - char *oldmono, *newmono, *wrapped; - --#ifdef HAVE_LIBCRACK -- char *dictpath; -- -- char *FascistCheck (); --#endif -- - if (strcmp (new, old) == 0) { - return _("no change"); - } -@@ -121,17 +110,6 @@ static /*@observer@*//*@null@*/const char *password_check ( - msg = _("too similar"); - } else if (strstr (wrapped, newmono) != NULL) { - msg = _("rotated"); -- } else { --#ifdef HAVE_LIBCRACK -- /* -- * Invoke Alec Muffett's cracklib routines. -- */ -- -- dictpath = getdef_str ("CRACKLIB_DICTPATH"); -- if (NULL != dictpath) { -- msg = FascistCheck (new, dictpath); -- } --#endif - } - strzero (newmono); - strzero (oldmono); -diff --git a/libsubid/Makefile.am b/libsubid/Makefile.am -index 5ba0ab35..b6488e77 100644 ---- a/libsubid/Makefile.am -+++ b/libsubid/Makefile.am -@@ -8,7 +8,6 @@ MISCLIBS = \ - $(LIBAUDIT) \ - $(LIBSELINUX) \ - $(LIBSEMANAGE) \ -- $(LIBCRACK) \ - $(LIBCRYPT_NOPAM) \ - $(LIBSKEY) \ - $(LIBMD) \ -diff --git a/src/Makefile.am b/src/Makefile.am -index fcfee9d2..b6cb09ef 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -123,7 +123,7 @@ login_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(L - newgrp_LDADD = $(LDADD) $(LIBAUDIT) $(LIBCRYPT) $(LIBECONF) - newusers_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF) -ldl - nologin_LDADD = --passwd_LDADD = $(LDADD) $(LIBPAM) $(LIBCRACK) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBECONF) -ldl -+passwd_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBECONF) -ldl - pwck_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) - pwconv_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) - pwunconv_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) --- -2.43.0 - diff --git a/shadow-4.14.0-useradd-def-usrtemplate-selinux-label.patch b/shadow-4.14.0-useradd-def-usrtemplate-selinux-label.patch deleted file mode 100644 index 97b709a..0000000 --- a/shadow-4.14.0-useradd-def-usrtemplate-selinux-label.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 48aa12af31c0b72872b411857d03a518a4200a3d Mon Sep 17 00:00:00 2001 -From: Johannes Segitz -Date: Tue, 26 Sep 2023 15:14:14 +0200 -Subject: [PATCH] useradd: Set proper SELinux labels for def_usrtemplate - -Fixes: 74c17c716 ("Add support for skeleton files from /usr/etc/skel") - -Signed-off-by: Johannes Segitz ---- - src/useradd.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/useradd.c b/src/useradd.c -index 76a4d649..fe62a051 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -2788,7 +2788,7 @@ int main (int argc, char **argv) - if (home_added) { - copy_tree (def_template, prefix_user_home, false, true, - (uid_t)-1, user_id, (gid_t)-1, user_gid); -- copy_tree (def_usrtemplate, prefix_user_home, false, false, -+ copy_tree (def_usrtemplate, prefix_user_home, false, true, - (uid_t)-1, user_id, (gid_t)-1, user_gid); - } else { - fprintf (stderr, --- -2.41.0 - diff --git a/shadow-4.14.0-audit-update.patch b/shadow-4.15.0-audit-update.patch similarity index 80% rename from shadow-4.14.0-audit-update.patch rename to shadow-4.15.0-audit-update.patch index 0ff7dae..60c1ad7 100644 --- a/shadow-4.14.0-audit-update.patch +++ b/shadow-4.15.0-audit-update.patch @@ -1,7 +1,7 @@ -diff -up shadow-4.14.0/libmisc/audit_help.c.audit-update shadow-4.14.0/libmisc/audit_help.c ---- shadow-4.14.0/libmisc/audit_help.c.audit-update 2023-05-26 04:56:11.000000000 +0200 -+++ shadow-4.14.0/libmisc/audit_help.c 2023-08-04 09:30:25.206963536 +0200 -@@ -46,7 +46,7 @@ void audit_help_open (void) +diff -up shadow-4.15.0/lib/audit_help.c.audit-update shadow-4.15.0/lib/audit_help.c +--- shadow-4.15.0/lib/audit_help.c.audit-update 2024-02-01 23:59:36.000000000 +0100 ++++ shadow-4.15.0/lib/audit_help.c 2024-02-09 10:49:57.106840590 +0100 +@@ -48,7 +48,7 @@ void audit_help_open (void) * This function will log a message to the audit system using a predefined * message format. Parameter usage is as follows: * @@ -10,7 +10,7 @@ diff -up shadow-4.14.0/libmisc/audit_help.c.audit-update shadow-4.14.0/libmisc/a * attributes. * pgname - program's name * op - operation. "adding user", "changing finger info", "deleting group" -@@ -66,6 +66,39 @@ void audit_logger (int type, unused cons +@@ -68,6 +68,39 @@ void audit_logger (int type, MAYBE_UNUSE } } @@ -27,7 +27,7 @@ diff -up shadow-4.14.0/libmisc/audit_help.c.audit-update shadow-4.14.0/libmisc/a + * only when user is NULL. + * grp - group name associated with event + */ -+void audit_logger_with_group (int type, unused const char *pgname, ++void audit_logger_with_group (int type, MAYBE_UNUSED const char *pgname, + const char *op, const char *name, unsigned int id, + const char *grp, shadow_audit_result result) +{ @@ -50,10 +50,10 @@ diff -up shadow-4.14.0/libmisc/audit_help.c.audit-update shadow-4.14.0/libmisc/a void audit_logger_message (const char *message, shadow_audit_result result) { if (audit_fd < 0) { -diff -up shadow-4.14.0/libmisc/cleanup_group.c.audit-update shadow-4.14.0/libmisc/cleanup_group.c ---- shadow-4.14.0/libmisc/cleanup_group.c.audit-update 2023-05-26 04:56:11.000000000 +0200 -+++ shadow-4.14.0/libmisc/cleanup_group.c 2023-08-04 09:30:25.207963539 +0200 -@@ -61,7 +61,7 @@ void cleanup_report_mod_group (void *cle +diff -up shadow-4.15.0/lib/cleanup_group.c.audit-update shadow-4.15.0/lib/cleanup_group.c +--- shadow-4.15.0/lib/cleanup_group.c.audit-update 2024-02-01 23:59:36.000000000 +0100 ++++ shadow-4.15.0/lib/cleanup_group.c 2024-02-09 10:49:57.106840590 +0100 +@@ -62,7 +62,7 @@ void cleanup_report_mod_group (void *cle gr_dbname (), info->action)); #ifdef WITH_AUDIT @@ -62,7 +62,7 @@ diff -up shadow-4.14.0/libmisc/cleanup_group.c.audit-update shadow-4.14.0/libmis info->audit_msg, info->name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); -@@ -79,7 +79,7 @@ void cleanup_report_mod_gshadow (void *c +@@ -80,7 +80,7 @@ void cleanup_report_mod_gshadow (void *c sgr_dbname (), info->action)); #ifdef WITH_AUDIT @@ -71,7 +71,7 @@ diff -up shadow-4.14.0/libmisc/cleanup_group.c.audit-update shadow-4.14.0/libmis info->audit_msg, info->name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); -@@ -100,7 +100,7 @@ void cleanup_report_add_group_group (voi +@@ -101,7 +101,7 @@ void cleanup_report_add_group_group (voi SYSLOG ((LOG_ERR, "failed to add group %s to %s", name, gr_dbname ())); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_GROUP, log_get_progname(), @@ -80,7 +80,7 @@ diff -up shadow-4.14.0/libmisc/cleanup_group.c.audit-update shadow-4.14.0/libmis name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -119,8 +119,8 @@ void cleanup_report_add_group_gshadow (v +@@ -120,8 +120,8 @@ void cleanup_report_add_group_gshadow (v SYSLOG ((LOG_ERR, "failed to add group %s to %s", name, sgr_dbname ())); #ifdef WITH_AUDIT @@ -91,7 +91,7 @@ diff -up shadow-4.14.0/libmisc/cleanup_group.c.audit-update shadow-4.14.0/libmis name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -142,8 +142,8 @@ void cleanup_report_del_group_group (voi +@@ -143,8 +143,8 @@ void cleanup_report_del_group_group (voi "failed to remove group %s from %s", name, gr_dbname ())); #ifdef WITH_AUDIT @@ -102,7 +102,7 @@ diff -up shadow-4.14.0/libmisc/cleanup_group.c.audit-update shadow-4.14.0/libmis name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -165,8 +165,8 @@ void cleanup_report_del_group_gshadow (v +@@ -166,8 +166,8 @@ void cleanup_report_del_group_gshadow (v "failed to remove group %s from %s", name, sgr_dbname ())); #ifdef WITH_AUDIT @@ -113,7 +113,7 @@ diff -up shadow-4.14.0/libmisc/cleanup_group.c.audit-update shadow-4.14.0/libmis name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -186,7 +186,7 @@ void cleanup_unlock_group (unused void * +@@ -187,7 +187,7 @@ void cleanup_unlock_group (MAYBE_UNUSED log_get_progname(), gr_dbname ()); SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); #ifdef WITH_AUDIT @@ -122,7 +122,7 @@ diff -up shadow-4.14.0/libmisc/cleanup_group.c.audit-update shadow-4.14.0/libmis SHADOW_AUDIT_FAILURE); #endif } -@@ -206,7 +206,7 @@ void cleanup_unlock_gshadow (unused void +@@ -207,7 +207,7 @@ void cleanup_unlock_gshadow (MAYBE_UNUSE log_get_progname(), sgr_dbname ()); SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); #ifdef WITH_AUDIT @@ -131,10 +131,10 @@ diff -up shadow-4.14.0/libmisc/cleanup_group.c.audit-update shadow-4.14.0/libmis SHADOW_AUDIT_FAILURE); #endif } -diff -up shadow-4.14.0/libmisc/cleanup_user.c.audit-update shadow-4.14.0/libmisc/cleanup_user.c ---- shadow-4.14.0/libmisc/cleanup_user.c.audit-update 2023-05-26 04:56:11.000000000 +0200 -+++ shadow-4.14.0/libmisc/cleanup_user.c 2023-08-04 09:30:25.207963539 +0200 -@@ -43,7 +43,7 @@ void cleanup_report_mod_passwd (void *cl +diff -up shadow-4.15.0/lib/cleanup_user.c.audit-update shadow-4.15.0/lib/cleanup_user.c +--- shadow-4.15.0/lib/cleanup_user.c.audit-update 2024-02-01 23:59:36.000000000 +0100 ++++ shadow-4.15.0/lib/cleanup_user.c 2024-02-09 10:49:57.106840590 +0100 +@@ -44,7 +44,7 @@ void cleanup_report_mod_passwd (void *cl pw_dbname (), info->action)); #ifdef WITH_AUDIT @@ -143,7 +143,7 @@ diff -up shadow-4.14.0/libmisc/cleanup_user.c.audit-update shadow-4.14.0/libmisc info->audit_msg, info->name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); -@@ -64,7 +64,7 @@ void cleanup_report_add_user_passwd (voi +@@ -65,7 +65,7 @@ void cleanup_report_add_user_passwd (voi SYSLOG ((LOG_ERR, "failed to add user %s to %s", name, pw_dbname ())); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, log_get_progname(), @@ -152,7 +152,7 @@ diff -up shadow-4.14.0/libmisc/cleanup_user.c.audit-update shadow-4.14.0/libmisc name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -83,8 +83,8 @@ void cleanup_report_add_user_shadow (voi +@@ -84,8 +84,8 @@ void cleanup_report_add_user_shadow (voi SYSLOG ((LOG_ERR, "failed to add user %s to %s", name, spw_dbname ())); #ifdef WITH_AUDIT @@ -163,7 +163,7 @@ diff -up shadow-4.14.0/libmisc/cleanup_user.c.audit-update shadow-4.14.0/libmisc name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -103,7 +103,7 @@ void cleanup_unlock_passwd (unused void +@@ -104,7 +104,7 @@ void cleanup_unlock_passwd (MAYBE_UNUSED log_get_progname(), pw_dbname ()); SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); #ifdef WITH_AUDIT @@ -172,7 +172,7 @@ diff -up shadow-4.14.0/libmisc/cleanup_user.c.audit-update shadow-4.14.0/libmisc SHADOW_AUDIT_FAILURE); #endif } -@@ -122,7 +122,7 @@ void cleanup_unlock_shadow (unused void +@@ -123,7 +123,7 @@ void cleanup_unlock_shadow (MAYBE_UNUSED log_get_progname(), spw_dbname ()); SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); #ifdef WITH_AUDIT @@ -181,10 +181,10 @@ diff -up shadow-4.14.0/libmisc/cleanup_user.c.audit-update shadow-4.14.0/libmisc SHADOW_AUDIT_FAILURE); #endif } -diff -up shadow-4.14.0/lib/prototypes.h.audit-update shadow-4.14.0/lib/prototypes.h ---- shadow-4.14.0/lib/prototypes.h.audit-update 2023-08-03 18:28:35.000000000 +0200 -+++ shadow-4.14.0/lib/prototypes.h 2023-08-04 09:30:25.207963539 +0200 -@@ -202,12 +202,21 @@ extern int audit_fd; +diff -up shadow-4.15.0/lib/prototypes.h.audit-update shadow-4.15.0/lib/prototypes.h +--- shadow-4.15.0/lib/prototypes.h.audit-update 2024-02-01 23:59:36.000000000 +0100 ++++ shadow-4.15.0/lib/prototypes.h 2024-02-09 10:49:57.106840590 +0100 +@@ -198,12 +198,21 @@ extern int audit_fd; extern void audit_help_open (void); /* Use AUDIT_NO_ID when a name is provided to audit_logger instead of an ID */ #define AUDIT_NO_ID ((unsigned int) -1) @@ -200,16 +200,16 @@ diff -up shadow-4.14.0/lib/prototypes.h.audit-update shadow-4.14.0/lib/prototype extern void audit_logger (int type, const char *pgname, const char *op, const char *name, unsigned int id, shadow_audit_result result); -+void audit_logger_with_group (int type, unused const char *pgname, ++void audit_logger_with_group (int type, MAYBE_UNUSED const char *pgname, + const char *op, const char *name, unsigned int id, + const char *grp, shadow_audit_result result); void audit_logger_message (const char *message, shadow_audit_result result); #endif -diff -up shadow-4.14.0/src/chage.c.audit-update shadow-4.14.0/src/chage.c ---- shadow-4.14.0/src/chage.c.audit-update 2023-08-04 09:30:25.207963539 +0200 -+++ shadow-4.14.0/src/chage.c 2023-08-04 09:31:12.237080212 +0200 -@@ -106,8 +106,8 @@ fail_exit (int code) +diff -up shadow-4.15.0/src/chage.c.audit-update shadow-4.15.0/src/chage.c +--- shadow-4.15.0/src/chage.c.audit-update 2024-01-22 22:36:43.000000000 +0100 ++++ shadow-4.15.0/src/chage.c 2024-02-09 10:49:57.106840590 +0100 +@@ -110,8 +110,8 @@ fail_exit (int code) #ifdef WITH_AUDIT if (E_SUCCESS != code) { @@ -220,7 +220,7 @@ diff -up shadow-4.14.0/src/chage.c.audit-update shadow-4.14.0/src/chage.c } #endif -@@ -841,10 +841,7 @@ int main (int argc, char **argv) +@@ -845,10 +845,7 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: Permission denied.\n"), Prog); fail_exit (E_NOPERM); } @@ -232,7 +232,7 @@ diff -up shadow-4.14.0/src/chage.c.audit-update shadow-4.14.0/src/chage.c list_fields (); fail_exit (E_SUCCESS); } -@@ -863,39 +860,39 @@ int main (int argc, char **argv) +@@ -867,39 +864,39 @@ int main (int argc, char **argv) } #ifdef WITH_AUDIT else { @@ -287,10 +287,10 @@ diff -up shadow-4.14.0/src/chage.c.audit-update shadow-4.14.0/src/chage.c user_name, user_uid, 1); } #endif -diff -up shadow-4.14.0/src/gpasswd.c.audit-update shadow-4.14.0/src/gpasswd.c ---- shadow-4.14.0/src/gpasswd.c.audit-update 2023-06-11 03:35:50.000000000 +0200 -+++ shadow-4.14.0/src/gpasswd.c 2023-08-04 09:30:25.207963539 +0200 -@@ -118,7 +118,7 @@ static void usage (int status) +diff -up shadow-4.15.0/src/gpasswd.c.audit-update shadow-4.15.0/src/gpasswd.c +--- shadow-4.15.0/src/gpasswd.c.audit-update 2024-02-01 23:59:36.000000000 +0100 ++++ shadow-4.15.0/src/gpasswd.c 2024-02-09 10:55:42.642444103 +0100 +@@ -125,7 +125,7 @@ static void usage (int status) (void) fputs (_(" -d, --delete USER remove USER from GROUP\n"), usageout); (void) fputs (_(" -h, --help display this help message and exit\n"), usageout); (void) fputs (_(" -Q, --root CHROOT_DIR directory to chroot into\n"), usageout); @@ -299,22 +299,21 @@ diff -up shadow-4.14.0/src/gpasswd.c.audit-update shadow-4.14.0/src/gpasswd.c (void) fputs (_(" -R, --restrict restrict access to GROUP to its members\n"), usageout); (void) fputs (_(" -M, --members USER,... set the list of members of GROUP\n"), usageout); #ifdef SHADOWGRP -@@ -377,21 +377,14 @@ static void open_files (void) +@@ -384,20 +384,14 @@ static void open_files (void) static void log_gpasswd_failure (const char *suffix) { -#ifdef WITH_AUDIT -- char buf[1024]; +- char buf[1024]; -#endif +- if (aflg) { SYSLOG ((LOG_ERR, "%s failed to add user %s to group %s%s", myname, user, group, suffix)); #ifdef WITH_AUDIT -- snprintf (buf, 1023, -- "%s failed to add user %s to group %s%s", -- myname, user, group, suffix); -- buf[1023] = '\0'; +- SNPRINTF(buf, "%s failed to add user %s to group %s%s", +- myname, user, group, suffix); - audit_logger (AUDIT_USER_ACCT, Prog, - buf, - group, AUDIT_NO_ID, @@ -324,14 +323,12 @@ diff -up shadow-4.14.0/src/gpasswd.c.audit-update shadow-4.14.0/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } else if (dflg) { -@@ -399,13 +392,9 @@ static void log_gpasswd_failure (const c +@@ -405,11 +399,9 @@ static void log_gpasswd_failure (const c "%s failed to remove user %s from group %s%s", myname, user, group, suffix)); #ifdef WITH_AUDIT -- snprintf (buf, 1023, -- "%s failed to remove user %s from group %s%s", -- myname, user, group, suffix); -- buf[1023] = '\0'; +- SNPRINTF(buf, "%s failed to remove user %s from group %s%s", +- myname, user, group, suffix); - audit_logger (AUDIT_USER_ACCT, Prog, - buf, - group, AUDIT_NO_ID, @@ -341,14 +338,12 @@ diff -up shadow-4.14.0/src/gpasswd.c.audit-update shadow-4.14.0/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } else if (rflg) { -@@ -413,13 +402,9 @@ static void log_gpasswd_failure (const c +@@ -417,11 +409,9 @@ static void log_gpasswd_failure (const c "%s failed to remove password of group %s%s", myname, group, suffix)); #ifdef WITH_AUDIT -- snprintf (buf, 1023, -- "%s failed to remove password of group %s%s", -- myname, group, suffix); -- buf[1023] = '\0'; +- SNPRINTF(buf, "%s failed to remove password of group %s%s", +- myname, group, suffix); - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, - buf, - group, AUDIT_NO_ID, @@ -358,14 +353,12 @@ diff -up shadow-4.14.0/src/gpasswd.c.audit-update shadow-4.14.0/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } else if (Rflg) { -@@ -427,13 +412,9 @@ static void log_gpasswd_failure (const c +@@ -429,11 +429,9 @@ static void log_gpasswd_failure (const c "%s failed to restrict access to group %s%s", myname, group, suffix)); #ifdef WITH_AUDIT -- snprintf (buf, 1023, -- "%s failed to restrict access to group %s%s", -- myname, group, suffix); -- buf[1023] = '\0'; +- SNPRINTF(buf, "%s failed to restrict access to group %s%s", +- myname, group, suffix); - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, - buf, - group, AUDIT_NO_ID, @@ -375,14 +368,12 @@ diff -up shadow-4.14.0/src/gpasswd.c.audit-update shadow-4.14.0/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } else if (Aflg || Mflg) { -@@ -443,13 +424,9 @@ static void log_gpasswd_failure (const c +@@ -443,11 +433,9 @@ static void log_gpasswd_failure (const c "%s failed to set the administrators of group %s to %s%s", myname, group, admins, suffix)); #ifdef WITH_AUDIT -- snprintf (buf, 1023, -- "%s failed to set the administrators of group %s to %s%s", -- myname, group, admins, suffix); -- buf[1023] = '\0'; +- SNPRINTF(buf, "%s failed to set the administrators of group %s to %s%s", +- myname, group, admins, suffix); - audit_logger (AUDIT_USER_ACCT, Prog, - buf, - group, AUDIT_NO_ID, @@ -392,14 +383,12 @@ diff -up shadow-4.14.0/src/gpasswd.c.audit-update shadow-4.14.0/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } -@@ -459,13 +436,9 @@ static void log_gpasswd_failure (const c +@@ -457,11 +457,9 @@ static void log_gpasswd_failure (const c "%s failed to set the members of group %s to %s%s", myname, group, members, suffix)); #ifdef WITH_AUDIT -- snprintf (buf, 1023, -- "%s failed to set the members of group %s to %s%s", -- myname, group, members, suffix); -- buf[1023] = '\0'; +- SNPRINTF(buf, "%s failed to set the members of group %s to %s%s", +- myname, group, members, suffix); - audit_logger (AUDIT_USER_ACCT, Prog, - buf, - group, AUDIT_NO_ID, @@ -409,14 +398,12 @@ diff -up shadow-4.14.0/src/gpasswd.c.audit-update shadow-4.14.0/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } -@@ -474,13 +447,9 @@ static void log_gpasswd_failure (const c +@@ -470,11 +468,9 @@ static void log_gpasswd_failure (const c "%s failed to change password of group %s%s", myname, group, suffix)); #ifdef WITH_AUDIT -- snprintf (buf, 1023, -- "%s failed to change password of group %s%s", -- myname, group, suffix); -- buf[1023] = '\0'; +- SNPRINTF(buf, "%s failed to change password of group %s%s", +- myname, group, suffix); - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, - buf, - group, AUDIT_NO_ID, @@ -426,22 +413,12 @@ diff -up shadow-4.14.0/src/gpasswd.c.audit-update shadow-4.14.0/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } -@@ -511,21 +480,14 @@ static void log_gpasswd_failure_gshadow - - static void log_gpasswd_success (const char *suffix) - { --#ifdef WITH_AUDIT -- char buf[1024]; --#endif - if (aflg) { - SYSLOG ((LOG_INFO, +@@ -514,11 +502,9 @@ static void log_gpasswd_success (const c "user %s added by %s to group %s%s", user, myname, group, suffix)); #ifdef WITH_AUDIT -- snprintf (buf, 1023, -- "user %s added by %s to group %s%s", -- user, myname, group, suffix); -- buf[1023] = '\0'; +- SNPRINTF(buf, "user %s added by %s to group %s%s", +- user, myname, group, suffix); - audit_logger (AUDIT_USER_ACCT, Prog, - buf, - group, AUDIT_NO_ID, @@ -451,14 +428,12 @@ diff -up shadow-4.14.0/src/gpasswd.c.audit-update shadow-4.14.0/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } else if (dflg) { -@@ -533,13 +495,9 @@ static void log_gpasswd_success (const c +@@ -526,11 +512,9 @@ static void log_gpasswd_success (const c "user %s removed by %s from group %s%s", user, myname, group, suffix)); #ifdef WITH_AUDIT -- snprintf (buf, 1023, -- "user %s removed by %s from group %s%s", -- user, myname, group, suffix); -- buf[1023] = '\0'; +- SNPRINTF(buf, "user %s removed by %s from group %s%s", +- user, myname, group, suffix); - audit_logger (AUDIT_USER_ACCT, Prog, - buf, - group, AUDIT_NO_ID, @@ -468,14 +443,10 @@ diff -up shadow-4.14.0/src/gpasswd.c.audit-update shadow-4.14.0/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } else if (rflg) { -@@ -547,13 +505,9 @@ static void log_gpasswd_success (const c - "password of group %s removed by %s%s", - group, myname, suffix)); +@@ -540,9 +524,9 @@ static void log_gpasswd_success (const c #ifdef WITH_AUDIT -- snprintf (buf, 1023, -- "password of group %s removed by %s%s", -- group, myname, suffix); -- buf[1023] = '\0'; + SNPRINTF(buf, "password of group %s removed by %s%s", + group, myname, suffix); - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, - buf, - group, AUDIT_NO_ID, @@ -485,14 +456,10 @@ diff -up shadow-4.14.0/src/gpasswd.c.audit-update shadow-4.14.0/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } else if (Rflg) { -@@ -561,13 +515,9 @@ static void log_gpasswd_success (const c - "access to group %s restricted by %s%s", - group, myname, suffix)); +@@ -552,9 +536,9 @@ static void log_gpasswd_success (const c #ifdef WITH_AUDIT -- snprintf (buf, 1023, -- "access to group %s restricted by %s%s", -- group, myname, suffix); -- buf[1023] = '\0'; + SNPRINTF(buf, "access to group %s restricted by %s%s", + group, myname, suffix); - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, - buf, - group, AUDIT_NO_ID, @@ -502,14 +469,12 @@ diff -up shadow-4.14.0/src/gpasswd.c.audit-update shadow-4.14.0/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } else if (Aflg || Mflg) { -@@ -577,13 +527,9 @@ static void log_gpasswd_success (const c +@@ -564,11 +548,9 @@ static void log_gpasswd_success (const c "administrators of group %s set by %s to %s%s", group, myname, admins, suffix)); #ifdef WITH_AUDIT -- snprintf (buf, 1023, -- "administrators of group %s set by %s to %s%s", -- group, myname, admins, suffix); -- buf[1023] = '\0'; +- SNPRINTF(buf, "administrators of group %s set by %s to %s%s", +- group, myname, admins, suffix); - audit_logger (AUDIT_USER_ACCT, Prog, - buf, - group, AUDIT_NO_ID, @@ -519,14 +484,12 @@ diff -up shadow-4.14.0/src/gpasswd.c.audit-update shadow-4.14.0/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } -@@ -593,13 +539,9 @@ static void log_gpasswd_success (const c +@@ -578,11 +560,9 @@ static void log_gpasswd_success (const c "members of group %s set by %s to %s%s", group, myname, members, suffix)); #ifdef WITH_AUDIT -- snprintf (buf, 1023, -- "members of group %s set by %s to %s%s", -- group, myname, members, suffix); -- buf[1023] = '\0'; +- SNPRINTF(buf, "members of group %s set by %s to %s%s", +- group, myname, members, suffix); - audit_logger (AUDIT_USER_ACCT, Prog, - buf, - group, AUDIT_NO_ID, @@ -536,14 +499,12 @@ diff -up shadow-4.14.0/src/gpasswd.c.audit-update shadow-4.14.0/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } -@@ -608,13 +550,9 @@ static void log_gpasswd_success (const c +@@ -591,11 +571,9 @@ static void log_gpasswd_success (const c "password of group %s changed by %s%s", group, myname, suffix)); #ifdef WITH_AUDIT -- snprintf (buf, 1023, -- "password of group %s changed by %s%s", -- group, myname, suffix); -- buf[1023] = '\0'; +- SNPRINTF(buf, "password of group %s changed by %s%s", +- group, myname, suffix); - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, - buf, - group, AUDIT_NO_ID, @@ -553,10 +514,10 @@ diff -up shadow-4.14.0/src/gpasswd.c.audit-update shadow-4.14.0/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } -diff -up shadow-4.14.0/src/groupadd.c.audit-update shadow-4.14.0/src/groupadd.c ---- shadow-4.14.0/src/groupadd.c.audit-update 2023-05-26 04:56:11.000000000 +0200 -+++ shadow-4.14.0/src/groupadd.c 2023-08-04 09:34:34.125581046 +0200 -@@ -114,6 +114,15 @@ usage (int status) +diff -up shadow-4.15.0/src/groupadd.c.audit-update shadow-4.15.0/src/groupadd.c +--- shadow-4.15.0/src/groupadd.c.audit-update 2024-01-22 22:36:43.000000000 +0100 ++++ shadow-4.15.0/src/groupadd.c 2024-02-09 10:58:18.325715738 +0100 +@@ -115,6 +115,15 @@ usage (int status) exit (status); } @@ -572,7 +533,7 @@ diff -up shadow-4.14.0/src/groupadd.c.audit-update shadow-4.14.0/src/groupadd.c /* * new_grent - initialize the values in a group file entry * -@@ -210,7 +219,7 @@ static void grp_update (void) +@@ -211,7 +220,7 @@ static void grp_update (void) fprintf (stderr, _("%s: failed to prepare the new %s entry '%s'\n"), Prog, gr_dbname (), grp.gr_name); @@ -581,7 +542,7 @@ diff -up shadow-4.14.0/src/groupadd.c.audit-update shadow-4.14.0/src/groupadd.c } #ifdef SHADOWGRP /* -@@ -220,7 +229,7 @@ static void grp_update (void) +@@ -221,7 +230,7 @@ static void grp_update (void) fprintf (stderr, _("%s: failed to prepare the new %s entry '%s'\n"), Prog, sgr_dbname (), sgrp.sg_name); @@ -590,7 +551,7 @@ diff -up shadow-4.14.0/src/groupadd.c.audit-update shadow-4.14.0/src/groupadd.c } #endif /* SHADOWGRP */ } -@@ -244,7 +253,7 @@ static void check_new_name (void) +@@ -245,7 +254,7 @@ static void check_new_name (void) fprintf (stderr, _("%s: '%s' is not a valid group name\n"), Prog, group_name); @@ -599,7 +560,7 @@ diff -up shadow-4.14.0/src/groupadd.c.audit-update shadow-4.14.0/src/groupadd.c } /* -@@ -260,11 +269,11 @@ static void close_files (void) +@@ -261,11 +270,11 @@ static void close_files (void) fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, gr_dbname ()); @@ -613,7 +574,7 @@ diff -up shadow-4.14.0/src/groupadd.c.audit-update shadow-4.14.0/src/groupadd.c group_name, group_id, SHADOW_AUDIT_SUCCESS); #endif SYSLOG ((LOG_INFO, "group added to %s: name=%s, GID=%u", -@@ -281,11 +290,11 @@ static void close_files (void) +@@ -282,11 +291,11 @@ static void close_files (void) fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sgr_dbname ()); @@ -628,7 +589,7 @@ diff -up shadow-4.14.0/src/groupadd.c.audit-update shadow-4.14.0/src/groupadd.c group_name, group_id, SHADOW_AUDIT_SUCCESS); #endif SYSLOG ((LOG_INFO, "group added to %s: name=%s", -@@ -298,10 +307,6 @@ static void close_files (void) +@@ -299,10 +308,6 @@ static void close_files (void) #endif /* SHADOWGRP */ /* Report success at the system level */ @@ -639,7 +600,7 @@ diff -up shadow-4.14.0/src/groupadd.c.audit-update shadow-4.14.0/src/groupadd.c SYSLOG ((LOG_INFO, "new group: name=%s, GID=%u", group_name, (unsigned int) group_id)); del_cleanup (cleanup_report_add_group); -@@ -319,7 +324,7 @@ static void open_files (void) +@@ -320,7 +325,7 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, gr_dbname ()); @@ -648,7 +609,7 @@ diff -up shadow-4.14.0/src/groupadd.c.audit-update shadow-4.14.0/src/groupadd.c } add_cleanup (cleanup_unlock_group, NULL); -@@ -329,7 +334,7 @@ static void open_files (void) +@@ -330,7 +335,7 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, sgr_dbname ()); @@ -657,25 +618,25 @@ diff -up shadow-4.14.0/src/groupadd.c.audit-update shadow-4.14.0/src/groupadd.c } add_cleanup (cleanup_unlock_gshadow, NULL); } -@@ -345,7 +350,7 @@ static void open_files (void) +@@ -346,7 +351,7 @@ static void open_files (void) if (gr_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_WARN, "cannot open %s", gr_dbname ())); + fprintf (stderr, _("%s: cannot open %s: %s\n"), Prog, gr_dbname (), strerror(errno)); + SYSLOG ((LOG_WARN, "cannot open %s: %s", gr_dbname (), strerror(errno))); - exit (E_GRP_UPDATE); + fail_exit (E_GRP_UPDATE); } #ifdef SHADOWGRP -@@ -355,7 +360,7 @@ static void open_files (void) - _("%s: cannot open %s\n"), - Prog, sgr_dbname ()); - SYSLOG ((LOG_WARN, "cannot open %s", sgr_dbname ())); +@@ -356,7 +361,7 @@ static void open_files (void) + _("%s: cannot open %s: %s\n"), + Prog, sgr_dbname (), strerror(errno)); + SYSLOG ((LOG_WARN, "cannot open %s: %s", sgr_dbname (), strerror(errno))); - exit (E_GRP_UPDATE); + fail_exit (E_GRP_UPDATE); } } #endif /* SHADOWGRP */ -@@ -492,7 +497,7 @@ static void check_flags (void) +@@ -493,7 +498,7 @@ static void check_flags (void) fprintf (stderr, _("%s: group '%s' already exists\n"), Prog, group_name); @@ -684,16 +645,16 @@ diff -up shadow-4.14.0/src/groupadd.c.audit-update shadow-4.14.0/src/groupadd.c } if (gflg && (prefix_getgrgid (group_id) != NULL)) { -@@ -511,7 +516,7 @@ static void check_flags (void) +@@ -512,7 +517,7 @@ static void check_flags (void) fprintf (stderr, _("%s: GID '%lu' already exists\n"), - Prog, (unsigned long int) group_id); + Prog, (unsigned long) group_id); - exit (E_GID_IN_USE); + fail_exit (E_GID_IN_USE); } } } -@@ -539,7 +544,7 @@ static void check_perms (void) +@@ -540,7 +545,7 @@ static void check_perms (void) fprintf (stderr, _("%s: Cannot determine your user name.\n"), Prog); @@ -702,7 +663,7 @@ diff -up shadow-4.14.0/src/groupadd.c.audit-update shadow-4.14.0/src/groupadd.c } retval = pam_start ("groupadd", pampw->pw_name, &conv, &pamh); -@@ -559,7 +564,7 @@ static void check_perms (void) +@@ -560,7 +565,7 @@ static void check_perms (void) if (NULL != pamh) { (void) pam_end (pamh, retval); } @@ -711,7 +672,7 @@ diff -up shadow-4.14.0/src/groupadd.c.audit-update shadow-4.14.0/src/groupadd.c } (void) pam_end (pamh, retval); #endif /* USE_PAM */ -@@ -594,7 +599,7 @@ int main (int argc, char **argv) +@@ -595,7 +600,7 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: Cannot setup cleanup service.\n"), Prog); @@ -720,7 +681,7 @@ diff -up shadow-4.14.0/src/groupadd.c.audit-update shadow-4.14.0/src/groupadd.c } /* -@@ -621,7 +626,7 @@ int main (int argc, char **argv) +@@ -622,7 +627,7 @@ int main (int argc, char **argv) if (!gflg) { if (find_new_gid (rflg, &group_id, NULL) < 0) { @@ -729,9 +690,9 @@ diff -up shadow-4.14.0/src/groupadd.c.audit-update shadow-4.14.0/src/groupadd.c } } -diff -up shadow-4.14.0/src/groupdel.c.audit-update shadow-4.14.0/src/groupdel.c ---- shadow-4.14.0/src/groupdel.c.audit-update 2023-05-26 04:56:11.000000000 +0200 -+++ shadow-4.14.0/src/groupdel.c 2023-08-04 09:36:42.778900250 +0200 +diff -up shadow-4.15.0/src/groupdel.c.audit-update shadow-4.15.0/src/groupdel.c +--- shadow-4.15.0/src/groupdel.c.audit-update 2023-05-26 04:56:11.000000000 +0200 ++++ shadow-4.15.0/src/groupdel.c 2024-02-09 10:49:57.107840592 +0100 @@ -87,6 +87,15 @@ usage (int status) exit (status); } @@ -899,10 +860,10 @@ diff -up shadow-4.14.0/src/groupdel.c.audit-update shadow-4.14.0/src/groupdel.c } #endif -diff -up shadow-4.14.0/src/groupmod.c.audit-update shadow-4.14.0/src/groupmod.c ---- shadow-4.14.0/src/groupmod.c.audit-update 2023-06-10 02:02:29.000000000 +0200 -+++ shadow-4.14.0/src/groupmod.c 2023-08-04 09:30:25.208963541 +0200 -@@ -473,7 +473,7 @@ static void close_files (void) +diff -up shadow-4.15.0/src/groupmod.c.audit-update shadow-4.15.0/src/groupmod.c +--- shadow-4.15.0/src/groupmod.c.audit-update 2024-01-22 22:36:43.000000000 +0100 ++++ shadow-4.15.0/src/groupmod.c 2024-02-09 10:49:57.107840592 +0100 +@@ -474,7 +474,7 @@ static void close_files (void) exit (E_GRP_UPDATE); } #ifdef WITH_AUDIT @@ -911,7 +872,7 @@ diff -up shadow-4.14.0/src/groupmod.c.audit-update shadow-4.14.0/src/groupmod.c info_group.audit_msg, group_name, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); -@@ -496,7 +496,14 @@ static void close_files (void) +@@ -497,7 +497,14 @@ static void close_files (void) exit (E_GRP_UPDATE); } #ifdef WITH_AUDIT @@ -927,7 +888,7 @@ diff -up shadow-4.14.0/src/groupmod.c.audit-update shadow-4.14.0/src/groupmod.c info_gshadow.audit_msg, group_name, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); -@@ -519,7 +526,7 @@ static void close_files (void) +@@ -520,7 +527,7 @@ static void close_files (void) exit (E_GRP_UPDATE); } #ifdef WITH_AUDIT @@ -936,7 +897,7 @@ diff -up shadow-4.14.0/src/groupmod.c.audit-update shadow-4.14.0/src/groupmod.c info_passwd.audit_msg, group_name, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); -@@ -534,8 +541,8 @@ static void close_files (void) +@@ -535,8 +542,8 @@ static void close_files (void) } #ifdef WITH_AUDIT @@ -947,43 +908,42 @@ diff -up shadow-4.14.0/src/groupmod.c.audit-update shadow-4.14.0/src/groupmod.c group_name, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); #endif -diff -up shadow-4.14.0/src/newgrp.c.audit-update shadow-4.14.0/src/newgrp.c ---- shadow-4.14.0/src/newgrp.c.audit-update 2023-08-04 09:30:25.208963541 +0200 -+++ shadow-4.14.0/src/newgrp.c 2023-08-04 09:51:28.354208322 +0200 -@@ -186,10 +186,10 @@ static void check_perms (const struct gr +diff -up shadow-4.15.0/src/newgrp.c.audit-update shadow-4.15.0/src/newgrp.c +--- shadow-4.15.0/src/newgrp.c.audit-update 2023-12-27 16:58:48.000000000 +0100 ++++ shadow-4.15.0/src/newgrp.c 2024-02-09 11:02:30.575155871 +0100 +@@ -188,10 +188,10 @@ static void check_perms (const struct gr + if (grp->gr_passwd[0] == '\0' || strcmp (cpasswd, grp->gr_passwd) != 0) { #ifdef WITH_AUDIT - snprintf (audit_buf, sizeof(audit_buf), -- "authentication new-gid=%lu", -+ "authentication new_gid=%lu", - (unsigned long) grp->gr_gid); +- SNPRINTF(audit_buf, "authentication new-gid=%lu", ++ SNPRINTF(audit_buf, "authentication new_gid=%lu", + (unsigned long) grp->gr_gid); audit_logger (AUDIT_GRP_AUTH, Prog, - audit_buf, NULL, getuid (), 0); + audit_buf, NULL, getuid (), SHADOW_AUDIT_FAILURE); #endif SYSLOG ((LOG_INFO, "Invalid password for group '%s' from '%s'", -@@ -200,10 +200,10 @@ static void check_perms (const struct gr +@@ -201,10 +201,10 @@ static void check_perms (const struct gr + goto failure; } #ifdef WITH_AUDIT - snprintf (audit_buf, sizeof(audit_buf), -- "authentication new-gid=%lu", -+ "authentication new_gid=%lu", - (unsigned long) grp->gr_gid); +- SNPRINTF(audit_buf, "authentication new-gid=%lu", ++ SNPRINTF(audit_buf, "authentication new_gid=%lu", + (unsigned long) grp->gr_gid); audit_logger (AUDIT_GRP_AUTH, Prog, - audit_buf, NULL, getuid (), 1); + audit_buf, NULL, getuid (), SHADOW_AUDIT_SUCCESS); #endif } -@@ -214,17 +214,6 @@ failure: +@@ -215,16 +215,6 @@ failure: * harm. -- JWP */ closelog (); -#ifdef WITH_AUDIT - if (groupname) { -- snprintf (audit_buf, sizeof(audit_buf), -- "changing new-group=%s", groupname); +- SNPRINTF(audit_buf, "changing new-group=%s", groupname); - audit_logger (AUDIT_CHGRP_ID, Prog, - audit_buf, NULL, getuid (), 0); - } else { @@ -994,12 +954,12 @@ diff -up shadow-4.14.0/src/newgrp.c.audit-update shadow-4.14.0/src/newgrp.c exit (EXIT_FAILURE); } -@@ -298,13 +287,23 @@ static void syslog_sg (const char *name, +@@ -298,13 +288,23 @@ static void syslog_sg (const char *name, is_newgrp ? "newgrp" : "sg", strerror (errno)); #ifdef WITH_AUDIT if (group) { -- snprintf (audit_buf, sizeof(audit_buf), -- "changing new-group=%s", group); +- SNPRINTF(audit_buf, +- "changing new-group=%s", group); + char enc_group[(GROUP_NAME_MAX_LENGTH*2)+1]; + int len = strnlen(group, sizeof(enc_group)/2); + if (audit_value_needs_encoding(group, len)) { @@ -1022,7 +982,7 @@ diff -up shadow-4.14.0/src/newgrp.c.audit-update shadow-4.14.0/src/newgrp.c } #endif exit (EXIT_FAILURE); -@@ -440,7 +439,7 @@ int main (int argc, char **argv) +@@ -440,7 +440,7 @@ int main (int argc, char **argv) Prog); #ifdef WITH_AUDIT audit_logger (AUDIT_CHGRP_ID, Prog, @@ -1031,12 +991,11 @@ diff -up shadow-4.14.0/src/newgrp.c.audit-update shadow-4.14.0/src/newgrp.c #endif SYSLOG ((LOG_WARN, "Cannot determine the user name of the caller (UID %lu)", (unsigned long) getuid ())); -@@ -556,13 +555,22 @@ int main (int argc, char **argv) +@@ -556,12 +556,22 @@ int main (int argc, char **argv) perror ("getgroups"); #ifdef WITH_AUDIT if (group) { -- snprintf (audit_buf, sizeof(audit_buf), -- "changing new-group=%s", group); +- SNPRINTF(audit_buf, "changing new-group=%s", group); + char enc_group[(GROUP_NAME_MAX_LENGTH*2)+1]; + int len = strnlen(group, sizeof(enc_group)/2); + if (audit_value_needs_encoding(group, len)) { @@ -1058,61 +1017,59 @@ diff -up shadow-4.14.0/src/newgrp.c.audit-update shadow-4.14.0/src/newgrp.c } #endif exit (EXIT_FAILURE); -@@ -717,9 +725,9 @@ int main (int argc, char **argv) +@@ -715,9 +725,9 @@ int main (int argc, char **argv) + if (setgid (gid) != 0) { perror ("setgid"); #ifdef WITH_AUDIT - snprintf (audit_buf, sizeof(audit_buf), -- "changing new-gid=%lu", (unsigned long) gid); -+ "changing new_gid=%lu", (unsigned long) gid); +- SNPRINTF(audit_buf, "changing new-gid=%lu", (unsigned long) gid); ++ SNPRINTF(audit_buf, "changing new_gid=%lu", (unsigned long) gid); audit_logger (AUDIT_CHGRP_ID, Prog, - audit_buf, NULL, getuid (), 0); + audit_buf, NULL, getuid (), SHADOW_AUDIT_FAILURE); #endif exit (EXIT_FAILURE); } -@@ -728,9 +736,9 @@ int main (int argc, char **argv) +@@ -725,9 +735,9 @@ int main (int argc, char **argv) + if (setuid (getuid ()) != 0) { perror ("setuid"); #ifdef WITH_AUDIT - snprintf (audit_buf, sizeof(audit_buf), -- "changing new-gid=%lu", (unsigned long) gid); -+ "changing new_gid=%lu", (unsigned long) gid); +- SNPRINTF(audit_buf, "changing new-gid=%lu", (unsigned long) gid); ++ SNPRINTF(audit_buf, "changing new_gid=%lu", (unsigned long) gid); audit_logger (AUDIT_CHGRP_ID, Prog, - audit_buf, NULL, getuid (), 0); + audit_buf, NULL, getuid (), SHADOW_AUDIT_FAILURE); #endif exit (EXIT_FAILURE); } -@@ -744,9 +752,9 @@ int main (int argc, char **argv) +@@ -740,9 +750,9 @@ int main (int argc, char **argv) + closelog (); execl (SHELL, "sh", "-c", command, (char *) NULL); #ifdef WITH_AUDIT - snprintf (audit_buf, sizeof(audit_buf), -- "changing new-gid=%lu", (unsigned long) gid); -+ "changing new_gid=%lu", (unsigned long) gid); +- SNPRINTF(audit_buf, "changing new-gid=%lu", (unsigned long) gid); ++ SNPRINTF(audit_buf, "changing new_gid=%lu", (unsigned long) gid); audit_logger (AUDIT_CHGRP_ID, Prog, - audit_buf, NULL, getuid (), 0); + audit_buf, NULL, getuid (), SHADOW_AUDIT_FAILURE); #endif perror (SHELL); exit ((errno == ENOENT) ? E_CMD_NOTFOUND : E_CMD_NOEXEC); -@@ -810,10 +818,10 @@ int main (int argc, char **argv) +@@ -806,9 +816,9 @@ int main (int argc, char **argv) } #ifdef WITH_AUDIT -- snprintf (audit_buf, sizeof(audit_buf), "changing new-gid=%lu", -+ snprintf (audit_buf, sizeof(audit_buf), "changing new_gid=%lu", - (unsigned long) gid); +- SNPRINTF(audit_buf, "changing new-gid=%lu", (unsigned long) gid); ++ SNPRINTF(audit_buf, "changing new_gid=%lu", (unsigned long) gid); audit_logger (AUDIT_CHGRP_ID, Prog, - audit_buf, NULL, getuid (), 1); + audit_buf, NULL, getuid (), SHADOW_AUDIT_SUCCESS); #endif /* * Exec the login shell and go away. We are trying to get back to -@@ -837,13 +845,22 @@ int main (int argc, char **argv) +@@ -832,12 +842,22 @@ int main (int argc, char **argv) closelog (); #ifdef WITH_AUDIT if (NULL != group) { -- snprintf (audit_buf, sizeof(audit_buf), -- "changing new-group=%s", group); +- SNPRINTF(audit_buf, "changing new-group=%s", group); + char enc_group[(GROUP_NAME_MAX_LENGTH*2)+1]; + int len = strnlen(group, sizeof(enc_group)/2); + if (audit_value_needs_encoding(group, len)) { @@ -1134,10 +1091,10 @@ diff -up shadow-4.14.0/src/newgrp.c.audit-update shadow-4.14.0/src/newgrp.c } #endif exit (EXIT_FAILURE); -diff -up shadow-4.14.0/src/useradd.c.audit-update shadow-4.14.0/src/useradd.c ---- shadow-4.14.0/src/useradd.c.audit-update 2023-07-30 12:38:39.000000000 +0200 -+++ shadow-4.14.0/src/useradd.c 2023-08-04 10:02:18.851935396 +0200 -@@ -240,6 +240,8 @@ static void check_uid_range(int rflg, ui +diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c +--- shadow-4.15.0/src/useradd.c.audit-update 2024-02-01 23:59:36.000000000 +0100 ++++ shadow-4.15.0/src/useradd.c 2024-02-09 10:49:57.108840594 +0100 +@@ -242,6 +242,8 @@ static void check_uid_range(int rflg, ui */ static void fail_exit (int code) { @@ -1146,7 +1103,7 @@ diff -up shadow-4.14.0/src/useradd.c.audit-update shadow-4.14.0/src/useradd.c if (home_added && rmdir(prefix_user_home) != 0) { fprintf(stderr, _("%s: %s was created, but could not be removed\n"), -@@ -250,38 +252,22 @@ static void fail_exit (int code) +@@ -252,38 +254,22 @@ static void fail_exit (int code) if (spw_locked && spw_unlock() == 0) { fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname()); SYSLOG((LOG_ERR, "failed to unlock %s", spw_dbname())); @@ -1185,7 +1142,7 @@ diff -up shadow-4.14.0/src/useradd.c.audit-update shadow-4.14.0/src/useradd.c /* continue */ } #endif -@@ -289,27 +275,23 @@ static void fail_exit (int code) +@@ -291,27 +277,23 @@ static void fail_exit (int code) if (sub_uid_locked && sub_uid_unlock() == 0) { fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname()); SYSLOG((LOG_ERR, "failed to unlock %s", sub_uid_dbname())); @@ -1220,7 +1177,7 @@ diff -up shadow-4.14.0/src/useradd.c.audit-update shadow-4.14.0/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif SYSLOG((LOG_INFO, "failed adding user '%s', exit code: %d", user_name, code)); -@@ -759,7 +741,7 @@ static int set_defaults (void) +@@ -732,7 +714,7 @@ static int set_defaults (void) } #ifdef WITH_AUDIT audit_logger (AUDIT_USYS_CONFIG, Prog, @@ -1229,7 +1186,7 @@ diff -up shadow-4.14.0/src/useradd.c.audit-update shadow-4.14.0/src/useradd.c NULL, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); #endif -@@ -1096,12 +1078,6 @@ static void grp_update (void) +@@ -1060,12 +1042,6 @@ static void grp_update (void) _("%s: Out of memory. Cannot update %s.\n"), Prog, gr_dbname ()); SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", gr_dbname (), user_name)); @@ -1242,7 +1199,7 @@ diff -up shadow-4.14.0/src/useradd.c.audit-update shadow-4.14.0/src/useradd.c fail_exit (E_GRP_UPDATE); /* XXX */ } -@@ -1115,18 +1091,12 @@ static void grp_update (void) +@@ -1079,18 +1055,12 @@ static void grp_update (void) _("%s: failed to prepare the new %s entry '%s'\n"), Prog, gr_dbname (), ngrp->gr_name); SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", gr_dbname (), user_name)); @@ -1264,7 +1221,7 @@ diff -up shadow-4.14.0/src/useradd.c.audit-update shadow-4.14.0/src/useradd.c SHADOW_AUDIT_SUCCESS); #endif SYSLOG ((LOG_INFO, -@@ -1171,12 +1141,6 @@ static void grp_update (void) +@@ -1135,12 +1105,6 @@ static void grp_update (void) _("%s: Out of memory. Cannot update %s.\n"), Prog, sgr_dbname ()); SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", sgr_dbname (), user_name)); @@ -1277,7 +1234,7 @@ diff -up shadow-4.14.0/src/useradd.c.audit-update shadow-4.14.0/src/useradd.c fail_exit (E_GRP_UPDATE); /* XXX */ } -@@ -1190,18 +1154,13 @@ static void grp_update (void) +@@ -1154,18 +1118,13 @@ static void grp_update (void) _("%s: failed to prepare the new %s entry '%s'\n"), Prog, sgr_dbname (), nsgrp->sg_name); SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", sgr_dbname (), user_name)); @@ -1300,7 +1257,7 @@ diff -up shadow-4.14.0/src/useradd.c.audit-update shadow-4.14.0/src/useradd.c SHADOW_AUDIT_SUCCESS); #endif SYSLOG ((LOG_INFO, -@@ -1596,7 +1555,7 @@ static void process_flags (int argc, cha +@@ -1560,7 +1519,7 @@ static void process_flags (int argc, cha Prog, user_name); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1309,7 +1266,7 @@ diff -up shadow-4.14.0/src/useradd.c.audit-update shadow-4.14.0/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1705,7 +1664,7 @@ static void close_files (void) +@@ -1660,7 +1619,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1318,7 +1275,7 @@ diff -up shadow-4.14.0/src/useradd.c.audit-update shadow-4.14.0/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1718,7 +1677,7 @@ static void close_files (void) +@@ -1673,7 +1632,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1327,7 +1284,7 @@ diff -up shadow-4.14.0/src/useradd.c.audit-update shadow-4.14.0/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1735,7 +1694,7 @@ static void close_files (void) +@@ -1690,7 +1649,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1336,7 +1293,7 @@ diff -up shadow-4.14.0/src/useradd.c.audit-update shadow-4.14.0/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1749,7 +1708,7 @@ static void close_files (void) +@@ -1704,7 +1663,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1345,7 +1302,7 @@ diff -up shadow-4.14.0/src/useradd.c.audit-update shadow-4.14.0/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -2012,7 +1971,7 @@ static void grp_add (void) +@@ -1967,7 +1926,7 @@ static void grp_add (void) Prog, gr_dbname (), grp.gr_name); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_GROUP, Prog, @@ -1354,7 +1311,7 @@ diff -up shadow-4.14.0/src/useradd.c.audit-update shadow-4.14.0/src/useradd.c grp.gr_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -2028,7 +1987,7 @@ static void grp_add (void) +@@ -1983,7 +1942,7 @@ static void grp_add (void) Prog, sgr_dbname (), sgrp.sg_name); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_GROUP, Prog, @@ -1363,7 +1320,7 @@ diff -up shadow-4.14.0/src/useradd.c.audit-update shadow-4.14.0/src/useradd.c grp.gr_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -2038,7 +1997,7 @@ static void grp_add (void) +@@ -1993,7 +1952,7 @@ static void grp_add (void) SYSLOG ((LOG_INFO, "new group: name=%s, GID=%u", user_name, user_gid)); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_GROUP, Prog, @@ -1372,7 +1329,7 @@ diff -up shadow-4.14.0/src/useradd.c.audit-update shadow-4.14.0/src/useradd.c grp.gr_name, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); #endif -@@ -2240,11 +2199,6 @@ static void usr_update (unsigned long su +@@ -2195,11 +2154,6 @@ static void usr_update (unsigned long su fprintf (stderr, _("%s: failed to prepare the new %s entry '%s'\n"), Prog, spw_dbname (), spent.sp_namp); @@ -1384,7 +1341,7 @@ diff -up shadow-4.14.0/src/useradd.c.audit-update shadow-4.14.0/src/useradd.c fail_exit (E_PW_UPDATE); } #ifdef ENABLE_SUBIDS -@@ -2271,7 +2225,7 @@ static void usr_update (unsigned long su +@@ -2226,7 +2180,7 @@ static void usr_update (unsigned long su * and we can use the real ID thereafter. */ audit_logger (AUDIT_ADD_USER, Prog, @@ -1393,7 +1350,7 @@ diff -up shadow-4.14.0/src/useradd.c.audit-update shadow-4.14.0/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); #endif -@@ -2365,10 +2319,6 @@ static void create_home (void) +@@ -2321,10 +2275,6 @@ static void create_home (void) if (mkdir(path, 0) != 0) { fprintf(stderr, _("%s: cannot create directory %s\n"), Prog, path); @@ -1404,7 +1361,7 @@ diff -up shadow-4.14.0/src/useradd.c.audit-update shadow-4.14.0/src/useradd.c fail_exit(E_HOMEDIR); } if (chown(path, 0, 0) < 0) { -@@ -2393,7 +2343,7 @@ static void create_home (void) +@@ -2349,7 +2299,7 @@ static void create_home (void) } home_added = true; #ifdef WITH_AUDIT @@ -1413,7 +1370,7 @@ diff -up shadow-4.14.0/src/useradd.c.audit-update shadow-4.14.0/src/useradd.c user_name, user_id, SHADOW_AUDIT_SUCCESS); #endif #ifdef WITH_SELINUX -@@ -2637,12 +2587,6 @@ int main (int argc, char **argv) +@@ -2594,12 +2544,6 @@ int main (int argc, char **argv) */ if (prefix_getpwnam (user_name) != NULL) { /* local, no need for xgetpwnam */ fprintf (stderr, _("%s: user '%s' already exists\n"), Prog, user_name); @@ -1426,7 +1383,7 @@ diff -up shadow-4.14.0/src/useradd.c.audit-update shadow-4.14.0/src/useradd.c fail_exit (E_NAME_IN_USE); } -@@ -2658,12 +2602,6 @@ int main (int argc, char **argv) +@@ -2615,12 +2559,6 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: group %s exists - if you want to add this user to that group, use -g.\n"), Prog, user_name); @@ -1439,7 +1396,7 @@ diff -up shadow-4.14.0/src/useradd.c.audit-update shadow-4.14.0/src/useradd.c fail_exit (E_NAME_IN_USE); } } -@@ -2693,12 +2631,6 @@ int main (int argc, char **argv) +@@ -2650,12 +2588,6 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: UID %lu is not unique\n"), Prog, (unsigned long) user_id); @@ -1452,7 +1409,7 @@ diff -up shadow-4.14.0/src/useradd.c.audit-update shadow-4.14.0/src/useradd.c fail_exit (E_UID_IN_USE); } } -@@ -2773,9 +2705,9 @@ int main (int argc, char **argv) +@@ -2730,9 +2662,9 @@ int main (int argc, char **argv) _("%s: warning: the user name %s to %s SELinux user mapping failed.\n"), Prog, user_name, user_selinux); #ifdef WITH_AUDIT @@ -1465,10 +1422,10 @@ diff -up shadow-4.14.0/src/useradd.c.audit-update shadow-4.14.0/src/useradd.c #endif /* WITH_AUDIT */ fail_exit (E_SE_UPDATE); } -diff -up shadow-4.14.0/src/userdel.c.audit-update shadow-4.14.0/src/userdel.c ---- shadow-4.14.0/src/userdel.c.audit-update 2023-06-10 02:02:29.000000000 +0200 -+++ shadow-4.14.0/src/userdel.c 2023-08-04 10:26:18.225695416 +0200 -@@ -204,9 +204,9 @@ static void update_groups (void) +diff -up shadow-4.15.0/src/userdel.c.audit-update shadow-4.15.0/src/userdel.c +--- shadow-4.15.0/src/userdel.c.audit-update 2023-12-27 16:58:48.000000000 +0100 ++++ shadow-4.15.0/src/userdel.c 2024-02-09 10:49:57.108840594 +0100 +@@ -206,9 +206,9 @@ static void update_groups (void) * Update the DBM group file with the new entry as well. */ #ifdef WITH_AUDIT @@ -1481,7 +1438,7 @@ diff -up shadow-4.14.0/src/userdel.c.audit-update shadow-4.14.0/src/userdel.c #endif /* WITH_AUDIT */ SYSLOG ((LOG_INFO, "delete '%s' from group '%s'\n", user_name, ngrp->gr_name)); -@@ -265,9 +265,9 @@ static void update_groups (void) +@@ -267,9 +267,9 @@ static void update_groups (void) exit (E_GRP_UPDATE); } #ifdef WITH_AUDIT @@ -1494,7 +1451,7 @@ diff -up shadow-4.14.0/src/userdel.c.audit-update shadow-4.14.0/src/userdel.c #endif /* WITH_AUDIT */ SYSLOG ((LOG_INFO, "delete '%s' from shadow group '%s'\n", user_name, nsgrp->sg_name)); -@@ -343,9 +343,9 @@ static void remove_usergroup (void) +@@ -345,9 +345,9 @@ static void remove_usergroup (void) } #ifdef WITH_AUDIT @@ -1507,7 +1464,7 @@ diff -up shadow-4.14.0/src/userdel.c.audit-update shadow-4.14.0/src/userdel.c SHADOW_AUDIT_SUCCESS); #endif /* WITH_AUDIT */ SYSLOG ((LOG_INFO, -@@ -361,9 +361,9 @@ static void remove_usergroup (void) +@@ -363,9 +363,9 @@ static void remove_usergroup (void) fail_exit (E_GRP_UPDATE); } #ifdef WITH_AUDIT @@ -1520,7 +1477,7 @@ diff -up shadow-4.14.0/src/userdel.c.audit-update shadow-4.14.0/src/userdel.c SHADOW_AUDIT_SUCCESS); #endif /* WITH_AUDIT */ SYSLOG ((LOG_INFO, -@@ -525,7 +525,7 @@ static void fail_exit (int code) +@@ -527,7 +527,7 @@ static void fail_exit (int code) #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, @@ -1529,7 +1486,7 @@ diff -up shadow-4.14.0/src/userdel.c.audit-update shadow-4.14.0/src/userdel.c user_name, user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -544,22 +544,12 @@ static void open_files (void) +@@ -546,22 +546,12 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, pw_dbname ()); @@ -1552,7 +1509,7 @@ diff -up shadow-4.14.0/src/userdel.c.audit-update shadow-4.14.0/src/userdel.c fail_exit (E_PW_UPDATE); } if (is_shadow_pwd) { -@@ -567,11 +557,6 @@ static void open_files (void) +@@ -569,11 +559,6 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, spw_dbname ()); @@ -1564,7 +1521,7 @@ diff -up shadow-4.14.0/src/userdel.c.audit-update shadow-4.14.0/src/userdel.c fail_exit (E_PW_UPDATE); } spw_locked = true; -@@ -579,11 +564,6 @@ static void open_files (void) +@@ -581,11 +566,6 @@ static void open_files (void) fprintf (stderr, _("%s: cannot open %s\n"), Prog, spw_dbname ()); @@ -1576,7 +1533,7 @@ diff -up shadow-4.14.0/src/userdel.c.audit-update shadow-4.14.0/src/userdel.c fail_exit (E_PW_UPDATE); } } -@@ -591,21 +571,11 @@ static void open_files (void) +@@ -593,21 +573,11 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, gr_dbname ()); @@ -1598,7 +1555,7 @@ diff -up shadow-4.14.0/src/userdel.c.audit-update shadow-4.14.0/src/userdel.c fail_exit (E_GRP_UPDATE); } #ifdef SHADOWGRP -@@ -614,22 +584,12 @@ static void open_files (void) +@@ -616,22 +586,12 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, sgr_dbname ()); @@ -1621,7 +1578,7 @@ diff -up shadow-4.14.0/src/userdel.c.audit-update shadow-4.14.0/src/userdel.c fail_exit (E_GRP_UPDATE); } } -@@ -640,22 +600,12 @@ static void open_files (void) +@@ -642,22 +602,12 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, sub_uid_dbname ()); @@ -1644,7 +1601,7 @@ diff -up shadow-4.14.0/src/userdel.c.audit-update shadow-4.14.0/src/userdel.c fail_exit (E_SUB_UID_UPDATE); } } -@@ -664,22 +614,12 @@ static void open_files (void) +@@ -666,22 +616,12 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, sub_gid_dbname ()); @@ -1667,7 +1624,7 @@ diff -up shadow-4.14.0/src/userdel.c.audit-update shadow-4.14.0/src/userdel.c fail_exit (E_SUB_GID_UPDATE); } } -@@ -724,7 +664,7 @@ static void update_user (void) +@@ -726,7 +666,7 @@ static void update_user (void) #endif /* ENABLE_SUBIDS */ #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, @@ -1676,7 +1633,7 @@ diff -up shadow-4.14.0/src/userdel.c.audit-update shadow-4.14.0/src/userdel.c user_name, user_id, SHADOW_AUDIT_SUCCESS); #endif /* WITH_AUDIT */ SYSLOG ((LOG_INFO, "delete user '%s'\n", user_name)); -@@ -831,7 +771,7 @@ static int remove_mailbox (void) +@@ -824,7 +764,7 @@ static int remove_mailbox (void) SYSLOG ((LOG_ERR, "Cannot remove %s: %s", mailfile, strerror (errno))); #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, @@ -1685,7 +1642,7 @@ diff -up shadow-4.14.0/src/userdel.c.audit-update shadow-4.14.0/src/userdel.c user_name, user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ free(mailfile); -@@ -847,7 +787,7 @@ static int remove_mailbox (void) +@@ -840,7 +780,7 @@ static int remove_mailbox (void) SYSLOG ((LOG_ERR, "Cannot remove %s: %s", mailfile, strerror (errno))); #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, @@ -1694,7 +1651,7 @@ diff -up shadow-4.14.0/src/userdel.c.audit-update shadow-4.14.0/src/userdel.c user_name, user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ errors = 1; -@@ -856,8 +796,8 @@ static int remove_mailbox (void) +@@ -849,8 +789,8 @@ static int remove_mailbox (void) #ifdef WITH_AUDIT else { @@ -1705,7 +1662,7 @@ diff -up shadow-4.14.0/src/userdel.c.audit-update shadow-4.14.0/src/userdel.c user_name, user_id, SHADOW_AUDIT_SUCCESS); } #endif /* WITH_AUDIT */ -@@ -874,7 +814,7 @@ static int remove_mailbox (void) +@@ -867,7 +807,7 @@ static int remove_mailbox (void) mailfile, strerror (errno))); #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, @@ -1714,7 +1671,7 @@ diff -up shadow-4.14.0/src/userdel.c.audit-update shadow-4.14.0/src/userdel.c user_name, user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ free(mailfile); -@@ -890,7 +830,7 @@ static int remove_mailbox (void) +@@ -883,7 +823,7 @@ static int remove_mailbox (void) SYSLOG ((LOG_ERR, "Cannot remove %s: %s", mailfile, strerror (errno))); #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, @@ -1723,7 +1680,7 @@ diff -up shadow-4.14.0/src/userdel.c.audit-update shadow-4.14.0/src/userdel.c user_name, user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ errors = 1; -@@ -899,8 +839,8 @@ static int remove_mailbox (void) +@@ -892,8 +832,8 @@ static int remove_mailbox (void) #ifdef WITH_AUDIT else { @@ -1734,7 +1691,7 @@ diff -up shadow-4.14.0/src/userdel.c.audit-update shadow-4.14.0/src/userdel.c user_name, user_id, SHADOW_AUDIT_SUCCESS); } #endif /* WITH_AUDIT */ -@@ -1118,7 +1058,7 @@ int main (int argc, char **argv) +@@ -1108,7 +1048,7 @@ int main (int argc, char **argv) Prog, user_name); #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, @@ -1743,7 +1700,7 @@ diff -up shadow-4.14.0/src/userdel.c.audit-update shadow-4.14.0/src/userdel.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -1174,7 +1114,7 @@ int main (int argc, char **argv) +@@ -1158,7 +1098,7 @@ int main (int argc, char **argv) if (!fflg) { #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, @@ -1752,7 +1709,7 @@ diff -up shadow-4.14.0/src/userdel.c.audit-update shadow-4.14.0/src/userdel.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -1268,8 +1208,8 @@ int main (int argc, char **argv) +@@ -1252,8 +1192,8 @@ int main (int argc, char **argv) #ifdef WITH_AUDIT else { @@ -1763,7 +1720,7 @@ diff -up shadow-4.14.0/src/userdel.c.audit-update shadow-4.14.0/src/userdel.c user_name, user_id, SHADOW_AUDIT_SUCCESS); } #endif /* WITH_AUDIT */ -@@ -1277,7 +1217,7 @@ int main (int argc, char **argv) +@@ -1261,7 +1201,7 @@ int main (int argc, char **argv) #ifdef WITH_AUDIT if (0 != errors) { audit_logger (AUDIT_DEL_USER, Prog, @@ -1772,7 +1729,7 @@ diff -up shadow-4.14.0/src/userdel.c.audit-update shadow-4.14.0/src/userdel.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); } -@@ -1290,8 +1230,8 @@ int main (int argc, char **argv) +@@ -1274,8 +1214,8 @@ int main (int argc, char **argv) _("%s: warning: the user name %s to SELinux user mapping removal failed.\n"), Prog, user_name); #ifdef WITH_AUDIT @@ -1783,10 +1740,10 @@ diff -up shadow-4.14.0/src/userdel.c.audit-update shadow-4.14.0/src/userdel.c user_name, user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ fail_exit (E_SE_UPDATE); -diff -up shadow-4.14.0/src/usermod.c.audit-update shadow-4.14.0/src/usermod.c ---- shadow-4.14.0/src/usermod.c.audit-update 2023-07-30 12:38:39.000000000 +0200 -+++ shadow-4.14.0/src/usermod.c 2023-08-04 10:33:04.601749324 +0200 -@@ -427,7 +427,7 @@ static char *new_pw_passwd (char *pw_pas +diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c +--- shadow-4.15.0/src/usermod.c.audit-update 2024-02-01 23:59:36.000000000 +0100 ++++ shadow-4.15.0/src/usermod.c 2024-02-09 10:49:57.108840594 +0100 +@@ -431,7 +431,7 @@ static char *new_pw_passwd (char *pw_pas #ifdef WITH_AUDIT audit_logger (AUDIT_USER_CHAUTHTOK, Prog, @@ -1795,7 +1752,7 @@ diff -up shadow-4.14.0/src/usermod.c.audit-update shadow-4.14.0/src/usermod.c #endif SYSLOG ((LOG_INFO, "lock user '%s' password", user_newname)); strcpy (buf, "!"); -@@ -444,14 +444,14 @@ static char *new_pw_passwd (char *pw_pas +@@ -448,14 +448,14 @@ static char *new_pw_passwd (char *pw_pas #ifdef WITH_AUDIT audit_logger (AUDIT_USER_CHAUTHTOK, Prog, @@ -1812,7 +1769,7 @@ diff -up shadow-4.14.0/src/usermod.c.audit-update shadow-4.14.0/src/usermod.c #endif SYSLOG ((LOG_INFO, "change user '%s' password", user_newname)); pw_pass = xstrdup (user_pass); -@@ -479,8 +479,8 @@ static void new_pwent (struct passwd *pw +@@ -483,8 +483,8 @@ static void new_pwent (struct passwd *pw fail_exit (E_NAME_IN_USE); } #ifdef WITH_AUDIT @@ -1823,7 +1780,7 @@ diff -up shadow-4.14.0/src/usermod.c.audit-update shadow-4.14.0/src/usermod.c #endif SYSLOG ((LOG_INFO, "change user name '%s' to '%s'", -@@ -499,8 +499,8 @@ static void new_pwent (struct passwd *pw +@@ -503,8 +503,8 @@ static void new_pwent (struct passwd *pw if (uflg) { #ifdef WITH_AUDIT @@ -1834,7 +1791,7 @@ diff -up shadow-4.14.0/src/usermod.c.audit-update shadow-4.14.0/src/usermod.c #endif SYSLOG ((LOG_INFO, "change user '%s' UID from '%d' to '%d'", -@@ -509,8 +509,8 @@ static void new_pwent (struct passwd *pw +@@ -513,8 +513,8 @@ static void new_pwent (struct passwd *pw } if (gflg) { #ifdef WITH_AUDIT @@ -1845,7 +1802,7 @@ diff -up shadow-4.14.0/src/usermod.c.audit-update shadow-4.14.0/src/usermod.c user_newname, user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -520,16 +520,16 @@ static void new_pwent (struct passwd *pw +@@ -524,16 +524,16 @@ static void new_pwent (struct passwd *pw } if (cflg) { #ifdef WITH_AUDIT @@ -1866,7 +1823,7 @@ diff -up shadow-4.14.0/src/usermod.c.audit-update shadow-4.14.0/src/usermod.c user_newname, user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -545,8 +545,8 @@ static void new_pwent (struct passwd *pw +@@ -549,8 +549,8 @@ static void new_pwent (struct passwd *pw } if (sflg) { #ifdef WITH_AUDIT @@ -1877,7 +1834,7 @@ diff -up shadow-4.14.0/src/usermod.c.audit-update shadow-4.14.0/src/usermod.c user_newname, user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -576,8 +576,8 @@ static void new_spent (struct spwd *spen +@@ -580,8 +580,8 @@ static void new_spent (struct spwd *spen if (fflg) { #ifdef WITH_AUDIT @@ -1888,7 +1845,7 @@ diff -up shadow-4.14.0/src/usermod.c.audit-update shadow-4.14.0/src/usermod.c user_newname, user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -591,8 +591,8 @@ static void new_spent (struct spwd *spen +@@ -595,8 +595,8 @@ static void new_spent (struct spwd *spen date_to_str (sizeof(new_exp), new_exp, user_newexpire * DAY); date_to_str (sizeof(old_exp), old_exp, user_expire * DAY); #ifdef WITH_AUDIT @@ -1899,7 +1856,7 @@ diff -up shadow-4.14.0/src/usermod.c.audit-update shadow-4.14.0/src/usermod.c user_newname, user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -677,9 +677,9 @@ fail_exit (int code) +@@ -681,9 +681,9 @@ fail_exit (int code) #endif /* ENABLE_SUBIDS */ #ifdef WITH_AUDIT @@ -1912,7 +1869,7 @@ diff -up shadow-4.14.0/src/usermod.c.audit-update shadow-4.14.0/src/usermod.c #endif exit (code); } -@@ -741,9 +741,12 @@ static void update_group (void) +@@ -745,9 +745,12 @@ static void update_group (void) user_newname); changed = true; #ifdef WITH_AUDIT @@ -1928,7 +1885,7 @@ diff -up shadow-4.14.0/src/usermod.c.audit-update shadow-4.14.0/src/usermod.c #endif SYSLOG ((LOG_INFO, "change '%s' to '%s' in group '%s'", -@@ -757,9 +760,11 @@ static void update_group (void) +@@ -761,9 +764,11 @@ static void update_group (void) ngrp->gr_mem = del_list (ngrp->gr_mem, user_name); changed = true; #ifdef WITH_AUDIT @@ -1943,7 +1900,7 @@ diff -up shadow-4.14.0/src/usermod.c.audit-update shadow-4.14.0/src/usermod.c #endif SYSLOG ((LOG_INFO, "delete '%s' from group '%s'", -@@ -772,9 +777,11 @@ static void update_group (void) +@@ -776,9 +781,11 @@ static void update_group (void) ngrp->gr_mem = add_list (ngrp->gr_mem, user_newname); changed = true; #ifdef WITH_AUDIT @@ -1958,7 +1915,7 @@ diff -up shadow-4.14.0/src/usermod.c.audit-update shadow-4.14.0/src/usermod.c #endif SYSLOG ((LOG_INFO, "add '%s' to group '%s'", user_newname, ngrp->gr_name)); -@@ -859,9 +866,10 @@ static void update_gshadow (void) +@@ -863,9 +870,10 @@ static void update_gshadow (void) nsgrp->sg_adm = add_list (nsgrp->sg_adm, user_newname); changed = true; #ifdef WITH_AUDIT @@ -1972,7 +1929,7 @@ diff -up shadow-4.14.0/src/usermod.c.audit-update shadow-4.14.0/src/usermod.c #endif SYSLOG ((LOG_INFO, "change admin '%s' to '%s' in shadow group '%s'", -@@ -881,9 +889,10 @@ static void update_gshadow (void) +@@ -885,9 +893,10 @@ static void update_gshadow (void) user_newname); changed = true; #ifdef WITH_AUDIT @@ -1986,7 +1943,7 @@ diff -up shadow-4.14.0/src/usermod.c.audit-update shadow-4.14.0/src/usermod.c #endif SYSLOG ((LOG_INFO, "change '%s' to '%s' in shadow group '%s'", -@@ -897,9 +906,10 @@ static void update_gshadow (void) +@@ -901,9 +910,10 @@ static void update_gshadow (void) nsgrp->sg_mem = del_list (nsgrp->sg_mem, user_name); changed = true; #ifdef WITH_AUDIT @@ -2000,7 +1957,7 @@ diff -up shadow-4.14.0/src/usermod.c.audit-update shadow-4.14.0/src/usermod.c #endif SYSLOG ((LOG_INFO, "delete '%s' from shadow group '%s'", -@@ -912,9 +922,10 @@ static void update_gshadow (void) +@@ -916,9 +926,10 @@ static void update_gshadow (void) nsgrp->sg_mem = add_list (nsgrp->sg_mem, user_newname); changed = true; #ifdef WITH_AUDIT @@ -2014,7 +1971,7 @@ diff -up shadow-4.14.0/src/usermod.c.audit-update shadow-4.14.0/src/usermod.c #endif SYSLOG ((LOG_INFO, "add '%s' to shadow group '%s'", user_newname, nsgrp->sg_name)); -@@ -1830,8 +1841,8 @@ static void move_home (void) +@@ -1829,8 +1840,8 @@ static void move_home (void) #ifdef WITH_AUDIT if (uflg || gflg) { @@ -2025,7 +1982,7 @@ diff -up shadow-4.14.0/src/usermod.c.audit-update shadow-4.14.0/src/usermod.c user_newname, user_newid, 1); } #endif -@@ -1849,8 +1860,8 @@ static void move_home (void) +@@ -1848,8 +1859,8 @@ static void move_home (void) fail_exit (E_HOMEDIR); } #ifdef WITH_AUDIT @@ -2036,7 +1993,7 @@ diff -up shadow-4.14.0/src/usermod.c.audit-update shadow-4.14.0/src/usermod.c user_newname, user_newid, 1); #endif return; -@@ -1877,9 +1888,9 @@ static void move_home (void) +@@ -1876,9 +1887,9 @@ static void move_home (void) Prog, prefix_user_home); } #ifdef WITH_AUDIT @@ -2048,7 +2005,7 @@ diff -up shadow-4.14.0/src/usermod.c.audit-update shadow-4.14.0/src/usermod.c user_newname, user_newid, 1); -@@ -2100,8 +2111,8 @@ static void move_mailbox (void) +@@ -2102,8 +2113,8 @@ static void move_mailbox (void) } #ifdef WITH_AUDIT else { @@ -2059,7 +2016,7 @@ diff -up shadow-4.14.0/src/usermod.c.audit-update shadow-4.14.0/src/usermod.c user_newname, user_newid, 1); } #endif -@@ -2129,8 +2140,8 @@ static void move_mailbox (void) +@@ -2126,8 +2137,8 @@ static void move_mailbox (void) } #ifdef WITH_AUDIT else { @@ -2070,7 +2027,7 @@ diff -up shadow-4.14.0/src/usermod.c.audit-update shadow-4.14.0/src/usermod.c user_newname, user_newid, 1); } -@@ -2331,8 +2342,8 @@ int main (int argc, char **argv) +@@ -2328,8 +2339,8 @@ int main (int argc, char **argv) _("%s: warning: the user name %s to %s SELinux user mapping failed.\n"), Prog, user_name, user_selinux); #ifdef WITH_AUDIT @@ -2081,7 +2038,7 @@ diff -up shadow-4.14.0/src/usermod.c.audit-update shadow-4.14.0/src/usermod.c user_name, user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -2344,8 +2355,8 @@ int main (int argc, char **argv) +@@ -2341,8 +2352,8 @@ int main (int argc, char **argv) _("%s: warning: the user name %s to SELinux user mapping removal failed.\n"), Prog, user_name); #ifdef WITH_AUDIT @@ -2092,7 +2049,7 @@ diff -up shadow-4.14.0/src/usermod.c.audit-update shadow-4.14.0/src/usermod.c user_name, user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -2388,8 +2399,8 @@ int main (int argc, char **argv) +@@ -2385,8 +2396,8 @@ int main (int argc, char **argv) */ #ifdef WITH_AUDIT if (uflg || gflg) { diff --git a/shadow-4.2.1-date-parsing.patch b/shadow-4.15.0-date-parsing.patch similarity index 93% rename from shadow-4.2.1-date-parsing.patch rename to shadow-4.15.0-date-parsing.patch index 2a798d0..272d2df 100644 --- a/shadow-4.2.1-date-parsing.patch +++ b/shadow-4.15.0-date-parsing.patch @@ -1,7 +1,7 @@ -Index: shadow-4.5/libmisc/getdate.y +Index: shadow-4.5/lib/getdate.y =================================================================== ---- shadow-4.5.orig/libmisc/getdate.y -+++ shadow-4.5/libmisc/getdate.y +--- shadow-4.5.orig/lib/getdate.y ++++ shadow-4.5/lib/getdate.y @@ -152,6 +152,7 @@ static int yyHaveDay; static int yyHaveRel; static int yyHaveTime; diff --git a/shadow-4.14.0-manfix.patch b/shadow-4.15.0-manfix.patch similarity index 76% rename from shadow-4.14.0-manfix.patch rename to shadow-4.15.0-manfix.patch index 70f030e..34e62f9 100644 --- a/shadow-4.14.0-manfix.patch +++ b/shadow-4.15.0-manfix.patch @@ -1,7 +1,7 @@ -diff -up shadow-4.8.1/man/groupmems.8.xml.manfix shadow-4.8.1/man/groupmems.8.xml ---- shadow-4.8.1/man/groupmems.8.xml.manfix 2020-03-17 15:34:48.750414984 +0100 -+++ shadow-4.8.1/man/groupmems.8.xml 2020-03-17 15:41:13.383588722 +0100 -@@ -179,20 +179,10 @@ +diff -up shadow-4.15.0/man/groupmems.8.xml.manfix shadow-4.15.0/man/groupmems.8.xml +--- shadow-4.15.0/man/groupmems.8.xml.manfix 2023-05-26 04:56:11.000000000 +0200 ++++ shadow-4.15.0/man/groupmems.8.xml 2024-02-09 10:42:20.337036378 +0100 +@@ -156,20 +156,10 @@ SETUP @@ -25,10 +25,10 @@ diff -up shadow-4.8.1/man/groupmems.8.xml.manfix shadow-4.8.1/man/groupmems.8.xm -diff -up shadow-4.8.1/man/ja/man5/login.defs.5.manfix shadow-4.8.1/man/ja/man5/login.defs.5 ---- shadow-4.8.1/man/ja/man5/login.defs.5.manfix 2019-07-23 17:26:08.000000000 +0200 -+++ shadow-4.8.1/man/ja/man5/login.defs.5 2020-03-17 15:34:48.750414984 +0100 -@@ -147,10 +147,6 @@ 以下の参照表は、 +diff -up shadow-4.15.0/man/ja/man5/login.defs.5.manfix shadow-4.15.0/man/ja/man5/login.defs.5 +--- shadow-4.15.0/man/ja/man5/login.defs.5.manfix 2023-03-13 21:58:56.000000000 +0100 ++++ shadow-4.15.0/man/ja/man5/login.defs.5 2024-02-09 10:42:20.337036378 +0100 +@@ -123,10 +123,6 @@ 以下の参照表は、 shadow パスワード機能のどのプログラムが どのパラメータを使用するかを示したものである。 .na @@ -39,10 +39,10 @@ diff -up shadow-4.8.1/man/ja/man5/login.defs.5.manfix shadow-4.8.1/man/ja/man5/l .IP groupadd 12 GID_MAX GID_MIN .IP newusers 12 -diff -up shadow-4.8.1/man/login.defs.5.xml.manfix shadow-4.8.1/man/login.defs.5.xml ---- shadow-4.8.1/man/login.defs.5.xml.manfix 2020-01-17 16:47:56.000000000 +0100 -+++ shadow-4.8.1/man/login.defs.5.xml 2020-03-17 15:34:48.750414984 +0100 -@@ -164,6 +164,17 @@ +diff -up shadow-4.15.0/man/login.defs.5.xml.manfix shadow-4.15.0/man/login.defs.5.xml +--- shadow-4.15.0/man/login.defs.5.xml.manfix 2024-01-22 22:36:43.000000000 +0100 ++++ shadow-4.15.0/man/login.defs.5.xml 2024-02-09 10:45:49.014407259 +0100 +@@ -144,6 +144,17 @@ long numeric parameters is machine-dependent. @@ -60,7 +60,7 @@ diff -up shadow-4.8.1/man/login.defs.5.xml.manfix shadow-4.8.1/man/login.defs.5. The following configuration items are provided: -@@ -256,16 +267,6 @@ +@@ -240,16 +251,6 @@ @@ -77,7 +77,7 @@ diff -up shadow-4.8.1/man/login.defs.5.xml.manfix shadow-4.8.1/man/login.defs.5. chgpasswd -@@ -286,14 +287,6 @@ +@@ -276,14 +277,6 @@ @@ -92,7 +92,7 @@ diff -up shadow-4.8.1/man/login.defs.5.xml.manfix shadow-4.8.1/man/login.defs.5. -@@ -359,34 +352,6 @@ +@@ -352,34 +345,6 @@ LASTLOG_UID_MAX @@ -127,25 +127,7 @@ diff -up shadow-4.8.1/man/login.defs.5.xml.manfix shadow-4.8.1/man/login.defs.5. newgrp / sg -@@ -415,17 +380,6 @@ - - - -- -- passwd -- -- -- ENCRYPT_METHOD MD5_CRYPT_ENAB OBSCURE_CHECKS_ENAB -- PASS_ALWAYS_WARN PASS_CHANGE_TRIES PASS_MAX_LEN PASS_MIN_LEN -- SHA_CRYPT_MAX_ROUNDS -- SHA_CRYPT_MIN_ROUNDS -- -- -- - - pwck - -@@ -452,32 +406,6 @@ +@@ -451,32 +416,6 @@ @@ -166,12 +148,12 @@ diff -up shadow-4.8.1/man/login.defs.5.xml.manfix shadow-4.8.1/man/login.defs.5. - - - -- +- - sulogin - - - ENV_HZ -- ENV_TZ +- ENV_TZ - - - diff --git a/shadow-utils.spec b/shadow-utils.spec index 6b705cd..2892562 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils -Version: 4.14.0 -Release: 6%{?dist} +Version: 4.15.0rc2 +Release: 1%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -19,20 +19,13 @@ Source7: passwd.pamd ### Patches ### # Misc manual page changes - non-upstreamable -Patch0: shadow-4.14.0-manfix.patch +Patch0: shadow-4.15.0-manfix.patch # Date parsing improvement - could be upstreamed -Patch1: shadow-4.2.1-date-parsing.patch +Patch1: shadow-4.15.0-date-parsing.patch # Audit message changes - partially upstreamed -Patch2: shadow-4.14.0-audit-update.patch -# https://github.com/shadow-maint/shadow/pull/812 -Patch3: shadow-4.14.0-useradd-def-usrtemplate-selinux-label.patch +Patch2: shadow-4.15.0-audit-update.patch # Probably non-upstreamable -Patch4: shadow-4.14.0-account-tools-setuid.patch -# https://github.com/shadow-maint/shadow/commit/43b4e5a6c41f5c43cad18810f9229e40e8c4a57e -# https://github.com/shadow-maint/shadow/commit/45f34ee8c196a98397504cb7ed8576b6f1825cf9 -Patch5: shadow-4.14.0-remove-libcrack.patch -# https://github.com/shadow-maint/shadow/pull/927 -Patch6: shadow-4.14.0-passwd-stdin.patch +Patch3: shadow-4.14.0-account-tools-setuid.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -107,7 +100,7 @@ cp -a %{SOURCE4} %{SOURCE5} . cp -a %{SOURCE6} man/login.defs.d/HOME_MODE.xml # Force regeneration of getdate.c -rm libmisc/getdate.c +rm lib/getdate.c %build %ifarch sparc64 @@ -193,9 +186,11 @@ rm $RPM_BUILD_ROOT%{_mandir}/*/man8/faillog.* # Remove PAM service files we don't use. rm $RPM_BUILD_ROOT%{_pam_confdir}/chfn +rm $RPM_BUILD_ROOT%{_pam_confdir}/chpasswd rm $RPM_BUILD_ROOT%{_pam_confdir}/chsh rm $RPM_BUILD_ROOT%{_pam_confdir}/groupmems rm $RPM_BUILD_ROOT%{_pam_confdir}/login +rm $RPM_BUILD_ROOT%{_pam_confdir}/newusers rm $RPM_BUILD_ROOT%{_pam_confdir}/su find $RPM_BUILD_ROOT%{_mandir} -depth -type d -empty -delete @@ -278,6 +273,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Fri Feb 16 2024 Iker Pedrosa - 2:4.15.0rc2-1 +- Rebase to version 4.15.0rc2 + * Mon Feb 12 2024 Iker Pedrosa - 2:4.14.0-6 - Build linking `libpam` diff --git a/sources b/sources index 1ec1caa..a023638 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (shadow-4.14.0.tar.xz) = ff960481d576f9db5a9f10becc4e1a74c03de484ecfdcd7f1ea735fded683d7ba0f9cd895dc6a431b77e5a633752273178b1bcda4cefaa5adbf0f143c9a0c86f -SHA512 (shadow-4.14.0.tar.xz.asc) = d011a732d73b4b066ca8d204c0420303f925c87efc7655feb5c5f60b619d67da450e220ee44f6c86929ae79cbd4343136fe9c20d25b39fa0a228a48e57636309 +SHA512 (shadow-4.15.0rc2.tar.xz) = d54808226fb40998801d64c5835cdbd07d4fa78536611c5d4cdfc0ade04798c10cf279af6667e0f50cf1995a122a36fa525c5372fa9fbdbe72aef656ecc88dc8 +SHA512 (shadow-4.15.0rc2.tar.xz.asc) = b258c261cf6a7f16b078635a0c900144fc1868fd0686336255823e22b589e9b19459a5e43bb52cff7104b794e62c81de84d52d24d380c8e262d56b7e8cb5eb8b From 54fe2d4ca44c281bb7424a2aa7e69f79dda88f9b Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Fri, 1 Mar 2024 09:33:00 +0100 Subject: [PATCH 081/134] Rebase to version 4.15.0rc3 Signed-off-by: Iker Pedrosa --- .gitignore | 2 ++ shadow-utils.spec | 5 ++++- sources | 4 ++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 8b8ecf6..26ea3ae 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,5 @@ shadow-4.1.4.2.tar.bz2 /shadow-4.14.0.tar.xz.asc /shadow-4.15.0rc2.tar.xz /shadow-4.15.0rc2.tar.xz.asc +/shadow-4.15.0rc3.tar.xz +/shadow-4.15.0rc3.tar.xz.asc diff --git a/shadow-utils.spec b/shadow-utils.spec index 2892562..b864952 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,6 +1,6 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils -Version: 4.15.0rc2 +Version: 4.15.0rc3 Release: 1%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later @@ -273,6 +273,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Fri Mar 1 2024 Iker Pedrosa - 2:4.15.0rc3-1 +- Rebase to version 4.15.0rc3 + * Fri Feb 16 2024 Iker Pedrosa - 2:4.15.0rc2-1 - Rebase to version 4.15.0rc2 diff --git a/sources b/sources index a023638..a6a9165 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (shadow-4.15.0rc2.tar.xz) = d54808226fb40998801d64c5835cdbd07d4fa78536611c5d4cdfc0ade04798c10cf279af6667e0f50cf1995a122a36fa525c5372fa9fbdbe72aef656ecc88dc8 -SHA512 (shadow-4.15.0rc2.tar.xz.asc) = b258c261cf6a7f16b078635a0c900144fc1868fd0686336255823e22b589e9b19459a5e43bb52cff7104b794e62c81de84d52d24d380c8e262d56b7e8cb5eb8b +SHA512 (shadow-4.15.0rc3.tar.xz) = 4b5329c73e495c2ff4ab69070ce30c1fd8219a8f87a394effa2a301949849e0db53ace5356a373e75707847e2248710fe9943db8c2d3238e76ee2a73e4274d9c +SHA512 (shadow-4.15.0rc3.tar.xz.asc) = 5261e179ca264a7ad8c5d8ae62c5bed606bb6db2b17e16ef863fade88938bcc6e27e19deed7c58099ec51bb39e0d3b4332a7d8b58dcde8280b49993da7774e23 From 7c3405fb6a0afdae840b6f0d775243135240807c Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Mon, 11 Mar 2024 11:36:23 +0100 Subject: [PATCH 082/134] Rebase to version 4.15.0 Signed-off-by: Iker Pedrosa --- .gitignore | 2 + ...> shadow-4.15.0-account-tools-setuid.patch | 71 ++++---- shadow-4.15.0-audit-update.patch | 164 +++++++++--------- shadow-utils.spec | 11 +- sources | 4 +- 5 files changed, 124 insertions(+), 128 deletions(-) rename shadow-4.14.0-account-tools-setuid.patch => shadow-4.15.0-account-tools-setuid.patch (81%) diff --git a/.gitignore b/.gitignore index 26ea3ae..db3a21c 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,5 @@ shadow-4.1.4.2.tar.bz2 /shadow-4.15.0rc2.tar.xz.asc /shadow-4.15.0rc3.tar.xz /shadow-4.15.0rc3.tar.xz.asc +/shadow-4.15.0.tar.xz +/shadow-4.15.0.tar.xz.asc diff --git a/shadow-4.14.0-account-tools-setuid.patch b/shadow-4.15.0-account-tools-setuid.patch similarity index 81% rename from shadow-4.14.0-account-tools-setuid.patch rename to shadow-4.15.0-account-tools-setuid.patch index 17d8918..d162487 100644 --- a/shadow-4.14.0-account-tools-setuid.patch +++ b/shadow-4.15.0-account-tools-setuid.patch @@ -1,7 +1,6 @@ -diff --git a/src/chpasswd.c b/src/chpasswd.c -index 3a4bd4fe..246e4176 100644 ---- a/src/chpasswd.c -+++ b/src/chpasswd.c +diff -up shadow-4.15.0/src/chpasswd.c.account-tools-setuid shadow-4.15.0/src/chpasswd.c +--- shadow-4.15.0/src/chpasswd.c.account-tools-setuid 2024-03-08 22:27:04.000000000 +0100 ++++ shadow-4.15.0/src/chpasswd.c 2024-03-11 11:21:57.561150382 +0100 @@ -443,9 +443,11 @@ int main (int argc, char **argv) char *cp; const char *salt; @@ -14,7 +13,7 @@ index 3a4bd4fe..246e4176 100644 int errors = 0; int line = 0; -@@ -470,19 +472,23 @@ int main (int argc, char **argv) +@@ -469,19 +471,23 @@ int main (int argc, char **argv) process_root_flag ("-R", argc, argv); prefix = process_prefix_flag ("-P", argc, argv); @@ -26,7 +25,7 @@ index 3a4bd4fe..246e4176 100644 #endif /* USE_PAM */ +#endif /* ACCT_TOOLS_SETUID */ - OPENLOG ("chpasswd"); + OPENLOG (Prog); check_perms (); @@ -38,15 +37,15 @@ index 3a4bd4fe..246e4176 100644 { is_shadow_pwd = spw_file_present (); -@@ -544,6 +550,7 @@ int main (int argc, char **argv) +@@ -543,6 +549,7 @@ int main (int argc, char **argv) } newpwd = cp; +#ifdef ACCT_TOOLS_SETUID #ifdef USE_PAM if (use_pam) { - if (do_pam_passwd_non_interactive ("chpasswd", name, newpwd) != 0) { -@@ -554,6 +561,7 @@ int main (int argc, char **argv) + if (do_pam_passwd_non_interactive (Prog, name, newpwd) != 0) { +@@ -553,6 +560,7 @@ int main (int argc, char **argv) } } else #endif /* USE_PAM */ @@ -54,7 +53,7 @@ index 3a4bd4fe..246e4176 100644 { const struct spwd *sp; struct spwd newsp; -@@ -673,9 +681,11 @@ int main (int argc, char **argv) +@@ -672,9 +680,11 @@ int main (int argc, char **argv) * password database. */ if (0 != errors) { @@ -66,7 +65,7 @@ index 3a4bd4fe..246e4176 100644 { fprintf (stderr, _("%s: error detected, changes ignored\n"), -@@ -684,9 +694,11 @@ int main (int argc, char **argv) +@@ -683,9 +693,11 @@ int main (int argc, char **argv) fail_exit (1); } @@ -78,10 +77,9 @@ index 3a4bd4fe..246e4176 100644 { /* Save the changes */ close_files (); -diff --git a/src/groupmems.c b/src/groupmems.c -index 63a1601c..73f7310e 100644 ---- a/src/groupmems.c -+++ b/src/groupmems.c +diff -up shadow-4.15.0/src/groupmems.c.account-tools-setuid shadow-4.15.0/src/groupmems.c +--- shadow-4.15.0/src/groupmems.c.account-tools-setuid 2024-03-08 22:27:04.000000000 +0100 ++++ shadow-4.15.0/src/groupmems.c 2024-03-11 11:16:18.365408572 +0100 @@ -14,9 +14,11 @@ #include #include @@ -94,7 +92,7 @@ index 63a1601c..73f7310e 100644 #include #include "alloc.h" -@@ -430,6 +432,7 @@ static void process_flags (int argc, char **argv) +@@ -430,6 +432,7 @@ static void process_flags (int argc, cha static void check_perms (void) { if (!list) { @@ -112,12 +110,11 @@ index 63a1601c..73f7310e 100644 } } -diff --git a/src/newusers.c b/src/newusers.c -index 09e14a48..96b60de2 100644 ---- a/src/newusers.c -+++ b/src/newusers.c +diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/newusers.c +--- shadow-4.15.0/src/newusers.c.account-tools-setuid 2024-03-08 22:27:04.000000000 +0100 ++++ shadow-4.15.0/src/newusers.c 2024-03-11 11:20:07.198909046 +0100 @@ -59,6 +59,7 @@ - const char *Prog; + static const char Prog[] = "newusers"; static bool rflg = false; /* create a system account */ +#ifndef ACCT_TOOLS_SETUID @@ -172,7 +169,7 @@ index 09e14a48..96b60de2 100644 (void) fputs ("\n", usageout); exit (status); -@@ -405,6 +413,7 @@ static int add_user (const char *name, uid_t uid, gid_t gid) +@@ -405,6 +413,7 @@ static int add_user (const char *name, u return (pw_update (&pwent) == 0) ? -1 : 0; } @@ -180,7 +177,7 @@ index 09e14a48..96b60de2 100644 #ifndef USE_PAM /* * update_passwd - update the password in the passwd entry -@@ -457,6 +466,7 @@ static int update_passwd (struct passwd *pwd, const char *password) +@@ -457,6 +466,7 @@ static int update_passwd (struct passwd return 0; } #endif /* !USE_PAM */ @@ -188,7 +185,7 @@ index 09e14a48..96b60de2 100644 /* * add_passwd - add or update the encrypted password -@@ -465,10 +475,13 @@ static int add_passwd (struct passwd *pwd, const char *password) +@@ -465,10 +475,13 @@ static int add_passwd (struct passwd *pw { const struct spwd *sp; struct spwd spent; @@ -202,7 +199,7 @@ index 09e14a48..96b60de2 100644 #ifndef USE_PAM void *crypt_arg = NULL; if (NULL != crypt_method) { -@@ -505,13 +518,14 @@ static int add_passwd (struct passwd *pwd, const char *password) +@@ -505,13 +518,14 @@ static int add_passwd (struct passwd *pw return update_passwd (pwd, password); } #endif /* USE_PAM */ @@ -218,7 +215,7 @@ index 09e14a48..96b60de2 100644 if (NULL != sp) { spent = *sp; if ( (NULL != crypt_method) -@@ -547,7 +561,7 @@ static int add_passwd (struct passwd *pwd, const char *password) +@@ -547,7 +561,7 @@ static int add_passwd (struct passwd *pw if (strcmp (pwd->pw_passwd, "x") != 0) { return update_passwd (pwd, password); } @@ -227,7 +224,7 @@ index 09e14a48..96b60de2 100644 /* * If there is already a shadow entry, do not touch it. * If there is already a passwd entry with a password, do not -@@ -558,14 +572,14 @@ static int add_passwd (struct passwd *pwd, const char *password) +@@ -558,14 +572,14 @@ static int add_passwd (struct passwd *pw || (strcmp (pwd->pw_passwd, "x") != 0)) { return 0; } @@ -244,7 +241,7 @@ index 09e14a48..96b60de2 100644 if ((crypt_method != NULL) && (0 == strcmp(crypt_method, "NONE"))) { spent.sp_pwdp = (char *)password; } else { -@@ -610,35 +624,41 @@ static int add_passwd (struct passwd *pwd, const char *password) +@@ -610,35 +624,41 @@ static int add_passwd (struct passwd *pw static void process_flags (int argc, char **argv) { int c; @@ -288,7 +285,7 @@ index 09e14a48..96b60de2 100644 "bhr", #endif long_options, NULL)) != -1) { -@@ -646,11 +666,13 @@ static void process_flags (int argc, char **argv) +@@ -646,11 +666,13 @@ static void process_flags (int argc, cha case 'b': allow_bad_names = true; break; @@ -302,7 +299,7 @@ index 09e14a48..96b60de2 100644 case 'h': usage (EXIT_SUCCESS); break; -@@ -659,6 +681,7 @@ static void process_flags (int argc, char **argv) +@@ -659,6 +681,7 @@ static void process_flags (int argc, cha break; case 'R': /* no-op, handled in process_root_flag () */ break; @@ -310,7 +307,7 @@ index 09e14a48..96b60de2 100644 #ifndef USE_PAM #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) case 's': -@@ -698,6 +721,7 @@ static void process_flags (int argc, char **argv) +@@ -698,6 +721,7 @@ static void process_flags (int argc, cha break; #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ #endif /* !USE_PAM */ @@ -318,7 +315,7 @@ index 09e14a48..96b60de2 100644 default: usage (EXIT_FAILURE); break; -@@ -730,6 +754,7 @@ static void process_flags (int argc, char **argv) +@@ -730,6 +754,7 @@ static void process_flags (int argc, cha */ static void check_flags (void) { @@ -347,9 +344,9 @@ index 09e14a48..96b60de2 100644 #endif /* USE_PAM */ +#endif /* ACCT_TOOLS_SETUID */ - Prog = Basename (argv[0]); log_set_progname(Prog); -@@ -1196,6 +1224,7 @@ int main (int argc, char **argv) + log_set_logfd(stderr); +@@ -1195,6 +1223,7 @@ int main (int argc, char **argv) } newpw = *pw; @@ -357,7 +354,7 @@ index 09e14a48..96b60de2 100644 #ifdef USE_PAM /* keep the list of user/password for later update by PAM */ nusers++; -@@ -1212,6 +1241,7 @@ int main (int argc, char **argv) +@@ -1211,6 +1240,7 @@ int main (int argc, char **argv) usernames[nusers-1] = strdup (fields[0]); passwords[nusers-1] = strdup (fields[1]); #endif /* USE_PAM */ @@ -365,7 +362,7 @@ index 09e14a48..96b60de2 100644 if (add_passwd (&newpw, fields[1]) != 0) { fprintf (stderr, _("%s: line %d: can't update password\n"), -@@ -1328,6 +1358,7 @@ int main (int argc, char **argv) +@@ -1327,6 +1357,7 @@ int main (int argc, char **argv) nscd_flush_cache ("group"); sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP); @@ -373,7 +370,7 @@ index 09e14a48..96b60de2 100644 #ifdef USE_PAM unsigned int i; /* Now update the passwords using PAM */ -@@ -1340,6 +1371,7 @@ int main (int argc, char **argv) +@@ -1339,6 +1370,7 @@ int main (int argc, char **argv) } } #endif /* USE_PAM */ diff --git a/shadow-4.15.0-audit-update.patch b/shadow-4.15.0-audit-update.patch index 60c1ad7..a625c5c 100644 --- a/shadow-4.15.0-audit-update.patch +++ b/shadow-4.15.0-audit-update.patch @@ -1,6 +1,6 @@ diff -up shadow-4.15.0/lib/audit_help.c.audit-update shadow-4.15.0/lib/audit_help.c ---- shadow-4.15.0/lib/audit_help.c.audit-update 2024-02-01 23:59:36.000000000 +0100 -+++ shadow-4.15.0/lib/audit_help.c 2024-02-09 10:49:57.106840590 +0100 +--- shadow-4.15.0/lib/audit_help.c.audit-update 2024-03-01 02:50:52.000000000 +0100 ++++ shadow-4.15.0/lib/audit_help.c 2024-03-11 10:56:20.233991612 +0100 @@ -48,7 +48,7 @@ void audit_help_open (void) * This function will log a message to the audit system using a predefined * message format. Parameter usage is as follows: @@ -51,8 +51,8 @@ diff -up shadow-4.15.0/lib/audit_help.c.audit-update shadow-4.15.0/lib/audit_hel { if (audit_fd < 0) { diff -up shadow-4.15.0/lib/cleanup_group.c.audit-update shadow-4.15.0/lib/cleanup_group.c ---- shadow-4.15.0/lib/cleanup_group.c.audit-update 2024-02-01 23:59:36.000000000 +0100 -+++ shadow-4.15.0/lib/cleanup_group.c 2024-02-09 10:49:57.106840590 +0100 +--- shadow-4.15.0/lib/cleanup_group.c.audit-update 2024-03-01 02:50:52.000000000 +0100 ++++ shadow-4.15.0/lib/cleanup_group.c 2024-03-11 10:56:20.233991612 +0100 @@ -62,7 +62,7 @@ void cleanup_report_mod_group (void *cle gr_dbname (), info->action)); @@ -132,8 +132,8 @@ diff -up shadow-4.15.0/lib/cleanup_group.c.audit-update shadow-4.15.0/lib/cleanu #endif } diff -up shadow-4.15.0/lib/cleanup_user.c.audit-update shadow-4.15.0/lib/cleanup_user.c ---- shadow-4.15.0/lib/cleanup_user.c.audit-update 2024-02-01 23:59:36.000000000 +0100 -+++ shadow-4.15.0/lib/cleanup_user.c 2024-02-09 10:49:57.106840590 +0100 +--- shadow-4.15.0/lib/cleanup_user.c.audit-update 2024-03-01 02:50:52.000000000 +0100 ++++ shadow-4.15.0/lib/cleanup_user.c 2024-03-11 10:56:20.233991612 +0100 @@ -44,7 +44,7 @@ void cleanup_report_mod_passwd (void *cl pw_dbname (), info->action)); @@ -182,8 +182,8 @@ diff -up shadow-4.15.0/lib/cleanup_user.c.audit-update shadow-4.15.0/lib/cleanup #endif } diff -up shadow-4.15.0/lib/prototypes.h.audit-update shadow-4.15.0/lib/prototypes.h ---- shadow-4.15.0/lib/prototypes.h.audit-update 2024-02-01 23:59:36.000000000 +0100 -+++ shadow-4.15.0/lib/prototypes.h 2024-02-09 10:49:57.106840590 +0100 +--- shadow-4.15.0/lib/prototypes.h.audit-update 2024-03-01 02:50:52.000000000 +0100 ++++ shadow-4.15.0/lib/prototypes.h 2024-03-11 10:56:20.233991612 +0100 @@ -198,12 +198,21 @@ extern int audit_fd; extern void audit_help_open (void); /* Use AUDIT_NO_ID when a name is provided to audit_logger instead of an ID */ @@ -207,8 +207,8 @@ diff -up shadow-4.15.0/lib/prototypes.h.audit-update shadow-4.15.0/lib/prototype #endif diff -up shadow-4.15.0/src/chage.c.audit-update shadow-4.15.0/src/chage.c ---- shadow-4.15.0/src/chage.c.audit-update 2024-01-22 22:36:43.000000000 +0100 -+++ shadow-4.15.0/src/chage.c 2024-02-09 10:49:57.106840590 +0100 +--- shadow-4.15.0/src/chage.c.audit-update 2024-03-08 22:27:04.000000000 +0100 ++++ shadow-4.15.0/src/chage.c 2024-03-11 10:56:20.234991618 +0100 @@ -110,8 +110,8 @@ fail_exit (int code) #ifdef WITH_AUDIT @@ -220,7 +220,7 @@ diff -up shadow-4.15.0/src/chage.c.audit-update shadow-4.15.0/src/chage.c } #endif -@@ -845,10 +845,7 @@ int main (int argc, char **argv) +@@ -846,10 +846,7 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: Permission denied.\n"), Prog); fail_exit (E_NOPERM); } @@ -232,7 +232,7 @@ diff -up shadow-4.15.0/src/chage.c.audit-update shadow-4.15.0/src/chage.c list_fields (); fail_exit (E_SUCCESS); } -@@ -867,39 +864,39 @@ int main (int argc, char **argv) +@@ -868,39 +865,39 @@ int main (int argc, char **argv) } #ifdef WITH_AUDIT else { @@ -288,8 +288,8 @@ diff -up shadow-4.15.0/src/chage.c.audit-update shadow-4.15.0/src/chage.c } #endif diff -up shadow-4.15.0/src/gpasswd.c.audit-update shadow-4.15.0/src/gpasswd.c ---- shadow-4.15.0/src/gpasswd.c.audit-update 2024-02-01 23:59:36.000000000 +0100 -+++ shadow-4.15.0/src/gpasswd.c 2024-02-09 10:55:42.642444103 +0100 +--- shadow-4.15.0/src/gpasswd.c.audit-update 2024-03-08 22:27:04.000000000 +0100 ++++ shadow-4.15.0/src/gpasswd.c 2024-03-11 10:56:20.234991618 +0100 @@ -125,7 +125,7 @@ static void usage (int status) (void) fputs (_(" -d, --delete USER remove USER from GROUP\n"), usageout); (void) fputs (_(" -h, --help display this help message and exit\n"), usageout); @@ -353,7 +353,7 @@ diff -up shadow-4.15.0/src/gpasswd.c.audit-update shadow-4.15.0/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } else if (Rflg) { -@@ -429,11 +429,9 @@ static void log_gpasswd_failure (const c +@@ -429,11 +419,9 @@ static void log_gpasswd_failure (const c "%s failed to restrict access to group %s%s", myname, group, suffix)); #ifdef WITH_AUDIT @@ -368,7 +368,7 @@ diff -up shadow-4.15.0/src/gpasswd.c.audit-update shadow-4.15.0/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } else if (Aflg || Mflg) { -@@ -443,11 +433,9 @@ static void log_gpasswd_failure (const c +@@ -443,11 +431,9 @@ static void log_gpasswd_failure (const c "%s failed to set the administrators of group %s to %s%s", myname, group, admins, suffix)); #ifdef WITH_AUDIT @@ -383,7 +383,7 @@ diff -up shadow-4.15.0/src/gpasswd.c.audit-update shadow-4.15.0/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } -@@ -457,11 +457,9 @@ static void log_gpasswd_failure (const c +@@ -457,11 +443,9 @@ static void log_gpasswd_failure (const c "%s failed to set the members of group %s to %s%s", myname, group, members, suffix)); #ifdef WITH_AUDIT @@ -398,7 +398,7 @@ diff -up shadow-4.15.0/src/gpasswd.c.audit-update shadow-4.15.0/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } -@@ -470,11 +468,9 @@ static void log_gpasswd_failure (const c +@@ -470,11 +454,9 @@ static void log_gpasswd_failure (const c "%s failed to change password of group %s%s", myname, group, suffix)); #ifdef WITH_AUDIT @@ -413,7 +413,7 @@ diff -up shadow-4.15.0/src/gpasswd.c.audit-update shadow-4.15.0/src/gpasswd.c SHADOW_AUDIT_FAILURE); #endif } -@@ -514,11 +502,9 @@ static void log_gpasswd_success (const c +@@ -514,11 +496,9 @@ static void log_gpasswd_success (const c "user %s added by %s to group %s%s", user, myname, group, suffix)); #ifdef WITH_AUDIT @@ -428,7 +428,7 @@ diff -up shadow-4.15.0/src/gpasswd.c.audit-update shadow-4.15.0/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } else if (dflg) { -@@ -526,11 +512,9 @@ static void log_gpasswd_success (const c +@@ -526,11 +506,9 @@ static void log_gpasswd_success (const c "user %s removed by %s from group %s%s", user, myname, group, suffix)); #ifdef WITH_AUDIT @@ -443,7 +443,7 @@ diff -up shadow-4.15.0/src/gpasswd.c.audit-update shadow-4.15.0/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } else if (rflg) { -@@ -540,9 +524,9 @@ static void log_gpasswd_success (const c +@@ -540,9 +518,9 @@ static void log_gpasswd_success (const c #ifdef WITH_AUDIT SNPRINTF(buf, "password of group %s removed by %s%s", group, myname, suffix); @@ -456,7 +456,7 @@ diff -up shadow-4.15.0/src/gpasswd.c.audit-update shadow-4.15.0/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } else if (Rflg) { -@@ -552,9 +536,9 @@ static void log_gpasswd_success (const c +@@ -552,9 +530,9 @@ static void log_gpasswd_success (const c #ifdef WITH_AUDIT SNPRINTF(buf, "access to group %s restricted by %s%s", group, myname, suffix); @@ -469,7 +469,7 @@ diff -up shadow-4.15.0/src/gpasswd.c.audit-update shadow-4.15.0/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } else if (Aflg || Mflg) { -@@ -564,11 +548,9 @@ static void log_gpasswd_success (const c +@@ -564,11 +542,9 @@ static void log_gpasswd_success (const c "administrators of group %s set by %s to %s%s", group, myname, admins, suffix)); #ifdef WITH_AUDIT @@ -484,7 +484,7 @@ diff -up shadow-4.15.0/src/gpasswd.c.audit-update shadow-4.15.0/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } -@@ -578,11 +560,9 @@ static void log_gpasswd_success (const c +@@ -578,11 +554,9 @@ static void log_gpasswd_success (const c "members of group %s set by %s to %s%s", group, myname, members, suffix)); #ifdef WITH_AUDIT @@ -499,7 +499,7 @@ diff -up shadow-4.15.0/src/gpasswd.c.audit-update shadow-4.15.0/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } -@@ -591,11 +571,9 @@ static void log_gpasswd_success (const c +@@ -591,11 +565,9 @@ static void log_gpasswd_success (const c "password of group %s changed by %s%s", group, myname, suffix)); #ifdef WITH_AUDIT @@ -515,8 +515,8 @@ diff -up shadow-4.15.0/src/gpasswd.c.audit-update shadow-4.15.0/src/gpasswd.c #endif } diff -up shadow-4.15.0/src/groupadd.c.audit-update shadow-4.15.0/src/groupadd.c ---- shadow-4.15.0/src/groupadd.c.audit-update 2024-01-22 22:36:43.000000000 +0100 -+++ shadow-4.15.0/src/groupadd.c 2024-02-09 10:58:18.325715738 +0100 +--- shadow-4.15.0/src/groupadd.c.audit-update 2024-03-08 22:27:04.000000000 +0100 ++++ shadow-4.15.0/src/groupadd.c 2024-03-11 10:59:11.522108956 +0100 @@ -115,6 +115,15 @@ usage (int status) exit (status); } @@ -662,7 +662,7 @@ diff -up shadow-4.15.0/src/groupadd.c.audit-update shadow-4.15.0/src/groupadd.c + fail_exit (1); } - retval = pam_start ("groupadd", pampw->pw_name, &conv, &pamh); + retval = pam_start (Prog, pampw->pw_name, &conv, &pamh); @@ -560,7 +565,7 @@ static void check_perms (void) if (NULL != pamh) { (void) pam_end (pamh, retval); @@ -672,7 +672,7 @@ diff -up shadow-4.15.0/src/groupadd.c.audit-update shadow-4.15.0/src/groupadd.c } (void) pam_end (pamh, retval); #endif /* USE_PAM */ -@@ -595,7 +600,7 @@ int main (int argc, char **argv) +@@ -591,7 +596,7 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: Cannot setup cleanup service.\n"), Prog); @@ -681,7 +681,7 @@ diff -up shadow-4.15.0/src/groupadd.c.audit-update shadow-4.15.0/src/groupadd.c } /* -@@ -622,7 +627,7 @@ int main (int argc, char **argv) +@@ -618,7 +623,7 @@ int main (int argc, char **argv) if (!gflg) { if (find_new_gid (rflg, &group_id, NULL) < 0) { @@ -691,8 +691,8 @@ diff -up shadow-4.15.0/src/groupadd.c.audit-update shadow-4.15.0/src/groupadd.c } diff -up shadow-4.15.0/src/groupdel.c.audit-update shadow-4.15.0/src/groupdel.c ---- shadow-4.15.0/src/groupdel.c.audit-update 2023-05-26 04:56:11.000000000 +0200 -+++ shadow-4.15.0/src/groupdel.c 2024-02-09 10:49:57.107840592 +0100 +--- shadow-4.15.0/src/groupdel.c.audit-update 2024-03-08 22:27:04.000000000 +0100 ++++ shadow-4.15.0/src/groupdel.c 2024-03-11 11:14:20.572151046 +0100 @@ -87,6 +87,15 @@ usage (int status) exit (status); } @@ -815,7 +815,7 @@ diff -up shadow-4.15.0/src/groupdel.c.audit-update shadow-4.15.0/src/groupdel.c } /* -@@ -372,7 +376,7 @@ int main (int argc, char **argv) +@@ -368,7 +372,7 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: Cannot setup cleanup service.\n"), Prog); @@ -824,7 +824,7 @@ diff -up shadow-4.15.0/src/groupdel.c.audit-update shadow-4.15.0/src/groupdel.c } process_flags (argc, argv); -@@ -386,7 +390,7 @@ int main (int argc, char **argv) +@@ -382,7 +386,7 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: Cannot determine your user name.\n"), Prog); @@ -832,8 +832,8 @@ diff -up shadow-4.15.0/src/groupdel.c.audit-update shadow-4.15.0/src/groupdel.c + fail_exit (1); } - retval = pam_start ("groupdel", pampw->pw_name, &conv, &pamh); -@@ -407,7 +411,7 @@ int main (int argc, char **argv) + retval = pam_start (Prog, pampw->pw_name, &conv, &pamh); +@@ -403,7 +407,7 @@ int main (int argc, char **argv) if (NULL != pamh) { (void) pam_end (pamh, retval); } @@ -842,7 +842,7 @@ diff -up shadow-4.15.0/src/groupdel.c.audit-update shadow-4.15.0/src/groupdel.c } (void) pam_end (pamh, retval); #endif /* USE_PAM */ -@@ -427,7 +431,7 @@ int main (int argc, char **argv) +@@ -423,7 +427,7 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: group '%s' does not exist\n"), Prog, group_name); @@ -851,7 +851,7 @@ diff -up shadow-4.15.0/src/groupdel.c.audit-update shadow-4.15.0/src/groupdel.c } group_id = grp->gr_gid; -@@ -451,7 +455,7 @@ int main (int argc, char **argv) +@@ -447,7 +451,7 @@ int main (int argc, char **argv) _("%s: %s is the NIS master\n"), Prog, nis_master); } @@ -861,8 +861,8 @@ diff -up shadow-4.15.0/src/groupdel.c.audit-update shadow-4.15.0/src/groupdel.c #endif diff -up shadow-4.15.0/src/groupmod.c.audit-update shadow-4.15.0/src/groupmod.c ---- shadow-4.15.0/src/groupmod.c.audit-update 2024-01-22 22:36:43.000000000 +0100 -+++ shadow-4.15.0/src/groupmod.c 2024-02-09 10:49:57.107840592 +0100 +--- shadow-4.15.0/src/groupmod.c.audit-update 2024-03-08 22:27:04.000000000 +0100 ++++ shadow-4.15.0/src/groupmod.c 2024-03-11 10:56:20.234991618 +0100 @@ -474,7 +474,7 @@ static void close_files (void) exit (E_GRP_UPDATE); } @@ -909,8 +909,8 @@ diff -up shadow-4.15.0/src/groupmod.c.audit-update shadow-4.15.0/src/groupmod.c SHADOW_AUDIT_SUCCESS); #endif diff -up shadow-4.15.0/src/newgrp.c.audit-update shadow-4.15.0/src/newgrp.c ---- shadow-4.15.0/src/newgrp.c.audit-update 2023-12-27 16:58:48.000000000 +0100 -+++ shadow-4.15.0/src/newgrp.c 2024-02-09 11:02:30.575155871 +0100 +--- shadow-4.15.0/src/newgrp.c.audit-update 2024-03-08 22:27:04.000000000 +0100 ++++ shadow-4.15.0/src/newgrp.c 2024-03-11 10:56:20.234991618 +0100 @@ -188,10 +188,10 @@ static void check_perms (const struct gr if (grp->gr_passwd[0] == '\0' || strcmp (cpasswd, grp->gr_passwd) != 0) { @@ -1092,8 +1092,8 @@ diff -up shadow-4.15.0/src/newgrp.c.audit-update shadow-4.15.0/src/newgrp.c #endif exit (EXIT_FAILURE); diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c ---- shadow-4.15.0/src/useradd.c.audit-update 2024-02-01 23:59:36.000000000 +0100 -+++ shadow-4.15.0/src/useradd.c 2024-02-09 10:49:57.108840594 +0100 +--- shadow-4.15.0/src/useradd.c.audit-update 2024-03-08 22:27:04.000000000 +0100 ++++ shadow-4.15.0/src/useradd.c 2024-03-11 10:56:20.235991625 +0100 @@ -242,6 +242,8 @@ static void check_uid_range(int rflg, ui */ static void fail_exit (int code) @@ -1370,7 +1370,7 @@ diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c user_name, user_id, SHADOW_AUDIT_SUCCESS); #endif #ifdef WITH_SELINUX -@@ -2594,12 +2544,6 @@ int main (int argc, char **argv) +@@ -2590,12 +2540,6 @@ int main (int argc, char **argv) */ if (prefix_getpwnam (user_name) != NULL) { /* local, no need for xgetpwnam */ fprintf (stderr, _("%s: user '%s' already exists\n"), Prog, user_name); @@ -1383,7 +1383,7 @@ diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c fail_exit (E_NAME_IN_USE); } -@@ -2615,12 +2559,6 @@ int main (int argc, char **argv) +@@ -2611,12 +2555,6 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: group %s exists - if you want to add this user to that group, use -g.\n"), Prog, user_name); @@ -1396,7 +1396,7 @@ diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c fail_exit (E_NAME_IN_USE); } } -@@ -2650,12 +2588,6 @@ int main (int argc, char **argv) +@@ -2646,12 +2584,6 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: UID %lu is not unique\n"), Prog, (unsigned long) user_id); @@ -1409,7 +1409,7 @@ diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c fail_exit (E_UID_IN_USE); } } -@@ -2730,9 +2662,9 @@ int main (int argc, char **argv) +@@ -2726,9 +2658,9 @@ int main (int argc, char **argv) _("%s: warning: the user name %s to %s SELinux user mapping failed.\n"), Prog, user_name, user_selinux); #ifdef WITH_AUDIT @@ -1423,8 +1423,8 @@ diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c fail_exit (E_SE_UPDATE); } diff -up shadow-4.15.0/src/userdel.c.audit-update shadow-4.15.0/src/userdel.c ---- shadow-4.15.0/src/userdel.c.audit-update 2023-12-27 16:58:48.000000000 +0100 -+++ shadow-4.15.0/src/userdel.c 2024-02-09 10:49:57.108840594 +0100 +--- shadow-4.15.0/src/userdel.c.audit-update 2024-03-08 22:27:04.000000000 +0100 ++++ shadow-4.15.0/src/userdel.c 2024-03-11 10:56:20.235991625 +0100 @@ -206,9 +206,9 @@ static void update_groups (void) * Update the DBM group file with the new entry as well. */ @@ -1691,7 +1691,7 @@ diff -up shadow-4.15.0/src/userdel.c.audit-update shadow-4.15.0/src/userdel.c user_name, user_id, SHADOW_AUDIT_SUCCESS); } #endif /* WITH_AUDIT */ -@@ -1108,7 +1048,7 @@ int main (int argc, char **argv) +@@ -1104,7 +1044,7 @@ int main (int argc, char **argv) Prog, user_name); #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, @@ -1700,7 +1700,7 @@ diff -up shadow-4.15.0/src/userdel.c.audit-update shadow-4.15.0/src/userdel.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -1158,7 +1098,7 @@ int main (int argc, char **argv) +@@ -1154,7 +1094,7 @@ int main (int argc, char **argv) if (!fflg) { #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, @@ -1709,7 +1709,7 @@ diff -up shadow-4.15.0/src/userdel.c.audit-update shadow-4.15.0/src/userdel.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -1252,8 +1192,8 @@ int main (int argc, char **argv) +@@ -1248,8 +1188,8 @@ int main (int argc, char **argv) #ifdef WITH_AUDIT else { @@ -1720,7 +1720,7 @@ diff -up shadow-4.15.0/src/userdel.c.audit-update shadow-4.15.0/src/userdel.c user_name, user_id, SHADOW_AUDIT_SUCCESS); } #endif /* WITH_AUDIT */ -@@ -1261,7 +1201,7 @@ int main (int argc, char **argv) +@@ -1257,7 +1197,7 @@ int main (int argc, char **argv) #ifdef WITH_AUDIT if (0 != errors) { audit_logger (AUDIT_DEL_USER, Prog, @@ -1729,7 +1729,7 @@ diff -up shadow-4.15.0/src/userdel.c.audit-update shadow-4.15.0/src/userdel.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); } -@@ -1274,8 +1214,8 @@ int main (int argc, char **argv) +@@ -1270,8 +1210,8 @@ int main (int argc, char **argv) _("%s: warning: the user name %s to SELinux user mapping removal failed.\n"), Prog, user_name); #ifdef WITH_AUDIT @@ -1741,9 +1741,9 @@ diff -up shadow-4.15.0/src/userdel.c.audit-update shadow-4.15.0/src/userdel.c #endif /* WITH_AUDIT */ fail_exit (E_SE_UPDATE); diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c ---- shadow-4.15.0/src/usermod.c.audit-update 2024-02-01 23:59:36.000000000 +0100 -+++ shadow-4.15.0/src/usermod.c 2024-02-09 10:49:57.108840594 +0100 -@@ -431,7 +431,7 @@ static char *new_pw_passwd (char *pw_pas +--- shadow-4.15.0/src/usermod.c.audit-update 2024-03-08 22:27:04.000000000 +0100 ++++ shadow-4.15.0/src/usermod.c 2024-03-11 10:56:20.235991625 +0100 +@@ -438,7 +438,7 @@ static char *new_pw_passwd (char *pw_pas #ifdef WITH_AUDIT audit_logger (AUDIT_USER_CHAUTHTOK, Prog, @@ -1752,7 +1752,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c #endif SYSLOG ((LOG_INFO, "lock user '%s' password", user_newname)); strcpy (buf, "!"); -@@ -448,14 +448,14 @@ static char *new_pw_passwd (char *pw_pas +@@ -455,14 +455,14 @@ static char *new_pw_passwd (char *pw_pas #ifdef WITH_AUDIT audit_logger (AUDIT_USER_CHAUTHTOK, Prog, @@ -1769,7 +1769,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c #endif SYSLOG ((LOG_INFO, "change user '%s' password", user_newname)); pw_pass = xstrdup (user_pass); -@@ -483,8 +483,8 @@ static void new_pwent (struct passwd *pw +@@ -490,8 +490,8 @@ static void new_pwent (struct passwd *pw fail_exit (E_NAME_IN_USE); } #ifdef WITH_AUDIT @@ -1780,7 +1780,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c #endif SYSLOG ((LOG_INFO, "change user name '%s' to '%s'", -@@ -503,8 +503,8 @@ static void new_pwent (struct passwd *pw +@@ -510,8 +510,8 @@ static void new_pwent (struct passwd *pw if (uflg) { #ifdef WITH_AUDIT @@ -1791,7 +1791,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c #endif SYSLOG ((LOG_INFO, "change user '%s' UID from '%d' to '%d'", -@@ -513,8 +513,8 @@ static void new_pwent (struct passwd *pw +@@ -520,8 +520,8 @@ static void new_pwent (struct passwd *pw } if (gflg) { #ifdef WITH_AUDIT @@ -1802,7 +1802,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c user_newname, user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -524,16 +524,16 @@ static void new_pwent (struct passwd *pw +@@ -531,16 +531,16 @@ static void new_pwent (struct passwd *pw } if (cflg) { #ifdef WITH_AUDIT @@ -1823,7 +1823,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c user_newname, user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -549,8 +549,8 @@ static void new_pwent (struct passwd *pw +@@ -556,8 +556,8 @@ static void new_pwent (struct passwd *pw } if (sflg) { #ifdef WITH_AUDIT @@ -1834,7 +1834,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c user_newname, user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -580,8 +580,8 @@ static void new_spent (struct spwd *spen +@@ -587,8 +587,8 @@ static void new_spent (struct spwd *spen if (fflg) { #ifdef WITH_AUDIT @@ -1845,7 +1845,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c user_newname, user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -595,8 +595,8 @@ static void new_spent (struct spwd *spen +@@ -602,8 +602,8 @@ static void new_spent (struct spwd *spen date_to_str (sizeof(new_exp), new_exp, user_newexpire * DAY); date_to_str (sizeof(old_exp), old_exp, user_expire * DAY); #ifdef WITH_AUDIT @@ -1856,7 +1856,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c user_newname, user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -681,9 +681,9 @@ fail_exit (int code) +@@ -688,9 +688,9 @@ fail_exit (int code) #endif /* ENABLE_SUBIDS */ #ifdef WITH_AUDIT @@ -1869,7 +1869,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c #endif exit (code); } -@@ -745,9 +745,12 @@ static void update_group (void) +@@ -752,9 +752,12 @@ static void update_group (void) user_newname); changed = true; #ifdef WITH_AUDIT @@ -1885,7 +1885,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c #endif SYSLOG ((LOG_INFO, "change '%s' to '%s' in group '%s'", -@@ -761,9 +764,11 @@ static void update_group (void) +@@ -768,9 +771,11 @@ static void update_group (void) ngrp->gr_mem = del_list (ngrp->gr_mem, user_name); changed = true; #ifdef WITH_AUDIT @@ -1900,7 +1900,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c #endif SYSLOG ((LOG_INFO, "delete '%s' from group '%s'", -@@ -776,9 +781,11 @@ static void update_group (void) +@@ -783,9 +788,11 @@ static void update_group (void) ngrp->gr_mem = add_list (ngrp->gr_mem, user_newname); changed = true; #ifdef WITH_AUDIT @@ -1915,7 +1915,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c #endif SYSLOG ((LOG_INFO, "add '%s' to group '%s'", user_newname, ngrp->gr_name)); -@@ -863,9 +870,10 @@ static void update_gshadow (void) +@@ -870,9 +877,10 @@ static void update_gshadow (void) nsgrp->sg_adm = add_list (nsgrp->sg_adm, user_newname); changed = true; #ifdef WITH_AUDIT @@ -1929,7 +1929,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c #endif SYSLOG ((LOG_INFO, "change admin '%s' to '%s' in shadow group '%s'", -@@ -885,9 +893,10 @@ static void update_gshadow (void) +@@ -892,9 +900,10 @@ static void update_gshadow (void) user_newname); changed = true; #ifdef WITH_AUDIT @@ -1943,7 +1943,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c #endif SYSLOG ((LOG_INFO, "change '%s' to '%s' in shadow group '%s'", -@@ -901,9 +910,10 @@ static void update_gshadow (void) +@@ -908,9 +917,10 @@ static void update_gshadow (void) nsgrp->sg_mem = del_list (nsgrp->sg_mem, user_name); changed = true; #ifdef WITH_AUDIT @@ -1957,7 +1957,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c #endif SYSLOG ((LOG_INFO, "delete '%s' from shadow group '%s'", -@@ -916,9 +926,10 @@ static void update_gshadow (void) +@@ -923,9 +933,10 @@ static void update_gshadow (void) nsgrp->sg_mem = add_list (nsgrp->sg_mem, user_newname); changed = true; #ifdef WITH_AUDIT @@ -1971,7 +1971,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c #endif SYSLOG ((LOG_INFO, "add '%s' to shadow group '%s'", user_newname, nsgrp->sg_name)); -@@ -1829,8 +1840,8 @@ static void move_home (void) +@@ -1836,8 +1847,8 @@ static void move_home (void) #ifdef WITH_AUDIT if (uflg || gflg) { @@ -1982,7 +1982,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c user_newname, user_newid, 1); } #endif -@@ -1848,8 +1859,8 @@ static void move_home (void) +@@ -1855,8 +1866,8 @@ static void move_home (void) fail_exit (E_HOMEDIR); } #ifdef WITH_AUDIT @@ -1993,7 +1993,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c user_newname, user_newid, 1); #endif return; -@@ -1876,9 +1887,9 @@ static void move_home (void) +@@ -1883,9 +1894,9 @@ static void move_home (void) Prog, prefix_user_home); } #ifdef WITH_AUDIT @@ -2005,7 +2005,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c user_newname, user_newid, 1); -@@ -2102,8 +2113,8 @@ static void move_mailbox (void) +@@ -2109,8 +2120,8 @@ static void move_mailbox (void) } #ifdef WITH_AUDIT else { @@ -2016,7 +2016,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c user_newname, user_newid, 1); } #endif -@@ -2126,8 +2137,8 @@ static void move_mailbox (void) +@@ -2133,8 +2144,8 @@ static void move_mailbox (void) } #ifdef WITH_AUDIT else { @@ -2027,7 +2027,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c user_newname, user_newid, 1); } -@@ -2328,8 +2339,8 @@ int main (int argc, char **argv) +@@ -2331,8 +2342,8 @@ int main (int argc, char **argv) _("%s: warning: the user name %s to %s SELinux user mapping failed.\n"), Prog, user_name, user_selinux); #ifdef WITH_AUDIT @@ -2038,7 +2038,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c user_name, user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -2341,8 +2352,8 @@ int main (int argc, char **argv) +@@ -2344,8 +2355,8 @@ int main (int argc, char **argv) _("%s: warning: the user name %s to SELinux user mapping removal failed.\n"), Prog, user_name); #ifdef WITH_AUDIT @@ -2049,7 +2049,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c user_name, user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -2385,8 +2396,8 @@ int main (int argc, char **argv) +@@ -2388,8 +2399,8 @@ int main (int argc, char **argv) */ #ifdef WITH_AUDIT if (uflg || gflg) { diff --git a/shadow-utils.spec b/shadow-utils.spec index b864952..bbd0a0d 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,6 +1,6 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils -Version: 4.15.0rc3 +Version: 4.15.0 Release: 1%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later @@ -25,7 +25,7 @@ Patch1: shadow-4.15.0-date-parsing.patch # Audit message changes - partially upstreamed Patch2: shadow-4.15.0-audit-update.patch # Probably non-upstreamable -Patch3: shadow-4.14.0-account-tools-setuid.patch +Patch3: shadow-4.15.0-account-tools-setuid.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -273,11 +273,8 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog -* Fri Mar 1 2024 Iker Pedrosa - 2:4.15.0rc3-1 -- Rebase to version 4.15.0rc3 - -* Fri Feb 16 2024 Iker Pedrosa - 2:4.15.0rc2-1 -- Rebase to version 4.15.0rc2 +* Mon Mar 11 2024 Iker Pedrosa - 2:4.15.0-1 +- Rebase to version 4.15.0 * Mon Feb 12 2024 Iker Pedrosa - 2:4.14.0-6 - Build linking `libpam` diff --git a/sources b/sources index a6a9165..c3c37d6 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (shadow-4.15.0rc3.tar.xz) = 4b5329c73e495c2ff4ab69070ce30c1fd8219a8f87a394effa2a301949849e0db53ace5356a373e75707847e2248710fe9943db8c2d3238e76ee2a73e4274d9c -SHA512 (shadow-4.15.0rc3.tar.xz.asc) = 5261e179ca264a7ad8c5d8ae62c5bed606bb6db2b17e16ef863fade88938bcc6e27e19deed7c58099ec51bb39e0d3b4332a7d8b58dcde8280b49993da7774e23 +SHA512 (shadow-4.15.0.tar.xz) = 88d72fb706f6792b460c14a9b1b42fe0b5962834ec3793f296cbc138807736b5ad73d3f802cda74db740a71545eb1c8ec47447c2250299eb730ed2b2674e2249 +SHA512 (shadow-4.15.0.tar.xz.asc) = 0a39d6a45b7d8df12aade89ed9fc9d481c91297dbd34e85fe831426c1d0051cbcf8478759306b8871cd6b1835604c5836decf398d0165c50ac52fee365561446 From f38dfa13570663ea7ad8f776619a3d7b0b5c3eff Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Tue, 12 Mar 2024 09:21:15 +0100 Subject: [PATCH 083/134] Bump the minor release to 4.15.1 Wrong versioning for 4.15.0 RC releases makes the oficial release look lower than them. Fix it by bumping the minor release to 4.15.1 Resolves: #2268690 Signed-off-by: Iker Pedrosa --- .gitignore | 2 ++ shadow-utils.spec | 6 +++++- sources | 4 ++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index db3a21c..5db8705 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,5 @@ shadow-4.1.4.2.tar.bz2 /shadow-4.15.0rc3.tar.xz.asc /shadow-4.15.0.tar.xz /shadow-4.15.0.tar.xz.asc +/shadow-4.15.1.tar.xz +/shadow-4.15.1.tar.xz.asc diff --git a/shadow-utils.spec b/shadow-utils.spec index bbd0a0d..a0e9990 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,6 +1,6 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils -Version: 4.15.0 +Version: 4.15.1 Release: 1%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later @@ -273,6 +273,10 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Tue Mar 12 2024 Iker Pedrosa - 2:4.15.1-1 +- Wrong versioning for 4.15.0 RC releases makes the oficial release look lower than them. + Fix it by bumping the minor release to 4.15.1. Resolves: #2268690 + * Mon Mar 11 2024 Iker Pedrosa - 2:4.15.0-1 - Rebase to version 4.15.0 diff --git a/sources b/sources index c3c37d6..ca5a1c9 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (shadow-4.15.0.tar.xz) = 88d72fb706f6792b460c14a9b1b42fe0b5962834ec3793f296cbc138807736b5ad73d3f802cda74db740a71545eb1c8ec47447c2250299eb730ed2b2674e2249 -SHA512 (shadow-4.15.0.tar.xz.asc) = 0a39d6a45b7d8df12aade89ed9fc9d481c91297dbd34e85fe831426c1d0051cbcf8478759306b8871cd6b1835604c5836decf398d0165c50ac52fee365561446 +SHA512 (shadow-4.15.1.tar.xz) = 2667a1d781066adce42e684463329c3f32d28c07b7b79b628525bffcd61c078f6ff430be3d42976d0509d9f9a55cd80f5a50d479b85155476cee7f00f06708d8 +SHA512 (shadow-4.15.1.tar.xz.asc) = 0a39d6a45b7d8df12aade89ed9fc9d481c91297dbd34e85fe831426c1d0051cbcf8478759306b8871cd6b1835604c5836decf398d0165c50ac52fee365561446 From 1f1cc49defa6b4bed84aacc74ceaa388d0420abf Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Thu, 21 Mar 2024 11:29:11 +0530 Subject: [PATCH 084/134] getdef: avoid spurious error messages Avoid spurious error messages about unknown configuration options Resolves: #2265291 Signed-off-by: Iker Pedrosa --- shadow-4.15.0-getdef-spurious-error.patch | 137 ++++++++++++++++++++++ shadow-utils.spec | 8 +- 2 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 shadow-4.15.0-getdef-spurious-error.patch diff --git a/shadow-4.15.0-getdef-spurious-error.patch b/shadow-4.15.0-getdef-spurious-error.patch new file mode 100644 index 0000000..9cec295 --- /dev/null +++ b/shadow-4.15.0-getdef-spurious-error.patch @@ -0,0 +1,137 @@ +From ead55e9ba8958504e23e29545f90c4dd925c7462 Mon Sep 17 00:00:00 2001 +From: Serge Hallyn +Date: Wed, 20 Mar 2024 17:39:46 -0500 +Subject: [PATCH] getdef: avoid spurious error messages about unknown + configuration options + +def_find can return NULL for unset, not just unknown, config options. So +move the decision of whether to log an error message about an unknown config +option back into def_find, which knows the difference. Only putdef_str() +will pass a char* srcfile to def_find, so only calls from putdef_str will +cause the message, which was the original intent of fa68441bc4be8. + +closes #967 + +fixes: fa68441bc4be8 ("Improve the login.defs unknown item error message") +Signed-off-by: Serge Hallyn +--- + lib/getdef.c | 30 ++++++++++++++++-------------- + 1 file changed, 16 insertions(+), 14 deletions(-) + +diff --git a/lib/getdef.c b/lib/getdef.c +index 4d4d4e19..ef2ae1f0 100644 +--- a/lib/getdef.c ++++ b/lib/getdef.c +@@ -176,7 +176,7 @@ static const char* def_fname = LOGINDEFS; /* login config defs file */ + static bool def_loaded = false; /* are defs already loaded? */ + + /* local function prototypes */ +-static /*@observer@*/ /*@null@*/struct itemdef *def_find (const char *); ++static /*@observer@*/ /*@null@*/struct itemdef *def_find (const char *, const char *); + static void def_load (void); + + +@@ -195,7 +195,7 @@ static void def_load (void); + def_load (); + } + +- d = def_find (item); ++ d = def_find (item, NULL); + return (NULL == d) ? NULL : d->value; + } + +@@ -214,7 +214,7 @@ bool getdef_bool (const char *item) + def_load (); + } + +- d = def_find (item); ++ d = def_find (item, NULL); + if ((NULL == d) || (NULL == d->value)) { + return false; + } +@@ -240,7 +240,7 @@ int getdef_num (const char *item, int dflt) + def_load (); + } + +- d = def_find (item); ++ d = def_find (item, NULL); + if ((NULL == d) || (NULL == d->value)) { + return dflt; + } +@@ -275,7 +275,7 @@ unsigned int getdef_unum (const char *item, unsigned int dflt) + def_load (); + } + +- d = def_find (item); ++ d = def_find (item, NULL); + if ((NULL == d) || (NULL == d->value)) { + return dflt; + } +@@ -310,7 +310,7 @@ long getdef_long (const char *item, long dflt) + def_load (); + } + +- d = def_find (item); ++ d = def_find (item, NULL); + if ((NULL == d) || (NULL == d->value)) { + return dflt; + } +@@ -342,7 +342,7 @@ unsigned long getdef_ulong (const char *item, unsigned long dflt) + def_load (); + } + +- d = def_find (item); ++ d = def_find (item, NULL); + if ((NULL == d) || (NULL == d->value)) { + return dflt; + } +@@ -375,12 +375,9 @@ int putdef_str (const char *name, const char *value, const char *srcfile) + * Locate the slot to save the value. If this parameter + * is unknown then "def_find" will print an err message. + */ +- d = def_find (name); +- if (NULL == d) { +- if (NULL != srcfile) +- SYSLOG ((LOG_CRIT, "shadow: unknown configuration item '%s' in '%s'", name, srcfile)); ++ d = def_find (name, srcfile); ++ if (NULL == d) + return -1; +- } + + /* + * Save off the value. +@@ -404,9 +401,12 @@ int putdef_str (const char *name, const char *value, const char *srcfile) + * + * Search through a table of configurable items to locate the + * specified configuration option. ++ * ++ * If srcfile is not NULL, and the item is not found, then report an error saying ++ * the unknown item was used in this file. + */ + +-static /*@observer@*/ /*@null@*/struct itemdef *def_find (const char *name) ++static /*@observer@*/ /*@null@*/struct itemdef *def_find (const char *name, const char *srcfile) + { + struct itemdef *ptr; + +@@ -432,6 +432,8 @@ static /*@observer@*/ /*@null@*/struct itemdef *def_find (const char *name) + fprintf (shadow_logfd, + _("configuration error - unknown item '%s' (notify administrator)\n"), + name); ++ if (srcfile != NULL) ++ SYSLOG ((LOG_CRIT, "shadow: unknown configuration item '%s' in '%s'", name, srcfile)); + + out: + return NULL; +@@ -610,7 +612,7 @@ int main (int argc, char **argv) + def_load (); + + for (i = 0; i < NUMDEFS; ++i) { +- d = def_find (def_table[i].name); ++ d = def_find (def_table[i].name, NULL); + if (NULL == d) { + printf ("error - lookup '%s' failed\n", + def_table[i].name); +-- +2.44.0 + diff --git a/shadow-utils.spec b/shadow-utils.spec index a0e9990..655174e 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.15.1 -Release: 1%{?dist} +Release: 2%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -26,6 +26,8 @@ Patch1: shadow-4.15.0-date-parsing.patch Patch2: shadow-4.15.0-audit-update.patch # Probably non-upstreamable Patch3: shadow-4.15.0-account-tools-setuid.patch +# https://github.com/shadow-maint/shadow/commit/ead55e9ba8958504e23e29545f90c4dd925c7462 +Patch4: shadow-4.15.0-getdef-spurious-error.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -273,6 +275,10 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Thu Mar 21 2024 Iker Pedrosa - 2:4.15.1-2 +- getdef: avoid spurious error messages about unknown configuration options. + Resolves: #2265291 + * Tue Mar 12 2024 Iker Pedrosa - 2:4.15.1-1 - Wrong versioning for 4.15.0 RC releases makes the oficial release look lower than them. Fix it by bumping the minor release to 4.15.1. Resolves: #2268690 From 39c1e07961334ffb76861182c2ac01967110cac5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 10 Apr 2024 13:43:36 +0200 Subject: [PATCH 085/134] Prepare for bin-sbin merge https://fedoraproject.org/wiki/Changes/Unify_bin_and_sbin First, fix build if %_sbindir == %_bindir. Second, add Provides for the old locations. We rely on the filesystem(unmerged-sbin-symlinks) feature to actually create the symlinks for us. This commit makes things compatible with the state before and after the merge. --- shadow-utils.spec | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index 655174e..ad712a1 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.15.1 -Release: 2%{?dist} +Release: 4%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -62,6 +62,19 @@ Provides: shadow = %{epoch}:%{version}-%{release} Provides: passwd = 0.80-18 Obsoletes: passwd <= 0.80-19 +%if "%{_sbindir}" == "%{_bindir}" +# Compat symlinks for Requires in other packages. +# We rely on filesystem to create the symlinks for us. +Requires: filesystem(unmerged-sbin-symlinks) +Provides: /usr/sbin/adduser +Provides: /usr/sbin/useradd +Provides: /usr/sbin/userdel +Provides: /usr/sbin/usermod +Provides: /usr/sbin/groupadd +Provides: /usr/sbin/groupdel +Provides: /usr/sbin/groupmod +%endif + %description The shadow-utils package includes the necessary programs for converting UNIX password files to the shadow password format, plus @@ -149,6 +162,11 @@ for subdir in $RPM_BUILD_ROOT%{_mandir}/{??,??_??,??_??.*}/man* ; do test -d $subdir && test -e $subdir/useradd.8 && echo ".so man8/useradd.8" > $subdir/adduser.8 done +%if "%{_sbindir}" == "%{_bindir}" +# The installation script doesn't actually use the configured paths :( +mv -v $RPM_BUILD_ROOT/usr/sbin/* $RPM_BUILD_ROOT%{_bindir}/ +%endif + # Remove binaries we don't use. rm $RPM_BUILD_ROOT%{_bindir}/chfn rm $RPM_BUILD_ROOT%{_bindir}/chsh @@ -275,6 +293,10 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Thu Apr 11 2024 Zbigniew Jedrzejewski-Szmek - 2:4.15.1-4 +- Fix build with %%_bindir==%%_sbindir +- Add virtual Provides for old file paths used by other packages + * Thu Mar 21 2024 Iker Pedrosa - 2:4.15.1-2 - getdef: avoid spurious error messages about unknown configuration options. Resolves: #2265291 From 6ad0830639f87cc09dd52228b4a2820dcaab05dc Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Mon, 20 May 2024 12:14:47 +0200 Subject: [PATCH 086/134] Several fixes for issues detected by static analyzer tools Signed-off-by: Iker Pedrosa --- ....patch => shadow-4.15.1-audit-update.patch | 302 ++-- shadow-4.15.1-sast-fixes.patch | 1413 +++++++++++++++++ shadow-utils.spec | 13 +- 3 files changed, 1573 insertions(+), 155 deletions(-) rename shadow-4.15.0-audit-update.patch => shadow-4.15.1-audit-update.patch (89%) create mode 100644 shadow-4.15.1-sast-fixes.patch diff --git a/shadow-4.15.0-audit-update.patch b/shadow-4.15.1-audit-update.patch similarity index 89% rename from shadow-4.15.0-audit-update.patch rename to shadow-4.15.1-audit-update.patch index a625c5c..a738d60 100644 --- a/shadow-4.15.0-audit-update.patch +++ b/shadow-4.15.1-audit-update.patch @@ -1,6 +1,6 @@ -diff -up shadow-4.15.0/lib/audit_help.c.audit-update shadow-4.15.0/lib/audit_help.c ---- shadow-4.15.0/lib/audit_help.c.audit-update 2024-03-01 02:50:52.000000000 +0100 -+++ shadow-4.15.0/lib/audit_help.c 2024-03-11 10:56:20.233991612 +0100 +diff -up shadow-4.15.1/lib/audit_help.c.audit-update shadow-4.15.1/lib/audit_help.c +--- shadow-4.15.1/lib/audit_help.c.audit-update 2024-03-01 02:50:52.000000000 +0100 ++++ shadow-4.15.1/lib/audit_help.c 2024-05-20 11:52:05.639758532 +0200 @@ -48,7 +48,7 @@ void audit_help_open (void) * This function will log a message to the audit system using a predefined * message format. Parameter usage is as follows: @@ -50,9 +50,9 @@ diff -up shadow-4.15.0/lib/audit_help.c.audit-update shadow-4.15.0/lib/audit_hel void audit_logger_message (const char *message, shadow_audit_result result) { if (audit_fd < 0) { -diff -up shadow-4.15.0/lib/cleanup_group.c.audit-update shadow-4.15.0/lib/cleanup_group.c ---- shadow-4.15.0/lib/cleanup_group.c.audit-update 2024-03-01 02:50:52.000000000 +0100 -+++ shadow-4.15.0/lib/cleanup_group.c 2024-03-11 10:56:20.233991612 +0100 +diff -up shadow-4.15.1/lib/cleanup_group.c.audit-update shadow-4.15.1/lib/cleanup_group.c +--- shadow-4.15.1/lib/cleanup_group.c.audit-update 2024-03-01 02:50:52.000000000 +0100 ++++ shadow-4.15.1/lib/cleanup_group.c 2024-05-20 11:52:05.639758532 +0200 @@ -62,7 +62,7 @@ void cleanup_report_mod_group (void *cle gr_dbname (), info->action)); @@ -131,9 +131,9 @@ diff -up shadow-4.15.0/lib/cleanup_group.c.audit-update shadow-4.15.0/lib/cleanu SHADOW_AUDIT_FAILURE); #endif } -diff -up shadow-4.15.0/lib/cleanup_user.c.audit-update shadow-4.15.0/lib/cleanup_user.c ---- shadow-4.15.0/lib/cleanup_user.c.audit-update 2024-03-01 02:50:52.000000000 +0100 -+++ shadow-4.15.0/lib/cleanup_user.c 2024-03-11 10:56:20.233991612 +0100 +diff -up shadow-4.15.1/lib/cleanup_user.c.audit-update shadow-4.15.1/lib/cleanup_user.c +--- shadow-4.15.1/lib/cleanup_user.c.audit-update 2024-03-01 02:50:52.000000000 +0100 ++++ shadow-4.15.1/lib/cleanup_user.c 2024-05-20 11:52:05.639758532 +0200 @@ -44,7 +44,7 @@ void cleanup_report_mod_passwd (void *cl pw_dbname (), info->action)); @@ -181,9 +181,9 @@ diff -up shadow-4.15.0/lib/cleanup_user.c.audit-update shadow-4.15.0/lib/cleanup SHADOW_AUDIT_FAILURE); #endif } -diff -up shadow-4.15.0/lib/prototypes.h.audit-update shadow-4.15.0/lib/prototypes.h ---- shadow-4.15.0/lib/prototypes.h.audit-update 2024-03-01 02:50:52.000000000 +0100 -+++ shadow-4.15.0/lib/prototypes.h 2024-03-11 10:56:20.233991612 +0100 +diff -up shadow-4.15.1/lib/prototypes.h.audit-update shadow-4.15.1/lib/prototypes.h +--- shadow-4.15.1/lib/prototypes.h.audit-update 2024-03-01 02:50:52.000000000 +0100 ++++ shadow-4.15.1/lib/prototypes.h 2024-05-20 11:52:05.639758532 +0200 @@ -198,12 +198,21 @@ extern int audit_fd; extern void audit_help_open (void); /* Use AUDIT_NO_ID when a name is provided to audit_logger instead of an ID */ @@ -206,9 +206,9 @@ diff -up shadow-4.15.0/lib/prototypes.h.audit-update shadow-4.15.0/lib/prototype void audit_logger_message (const char *message, shadow_audit_result result); #endif -diff -up shadow-4.15.0/src/chage.c.audit-update shadow-4.15.0/src/chage.c ---- shadow-4.15.0/src/chage.c.audit-update 2024-03-08 22:27:04.000000000 +0100 -+++ shadow-4.15.0/src/chage.c 2024-03-11 10:56:20.234991618 +0100 +diff -up shadow-4.15.1/src/chage.c.audit-update shadow-4.15.1/src/chage.c +--- shadow-4.15.1/src/chage.c.audit-update 2024-03-08 22:27:04.000000000 +0100 ++++ shadow-4.15.1/src/chage.c 2024-05-20 11:52:05.639758532 +0200 @@ -110,8 +110,8 @@ fail_exit (int code) #ifdef WITH_AUDIT @@ -287,9 +287,9 @@ diff -up shadow-4.15.0/src/chage.c.audit-update shadow-4.15.0/src/chage.c user_name, user_uid, 1); } #endif -diff -up shadow-4.15.0/src/gpasswd.c.audit-update shadow-4.15.0/src/gpasswd.c ---- shadow-4.15.0/src/gpasswd.c.audit-update 2024-03-08 22:27:04.000000000 +0100 -+++ shadow-4.15.0/src/gpasswd.c 2024-03-11 10:56:20.234991618 +0100 +diff -up shadow-4.15.1/src/gpasswd.c.audit-update shadow-4.15.1/src/gpasswd.c +--- shadow-4.15.1/src/gpasswd.c.audit-update 2024-03-08 22:27:04.000000000 +0100 ++++ shadow-4.15.1/src/gpasswd.c 2024-05-20 11:52:05.640758536 +0200 @@ -125,7 +125,7 @@ static void usage (int status) (void) fputs (_(" -d, --delete USER remove USER from GROUP\n"), usageout); (void) fputs (_(" -h, --help display this help message and exit\n"), usageout); @@ -514,9 +514,9 @@ diff -up shadow-4.15.0/src/gpasswd.c.audit-update shadow-4.15.0/src/gpasswd.c SHADOW_AUDIT_SUCCESS); #endif } -diff -up shadow-4.15.0/src/groupadd.c.audit-update shadow-4.15.0/src/groupadd.c ---- shadow-4.15.0/src/groupadd.c.audit-update 2024-03-08 22:27:04.000000000 +0100 -+++ shadow-4.15.0/src/groupadd.c 2024-03-11 10:59:11.522108956 +0100 +diff -up shadow-4.15.1/src/groupadd.c.audit-update shadow-4.15.1/src/groupadd.c +--- shadow-4.15.1/src/groupadd.c.audit-update 2024-03-08 22:27:04.000000000 +0100 ++++ shadow-4.15.1/src/groupadd.c 2024-05-20 11:52:05.640758536 +0200 @@ -115,6 +115,15 @@ usage (int status) exit (status); } @@ -690,9 +690,9 @@ diff -up shadow-4.15.0/src/groupadd.c.audit-update shadow-4.15.0/src/groupadd.c } } -diff -up shadow-4.15.0/src/groupdel.c.audit-update shadow-4.15.0/src/groupdel.c ---- shadow-4.15.0/src/groupdel.c.audit-update 2024-03-08 22:27:04.000000000 +0100 -+++ shadow-4.15.0/src/groupdel.c 2024-03-11 11:14:20.572151046 +0100 +diff -up shadow-4.15.1/src/groupdel.c.audit-update shadow-4.15.1/src/groupdel.c +--- shadow-4.15.1/src/groupdel.c.audit-update 2024-03-08 22:27:04.000000000 +0100 ++++ shadow-4.15.1/src/groupdel.c 2024-05-20 11:52:05.640758536 +0200 @@ -87,6 +87,15 @@ usage (int status) exit (status); } @@ -860,9 +860,9 @@ diff -up shadow-4.15.0/src/groupdel.c.audit-update shadow-4.15.0/src/groupdel.c } #endif -diff -up shadow-4.15.0/src/groupmod.c.audit-update shadow-4.15.0/src/groupmod.c ---- shadow-4.15.0/src/groupmod.c.audit-update 2024-03-08 22:27:04.000000000 +0100 -+++ shadow-4.15.0/src/groupmod.c 2024-03-11 10:56:20.234991618 +0100 +diff -up shadow-4.15.1/src/groupmod.c.audit-update shadow-4.15.1/src/groupmod.c +--- shadow-4.15.1/src/groupmod.c.audit-update 2024-03-08 22:27:04.000000000 +0100 ++++ shadow-4.15.1/src/groupmod.c 2024-05-20 11:52:05.640758536 +0200 @@ -474,7 +474,7 @@ static void close_files (void) exit (E_GRP_UPDATE); } @@ -908,9 +908,9 @@ diff -up shadow-4.15.0/src/groupmod.c.audit-update shadow-4.15.0/src/groupmod.c group_name, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); #endif -diff -up shadow-4.15.0/src/newgrp.c.audit-update shadow-4.15.0/src/newgrp.c ---- shadow-4.15.0/src/newgrp.c.audit-update 2024-03-08 22:27:04.000000000 +0100 -+++ shadow-4.15.0/src/newgrp.c 2024-03-11 10:56:20.234991618 +0100 +diff -up shadow-4.15.1/src/newgrp.c.audit-update shadow-4.15.1/src/newgrp.c +--- shadow-4.15.1/src/newgrp.c.audit-update 2024-03-08 22:27:04.000000000 +0100 ++++ shadow-4.15.1/src/newgrp.c 2024-05-20 11:52:05.640758536 +0200 @@ -188,10 +188,10 @@ static void check_perms (const struct gr if (grp->gr_passwd[0] == '\0' || strcmp (cpasswd, grp->gr_passwd) != 0) { @@ -1091,10 +1091,10 @@ diff -up shadow-4.15.0/src/newgrp.c.audit-update shadow-4.15.0/src/newgrp.c } #endif exit (EXIT_FAILURE); -diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c ---- shadow-4.15.0/src/useradd.c.audit-update 2024-03-08 22:27:04.000000000 +0100 -+++ shadow-4.15.0/src/useradd.c 2024-03-11 10:56:20.235991625 +0100 -@@ -242,6 +242,8 @@ static void check_uid_range(int rflg, ui +diff -up shadow-4.15.1/src/useradd.c.audit-update shadow-4.15.1/src/useradd.c +--- shadow-4.15.1/src/useradd.c.audit-update 2024-05-20 11:52:05.635758519 +0200 ++++ shadow-4.15.1/src/useradd.c 2024-05-20 11:52:05.640758536 +0200 +@@ -245,6 +245,8 @@ static FILE *fmkstemp(char *template); */ static void fail_exit (int code) { @@ -1103,7 +1103,7 @@ diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c if (home_added && rmdir(prefix_user_home) != 0) { fprintf(stderr, _("%s: %s was created, but could not be removed\n"), -@@ -252,38 +254,22 @@ static void fail_exit (int code) +@@ -255,38 +257,22 @@ static void fail_exit (int code) if (spw_locked && spw_unlock() == 0) { fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname()); SYSLOG((LOG_ERR, "failed to unlock %s", spw_dbname())); @@ -1142,7 +1142,7 @@ diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c /* continue */ } #endif -@@ -291,27 +277,23 @@ static void fail_exit (int code) +@@ -294,27 +280,23 @@ static void fail_exit (int code) if (sub_uid_locked && sub_uid_unlock() == 0) { fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname()); SYSLOG((LOG_ERR, "failed to unlock %s", sub_uid_dbname())); @@ -1177,7 +1177,7 @@ diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif SYSLOG((LOG_INFO, "failed adding user '%s', exit code: %d", user_name, code)); -@@ -732,7 +714,7 @@ static int set_defaults (void) +@@ -727,7 +709,7 @@ static int set_defaults (void) } #ifdef WITH_AUDIT audit_logger (AUDIT_USYS_CONFIG, Prog, @@ -1186,7 +1186,7 @@ diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c NULL, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); #endif -@@ -1060,12 +1042,6 @@ static void grp_update (void) +@@ -1056,12 +1038,6 @@ static void grp_update (void) _("%s: Out of memory. Cannot update %s.\n"), Prog, gr_dbname ()); SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", gr_dbname (), user_name)); @@ -1199,7 +1199,7 @@ diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c fail_exit (E_GRP_UPDATE); /* XXX */ } -@@ -1079,18 +1055,12 @@ static void grp_update (void) +@@ -1075,18 +1051,12 @@ static void grp_update (void) _("%s: failed to prepare the new %s entry '%s'\n"), Prog, gr_dbname (), ngrp->gr_name); SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", gr_dbname (), user_name)); @@ -1221,7 +1221,7 @@ diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c SHADOW_AUDIT_SUCCESS); #endif SYSLOG ((LOG_INFO, -@@ -1135,12 +1105,6 @@ static void grp_update (void) +@@ -1131,12 +1101,6 @@ static void grp_update (void) _("%s: Out of memory. Cannot update %s.\n"), Prog, sgr_dbname ()); SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", sgr_dbname (), user_name)); @@ -1234,7 +1234,7 @@ diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c fail_exit (E_GRP_UPDATE); /* XXX */ } -@@ -1154,18 +1118,13 @@ static void grp_update (void) +@@ -1150,18 +1114,13 @@ static void grp_update (void) _("%s: failed to prepare the new %s entry '%s'\n"), Prog, sgr_dbname (), nsgrp->sg_name); SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", sgr_dbname (), user_name)); @@ -1257,7 +1257,7 @@ diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c SHADOW_AUDIT_SUCCESS); #endif SYSLOG ((LOG_INFO, -@@ -1560,7 +1519,7 @@ static void process_flags (int argc, cha +@@ -1556,7 +1515,7 @@ static void process_flags (int argc, cha Prog, user_name); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1266,7 +1266,7 @@ diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1660,7 +1619,7 @@ static void close_files (void) +@@ -1656,7 +1615,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1275,7 +1275,7 @@ diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1673,7 +1632,7 @@ static void close_files (void) +@@ -1669,7 +1628,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1284,7 +1284,7 @@ diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1690,7 +1649,7 @@ static void close_files (void) +@@ -1686,7 +1645,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1293,7 +1293,7 @@ diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1704,7 +1663,7 @@ static void close_files (void) +@@ -1700,7 +1659,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1302,7 +1302,7 @@ diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1967,7 +1926,7 @@ static void grp_add (void) +@@ -1963,7 +1922,7 @@ static void grp_add (void) Prog, gr_dbname (), grp.gr_name); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_GROUP, Prog, @@ -1311,7 +1311,7 @@ diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c grp.gr_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1983,7 +1942,7 @@ static void grp_add (void) +@@ -1979,7 +1938,7 @@ static void grp_add (void) Prog, sgr_dbname (), sgrp.sg_name); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_GROUP, Prog, @@ -1320,7 +1320,7 @@ diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c grp.gr_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif -@@ -1993,7 +1952,7 @@ static void grp_add (void) +@@ -1989,7 +1948,7 @@ static void grp_add (void) SYSLOG ((LOG_INFO, "new group: name=%s, GID=%u", user_name, user_gid)); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_GROUP, Prog, @@ -1329,7 +1329,7 @@ diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c grp.gr_name, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); #endif -@@ -2195,11 +2154,6 @@ static void usr_update (unsigned long su +@@ -2191,11 +2150,6 @@ static void usr_update (unsigned long su fprintf (stderr, _("%s: failed to prepare the new %s entry '%s'\n"), Prog, spw_dbname (), spent.sp_namp); @@ -1341,7 +1341,7 @@ diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c fail_exit (E_PW_UPDATE); } #ifdef ENABLE_SUBIDS -@@ -2226,7 +2180,7 @@ static void usr_update (unsigned long su +@@ -2222,7 +2176,7 @@ static void usr_update (unsigned long su * and we can use the real ID thereafter. */ audit_logger (AUDIT_ADD_USER, Prog, @@ -1350,7 +1350,7 @@ diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c user_name, AUDIT_NO_ID, SHADOW_AUDIT_SUCCESS); #endif -@@ -2321,10 +2275,6 @@ static void create_home (void) +@@ -2317,10 +2271,6 @@ static void create_home (void) if (mkdir(path, 0) != 0) { fprintf(stderr, _("%s: cannot create directory %s\n"), Prog, path); @@ -1361,7 +1361,7 @@ diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c fail_exit(E_HOMEDIR); } if (chown(path, 0, 0) < 0) { -@@ -2349,7 +2299,7 @@ static void create_home (void) +@@ -2345,7 +2295,7 @@ static void create_home (void) } home_added = true; #ifdef WITH_AUDIT @@ -1370,7 +1370,7 @@ diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c user_name, user_id, SHADOW_AUDIT_SUCCESS); #endif #ifdef WITH_SELINUX -@@ -2590,12 +2540,6 @@ int main (int argc, char **argv) +@@ -2586,12 +2536,6 @@ int main (int argc, char **argv) */ if (prefix_getpwnam (user_name) != NULL) { /* local, no need for xgetpwnam */ fprintf (stderr, _("%s: user '%s' already exists\n"), Prog, user_name); @@ -1383,7 +1383,7 @@ diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c fail_exit (E_NAME_IN_USE); } -@@ -2611,12 +2555,6 @@ int main (int argc, char **argv) +@@ -2607,12 +2551,6 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: group %s exists - if you want to add this user to that group, use -g.\n"), Prog, user_name); @@ -1396,7 +1396,7 @@ diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c fail_exit (E_NAME_IN_USE); } } -@@ -2646,12 +2584,6 @@ int main (int argc, char **argv) +@@ -2642,12 +2580,6 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: UID %lu is not unique\n"), Prog, (unsigned long) user_id); @@ -1409,7 +1409,7 @@ diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c fail_exit (E_UID_IN_USE); } } -@@ -2726,9 +2658,9 @@ int main (int argc, char **argv) +@@ -2722,9 +2654,9 @@ int main (int argc, char **argv) _("%s: warning: the user name %s to %s SELinux user mapping failed.\n"), Prog, user_name, user_selinux); #ifdef WITH_AUDIT @@ -1422,9 +1422,9 @@ diff -up shadow-4.15.0/src/useradd.c.audit-update shadow-4.15.0/src/useradd.c #endif /* WITH_AUDIT */ fail_exit (E_SE_UPDATE); } -diff -up shadow-4.15.0/src/userdel.c.audit-update shadow-4.15.0/src/userdel.c ---- shadow-4.15.0/src/userdel.c.audit-update 2024-03-08 22:27:04.000000000 +0100 -+++ shadow-4.15.0/src/userdel.c 2024-03-11 10:56:20.235991625 +0100 +diff -up shadow-4.15.1/src/userdel.c.audit-update shadow-4.15.1/src/userdel.c +--- shadow-4.15.1/src/userdel.c.audit-update 2024-03-08 22:27:04.000000000 +0100 ++++ shadow-4.15.1/src/userdel.c 2024-05-20 11:52:05.641758539 +0200 @@ -206,9 +206,9 @@ static void update_groups (void) * Update the DBM group file with the new entry as well. */ @@ -1740,10 +1740,10 @@ diff -up shadow-4.15.0/src/userdel.c.audit-update shadow-4.15.0/src/userdel.c user_name, user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ fail_exit (E_SE_UPDATE); -diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c ---- shadow-4.15.0/src/usermod.c.audit-update 2024-03-08 22:27:04.000000000 +0100 -+++ shadow-4.15.0/src/usermod.c 2024-03-11 10:56:20.235991625 +0100 -@@ -438,7 +438,7 @@ static char *new_pw_passwd (char *pw_pas +diff -up shadow-4.15.1/src/usermod.c.audit-update shadow-4.15.1/src/usermod.c +--- shadow-4.15.1/src/usermod.c.audit-update 2024-05-20 11:52:05.638758529 +0200 ++++ shadow-4.15.1/src/usermod.c 2024-05-20 11:56:51.962509443 +0200 +@@ -440,7 +440,7 @@ static char *new_pw_passwd (char *pw_pas #ifdef WITH_AUDIT audit_logger (AUDIT_USER_CHAUTHTOK, Prog, @@ -1752,7 +1752,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c #endif SYSLOG ((LOG_INFO, "lock user '%s' password", user_newname)); strcpy (buf, "!"); -@@ -455,14 +455,14 @@ static char *new_pw_passwd (char *pw_pas +@@ -457,14 +457,14 @@ static char *new_pw_passwd (char *pw_pas #ifdef WITH_AUDIT audit_logger (AUDIT_USER_CHAUTHTOK, Prog, @@ -1769,7 +1769,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c #endif SYSLOG ((LOG_INFO, "change user '%s' password", user_newname)); pw_pass = xstrdup (user_pass); -@@ -490,8 +490,8 @@ static void new_pwent (struct passwd *pw +@@ -492,8 +492,8 @@ static void new_pwent (struct passwd *pw fail_exit (E_NAME_IN_USE); } #ifdef WITH_AUDIT @@ -1780,7 +1780,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c #endif SYSLOG ((LOG_INFO, "change user name '%s' to '%s'", -@@ -510,8 +510,8 @@ static void new_pwent (struct passwd *pw +@@ -512,8 +512,8 @@ static void new_pwent (struct passwd *pw if (uflg) { #ifdef WITH_AUDIT @@ -1791,7 +1791,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c #endif SYSLOG ((LOG_INFO, "change user '%s' UID from '%d' to '%d'", -@@ -520,8 +520,8 @@ static void new_pwent (struct passwd *pw +@@ -522,8 +522,8 @@ static void new_pwent (struct passwd *pw } if (gflg) { #ifdef WITH_AUDIT @@ -1802,7 +1802,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c user_newname, user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -531,16 +531,16 @@ static void new_pwent (struct passwd *pw +@@ -533,16 +533,16 @@ static void new_pwent (struct passwd *pw } if (cflg) { #ifdef WITH_AUDIT @@ -1823,7 +1823,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c user_newname, user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -556,8 +556,8 @@ static void new_pwent (struct passwd *pw +@@ -558,8 +558,8 @@ static void new_pwent (struct passwd *pw } if (sflg) { #ifdef WITH_AUDIT @@ -1834,7 +1834,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c user_newname, user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -587,8 +587,8 @@ static void new_spent (struct spwd *spen +@@ -589,8 +589,8 @@ static void new_spent (struct spwd *spen if (fflg) { #ifdef WITH_AUDIT @@ -1845,7 +1845,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c user_newname, user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -602,8 +602,8 @@ static void new_spent (struct spwd *spen +@@ -604,8 +604,8 @@ static void new_spent (struct spwd *spen date_to_str (sizeof(new_exp), new_exp, user_newexpire * DAY); date_to_str (sizeof(old_exp), old_exp, user_expire * DAY); #ifdef WITH_AUDIT @@ -1856,7 +1856,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c user_newname, user_newid, 1); #endif SYSLOG ((LOG_INFO, -@@ -688,9 +688,9 @@ fail_exit (int code) +@@ -690,9 +690,9 @@ fail_exit (int code) #endif /* ENABLE_SUBIDS */ #ifdef WITH_AUDIT @@ -1869,109 +1869,109 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c #endif exit (code); } -@@ -752,9 +752,12 @@ static void update_group (void) - user_newname); - changed = true; - #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "changing group member", -- user_newname, AUDIT_NO_ID, 1); -+ audit_logger_with_group ( -+ AUDIT_USER_MGMT, Prog, -+ "update-member-in-group", -+ user_newname, AUDIT_NO_ID, -+ ngrp->gr_name, -+ SHADOW_AUDIT_SUCCESS); - #endif - SYSLOG ((LOG_INFO, - "change '%s' to '%s' in group '%s'", -@@ -768,9 +771,11 @@ static void update_group (void) - ngrp->gr_mem = del_list (ngrp->gr_mem, user_name); +@@ -762,9 +762,12 @@ update_group(const struct group *grp) + user_newname); changed = true; #ifdef WITH_AUDIT - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "removing group member", -- user_name, AUDIT_NO_ID, 1); -+ audit_logger_with_group (AUDIT_USER_MGMT, Prog, -+ "delete-user-from-group", -+ user_name, AUDIT_NO_ID, +- "changing group member", +- user_newname, AUDIT_NO_ID, 1); ++ audit_logger_with_group ( ++ AUDIT_USER_MGMT, Prog, ++ "update-member-in-group", ++ user_newname, AUDIT_NO_ID, + ngrp->gr_name, + SHADOW_AUDIT_SUCCESS); #endif SYSLOG ((LOG_INFO, - "delete '%s' from group '%s'", -@@ -783,9 +788,11 @@ static void update_group (void) - ngrp->gr_mem = add_list (ngrp->gr_mem, user_newname); + "change '%s' to '%s' in group '%s'", +@@ -778,9 +781,11 @@ update_group(const struct group *grp) + ngrp->gr_mem = del_list (ngrp->gr_mem, user_name); changed = true; #ifdef WITH_AUDIT - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "adding user to group", -- user_name, AUDIT_NO_ID, 1); +- "removing group member", +- user_name, AUDIT_NO_ID, 1); + audit_logger_with_group (AUDIT_USER_MGMT, Prog, -+ "add-user-to-group", ++ "delete-user-from-group", + user_name, AUDIT_NO_ID, + ngrp->gr_name, -+ SHADOW_AUDIT_SUCCESS); - #endif - SYSLOG ((LOG_INFO, "add '%s' to group '%s'", - user_newname, ngrp->gr_name)); -@@ -870,9 +877,10 @@ static void update_gshadow (void) - nsgrp->sg_adm = add_list (nsgrp->sg_adm, user_newname); - changed = true; - #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "changing admin name in shadow group", -- user_name, AUDIT_NO_ID, 1); -+ audit_logger_with_group (AUDIT_GRP_MGMT, Prog, -+ "update-admin-name-in-shadow-group", -+ user_name, AUDIT_NO_ID, nsgrp->sg_name, + SHADOW_AUDIT_SUCCESS); #endif SYSLOG ((LOG_INFO, - "change admin '%s' to '%s' in shadow group '%s'", -@@ -892,9 +900,10 @@ static void update_gshadow (void) - user_newname); - changed = true; + "delete '%s' from group '%s'", +@@ -793,9 +798,11 @@ update_group(const struct group *grp) + ngrp->gr_mem = add_list (ngrp->gr_mem, user_newname); + changed = true; #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "changing member in shadow group", -- user_name, AUDIT_NO_ID, 1); -+ audit_logger_with_group (AUDIT_USER_MGMT, Prog, -+ "update-member-in-shadow-group", -+ user_name, AUDIT_NO_ID, -+ nsgrp->sg_name, 1); +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "adding user to group", +- user_name, AUDIT_NO_ID, 1); ++ audit_logger_with_group (AUDIT_USER_MGMT, Prog, ++ "add-user-to-group", ++ user_name, AUDIT_NO_ID, ++ ngrp->gr_name, ++ SHADOW_AUDIT_SUCCESS); #endif - SYSLOG ((LOG_INFO, - "change '%s' to '%s' in shadow group '%s'", -@@ -908,9 +917,10 @@ static void update_gshadow (void) - nsgrp->sg_mem = del_list (nsgrp->sg_mem, user_name); + SYSLOG ((LOG_INFO, "add '%s' to group '%s'", + user_newname, ngrp->gr_name)); +@@ -888,9 +895,10 @@ update_gshadow(const struct sgrp *sgrp) + nsgrp->sg_adm = add_list (nsgrp->sg_adm, user_newname); + changed = true; + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "changing admin name in shadow group", +- user_name, AUDIT_NO_ID, 1); ++ audit_logger_with_group (AUDIT_GRP_MGMT, Prog, ++ "update-admin-name-in-shadow-group", ++ user_name, AUDIT_NO_ID, nsgrp->sg_name, ++ SHADOW_AUDIT_SUCCESS); + #endif + SYSLOG ((LOG_INFO, + "change admin '%s' to '%s' in shadow group '%s'", +@@ -910,9 +918,10 @@ update_gshadow(const struct sgrp *sgrp) + user_newname); changed = true; #ifdef WITH_AUDIT - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "removing user from shadow group", -- user_name, AUDIT_NO_ID, 1); +- "changing member in shadow group", +- user_name, AUDIT_NO_ID, 1); + audit_logger_with_group (AUDIT_USER_MGMT, Prog, -+ "delete-user-from-shadow-group", ++ "update-member-in-shadow-group", + user_name, AUDIT_NO_ID, + nsgrp->sg_name, 1); #endif SYSLOG ((LOG_INFO, - "delete '%s' from shadow group '%s'", -@@ -923,9 +933,10 @@ static void update_gshadow (void) - nsgrp->sg_mem = add_list (nsgrp->sg_mem, user_newname); + "change '%s' to '%s' in shadow group '%s'", +@@ -926,9 +935,10 @@ update_gshadow(const struct sgrp *sgrp) + nsgrp->sg_mem = del_list (nsgrp->sg_mem, user_name); changed = true; #ifdef WITH_AUDIT - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "adding user to shadow group", -- user_newname, AUDIT_NO_ID, 1); +- "removing user from shadow group", +- user_name, AUDIT_NO_ID, 1); + audit_logger_with_group (AUDIT_USER_MGMT, Prog, -+ "add-user-to-shadow-group", -+ user_newname, AUDIT_NO_ID, ++ "delete-user-from-shadow-group", ++ user_name, AUDIT_NO_ID, + nsgrp->sg_name, 1); #endif - SYSLOG ((LOG_INFO, "add '%s' to shadow group '%s'", - user_newname, nsgrp->sg_name)); -@@ -1836,8 +1847,8 @@ static void move_home (void) + SYSLOG ((LOG_INFO, + "delete '%s' from shadow group '%s'", +@@ -941,9 +951,10 @@ update_gshadow(const struct sgrp *sgrp) + nsgrp->sg_mem = add_list (nsgrp->sg_mem, user_newname); + changed = true; + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "adding user to shadow group", +- user_newname, AUDIT_NO_ID, 1); ++ audit_logger_with_group (AUDIT_USER_MGMT, Prog, ++ "add-user-to-shadow-group", ++ user_newname, AUDIT_NO_ID, ++ nsgrp->sg_name, 1); + #endif + SYSLOG ((LOG_INFO, "add '%s' to shadow group '%s'", + user_newname, nsgrp->sg_name)); +@@ -1852,8 +1863,8 @@ static void move_home (void) #ifdef WITH_AUDIT if (uflg || gflg) { @@ -1982,7 +1982,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c user_newname, user_newid, 1); } #endif -@@ -1855,8 +1866,8 @@ static void move_home (void) +@@ -1871,8 +1882,8 @@ static void move_home (void) fail_exit (E_HOMEDIR); } #ifdef WITH_AUDIT @@ -1993,7 +1993,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c user_newname, user_newid, 1); #endif return; -@@ -1883,9 +1894,9 @@ static void move_home (void) +@@ -1899,9 +1910,9 @@ static void move_home (void) Prog, prefix_user_home); } #ifdef WITH_AUDIT @@ -2005,7 +2005,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c user_newname, user_newid, 1); -@@ -2109,8 +2120,8 @@ static void move_mailbox (void) +@@ -2125,8 +2136,8 @@ static void move_mailbox (void) } #ifdef WITH_AUDIT else { @@ -2016,7 +2016,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c user_newname, user_newid, 1); } #endif -@@ -2133,8 +2144,8 @@ static void move_mailbox (void) +@@ -2149,8 +2160,8 @@ static void move_mailbox (void) } #ifdef WITH_AUDIT else { @@ -2027,7 +2027,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c user_newname, user_newid, 1); } -@@ -2331,8 +2342,8 @@ int main (int argc, char **argv) +@@ -2347,8 +2358,8 @@ int main (int argc, char **argv) _("%s: warning: the user name %s to %s SELinux user mapping failed.\n"), Prog, user_name, user_selinux); #ifdef WITH_AUDIT @@ -2038,7 +2038,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c user_name, user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -2344,8 +2355,8 @@ int main (int argc, char **argv) +@@ -2360,8 +2371,8 @@ int main (int argc, char **argv) _("%s: warning: the user name %s to SELinux user mapping removal failed.\n"), Prog, user_name); #ifdef WITH_AUDIT @@ -2049,7 +2049,7 @@ diff -up shadow-4.15.0/src/usermod.c.audit-update shadow-4.15.0/src/usermod.c user_name, user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ -@@ -2388,8 +2399,8 @@ int main (int argc, char **argv) +@@ -2404,8 +2415,8 @@ int main (int argc, char **argv) */ #ifdef WITH_AUDIT if (uflg || gflg) { diff --git a/shadow-4.15.1-sast-fixes.patch b/shadow-4.15.1-sast-fixes.patch new file mode 100644 index 0000000..e674ebf --- /dev/null +++ b/shadow-4.15.1-sast-fixes.patch @@ -0,0 +1,1413 @@ +From 4c16416ebc5f0958d58a1ea1e7890eafd9f8bb75 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Wed, 15 May 2024 12:25:51 +0200 +Subject: [PATCH 01/16] port: fix OVERRUN (CWE-119) + +``` +shadow-4.15.0/lib/port.c:154:2: alias: Assigning: "port.pt_names" = "ttys". "port.pt_names" now points to element 0 of "ttys" (which consists of 65 8-byte elements). +shadow-4.15.0/lib/port.c:155:2: cond_const: Checking "j < 64" implies that "j" is 64 on the false branch. +shadow-4.15.0/lib/port.c:175:2: overrun-local: Overrunning array of 65 8-byte elements at element index 65 (byte offset 527) by dereferencing pointer "port.pt_names + (j + 1)". +173| *cp = '\0'; +174| cp++; +175|-> port.pt_names[j + 1] = NULL; +176| +177| /* +``` + +Resolves: https://issues.redhat.com/browse/RHEL-35383 + +Signed-off-by: Iker Pedrosa +Reviewed-by: Alejandro Colomar +--- + lib/port.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/port.c b/lib/port.c +index 05b95651..60ff8989 100644 +--- a/lib/port.c ++++ b/lib/port.c +@@ -168,7 +168,7 @@ again: + } + *cp = '\0'; + cp++; +- port.pt_names[j + 1] = NULL; ++ port.pt_names[j] = NULL; + + /* + * Get the list of user names. It is the second colon +-- +2.45.1 + + +From f8fc6371f69930bbd5801284256e182ba35ced2a Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Fri, 17 May 2024 14:05:31 +0200 +Subject: [PATCH 02/16] src/useradd.c: set_defaults(): Fix order of clean-ups + +Resources should be freed in the inverse order of the allocation. +This refactor prepares for the following commits, which fix some leaks. + +Reviewed-by: Iker Pedrosa +Signed-off-by: Alejandro Colomar +--- + src/useradd.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/src/useradd.c b/src/useradd.c +index 88d8ab7f..56a74559 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -745,10 +745,9 @@ static int set_defaults (void) + def_create_mail_spool, def_log_init)); + ret = 0; + setdef_err: +- free(new_file); +- if (prefix[0]) { ++ if (prefix[0]) + free(default_file); +- } ++ free(new_file); + + return ret; + } +-- +2.45.1 + + +From 37ae8827a0869ee4a723954c3c9e7c48165d9b50 Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Fri, 17 May 2024 14:28:50 +0200 +Subject: [PATCH 03/16] src/useradd.c: set_defaults(): Rename goto label + +This will help add other labels in the following commits. + +Reviewed-by: Iker Pedrosa +Signed-off-by: Alejandro Colomar +--- + src/useradd.c | 24 +++++++++++++----------- + 1 file changed, 13 insertions(+), 11 deletions(-) + +diff --git a/src/useradd.c b/src/useradd.c +index 56a74559..bc72e6bc 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -558,7 +558,7 @@ static int set_defaults (void) + fprintf(stderr, + _("%s: cannot create new defaults file: %s\n"), + Prog, strerror(errno)); +- goto setdef_err; ++ goto err_free_def; + } + } + +@@ -567,7 +567,7 @@ static int set_defaults (void) + fprintf (stderr, + _("%s: cannot create directory for defaults file\n"), + Prog); +- goto setdef_err; ++ goto err_free_def; + } + + ret = mkdir(dirname(new_file_dup), 0755); +@@ -576,7 +576,7 @@ static int set_defaults (void) + _("%s: cannot create directory for defaults file\n"), + Prog); + free(new_file_dup); +- goto setdef_err; ++ goto err_free_def; + } + free(new_file_dup); + +@@ -588,7 +588,7 @@ static int set_defaults (void) + fprintf (stderr, + _("%s: cannot create new defaults file\n"), + Prog); +- goto setdef_err; ++ goto err_free_def; + } + + ofp = fdopen (ofd, "w"); +@@ -596,7 +596,7 @@ static int set_defaults (void) + fprintf (stderr, + _("%s: cannot open new defaults file\n"), + Prog); +- goto setdef_err; ++ goto err_free_def; + } + + /* +@@ -623,7 +623,7 @@ static int set_defaults (void) + _("%s: line too long in %s: %s..."), + Prog, default_file, buf); + (void) fclose (ifp); +- goto setdef_err; ++ goto err_free_def; + } + } + +@@ -702,9 +702,10 @@ static int set_defaults (void) + (void) fflush (ofp); + if ( (ferror (ofp) != 0) + || (fsync (fileno (ofp)) != 0) +- || (fclose (ofp) != 0)) { ++ || (fclose (ofp) != 0)) ++ { + unlink (new_file); +- goto setdef_err; ++ goto err_free_def; + } + + /* +@@ -718,7 +719,7 @@ static int set_defaults (void) + _("%s: Cannot create backup file (%s): %s\n"), + Prog, buf, strerror (err)); + unlink (new_file); +- goto setdef_err; ++ goto err_free_def; + } + + /* +@@ -729,7 +730,7 @@ static int set_defaults (void) + fprintf (stderr, + _("%s: rename: %s: %s\n"), + Prog, new_file, strerror (err)); +- goto setdef_err; ++ goto err_free_def; + } + #ifdef WITH_AUDIT + audit_logger (AUDIT_USYS_CONFIG, Prog, +@@ -744,7 +745,8 @@ static int set_defaults (void) + def_inactive, def_expire, def_template, + def_create_mail_spool, def_log_init)); + ret = 0; +- setdef_err: ++ ++err_free_def: + if (prefix[0]) + free(default_file); + free(new_file); +-- +2.45.1 + + +From 701fe4cf1aeac9e66fa949369c91d135dbf375d2 Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Fri, 17 May 2024 13:10:46 +0200 +Subject: [PATCH 04/16] src/useradd.c: set_defaults(): Do not free(3) the + result of asprintf(3) if it failed +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +See asprintf(3): + +RETURN VALUE + When successful, these functions return the number of bytes + printed, just like sprintf(3). If memory allocation wasn’t possi‐ + ble, or some other error occurs, these functions will return -1, + and the contents of strp are undefined. + +Reviewed-by: Iker Pedrosa +Signed-off-by: Alejandro Colomar +--- + src/useradd.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/useradd.c b/src/useradd.c +index bc72e6bc..6a3edfe3 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -558,7 +558,7 @@ static int set_defaults (void) + fprintf(stderr, + _("%s: cannot create new defaults file: %s\n"), + Prog, strerror(errno)); +- goto err_free_def; ++ goto err_free_new; + } + } + +@@ -749,6 +749,7 @@ static int set_defaults (void) + err_free_def: + if (prefix[0]) + free(default_file); ++err_free_new: + free(new_file); + + return ret; +-- +2.45.1 + + +From a74c4b6ae124a55cd272e574e0d056102f331e17 Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Fri, 17 May 2024 13:14:31 +0200 +Subject: [PATCH 05/16] src/useradd.c: De-duplicate code + +Reviewed-by: Iker Pedrosa +Signed-off-by: Alejandro Colomar +--- + src/useradd.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/src/useradd.c b/src/useradd.c +index 6a3edfe3..ad2676c1 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -571,14 +571,13 @@ static int set_defaults (void) + } + + ret = mkdir(dirname(new_file_dup), 0755); ++ free(new_file_dup); + if (-1 == ret && EEXIST != errno) { + fprintf (stderr, + _("%s: cannot create directory for defaults file\n"), + Prog); +- free(new_file_dup); + goto err_free_def; + } +- free(new_file_dup); + + /* + * Create a temporary file to copy the new output to. +-- +2.45.1 + + +From e7d1508e076bbf4053faacc0370c6fe43d9c8f04 Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Fri, 17 May 2024 13:40:58 +0200 +Subject: [PATCH 06/16] src/useradd.c: Add fmkstemp() to fix file-descriptor + leak + +This function creates a temporary file, and returns a FILE pointer to +it. This avoids dealing with both a file descriptor and a FILE pointer, +and correctly deallocating the resources on error. + +The code before this patch was leaking the file descriptor if fdopen(3) +failed. + +Reviewed-by: Iker Pedrosa +Signed-off-by: Alejandro Colomar +--- + src/useradd.c | 34 ++++++++++++++++++++++++---------- + 1 file changed, 24 insertions(+), 10 deletions(-) + +diff --git a/src/useradd.c b/src/useradd.c +index ad2676c1..e0238457 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -238,6 +238,9 @@ static void create_home (void); + static void create_mail (void); + static void check_uid_range(int rflg, uid_t user_id); + ++static FILE *fmkstemp(char *template); ++ ++ + /* + * fail_exit - undo as much as possible + */ +@@ -524,7 +527,6 @@ static void show_defaults (void) + */ + static int set_defaults (void) + { +- int ofd; + int ret = -1; + bool out_group = false; + bool out_groups = false; +@@ -582,15 +584,7 @@ static int set_defaults (void) + /* + * Create a temporary file to copy the new output to. + */ +- ofd = mkstemp (new_file); +- if (-1 == ofd) { +- fprintf (stderr, +- _("%s: cannot create new defaults file\n"), +- Prog); +- goto err_free_def; +- } +- +- ofp = fdopen (ofd, "w"); ++ ofp = fmkstemp(new_file); + if (NULL == ofp) { + fprintf (stderr, + _("%s: cannot open new defaults file\n"), +@@ -2752,3 +2746,23 @@ int main (int argc, char **argv) + return E_SUCCESS; + } + ++ ++static FILE * ++fmkstemp(char *template) ++{ ++ int fd; ++ FILE *fp; ++ ++ fd = mkstemp(template); ++ if (fd == -1) ++ return NULL; ++ ++ fp = fdopen(fd, "w"); ++ if (fp == NULL) { ++ close(fd); ++ unlink(template); ++ return NULL; ++ } ++ ++ return fp; ++} +-- +2.45.1 + + +From 1ee066ae1e5b39ac42120ad0f6f8af0f102db952 Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Fri, 17 May 2024 13:52:07 +0200 +Subject: [PATCH 07/16] src/useradd.c: set_defaults(): Fix FILE* leak + +Report: +> shadow-4.15.0/src/useradd.c:575:2: alloc_fn: Storage is returned from allocation function "fdopen". +> shadow-4.15.0/src/useradd.c:575:2: var_assign: Assigning: "ofp" = storage returned from "fdopen(ofd, "w")". +> shadow-4.15.0/src/useradd.c:734:2: leaked_storage: Variable "ofp" going out of scope leaks the storage it points to. +> 732| } +> 733| +> 734|-> return ret; +> 735| } +> 736| + +Link: +Reported-by: Iker Pedrosa +Reviewed-by: Iker Pedrosa +Signed-off-by: Alejandro Colomar +--- + src/useradd.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/useradd.c b/src/useradd.c +index e0238457..347334a6 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -615,7 +615,8 @@ static int set_defaults (void) + fprintf (stderr, + _("%s: line too long in %s: %s..."), + Prog, default_file, buf); +- (void) fclose (ifp); ++ fclose(ifp); ++ fclose(ofp); + goto err_free_def; + } + } +-- +2.45.1 + + +From 151f14ad69de8100d25c1974947d53ae40d1448a Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Thu, 16 May 2024 13:52:15 +0200 +Subject: [PATCH 08/16] src/usermod.c: Reduce scope of local variables + +Signed-off-by: Alejandro Colomar +--- + src/usermod.c | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +diff --git a/src/usermod.c b/src/usermod.c +index 0fcf0325..57b58f5b 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -687,11 +687,8 @@ fail_exit (int code) + + static void update_group (void) + { +- bool is_member; +- bool was_member; +- bool changed; +- const struct group *grp; +- struct group *ngrp; ++ bool changed; ++ const struct group *grp; + + changed = false; + +@@ -700,6 +697,9 @@ static void update_group (void) + * the user is a member of. + */ + while ((grp = gr_next ()) != NULL) { ++ bool is_member; ++ bool was_member; ++ struct group *ngrp; + /* + * See if the user specified this group as one of their + * concurrent groups. +@@ -799,12 +799,8 @@ static void update_group (void) + #ifdef SHADOWGRP + static void update_gshadow (void) + { +- bool is_member; +- bool was_member; +- bool was_admin; +- bool changed; +- const struct sgrp *sgrp; +- struct sgrp *nsgrp; ++ bool changed; ++ const struct sgrp *sgrp; + + changed = false; + +@@ -813,6 +809,10 @@ static void update_gshadow (void) + * that the user is a member of. + */ + while ((sgrp = sgr_next ()) != NULL) { ++ bool is_member; ++ bool was_member; ++ bool was_admin; ++ struct sgrp *nsgrp; + + /* + * See if the user was a member of this group +-- +2.45.1 + + +From b089a63ab38f69c32d099320fe8181802f7f4092 Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Thu, 16 May 2024 13:49:34 +0200 +Subject: [PATCH 09/16] src/usermod.c: Rename update_group() => + update_group_file() + +Signed-off-by: Alejandro Colomar +--- + src/usermod.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/usermod.c b/src/usermod.c +index 57b58f5b..aaa83d7d 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -178,7 +178,7 @@ NORETURN static void usage (int status); + static void new_pwent (struct passwd *); + static void new_spent (struct spwd *); + NORETURN static void fail_exit (int); +-static void update_group (void); ++static void update_group_file(void); + + #ifdef SHADOWGRP + static void update_gshadow (void); +@@ -685,7 +685,8 @@ fail_exit (int code) + } + + +-static void update_group (void) ++static void ++update_group_file(void) + { + bool changed; + const struct group *grp; +@@ -950,7 +951,7 @@ static void update_gshadow (void) + */ + static void grp_update (void) + { +- update_group (); ++ update_group_file(); + #ifdef SHADOWGRP + if (is_shadow_grp) { + update_gshadow (); +-- +2.45.1 + + +From 81bc78ec5cdd59790bc7c591c9d1f66bd4d7b78e Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Fri, 17 May 2024 02:11:22 +0200 +Subject: [PATCH 10/16] src/usermod.c: Rename update_gshadow() => + update_gshadow_file() + +Signed-off-by: Alejandro Colomar +--- + src/usermod.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/usermod.c b/src/usermod.c +index aaa83d7d..3048f801 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -181,7 +181,7 @@ NORETURN static void fail_exit (int); + static void update_group_file(void); + + #ifdef SHADOWGRP +-static void update_gshadow (void); ++static void update_gshadow_file(void); + #endif + static void grp_update (void); + +@@ -798,7 +798,8 @@ update_group_file(void) + } + + #ifdef SHADOWGRP +-static void update_gshadow (void) ++static void ++update_gshadow_file(void) + { + bool changed; + const struct sgrp *sgrp; +@@ -954,7 +955,7 @@ static void grp_update (void) + update_group_file(); + #ifdef SHADOWGRP + if (is_shadow_grp) { +- update_gshadow (); ++ update_gshadow_file(); + } + #endif + } +-- +2.45.1 + + +From 61964aa06b9e6e0643a6519f64290f18ac04867f Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Thu, 16 May 2024 13:54:06 +0200 +Subject: [PATCH 11/16] src/usermod.c: update_group_file(): Fix RESOURCE_LEAK + (CWE-772) + +Report: +> shadow-4.15.0/src/usermod.c:734:3: alloc_fn: Storage is returned from allocation function "__gr_dup". +> shadow-4.15.0/src/usermod.c:734:3: var_assign: Assigning: "ngrp" = storage returned from "__gr_dup(grp)". +> shadow-4.15.0/src/usermod.c:815:1: leaked_storage: Variable "ngrp" going out of scope leaks the storage it points to. +> 813| gr_free(ngrp); +> 814| } +> 815|-> } +> 816| +> 817| #ifdef SHADOWGRP + +Link: https://issues.redhat.com/browse/RHEL-35383 +Reported-by: Iker Pedrosa +Signed-off-by: Alejandro Colomar +--- + src/usermod.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/usermod.c b/src/usermod.c +index 3048f801..e0cfdd83 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -780,9 +780,8 @@ update_group_file(void) + SYSLOG ((LOG_INFO, "add '%s' to group '%s'", + user_newname, ngrp->gr_name)); + } +- if (!changed) { +- continue; +- } ++ if (!changed) ++ goto free_ngrp; + + changed = false; + if (gr_update (ngrp) == 0) { +@@ -793,6 +792,7 @@ update_group_file(void) + fail_exit (E_GRP_UPDATE); + } + ++free_ngrp: + gr_free(ngrp); + } + } +-- +2.45.1 + + +From 71a3238b7996285fc3c8dec841244ba95d663fa5 Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Fri, 17 May 2024 02:15:15 +0200 +Subject: [PATCH 12/16] src/usermod.c: update_gshadow_file(): Fix RESOURCE_LEAK + (CWE-772) + +Report: +> shadow-4.15.0/src/usermod.c:864:3: alloc_fn: Storage is returned from allocation function "__sgr_dup". +> shadow-4.15.0/src/usermod.c:864:3: var_assign: Assigning: "nsgrp" = storage returned from "__sgr_dup(sgrp)". +> shadow-4.15.0/src/usermod.c:964:1: leaked_storage: Variable "nsgrp" going out of scope leaks the storage it points to. +> 962| free (nsgrp); +> 963| } +> 964|-> } +> 965| #endif /* SHADOWGRP */ +> 966| + +Link: https://issues.redhat.com/browse/RHEL-35383 +Reported-by: Iker Pedrosa +Signed-off-by: Alejandro Colomar +--- + src/usermod.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/usermod.c b/src/usermod.c +index e0cfdd83..bb5d3535 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -921,9 +921,8 @@ update_gshadow_file(void) + SYSLOG ((LOG_INFO, "add '%s' to shadow group '%s'", + user_newname, nsgrp->sg_name)); + } +- if (!changed) { +- continue; +- } ++ if (!changed) ++ goto free_nsgrp; + + changed = false; + +@@ -939,6 +938,7 @@ update_gshadow_file(void) + fail_exit (E_GRP_UPDATE); + } + ++free_nsgrp: + free (nsgrp); + } + } +-- +2.45.1 + + +From 68d42a8fbe42b89cf13d3f672ad8502dbaf05835 Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Thu, 16 May 2024 14:02:54 +0200 +Subject: [PATCH 13/16] src/usermod.c: update_group_file(): Reduce scope of + local variable + +After _every_ iteration, 'changed' is always 'false'. We don't need to +have it outside of the loop. + +See: + +$ grepc update_group_file . \ +| grep -e changed -e goto -e continue -e break -e free_ngrp -e '{' -e '}' \ +| pcre2grep -v -M '{\n\t*}'; +{ + bool changed; + changed = false; + while ((grp = gr_next ()) != NULL) { + if (!was_member && !is_member) { + continue; + } + if (was_member) { + if ((!Gflg) || is_member) { + if (lflg) { + changed = true; + } + } else { + changed = true; + } + } else if (is_member) { + changed = true; + } + if (!changed) + goto free_ngrp; + changed = false; +free_ngrp: + } +} + +This was already true in the commit that introduced the code: + +$ git show 45c6603cc:src/usermod.c \ +| grepc update_group \ +| grep -e changed -e goto -e break -e continue -e '\' -e '{' -e '}' \ +| pcre2grep -v -M '{\n\t*}'; +{ + int changed; + changed = 0; + while ((grp = gr_next())) { + * See if the user specified this group as one of their + if (!was_member && !is_member) + continue; + if (was_member && (!Gflg || is_member)) { + if (lflg) { + changed = 1; + } + } else if (was_member && Gflg && !is_member) { + changed = 1; + } else if (!was_member && Gflg && is_member) { + changed = 1; + } + if (!changed) + continue; + changed = 0; + } +} + +Fixes: 45c6603cc86c ("[svn-upgrade] Integrating new upstream version, shadow (19990709)") +Signed-off-by: Alejandro Colomar +--- + src/usermod.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/usermod.c b/src/usermod.c +index bb5d3535..30f47b8a 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -688,19 +688,20 @@ fail_exit (int code) + static void + update_group_file(void) + { +- bool changed; + const struct group *grp; + +- changed = false; +- + /* + * Scan through the entire group file looking for the groups that + * the user is a member of. + */ + while ((grp = gr_next ()) != NULL) { ++ bool changed; + bool is_member; + bool was_member; + struct group *ngrp; ++ ++ changed = false; ++ + /* + * See if the user specified this group as one of their + * concurrent groups. +@@ -783,7 +784,6 @@ update_group_file(void) + if (!changed) + goto free_ngrp; + +- changed = false; + if (gr_update (ngrp) == 0) { + fprintf (stderr, + _("%s: failed to prepare the new %s entry '%s'\n"), +-- +2.45.1 + + +From da77a82ecbc90e89808f143e7fa2abb7650f50d7 Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Fri, 17 May 2024 02:19:46 +0200 +Subject: [PATCH 14/16] src/usermod.c: update_gshadow_file(): Reduce scope of + local variable + +After _every_ iteration, 'changed' is always 'false'. We don't need to +have it outside of the loop. + +See: + +$ grepc update_gshadow_file . \ +| grep -e changed -e goto -e continue -e break -e free_ngrp -e '{' -e '}' \ +| pcre2grep -v -M '{\n\t*}'; +{ + bool changed; + changed = false; + while ((sgrp = sgr_next ()) != NULL) { + if (!was_member && !was_admin && !is_member) { + continue; + } + if (was_admin && lflg) { + changed = true; + } + if (was_member) { + if ((!Gflg) || is_member) { + if (lflg) { + changed = true; + } + } else { + changed = true; + } + } else if (is_member) { + changed = true; + } + if (!changed) + goto free_nsgrp; + changed = false; + } +} + +This was already true in the commit that introduced the code: + +$ git show 45c6603cc:src/usermod.c \ +| grepc update_gshadow \ +| grep -e changed -e goto -e break -e continue -e '\' -e '{' -e '}' \ +| pcre2grep -v -M '{\n\t*}'; +{ + int changed; + changed = 0; + while ((sgrp = sgr_next())) { + * See if the user was a member of this group + * See if the user was an administrator of this group + * See if the user specified this group as one of their + if (!was_member && !was_admin && !is_member) + continue; + if (was_admin && lflg) { + changed = 1; + } + if (was_member && (!Gflg || is_member)) { + if (lflg) { + changed = 1; + } + } else if (was_member && Gflg && !is_member) { + changed = 1; + } else if (!was_member && Gflg && is_member) { + changed = 1; + } + if (!changed) + continue; + changed = 0; + } +} + +Fixes: 45c6603cc86c ("[svn-upgrade] Integrating new upstream version, shadow (19990709)") +Signed-off-by: Alejandro Colomar +--- + src/usermod.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/src/usermod.c b/src/usermod.c +index 30f47b8a..7b1e0581 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -801,21 +801,21 @@ free_ngrp: + static void + update_gshadow_file(void) + { +- bool changed; + const struct sgrp *sgrp; + +- changed = false; +- + /* + * Scan through the entire shadow group file looking for the groups + * that the user is a member of. + */ + while ((sgrp = sgr_next ()) != NULL) { ++ bool changed; + bool is_member; + bool was_member; + bool was_admin; + struct sgrp *nsgrp; + ++ changed = false; ++ + /* + * See if the user was a member of this group + */ +@@ -924,8 +924,6 @@ update_gshadow_file(void) + if (!changed) + goto free_nsgrp; + +- changed = false; +- + /* + * Update the group entry to reflect the changes. + */ +-- +2.45.1 + + +From adf37cccd0fa4ce7d05644514b0af57fe71905c3 Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Thu, 16 May 2024 14:12:09 +0200 +Subject: [PATCH 15/16] src/usermod.c: update_group(): Add helper function + +Keep the while loop in the outer function, and move the iteration code +to this new helper. This makes it a bit more readable. + +Cc: Iker Pedrosa +Signed-off-by: Alejandro Colomar +--- + src/usermod.c | 167 ++++++++++++++++++++++++++------------------------ + 1 file changed, 87 insertions(+), 80 deletions(-) + +diff --git a/src/usermod.c b/src/usermod.c +index 7b1e0581..4ea11376 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -179,6 +179,7 @@ static void new_pwent (struct passwd *); + static void new_spent (struct spwd *); + NORETURN static void fail_exit (int); + static void update_group_file(void); ++static void update_group(const struct group *grp); + + #ifdef SHADOWGRP + static void update_gshadow_file(void); +@@ -694,109 +695,115 @@ update_group_file(void) + * Scan through the entire group file looking for the groups that + * the user is a member of. + */ +- while ((grp = gr_next ()) != NULL) { +- bool changed; +- bool is_member; +- bool was_member; +- struct group *ngrp; ++ while ((grp = gr_next()) != NULL) ++ update_group(grp); ++} + +- changed = false; + +- /* +- * See if the user specified this group as one of their +- * concurrent groups. +- */ +- was_member = is_on_list (grp->gr_mem, user_name); +- is_member = Gflg && ( (was_member && aflg) +- || is_on_list (user_groups, grp->gr_name)); ++static void ++update_group(const struct group *grp) ++{ ++ bool changed; ++ bool is_member; ++ bool was_member; ++ struct group *ngrp; + +- if (!was_member && !is_member) { +- continue; +- } ++ changed = false; + +- /* +- * If rflg+Gflg is passed in AKA -rG invert is_member flag, which removes +- * mentioned groups while leaving the others. +- */ +- if (Gflg && rflg) { +- is_member = !is_member; +- } ++ /* ++ * See if the user specified this group as one of their ++ * concurrent groups. ++ */ ++ was_member = is_on_list (grp->gr_mem, user_name); ++ is_member = Gflg && ( (was_member && aflg) ++ || is_on_list (user_groups, grp->gr_name)); + +- ngrp = __gr_dup (grp); +- if (NULL == ngrp) { +- fprintf (stderr, +- _("%s: Out of memory. Cannot update %s.\n"), +- Prog, gr_dbname ()); +- fail_exit (E_GRP_UPDATE); +- } ++ if (!was_member && !is_member) ++ return; + +- if (was_member) { +- if ((!Gflg) || is_member) { +- /* User was a member and is still a member +- * of this group. +- * But the user might have been renamed. +- */ +- if (lflg) { +- ngrp->gr_mem = del_list (ngrp->gr_mem, +- user_name); +- ngrp->gr_mem = add_list (ngrp->gr_mem, +- user_newname); +- changed = true; +-#ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "changing group member", +- user_newname, AUDIT_NO_ID, 1); +-#endif +- SYSLOG ((LOG_INFO, +- "change '%s' to '%s' in group '%s'", +- user_name, user_newname, +- ngrp->gr_name)); +- } +- } else { +- /* User was a member but is no more a +- * member of this group. +- */ +- ngrp->gr_mem = del_list (ngrp->gr_mem, user_name); ++ /* ++ * If rflg+Gflg is passed in AKA -rG invert is_member flag, which removes ++ * mentioned groups while leaving the others. ++ */ ++ if (Gflg && rflg) { ++ is_member = !is_member; ++ } ++ ++ ngrp = __gr_dup (grp); ++ if (NULL == ngrp) { ++ fprintf (stderr, ++ _("%s: Out of memory. Cannot update %s.\n"), ++ Prog, gr_dbname ()); ++ fail_exit (E_GRP_UPDATE); ++ } ++ ++ if (was_member) { ++ if ((!Gflg) || is_member) { ++ /* User was a member and is still a member ++ * of this group. ++ * But the user might have been renamed. ++ */ ++ if (lflg) { ++ ngrp->gr_mem = del_list (ngrp->gr_mem, ++ user_name); ++ ngrp->gr_mem = add_list (ngrp->gr_mem, ++ user_newname); + changed = true; + #ifdef WITH_AUDIT + audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "removing group member", +- user_name, AUDIT_NO_ID, 1); ++ "changing group member", ++ user_newname, AUDIT_NO_ID, 1); + #endif + SYSLOG ((LOG_INFO, +- "delete '%s' from group '%s'", +- user_name, ngrp->gr_name)); ++ "change '%s' to '%s' in group '%s'", ++ user_name, user_newname, ++ ngrp->gr_name)); + } +- } else if (is_member) { +- /* User was not a member but is now a member this +- * group. ++ } else { ++ /* User was a member but is no more a ++ * member of this group. + */ +- ngrp->gr_mem = add_list (ngrp->gr_mem, user_newname); ++ ngrp->gr_mem = del_list (ngrp->gr_mem, user_name); + changed = true; + #ifdef WITH_AUDIT + audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "adding user to group", +- user_name, AUDIT_NO_ID, 1); ++ "removing group member", ++ user_name, AUDIT_NO_ID, 1); + #endif +- SYSLOG ((LOG_INFO, "add '%s' to group '%s'", +- user_newname, ngrp->gr_name)); ++ SYSLOG ((LOG_INFO, ++ "delete '%s' from group '%s'", ++ user_name, ngrp->gr_name)); + } +- if (!changed) +- goto free_ngrp; ++ } else if (is_member) { ++ /* User was not a member but is now a member this ++ * group. ++ */ ++ ngrp->gr_mem = add_list (ngrp->gr_mem, user_newname); ++ changed = true; ++#ifdef WITH_AUDIT ++ audit_logger (AUDIT_USER_CHAUTHTOK, Prog, ++ "adding user to group", ++ user_name, AUDIT_NO_ID, 1); ++#endif ++ SYSLOG ((LOG_INFO, "add '%s' to group '%s'", ++ user_newname, ngrp->gr_name)); ++ } ++ if (!changed) ++ goto free_ngrp; + +- if (gr_update (ngrp) == 0) { +- fprintf (stderr, +- _("%s: failed to prepare the new %s entry '%s'\n"), +- Prog, gr_dbname (), ngrp->gr_name); +- SYSLOG ((LOG_WARN, "failed to prepare the new %s entry '%s'", gr_dbname (), ngrp->gr_name)); +- fail_exit (E_GRP_UPDATE); +- } ++ if (gr_update (ngrp) == 0) { ++ fprintf (stderr, ++ _("%s: failed to prepare the new %s entry '%s'\n"), ++ Prog, gr_dbname (), ngrp->gr_name); ++ SYSLOG ((LOG_WARN, "failed to prepare the new %s entry '%s'", gr_dbname (), ngrp->gr_name)); ++ fail_exit (E_GRP_UPDATE); ++ } + + free_ngrp: +- gr_free(ngrp); +- } ++ gr_free(ngrp); + } + ++ + #ifdef SHADOWGRP + static void + update_gshadow_file(void) +-- +2.45.1 + + +From d8e6a8b99b4d844328d875287babf6e13860d464 Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Fri, 17 May 2024 02:29:46 +0200 +Subject: [PATCH 16/16] src/usermod.c: update_gshadow(): Add helper function + +Keep the while loop in the outer function, and move the iteration code +to this new helper. This makes it a bit more readable. + +Cc: Iker Pedrosa +Signed-off-by: Alejandro Colomar +--- + src/usermod.c | 223 ++++++++++++++++++++++++++------------------------ + 1 file changed, 116 insertions(+), 107 deletions(-) + +diff --git a/src/usermod.c b/src/usermod.c +index 4ea11376..f8896984 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -183,6 +183,7 @@ static void update_group(const struct group *grp); + + #ifdef SHADOWGRP + static void update_gshadow_file(void); ++static void update_gshadow(const struct sgrp *sgrp); + #endif + static void grp_update (void); + +@@ -814,141 +815,149 @@ update_gshadow_file(void) + * Scan through the entire shadow group file looking for the groups + * that the user is a member of. + */ +- while ((sgrp = sgr_next ()) != NULL) { +- bool changed; +- bool is_member; +- bool was_member; +- bool was_admin; +- struct sgrp *nsgrp; ++ while ((sgrp = sgr_next()) != NULL) ++ update_gshadow(sgrp); ++} ++#endif /* SHADOWGRP */ + +- changed = false; + +- /* +- * See if the user was a member of this group +- */ +- was_member = is_on_list (sgrp->sg_mem, user_name); ++#ifdef SHADOWGRP ++static void ++update_gshadow(const struct sgrp *sgrp) ++{ ++ bool changed; ++ bool is_member; ++ bool was_member; ++ bool was_admin; ++ struct sgrp *nsgrp; + +- /* +- * See if the user was an administrator of this group +- */ +- was_admin = is_on_list (sgrp->sg_adm, user_name); ++ changed = false; + +- /* +- * See if the user specified this group as one of their +- * concurrent groups. +- */ +- is_member = Gflg && ( (was_member && aflg) +- || is_on_list (user_groups, sgrp->sg_name)); ++ /* ++ * See if the user was a member of this group ++ */ ++ was_member = is_on_list (sgrp->sg_mem, user_name); + +- if (!was_member && !was_admin && !is_member) { +- continue; +- } ++ /* ++ * See if the user was an administrator of this group ++ */ ++ was_admin = is_on_list (sgrp->sg_adm, user_name); + +- /* +- * If rflg+Gflg is passed in AKA -rG invert is_member, to remove targeted +- * groups while leaving the user apart of groups not mentioned +- */ +- if (Gflg && rflg) { +- is_member = !is_member; +- } ++ /* ++ * See if the user specified this group as one of their ++ * concurrent groups. ++ */ ++ is_member = Gflg && ( (was_member && aflg) ++ || is_on_list (user_groups, sgrp->sg_name)); + +- nsgrp = __sgr_dup (sgrp); +- if (NULL == nsgrp) { +- fprintf (stderr, +- _("%s: Out of memory. Cannot update %s.\n"), +- Prog, sgr_dbname ()); +- fail_exit (E_GRP_UPDATE); +- } ++ if (!was_member && !was_admin && !is_member) ++ return; + +- if (was_admin && lflg) { +- /* User was an admin of this group but the user +- * has been renamed. +- */ +- nsgrp->sg_adm = del_list (nsgrp->sg_adm, user_name); +- nsgrp->sg_adm = add_list (nsgrp->sg_adm, user_newname); +- changed = true; +-#ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "changing admin name in shadow group", +- user_name, AUDIT_NO_ID, 1); +-#endif +- SYSLOG ((LOG_INFO, +- "change admin '%s' to '%s' in shadow group '%s'", +- user_name, user_newname, nsgrp->sg_name)); +- } +- +- if (was_member) { +- if ((!Gflg) || is_member) { +- /* User was a member and is still a member +- * of this group. +- * But the user might have been renamed. +- */ +- if (lflg) { +- nsgrp->sg_mem = del_list (nsgrp->sg_mem, +- user_name); +- nsgrp->sg_mem = add_list (nsgrp->sg_mem, +- user_newname); +- changed = true; ++ /* ++ * If rflg+Gflg is passed in AKA -rG invert is_member, to remove targeted ++ * groups while leaving the user apart of groups not mentioned ++ */ ++ if (Gflg && rflg) { ++ is_member = !is_member; ++ } ++ ++ nsgrp = __sgr_dup (sgrp); ++ if (NULL == nsgrp) { ++ fprintf (stderr, ++ _("%s: Out of memory. Cannot update %s.\n"), ++ Prog, sgr_dbname ()); ++ fail_exit (E_GRP_UPDATE); ++ } ++ ++ if (was_admin && lflg) { ++ /* User was an admin of this group but the user ++ * has been renamed. ++ */ ++ nsgrp->sg_adm = del_list (nsgrp->sg_adm, user_name); ++ nsgrp->sg_adm = add_list (nsgrp->sg_adm, user_newname); ++ changed = true; + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "changing member in shadow group", +- user_name, AUDIT_NO_ID, 1); ++ audit_logger (AUDIT_USER_CHAUTHTOK, Prog, ++ "changing admin name in shadow group", ++ user_name, AUDIT_NO_ID, 1); + #endif +- SYSLOG ((LOG_INFO, +- "change '%s' to '%s' in shadow group '%s'", +- user_name, user_newname, +- nsgrp->sg_name)); +- } +- } else { +- /* User was a member but is no more a +- * member of this group. +- */ +- nsgrp->sg_mem = del_list (nsgrp->sg_mem, user_name); ++ SYSLOG ((LOG_INFO, ++ "change admin '%s' to '%s' in shadow group '%s'", ++ user_name, user_newname, nsgrp->sg_name)); ++ } ++ ++ if (was_member) { ++ if ((!Gflg) || is_member) { ++ /* User was a member and is still a member ++ * of this group. ++ * But the user might have been renamed. ++ */ ++ if (lflg) { ++ nsgrp->sg_mem = del_list (nsgrp->sg_mem, ++ user_name); ++ nsgrp->sg_mem = add_list (nsgrp->sg_mem, ++ user_newname); + changed = true; + #ifdef WITH_AUDIT + audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "removing user from shadow group", +- user_name, AUDIT_NO_ID, 1); ++ "changing member in shadow group", ++ user_name, AUDIT_NO_ID, 1); + #endif + SYSLOG ((LOG_INFO, +- "delete '%s' from shadow group '%s'", +- user_name, nsgrp->sg_name)); ++ "change '%s' to '%s' in shadow group '%s'", ++ user_name, user_newname, ++ nsgrp->sg_name)); + } +- } else if (is_member) { +- /* User was not a member but is now a member this +- * group. ++ } else { ++ /* User was a member but is no more a ++ * member of this group. + */ +- nsgrp->sg_mem = add_list (nsgrp->sg_mem, user_newname); ++ nsgrp->sg_mem = del_list (nsgrp->sg_mem, user_name); + changed = true; + #ifdef WITH_AUDIT + audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "adding user to shadow group", +- user_newname, AUDIT_NO_ID, 1); ++ "removing user from shadow group", ++ user_name, AUDIT_NO_ID, 1); + #endif +- SYSLOG ((LOG_INFO, "add '%s' to shadow group '%s'", +- user_newname, nsgrp->sg_name)); ++ SYSLOG ((LOG_INFO, ++ "delete '%s' from shadow group '%s'", ++ user_name, nsgrp->sg_name)); + } +- if (!changed) +- goto free_nsgrp; +- +- /* +- * Update the group entry to reflect the changes. ++ } else if (is_member) { ++ /* User was not a member but is now a member this ++ * group. + */ +- if (sgr_update (nsgrp) == 0) { +- fprintf (stderr, +- _("%s: failed to prepare the new %s entry '%s'\n"), +- Prog, sgr_dbname (), nsgrp->sg_name); +- SYSLOG ((LOG_WARN, "failed to prepare the new %s entry '%s'", +- sgr_dbname (), nsgrp->sg_name)); +- fail_exit (E_GRP_UPDATE); +- } ++ nsgrp->sg_mem = add_list (nsgrp->sg_mem, user_newname); ++ changed = true; ++#ifdef WITH_AUDIT ++ audit_logger (AUDIT_USER_CHAUTHTOK, Prog, ++ "adding user to shadow group", ++ user_newname, AUDIT_NO_ID, 1); ++#endif ++ SYSLOG ((LOG_INFO, "add '%s' to shadow group '%s'", ++ user_newname, nsgrp->sg_name)); ++ } ++ if (!changed) ++ goto free_nsgrp; + +-free_nsgrp: +- free (nsgrp); ++ /* ++ * Update the group entry to reflect the changes. ++ */ ++ if (sgr_update (nsgrp) == 0) { ++ fprintf (stderr, ++ _("%s: failed to prepare the new %s entry '%s'\n"), ++ Prog, sgr_dbname (), nsgrp->sg_name); ++ SYSLOG ((LOG_WARN, "failed to prepare the new %s entry '%s'", ++ sgr_dbname (), nsgrp->sg_name)); ++ fail_exit (E_GRP_UPDATE); + } ++ ++free_nsgrp: ++ free (nsgrp); + } + #endif /* SHADOWGRP */ + ++ + /* + * grp_update - add user to secondary group set + * +-- +2.45.1 + diff --git a/shadow-utils.spec b/shadow-utils.spec index ad712a1..c361429 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.15.1 -Release: 4%{?dist} +Release: 5%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -22,12 +22,14 @@ Source7: passwd.pamd Patch0: shadow-4.15.0-manfix.patch # Date parsing improvement - could be upstreamed Patch1: shadow-4.15.0-date-parsing.patch +# Several patches already available upstream. PRs:#994, #996, #997 +Patch2: shadow-4.15.1-sast-fixes.patch # Audit message changes - partially upstreamed -Patch2: shadow-4.15.0-audit-update.patch +Patch3: shadow-4.15.1-audit-update.patch # Probably non-upstreamable -Patch3: shadow-4.15.0-account-tools-setuid.patch +Patch4: shadow-4.15.0-account-tools-setuid.patch # https://github.com/shadow-maint/shadow/commit/ead55e9ba8958504e23e29545f90c4dd925c7462 -Patch4: shadow-4.15.0-getdef-spurious-error.patch +Patch5: shadow-4.15.0-getdef-spurious-error.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -293,6 +295,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Mon May 20 2024 Iker Pedrosa - 2:4.15.1-5 +- Several fixes for issues detected by static analyzer tools + * Thu Apr 11 2024 Zbigniew Jedrzejewski-Szmek - 2:4.15.1-4 - Fix build with %%_bindir==%%_sbindir - Add virtual Provides for old file paths used by other packages From e3591abba01fcc215e0622d58f4dec51d5f815e0 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Thu, 30 May 2024 16:01:39 +0200 Subject: [PATCH 087/134] chpasswd: use PAM again Resolves: #2283963 Signed-off-by: Iker Pedrosa --- shadow-4.15.0-account-tools-setuid.patch | 79 ------------------------ shadow-utils.spec | 5 +- 2 files changed, 4 insertions(+), 80 deletions(-) diff --git a/shadow-4.15.0-account-tools-setuid.patch b/shadow-4.15.0-account-tools-setuid.patch index d162487..5ab6406 100644 --- a/shadow-4.15.0-account-tools-setuid.patch +++ b/shadow-4.15.0-account-tools-setuid.patch @@ -1,82 +1,3 @@ -diff -up shadow-4.15.0/src/chpasswd.c.account-tools-setuid shadow-4.15.0/src/chpasswd.c ---- shadow-4.15.0/src/chpasswd.c.account-tools-setuid 2024-03-08 22:27:04.000000000 +0100 -+++ shadow-4.15.0/src/chpasswd.c 2024-03-11 11:21:57.561150382 +0100 -@@ -443,9 +443,11 @@ int main (int argc, char **argv) - char *cp; - const char *salt; - -+#ifdef ACCT_TOOLS_SETUID - #ifdef USE_PAM - bool use_pam = true; - #endif /* USE_PAM */ -+#endif /* ACCT_TOOLS_SETUID */ - - int errors = 0; - int line = 0; -@@ -469,19 +471,23 @@ int main (int argc, char **argv) - process_root_flag ("-R", argc, argv); - prefix = process_prefix_flag ("-P", argc, argv); - -+#ifdef ACCT_TOOLS_SETUID - #ifdef USE_PAM - if (md5flg || eflg || cflg || prefix[0]) { - use_pam = false; - } - #endif /* USE_PAM */ -+#endif /* ACCT_TOOLS_SETUID */ - - OPENLOG (Prog); - - check_perms (); - -+#ifdef ACCT_TOOLS_SETUID - #ifdef USE_PAM - if (!use_pam) - #endif /* USE_PAM */ -+#endif /* ACCT_TOOLS_SETUID */ - { - is_shadow_pwd = spw_file_present (); - -@@ -543,6 +549,7 @@ int main (int argc, char **argv) - } - newpwd = cp; - -+#ifdef ACCT_TOOLS_SETUID - #ifdef USE_PAM - if (use_pam) { - if (do_pam_passwd_non_interactive (Prog, name, newpwd) != 0) { -@@ -553,6 +560,7 @@ int main (int argc, char **argv) - } - } else - #endif /* USE_PAM */ -+#endif /* ACCT_TOOLS_SETUID */ - { - const struct spwd *sp; - struct spwd newsp; -@@ -672,9 +680,11 @@ int main (int argc, char **argv) - * password database. - */ - if (0 != errors) { -+#ifdef ACCT_TOOLS_SETUID - #ifdef USE_PAM - if (!use_pam) - #endif /* USE_PAM */ -+#endif /* ACCT_TOOLS_SETUID */ - { - fprintf (stderr, - _("%s: error detected, changes ignored\n"), -@@ -683,9 +693,11 @@ int main (int argc, char **argv) - fail_exit (1); - } - -+#ifdef ACCT_TOOLS_SETUID - #ifdef USE_PAM - if (!use_pam) - #endif /* USE_PAM */ -+#endif /* ACCT_TOOLS_SETUID */ - { - /* Save the changes */ - close_files (); diff -up shadow-4.15.0/src/groupmems.c.account-tools-setuid shadow-4.15.0/src/groupmems.c --- shadow-4.15.0/src/groupmems.c.account-tools-setuid 2024-03-08 22:27:04.000000000 +0100 +++ shadow-4.15.0/src/groupmems.c 2024-03-11 11:16:18.365408572 +0100 diff --git a/shadow-utils.spec b/shadow-utils.spec index c361429..53fe61b 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.15.1 -Release: 5%{?dist} +Release: 6%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -295,6 +295,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Thu May 30 2024 Iker Pedrosa - 2:4.15.1-6 +- chpasswd: use PAM again (#2283963) + * Mon May 20 2024 Iker Pedrosa - 2:4.15.1-5 - Several fixes for issues detected by static analyzer tools From 99c074978fd6ebe2cfe8ae8922cfb541fb0979b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 9 Jul 2024 13:56:48 +0200 Subject: [PATCH 088/134] Rebuilt for the bin-sbin merge https://fedoraproject.org/wiki/Changes/Unify_bin_and_sbin --- shadow-utils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index 53fe61b..3b9232d 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.15.1 -Release: 6%{?dist} +Release: 7%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -295,6 +295,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Tue Jul 09 2024 Zbigniew Jędrzejewski-Szmek - 2:4.15.1-7 +- Rebuilt for the bin-sbin merge + * Thu May 30 2024 Iker Pedrosa - 2:4.15.1-6 - chpasswd: use PAM again (#2283963) From 3f78d723fa1ad792c4e3d6fa949d89d80603aebe Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Sat, 20 Jul 2024 05:23:05 +0000 Subject: [PATCH 089/134] Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild --- shadow-utils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index 3b9232d..f1bdda5 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.15.1 -Release: 7%{?dist} +Release: 8%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -295,6 +295,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Sat Jul 20 2024 Fedora Release Engineering - 2:4.15.1-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild + * Tue Jul 09 2024 Zbigniew Jędrzejewski-Szmek - 2:4.15.1-7 - Rebuilt for the bin-sbin merge From 029086935e7eb96ea4e9f1e86984caaa113c593d Mon Sep 17 00:00:00 2001 From: Kevin Fenzi Date: Tue, 23 Jul 2024 14:03:06 -0700 Subject: [PATCH 090/134] Revert chpasswd: use PAM again for now. Revert chpasswd: use PAM again for now. Revert chpasswd: use PAM again for now. --- shadow-4.15.0-account-tools-setuid.patch | 79 ++++++++++++++++++++++++ shadow-utils.spec | 5 +- 2 files changed, 83 insertions(+), 1 deletion(-) diff --git a/shadow-4.15.0-account-tools-setuid.patch b/shadow-4.15.0-account-tools-setuid.patch index 5ab6406..d162487 100644 --- a/shadow-4.15.0-account-tools-setuid.patch +++ b/shadow-4.15.0-account-tools-setuid.patch @@ -1,3 +1,82 @@ +diff -up shadow-4.15.0/src/chpasswd.c.account-tools-setuid shadow-4.15.0/src/chpasswd.c +--- shadow-4.15.0/src/chpasswd.c.account-tools-setuid 2024-03-08 22:27:04.000000000 +0100 ++++ shadow-4.15.0/src/chpasswd.c 2024-03-11 11:21:57.561150382 +0100 +@@ -443,9 +443,11 @@ int main (int argc, char **argv) + char *cp; + const char *salt; + ++#ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + bool use_pam = true; + #endif /* USE_PAM */ ++#endif /* ACCT_TOOLS_SETUID */ + + int errors = 0; + int line = 0; +@@ -469,19 +471,23 @@ int main (int argc, char **argv) + process_root_flag ("-R", argc, argv); + prefix = process_prefix_flag ("-P", argc, argv); + ++#ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + if (md5flg || eflg || cflg || prefix[0]) { + use_pam = false; + } + #endif /* USE_PAM */ ++#endif /* ACCT_TOOLS_SETUID */ + + OPENLOG (Prog); + + check_perms (); + ++#ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + if (!use_pam) + #endif /* USE_PAM */ ++#endif /* ACCT_TOOLS_SETUID */ + { + is_shadow_pwd = spw_file_present (); + +@@ -543,6 +549,7 @@ int main (int argc, char **argv) + } + newpwd = cp; + ++#ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + if (use_pam) { + if (do_pam_passwd_non_interactive (Prog, name, newpwd) != 0) { +@@ -553,6 +560,7 @@ int main (int argc, char **argv) + } + } else + #endif /* USE_PAM */ ++#endif /* ACCT_TOOLS_SETUID */ + { + const struct spwd *sp; + struct spwd newsp; +@@ -672,9 +680,11 @@ int main (int argc, char **argv) + * password database. + */ + if (0 != errors) { ++#ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + if (!use_pam) + #endif /* USE_PAM */ ++#endif /* ACCT_TOOLS_SETUID */ + { + fprintf (stderr, + _("%s: error detected, changes ignored\n"), +@@ -683,9 +693,11 @@ int main (int argc, char **argv) + fail_exit (1); + } + ++#ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + if (!use_pam) + #endif /* USE_PAM */ ++#endif /* ACCT_TOOLS_SETUID */ + { + /* Save the changes */ + close_files (); diff -up shadow-4.15.0/src/groupmems.c.account-tools-setuid shadow-4.15.0/src/groupmems.c --- shadow-4.15.0/src/groupmems.c.account-tools-setuid 2024-03-08 22:27:04.000000000 +0100 +++ shadow-4.15.0/src/groupmems.c 2024-03-11 11:16:18.365408572 +0100 diff --git a/shadow-utils.spec b/shadow-utils.spec index f1bdda5..e3cd026 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.15.1 -Release: 8%{?dist} +Release: 9%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -295,6 +295,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Tue Jul 23 2024 Kevin Fenzi - 2:4.15.1-9 +- Revert chpasswd: use PAM again for now. + * Sat Jul 20 2024 Fedora Release Engineering - 2:4.15.1-8 - Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild From c3bc52a4f1222196953759c8bd3ef64ff81095fe Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Tue, 13 Aug 2024 09:57:02 +0200 Subject: [PATCH 091/134] Rebase to version 4.16.0 Resolves: #2293678 Signed-off-by: Iker Pedrosa --- .gitignore | 2 + shadow-4.15.0-getdef-spurious-error.patch | 137 -- shadow-4.15.1-audit-update.patch | 13 +- shadow-4.15.1-sast-fixes.patch | 1413 --------------------- shadow-utils.spec | 15 +- sources | 4 +- 6 files changed, 13 insertions(+), 1571 deletions(-) delete mode 100644 shadow-4.15.0-getdef-spurious-error.patch delete mode 100644 shadow-4.15.1-sast-fixes.patch diff --git a/.gitignore b/.gitignore index 5db8705..08e3c3f 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,5 @@ shadow-4.1.4.2.tar.bz2 /shadow-4.15.0.tar.xz.asc /shadow-4.15.1.tar.xz /shadow-4.15.1.tar.xz.asc +/shadow-4.16.0.tar.xz +/shadow-4.16.0.tar.xz.asc diff --git a/shadow-4.15.0-getdef-spurious-error.patch b/shadow-4.15.0-getdef-spurious-error.patch deleted file mode 100644 index 9cec295..0000000 --- a/shadow-4.15.0-getdef-spurious-error.patch +++ /dev/null @@ -1,137 +0,0 @@ -From ead55e9ba8958504e23e29545f90c4dd925c7462 Mon Sep 17 00:00:00 2001 -From: Serge Hallyn -Date: Wed, 20 Mar 2024 17:39:46 -0500 -Subject: [PATCH] getdef: avoid spurious error messages about unknown - configuration options - -def_find can return NULL for unset, not just unknown, config options. So -move the decision of whether to log an error message about an unknown config -option back into def_find, which knows the difference. Only putdef_str() -will pass a char* srcfile to def_find, so only calls from putdef_str will -cause the message, which was the original intent of fa68441bc4be8. - -closes #967 - -fixes: fa68441bc4be8 ("Improve the login.defs unknown item error message") -Signed-off-by: Serge Hallyn ---- - lib/getdef.c | 30 ++++++++++++++++-------------- - 1 file changed, 16 insertions(+), 14 deletions(-) - -diff --git a/lib/getdef.c b/lib/getdef.c -index 4d4d4e19..ef2ae1f0 100644 ---- a/lib/getdef.c -+++ b/lib/getdef.c -@@ -176,7 +176,7 @@ static const char* def_fname = LOGINDEFS; /* login config defs file */ - static bool def_loaded = false; /* are defs already loaded? */ - - /* local function prototypes */ --static /*@observer@*/ /*@null@*/struct itemdef *def_find (const char *); -+static /*@observer@*/ /*@null@*/struct itemdef *def_find (const char *, const char *); - static void def_load (void); - - -@@ -195,7 +195,7 @@ static void def_load (void); - def_load (); - } - -- d = def_find (item); -+ d = def_find (item, NULL); - return (NULL == d) ? NULL : d->value; - } - -@@ -214,7 +214,7 @@ bool getdef_bool (const char *item) - def_load (); - } - -- d = def_find (item); -+ d = def_find (item, NULL); - if ((NULL == d) || (NULL == d->value)) { - return false; - } -@@ -240,7 +240,7 @@ int getdef_num (const char *item, int dflt) - def_load (); - } - -- d = def_find (item); -+ d = def_find (item, NULL); - if ((NULL == d) || (NULL == d->value)) { - return dflt; - } -@@ -275,7 +275,7 @@ unsigned int getdef_unum (const char *item, unsigned int dflt) - def_load (); - } - -- d = def_find (item); -+ d = def_find (item, NULL); - if ((NULL == d) || (NULL == d->value)) { - return dflt; - } -@@ -310,7 +310,7 @@ long getdef_long (const char *item, long dflt) - def_load (); - } - -- d = def_find (item); -+ d = def_find (item, NULL); - if ((NULL == d) || (NULL == d->value)) { - return dflt; - } -@@ -342,7 +342,7 @@ unsigned long getdef_ulong (const char *item, unsigned long dflt) - def_load (); - } - -- d = def_find (item); -+ d = def_find (item, NULL); - if ((NULL == d) || (NULL == d->value)) { - return dflt; - } -@@ -375,12 +375,9 @@ int putdef_str (const char *name, const char *value, const char *srcfile) - * Locate the slot to save the value. If this parameter - * is unknown then "def_find" will print an err message. - */ -- d = def_find (name); -- if (NULL == d) { -- if (NULL != srcfile) -- SYSLOG ((LOG_CRIT, "shadow: unknown configuration item '%s' in '%s'", name, srcfile)); -+ d = def_find (name, srcfile); -+ if (NULL == d) - return -1; -- } - - /* - * Save off the value. -@@ -404,9 +401,12 @@ int putdef_str (const char *name, const char *value, const char *srcfile) - * - * Search through a table of configurable items to locate the - * specified configuration option. -+ * -+ * If srcfile is not NULL, and the item is not found, then report an error saying -+ * the unknown item was used in this file. - */ - --static /*@observer@*/ /*@null@*/struct itemdef *def_find (const char *name) -+static /*@observer@*/ /*@null@*/struct itemdef *def_find (const char *name, const char *srcfile) - { - struct itemdef *ptr; - -@@ -432,6 +432,8 @@ static /*@observer@*/ /*@null@*/struct itemdef *def_find (const char *name) - fprintf (shadow_logfd, - _("configuration error - unknown item '%s' (notify administrator)\n"), - name); -+ if (srcfile != NULL) -+ SYSLOG ((LOG_CRIT, "shadow: unknown configuration item '%s' in '%s'", name, srcfile)); - - out: - return NULL; -@@ -610,7 +612,7 @@ int main (int argc, char **argv) - def_load (); - - for (i = 0; i < NUMDEFS; ++i) { -- d = def_find (def_table[i].name); -+ d = def_find (def_table[i].name, NULL); - if (NULL == d) { - printf ("error - lookup '%s' failed\n", - def_table[i].name); --- -2.44.0 - diff --git a/shadow-4.15.1-audit-update.patch b/shadow-4.15.1-audit-update.patch index a738d60..0295ecc 100644 --- a/shadow-4.15.1-audit-update.patch +++ b/shadow-4.15.1-audit-update.patch @@ -851,15 +851,6 @@ diff -up shadow-4.15.1/src/groupdel.c.audit-update shadow-4.15.1/src/groupdel.c } group_id = grp->gr_gid; -@@ -447,7 +451,7 @@ int main (int argc, char **argv) - _("%s: %s is the NIS master\n"), - Prog, nis_master); - } -- exit (E_NOTFOUND); -+ fail_exit (E_NOTFOUND); - } - #endif - diff -up shadow-4.15.1/src/groupmod.c.audit-update shadow-4.15.1/src/groupmod.c --- shadow-4.15.1/src/groupmod.c.audit-update 2024-03-08 22:27:04.000000000 +0100 +++ shadow-4.15.1/src/groupmod.c 2024-05-20 11:52:05.640758536 +0200 @@ -1846,8 +1837,8 @@ diff -up shadow-4.15.1/src/usermod.c.audit-update shadow-4.15.1/src/usermod.c #endif SYSLOG ((LOG_INFO, @@ -604,8 +604,8 @@ static void new_spent (struct spwd *spen - date_to_str (sizeof(new_exp), new_exp, user_newexpire * DAY); - date_to_str (sizeof(old_exp), old_exp, user_expire * DAY); + DAY_TO_STR(new_exp, user_newexpire); + DAY_TO_STR(old_exp, user_expire); #ifdef WITH_AUDIT - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, - "changing expiration date", diff --git a/shadow-4.15.1-sast-fixes.patch b/shadow-4.15.1-sast-fixes.patch deleted file mode 100644 index e674ebf..0000000 --- a/shadow-4.15.1-sast-fixes.patch +++ /dev/null @@ -1,1413 +0,0 @@ -From 4c16416ebc5f0958d58a1ea1e7890eafd9f8bb75 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Wed, 15 May 2024 12:25:51 +0200 -Subject: [PATCH 01/16] port: fix OVERRUN (CWE-119) - -``` -shadow-4.15.0/lib/port.c:154:2: alias: Assigning: "port.pt_names" = "ttys". "port.pt_names" now points to element 0 of "ttys" (which consists of 65 8-byte elements). -shadow-4.15.0/lib/port.c:155:2: cond_const: Checking "j < 64" implies that "j" is 64 on the false branch. -shadow-4.15.0/lib/port.c:175:2: overrun-local: Overrunning array of 65 8-byte elements at element index 65 (byte offset 527) by dereferencing pointer "port.pt_names + (j + 1)". -173| *cp = '\0'; -174| cp++; -175|-> port.pt_names[j + 1] = NULL; -176| -177| /* -``` - -Resolves: https://issues.redhat.com/browse/RHEL-35383 - -Signed-off-by: Iker Pedrosa -Reviewed-by: Alejandro Colomar ---- - lib/port.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/lib/port.c b/lib/port.c -index 05b95651..60ff8989 100644 ---- a/lib/port.c -+++ b/lib/port.c -@@ -168,7 +168,7 @@ again: - } - *cp = '\0'; - cp++; -- port.pt_names[j + 1] = NULL; -+ port.pt_names[j] = NULL; - - /* - * Get the list of user names. It is the second colon --- -2.45.1 - - -From f8fc6371f69930bbd5801284256e182ba35ced2a Mon Sep 17 00:00:00 2001 -From: Alejandro Colomar -Date: Fri, 17 May 2024 14:05:31 +0200 -Subject: [PATCH 02/16] src/useradd.c: set_defaults(): Fix order of clean-ups - -Resources should be freed in the inverse order of the allocation. -This refactor prepares for the following commits, which fix some leaks. - -Reviewed-by: Iker Pedrosa -Signed-off-by: Alejandro Colomar ---- - src/useradd.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - -diff --git a/src/useradd.c b/src/useradd.c -index 88d8ab7f..56a74559 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -745,10 +745,9 @@ static int set_defaults (void) - def_create_mail_spool, def_log_init)); - ret = 0; - setdef_err: -- free(new_file); -- if (prefix[0]) { -+ if (prefix[0]) - free(default_file); -- } -+ free(new_file); - - return ret; - } --- -2.45.1 - - -From 37ae8827a0869ee4a723954c3c9e7c48165d9b50 Mon Sep 17 00:00:00 2001 -From: Alejandro Colomar -Date: Fri, 17 May 2024 14:28:50 +0200 -Subject: [PATCH 03/16] src/useradd.c: set_defaults(): Rename goto label - -This will help add other labels in the following commits. - -Reviewed-by: Iker Pedrosa -Signed-off-by: Alejandro Colomar ---- - src/useradd.c | 24 +++++++++++++----------- - 1 file changed, 13 insertions(+), 11 deletions(-) - -diff --git a/src/useradd.c b/src/useradd.c -index 56a74559..bc72e6bc 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -558,7 +558,7 @@ static int set_defaults (void) - fprintf(stderr, - _("%s: cannot create new defaults file: %s\n"), - Prog, strerror(errno)); -- goto setdef_err; -+ goto err_free_def; - } - } - -@@ -567,7 +567,7 @@ static int set_defaults (void) - fprintf (stderr, - _("%s: cannot create directory for defaults file\n"), - Prog); -- goto setdef_err; -+ goto err_free_def; - } - - ret = mkdir(dirname(new_file_dup), 0755); -@@ -576,7 +576,7 @@ static int set_defaults (void) - _("%s: cannot create directory for defaults file\n"), - Prog); - free(new_file_dup); -- goto setdef_err; -+ goto err_free_def; - } - free(new_file_dup); - -@@ -588,7 +588,7 @@ static int set_defaults (void) - fprintf (stderr, - _("%s: cannot create new defaults file\n"), - Prog); -- goto setdef_err; -+ goto err_free_def; - } - - ofp = fdopen (ofd, "w"); -@@ -596,7 +596,7 @@ static int set_defaults (void) - fprintf (stderr, - _("%s: cannot open new defaults file\n"), - Prog); -- goto setdef_err; -+ goto err_free_def; - } - - /* -@@ -623,7 +623,7 @@ static int set_defaults (void) - _("%s: line too long in %s: %s..."), - Prog, default_file, buf); - (void) fclose (ifp); -- goto setdef_err; -+ goto err_free_def; - } - } - -@@ -702,9 +702,10 @@ static int set_defaults (void) - (void) fflush (ofp); - if ( (ferror (ofp) != 0) - || (fsync (fileno (ofp)) != 0) -- || (fclose (ofp) != 0)) { -+ || (fclose (ofp) != 0)) -+ { - unlink (new_file); -- goto setdef_err; -+ goto err_free_def; - } - - /* -@@ -718,7 +719,7 @@ static int set_defaults (void) - _("%s: Cannot create backup file (%s): %s\n"), - Prog, buf, strerror (err)); - unlink (new_file); -- goto setdef_err; -+ goto err_free_def; - } - - /* -@@ -729,7 +730,7 @@ static int set_defaults (void) - fprintf (stderr, - _("%s: rename: %s: %s\n"), - Prog, new_file, strerror (err)); -- goto setdef_err; -+ goto err_free_def; - } - #ifdef WITH_AUDIT - audit_logger (AUDIT_USYS_CONFIG, Prog, -@@ -744,7 +745,8 @@ static int set_defaults (void) - def_inactive, def_expire, def_template, - def_create_mail_spool, def_log_init)); - ret = 0; -- setdef_err: -+ -+err_free_def: - if (prefix[0]) - free(default_file); - free(new_file); --- -2.45.1 - - -From 701fe4cf1aeac9e66fa949369c91d135dbf375d2 Mon Sep 17 00:00:00 2001 -From: Alejandro Colomar -Date: Fri, 17 May 2024 13:10:46 +0200 -Subject: [PATCH 04/16] src/useradd.c: set_defaults(): Do not free(3) the - result of asprintf(3) if it failed -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -See asprintf(3): - -RETURN VALUE - When successful, these functions return the number of bytes - printed, just like sprintf(3). If memory allocation wasn’t possi‐ - ble, or some other error occurs, these functions will return -1, - and the contents of strp are undefined. - -Reviewed-by: Iker Pedrosa -Signed-off-by: Alejandro Colomar ---- - src/useradd.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/src/useradd.c b/src/useradd.c -index bc72e6bc..6a3edfe3 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -558,7 +558,7 @@ static int set_defaults (void) - fprintf(stderr, - _("%s: cannot create new defaults file: %s\n"), - Prog, strerror(errno)); -- goto err_free_def; -+ goto err_free_new; - } - } - -@@ -749,6 +749,7 @@ static int set_defaults (void) - err_free_def: - if (prefix[0]) - free(default_file); -+err_free_new: - free(new_file); - - return ret; --- -2.45.1 - - -From a74c4b6ae124a55cd272e574e0d056102f331e17 Mon Sep 17 00:00:00 2001 -From: Alejandro Colomar -Date: Fri, 17 May 2024 13:14:31 +0200 -Subject: [PATCH 05/16] src/useradd.c: De-duplicate code - -Reviewed-by: Iker Pedrosa -Signed-off-by: Alejandro Colomar ---- - src/useradd.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/src/useradd.c b/src/useradd.c -index 6a3edfe3..ad2676c1 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -571,14 +571,13 @@ static int set_defaults (void) - } - - ret = mkdir(dirname(new_file_dup), 0755); -+ free(new_file_dup); - if (-1 == ret && EEXIST != errno) { - fprintf (stderr, - _("%s: cannot create directory for defaults file\n"), - Prog); -- free(new_file_dup); - goto err_free_def; - } -- free(new_file_dup); - - /* - * Create a temporary file to copy the new output to. --- -2.45.1 - - -From e7d1508e076bbf4053faacc0370c6fe43d9c8f04 Mon Sep 17 00:00:00 2001 -From: Alejandro Colomar -Date: Fri, 17 May 2024 13:40:58 +0200 -Subject: [PATCH 06/16] src/useradd.c: Add fmkstemp() to fix file-descriptor - leak - -This function creates a temporary file, and returns a FILE pointer to -it. This avoids dealing with both a file descriptor and a FILE pointer, -and correctly deallocating the resources on error. - -The code before this patch was leaking the file descriptor if fdopen(3) -failed. - -Reviewed-by: Iker Pedrosa -Signed-off-by: Alejandro Colomar ---- - src/useradd.c | 34 ++++++++++++++++++++++++---------- - 1 file changed, 24 insertions(+), 10 deletions(-) - -diff --git a/src/useradd.c b/src/useradd.c -index ad2676c1..e0238457 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -238,6 +238,9 @@ static void create_home (void); - static void create_mail (void); - static void check_uid_range(int rflg, uid_t user_id); - -+static FILE *fmkstemp(char *template); -+ -+ - /* - * fail_exit - undo as much as possible - */ -@@ -524,7 +527,6 @@ static void show_defaults (void) - */ - static int set_defaults (void) - { -- int ofd; - int ret = -1; - bool out_group = false; - bool out_groups = false; -@@ -582,15 +584,7 @@ static int set_defaults (void) - /* - * Create a temporary file to copy the new output to. - */ -- ofd = mkstemp (new_file); -- if (-1 == ofd) { -- fprintf (stderr, -- _("%s: cannot create new defaults file\n"), -- Prog); -- goto err_free_def; -- } -- -- ofp = fdopen (ofd, "w"); -+ ofp = fmkstemp(new_file); - if (NULL == ofp) { - fprintf (stderr, - _("%s: cannot open new defaults file\n"), -@@ -2752,3 +2746,23 @@ int main (int argc, char **argv) - return E_SUCCESS; - } - -+ -+static FILE * -+fmkstemp(char *template) -+{ -+ int fd; -+ FILE *fp; -+ -+ fd = mkstemp(template); -+ if (fd == -1) -+ return NULL; -+ -+ fp = fdopen(fd, "w"); -+ if (fp == NULL) { -+ close(fd); -+ unlink(template); -+ return NULL; -+ } -+ -+ return fp; -+} --- -2.45.1 - - -From 1ee066ae1e5b39ac42120ad0f6f8af0f102db952 Mon Sep 17 00:00:00 2001 -From: Alejandro Colomar -Date: Fri, 17 May 2024 13:52:07 +0200 -Subject: [PATCH 07/16] src/useradd.c: set_defaults(): Fix FILE* leak - -Report: -> shadow-4.15.0/src/useradd.c:575:2: alloc_fn: Storage is returned from allocation function "fdopen". -> shadow-4.15.0/src/useradd.c:575:2: var_assign: Assigning: "ofp" = storage returned from "fdopen(ofd, "w")". -> shadow-4.15.0/src/useradd.c:734:2: leaked_storage: Variable "ofp" going out of scope leaks the storage it points to. -> 732| } -> 733| -> 734|-> return ret; -> 735| } -> 736| - -Link: -Reported-by: Iker Pedrosa -Reviewed-by: Iker Pedrosa -Signed-off-by: Alejandro Colomar ---- - src/useradd.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/src/useradd.c b/src/useradd.c -index e0238457..347334a6 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -615,7 +615,8 @@ static int set_defaults (void) - fprintf (stderr, - _("%s: line too long in %s: %s..."), - Prog, default_file, buf); -- (void) fclose (ifp); -+ fclose(ifp); -+ fclose(ofp); - goto err_free_def; - } - } --- -2.45.1 - - -From 151f14ad69de8100d25c1974947d53ae40d1448a Mon Sep 17 00:00:00 2001 -From: Alejandro Colomar -Date: Thu, 16 May 2024 13:52:15 +0200 -Subject: [PATCH 08/16] src/usermod.c: Reduce scope of local variables - -Signed-off-by: Alejandro Colomar ---- - src/usermod.c | 22 +++++++++++----------- - 1 file changed, 11 insertions(+), 11 deletions(-) - -diff --git a/src/usermod.c b/src/usermod.c -index 0fcf0325..57b58f5b 100644 ---- a/src/usermod.c -+++ b/src/usermod.c -@@ -687,11 +687,8 @@ fail_exit (int code) - - static void update_group (void) - { -- bool is_member; -- bool was_member; -- bool changed; -- const struct group *grp; -- struct group *ngrp; -+ bool changed; -+ const struct group *grp; - - changed = false; - -@@ -700,6 +697,9 @@ static void update_group (void) - * the user is a member of. - */ - while ((grp = gr_next ()) != NULL) { -+ bool is_member; -+ bool was_member; -+ struct group *ngrp; - /* - * See if the user specified this group as one of their - * concurrent groups. -@@ -799,12 +799,8 @@ static void update_group (void) - #ifdef SHADOWGRP - static void update_gshadow (void) - { -- bool is_member; -- bool was_member; -- bool was_admin; -- bool changed; -- const struct sgrp *sgrp; -- struct sgrp *nsgrp; -+ bool changed; -+ const struct sgrp *sgrp; - - changed = false; - -@@ -813,6 +809,10 @@ static void update_gshadow (void) - * that the user is a member of. - */ - while ((sgrp = sgr_next ()) != NULL) { -+ bool is_member; -+ bool was_member; -+ bool was_admin; -+ struct sgrp *nsgrp; - - /* - * See if the user was a member of this group --- -2.45.1 - - -From b089a63ab38f69c32d099320fe8181802f7f4092 Mon Sep 17 00:00:00 2001 -From: Alejandro Colomar -Date: Thu, 16 May 2024 13:49:34 +0200 -Subject: [PATCH 09/16] src/usermod.c: Rename update_group() => - update_group_file() - -Signed-off-by: Alejandro Colomar ---- - src/usermod.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - -diff --git a/src/usermod.c b/src/usermod.c -index 57b58f5b..aaa83d7d 100644 ---- a/src/usermod.c -+++ b/src/usermod.c -@@ -178,7 +178,7 @@ NORETURN static void usage (int status); - static void new_pwent (struct passwd *); - static void new_spent (struct spwd *); - NORETURN static void fail_exit (int); --static void update_group (void); -+static void update_group_file(void); - - #ifdef SHADOWGRP - static void update_gshadow (void); -@@ -685,7 +685,8 @@ fail_exit (int code) - } - - --static void update_group (void) -+static void -+update_group_file(void) - { - bool changed; - const struct group *grp; -@@ -950,7 +951,7 @@ static void update_gshadow (void) - */ - static void grp_update (void) - { -- update_group (); -+ update_group_file(); - #ifdef SHADOWGRP - if (is_shadow_grp) { - update_gshadow (); --- -2.45.1 - - -From 81bc78ec5cdd59790bc7c591c9d1f66bd4d7b78e Mon Sep 17 00:00:00 2001 -From: Alejandro Colomar -Date: Fri, 17 May 2024 02:11:22 +0200 -Subject: [PATCH 10/16] src/usermod.c: Rename update_gshadow() => - update_gshadow_file() - -Signed-off-by: Alejandro Colomar ---- - src/usermod.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - -diff --git a/src/usermod.c b/src/usermod.c -index aaa83d7d..3048f801 100644 ---- a/src/usermod.c -+++ b/src/usermod.c -@@ -181,7 +181,7 @@ NORETURN static void fail_exit (int); - static void update_group_file(void); - - #ifdef SHADOWGRP --static void update_gshadow (void); -+static void update_gshadow_file(void); - #endif - static void grp_update (void); - -@@ -798,7 +798,8 @@ update_group_file(void) - } - - #ifdef SHADOWGRP --static void update_gshadow (void) -+static void -+update_gshadow_file(void) - { - bool changed; - const struct sgrp *sgrp; -@@ -954,7 +955,7 @@ static void grp_update (void) - update_group_file(); - #ifdef SHADOWGRP - if (is_shadow_grp) { -- update_gshadow (); -+ update_gshadow_file(); - } - #endif - } --- -2.45.1 - - -From 61964aa06b9e6e0643a6519f64290f18ac04867f Mon Sep 17 00:00:00 2001 -From: Alejandro Colomar -Date: Thu, 16 May 2024 13:54:06 +0200 -Subject: [PATCH 11/16] src/usermod.c: update_group_file(): Fix RESOURCE_LEAK - (CWE-772) - -Report: -> shadow-4.15.0/src/usermod.c:734:3: alloc_fn: Storage is returned from allocation function "__gr_dup". -> shadow-4.15.0/src/usermod.c:734:3: var_assign: Assigning: "ngrp" = storage returned from "__gr_dup(grp)". -> shadow-4.15.0/src/usermod.c:815:1: leaked_storage: Variable "ngrp" going out of scope leaks the storage it points to. -> 813| gr_free(ngrp); -> 814| } -> 815|-> } -> 816| -> 817| #ifdef SHADOWGRP - -Link: https://issues.redhat.com/browse/RHEL-35383 -Reported-by: Iker Pedrosa -Signed-off-by: Alejandro Colomar ---- - src/usermod.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/src/usermod.c b/src/usermod.c -index 3048f801..e0cfdd83 100644 ---- a/src/usermod.c -+++ b/src/usermod.c -@@ -780,9 +780,8 @@ update_group_file(void) - SYSLOG ((LOG_INFO, "add '%s' to group '%s'", - user_newname, ngrp->gr_name)); - } -- if (!changed) { -- continue; -- } -+ if (!changed) -+ goto free_ngrp; - - changed = false; - if (gr_update (ngrp) == 0) { -@@ -793,6 +792,7 @@ update_group_file(void) - fail_exit (E_GRP_UPDATE); - } - -+free_ngrp: - gr_free(ngrp); - } - } --- -2.45.1 - - -From 71a3238b7996285fc3c8dec841244ba95d663fa5 Mon Sep 17 00:00:00 2001 -From: Alejandro Colomar -Date: Fri, 17 May 2024 02:15:15 +0200 -Subject: [PATCH 12/16] src/usermod.c: update_gshadow_file(): Fix RESOURCE_LEAK - (CWE-772) - -Report: -> shadow-4.15.0/src/usermod.c:864:3: alloc_fn: Storage is returned from allocation function "__sgr_dup". -> shadow-4.15.0/src/usermod.c:864:3: var_assign: Assigning: "nsgrp" = storage returned from "__sgr_dup(sgrp)". -> shadow-4.15.0/src/usermod.c:964:1: leaked_storage: Variable "nsgrp" going out of scope leaks the storage it points to. -> 962| free (nsgrp); -> 963| } -> 964|-> } -> 965| #endif /* SHADOWGRP */ -> 966| - -Link: https://issues.redhat.com/browse/RHEL-35383 -Reported-by: Iker Pedrosa -Signed-off-by: Alejandro Colomar ---- - src/usermod.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/src/usermod.c b/src/usermod.c -index e0cfdd83..bb5d3535 100644 ---- a/src/usermod.c -+++ b/src/usermod.c -@@ -921,9 +921,8 @@ update_gshadow_file(void) - SYSLOG ((LOG_INFO, "add '%s' to shadow group '%s'", - user_newname, nsgrp->sg_name)); - } -- if (!changed) { -- continue; -- } -+ if (!changed) -+ goto free_nsgrp; - - changed = false; - -@@ -939,6 +938,7 @@ update_gshadow_file(void) - fail_exit (E_GRP_UPDATE); - } - -+free_nsgrp: - free (nsgrp); - } - } --- -2.45.1 - - -From 68d42a8fbe42b89cf13d3f672ad8502dbaf05835 Mon Sep 17 00:00:00 2001 -From: Alejandro Colomar -Date: Thu, 16 May 2024 14:02:54 +0200 -Subject: [PATCH 13/16] src/usermod.c: update_group_file(): Reduce scope of - local variable - -After _every_ iteration, 'changed' is always 'false'. We don't need to -have it outside of the loop. - -See: - -$ grepc update_group_file . \ -| grep -e changed -e goto -e continue -e break -e free_ngrp -e '{' -e '}' \ -| pcre2grep -v -M '{\n\t*}'; -{ - bool changed; - changed = false; - while ((grp = gr_next ()) != NULL) { - if (!was_member && !is_member) { - continue; - } - if (was_member) { - if ((!Gflg) || is_member) { - if (lflg) { - changed = true; - } - } else { - changed = true; - } - } else if (is_member) { - changed = true; - } - if (!changed) - goto free_ngrp; - changed = false; -free_ngrp: - } -} - -This was already true in the commit that introduced the code: - -$ git show 45c6603cc:src/usermod.c \ -| grepc update_group \ -| grep -e changed -e goto -e break -e continue -e '\' -e '{' -e '}' \ -| pcre2grep -v -M '{\n\t*}'; -{ - int changed; - changed = 0; - while ((grp = gr_next())) { - * See if the user specified this group as one of their - if (!was_member && !is_member) - continue; - if (was_member && (!Gflg || is_member)) { - if (lflg) { - changed = 1; - } - } else if (was_member && Gflg && !is_member) { - changed = 1; - } else if (!was_member && Gflg && is_member) { - changed = 1; - } - if (!changed) - continue; - changed = 0; - } -} - -Fixes: 45c6603cc86c ("[svn-upgrade] Integrating new upstream version, shadow (19990709)") -Signed-off-by: Alejandro Colomar ---- - src/usermod.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/src/usermod.c b/src/usermod.c -index bb5d3535..30f47b8a 100644 ---- a/src/usermod.c -+++ b/src/usermod.c -@@ -688,19 +688,20 @@ fail_exit (int code) - static void - update_group_file(void) - { -- bool changed; - const struct group *grp; - -- changed = false; -- - /* - * Scan through the entire group file looking for the groups that - * the user is a member of. - */ - while ((grp = gr_next ()) != NULL) { -+ bool changed; - bool is_member; - bool was_member; - struct group *ngrp; -+ -+ changed = false; -+ - /* - * See if the user specified this group as one of their - * concurrent groups. -@@ -783,7 +784,6 @@ update_group_file(void) - if (!changed) - goto free_ngrp; - -- changed = false; - if (gr_update (ngrp) == 0) { - fprintf (stderr, - _("%s: failed to prepare the new %s entry '%s'\n"), --- -2.45.1 - - -From da77a82ecbc90e89808f143e7fa2abb7650f50d7 Mon Sep 17 00:00:00 2001 -From: Alejandro Colomar -Date: Fri, 17 May 2024 02:19:46 +0200 -Subject: [PATCH 14/16] src/usermod.c: update_gshadow_file(): Reduce scope of - local variable - -After _every_ iteration, 'changed' is always 'false'. We don't need to -have it outside of the loop. - -See: - -$ grepc update_gshadow_file . \ -| grep -e changed -e goto -e continue -e break -e free_ngrp -e '{' -e '}' \ -| pcre2grep -v -M '{\n\t*}'; -{ - bool changed; - changed = false; - while ((sgrp = sgr_next ()) != NULL) { - if (!was_member && !was_admin && !is_member) { - continue; - } - if (was_admin && lflg) { - changed = true; - } - if (was_member) { - if ((!Gflg) || is_member) { - if (lflg) { - changed = true; - } - } else { - changed = true; - } - } else if (is_member) { - changed = true; - } - if (!changed) - goto free_nsgrp; - changed = false; - } -} - -This was already true in the commit that introduced the code: - -$ git show 45c6603cc:src/usermod.c \ -| grepc update_gshadow \ -| grep -e changed -e goto -e break -e continue -e '\' -e '{' -e '}' \ -| pcre2grep -v -M '{\n\t*}'; -{ - int changed; - changed = 0; - while ((sgrp = sgr_next())) { - * See if the user was a member of this group - * See if the user was an administrator of this group - * See if the user specified this group as one of their - if (!was_member && !was_admin && !is_member) - continue; - if (was_admin && lflg) { - changed = 1; - } - if (was_member && (!Gflg || is_member)) { - if (lflg) { - changed = 1; - } - } else if (was_member && Gflg && !is_member) { - changed = 1; - } else if (!was_member && Gflg && is_member) { - changed = 1; - } - if (!changed) - continue; - changed = 0; - } -} - -Fixes: 45c6603cc86c ("[svn-upgrade] Integrating new upstream version, shadow (19990709)") -Signed-off-by: Alejandro Colomar ---- - src/usermod.c | 8 +++----- - 1 file changed, 3 insertions(+), 5 deletions(-) - -diff --git a/src/usermod.c b/src/usermod.c -index 30f47b8a..7b1e0581 100644 ---- a/src/usermod.c -+++ b/src/usermod.c -@@ -801,21 +801,21 @@ free_ngrp: - static void - update_gshadow_file(void) - { -- bool changed; - const struct sgrp *sgrp; - -- changed = false; -- - /* - * Scan through the entire shadow group file looking for the groups - * that the user is a member of. - */ - while ((sgrp = sgr_next ()) != NULL) { -+ bool changed; - bool is_member; - bool was_member; - bool was_admin; - struct sgrp *nsgrp; - -+ changed = false; -+ - /* - * See if the user was a member of this group - */ -@@ -924,8 +924,6 @@ update_gshadow_file(void) - if (!changed) - goto free_nsgrp; - -- changed = false; -- - /* - * Update the group entry to reflect the changes. - */ --- -2.45.1 - - -From adf37cccd0fa4ce7d05644514b0af57fe71905c3 Mon Sep 17 00:00:00 2001 -From: Alejandro Colomar -Date: Thu, 16 May 2024 14:12:09 +0200 -Subject: [PATCH 15/16] src/usermod.c: update_group(): Add helper function - -Keep the while loop in the outer function, and move the iteration code -to this new helper. This makes it a bit more readable. - -Cc: Iker Pedrosa -Signed-off-by: Alejandro Colomar ---- - src/usermod.c | 167 ++++++++++++++++++++++++++------------------------ - 1 file changed, 87 insertions(+), 80 deletions(-) - -diff --git a/src/usermod.c b/src/usermod.c -index 7b1e0581..4ea11376 100644 ---- a/src/usermod.c -+++ b/src/usermod.c -@@ -179,6 +179,7 @@ static void new_pwent (struct passwd *); - static void new_spent (struct spwd *); - NORETURN static void fail_exit (int); - static void update_group_file(void); -+static void update_group(const struct group *grp); - - #ifdef SHADOWGRP - static void update_gshadow_file(void); -@@ -694,109 +695,115 @@ update_group_file(void) - * Scan through the entire group file looking for the groups that - * the user is a member of. - */ -- while ((grp = gr_next ()) != NULL) { -- bool changed; -- bool is_member; -- bool was_member; -- struct group *ngrp; -+ while ((grp = gr_next()) != NULL) -+ update_group(grp); -+} - -- changed = false; - -- /* -- * See if the user specified this group as one of their -- * concurrent groups. -- */ -- was_member = is_on_list (grp->gr_mem, user_name); -- is_member = Gflg && ( (was_member && aflg) -- || is_on_list (user_groups, grp->gr_name)); -+static void -+update_group(const struct group *grp) -+{ -+ bool changed; -+ bool is_member; -+ bool was_member; -+ struct group *ngrp; - -- if (!was_member && !is_member) { -- continue; -- } -+ changed = false; - -- /* -- * If rflg+Gflg is passed in AKA -rG invert is_member flag, which removes -- * mentioned groups while leaving the others. -- */ -- if (Gflg && rflg) { -- is_member = !is_member; -- } -+ /* -+ * See if the user specified this group as one of their -+ * concurrent groups. -+ */ -+ was_member = is_on_list (grp->gr_mem, user_name); -+ is_member = Gflg && ( (was_member && aflg) -+ || is_on_list (user_groups, grp->gr_name)); - -- ngrp = __gr_dup (grp); -- if (NULL == ngrp) { -- fprintf (stderr, -- _("%s: Out of memory. Cannot update %s.\n"), -- Prog, gr_dbname ()); -- fail_exit (E_GRP_UPDATE); -- } -+ if (!was_member && !is_member) -+ return; - -- if (was_member) { -- if ((!Gflg) || is_member) { -- /* User was a member and is still a member -- * of this group. -- * But the user might have been renamed. -- */ -- if (lflg) { -- ngrp->gr_mem = del_list (ngrp->gr_mem, -- user_name); -- ngrp->gr_mem = add_list (ngrp->gr_mem, -- user_newname); -- changed = true; --#ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "changing group member", -- user_newname, AUDIT_NO_ID, 1); --#endif -- SYSLOG ((LOG_INFO, -- "change '%s' to '%s' in group '%s'", -- user_name, user_newname, -- ngrp->gr_name)); -- } -- } else { -- /* User was a member but is no more a -- * member of this group. -- */ -- ngrp->gr_mem = del_list (ngrp->gr_mem, user_name); -+ /* -+ * If rflg+Gflg is passed in AKA -rG invert is_member flag, which removes -+ * mentioned groups while leaving the others. -+ */ -+ if (Gflg && rflg) { -+ is_member = !is_member; -+ } -+ -+ ngrp = __gr_dup (grp); -+ if (NULL == ngrp) { -+ fprintf (stderr, -+ _("%s: Out of memory. Cannot update %s.\n"), -+ Prog, gr_dbname ()); -+ fail_exit (E_GRP_UPDATE); -+ } -+ -+ if (was_member) { -+ if ((!Gflg) || is_member) { -+ /* User was a member and is still a member -+ * of this group. -+ * But the user might have been renamed. -+ */ -+ if (lflg) { -+ ngrp->gr_mem = del_list (ngrp->gr_mem, -+ user_name); -+ ngrp->gr_mem = add_list (ngrp->gr_mem, -+ user_newname); - changed = true; - #ifdef WITH_AUDIT - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "removing group member", -- user_name, AUDIT_NO_ID, 1); -+ "changing group member", -+ user_newname, AUDIT_NO_ID, 1); - #endif - SYSLOG ((LOG_INFO, -- "delete '%s' from group '%s'", -- user_name, ngrp->gr_name)); -+ "change '%s' to '%s' in group '%s'", -+ user_name, user_newname, -+ ngrp->gr_name)); - } -- } else if (is_member) { -- /* User was not a member but is now a member this -- * group. -+ } else { -+ /* User was a member but is no more a -+ * member of this group. - */ -- ngrp->gr_mem = add_list (ngrp->gr_mem, user_newname); -+ ngrp->gr_mem = del_list (ngrp->gr_mem, user_name); - changed = true; - #ifdef WITH_AUDIT - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "adding user to group", -- user_name, AUDIT_NO_ID, 1); -+ "removing group member", -+ user_name, AUDIT_NO_ID, 1); - #endif -- SYSLOG ((LOG_INFO, "add '%s' to group '%s'", -- user_newname, ngrp->gr_name)); -+ SYSLOG ((LOG_INFO, -+ "delete '%s' from group '%s'", -+ user_name, ngrp->gr_name)); - } -- if (!changed) -- goto free_ngrp; -+ } else if (is_member) { -+ /* User was not a member but is now a member this -+ * group. -+ */ -+ ngrp->gr_mem = add_list (ngrp->gr_mem, user_newname); -+ changed = true; -+#ifdef WITH_AUDIT -+ audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -+ "adding user to group", -+ user_name, AUDIT_NO_ID, 1); -+#endif -+ SYSLOG ((LOG_INFO, "add '%s' to group '%s'", -+ user_newname, ngrp->gr_name)); -+ } -+ if (!changed) -+ goto free_ngrp; - -- if (gr_update (ngrp) == 0) { -- fprintf (stderr, -- _("%s: failed to prepare the new %s entry '%s'\n"), -- Prog, gr_dbname (), ngrp->gr_name); -- SYSLOG ((LOG_WARN, "failed to prepare the new %s entry '%s'", gr_dbname (), ngrp->gr_name)); -- fail_exit (E_GRP_UPDATE); -- } -+ if (gr_update (ngrp) == 0) { -+ fprintf (stderr, -+ _("%s: failed to prepare the new %s entry '%s'\n"), -+ Prog, gr_dbname (), ngrp->gr_name); -+ SYSLOG ((LOG_WARN, "failed to prepare the new %s entry '%s'", gr_dbname (), ngrp->gr_name)); -+ fail_exit (E_GRP_UPDATE); -+ } - - free_ngrp: -- gr_free(ngrp); -- } -+ gr_free(ngrp); - } - -+ - #ifdef SHADOWGRP - static void - update_gshadow_file(void) --- -2.45.1 - - -From d8e6a8b99b4d844328d875287babf6e13860d464 Mon Sep 17 00:00:00 2001 -From: Alejandro Colomar -Date: Fri, 17 May 2024 02:29:46 +0200 -Subject: [PATCH 16/16] src/usermod.c: update_gshadow(): Add helper function - -Keep the while loop in the outer function, and move the iteration code -to this new helper. This makes it a bit more readable. - -Cc: Iker Pedrosa -Signed-off-by: Alejandro Colomar ---- - src/usermod.c | 223 ++++++++++++++++++++++++++------------------------ - 1 file changed, 116 insertions(+), 107 deletions(-) - -diff --git a/src/usermod.c b/src/usermod.c -index 4ea11376..f8896984 100644 ---- a/src/usermod.c -+++ b/src/usermod.c -@@ -183,6 +183,7 @@ static void update_group(const struct group *grp); - - #ifdef SHADOWGRP - static void update_gshadow_file(void); -+static void update_gshadow(const struct sgrp *sgrp); - #endif - static void grp_update (void); - -@@ -814,141 +815,149 @@ update_gshadow_file(void) - * Scan through the entire shadow group file looking for the groups - * that the user is a member of. - */ -- while ((sgrp = sgr_next ()) != NULL) { -- bool changed; -- bool is_member; -- bool was_member; -- bool was_admin; -- struct sgrp *nsgrp; -+ while ((sgrp = sgr_next()) != NULL) -+ update_gshadow(sgrp); -+} -+#endif /* SHADOWGRP */ - -- changed = false; - -- /* -- * See if the user was a member of this group -- */ -- was_member = is_on_list (sgrp->sg_mem, user_name); -+#ifdef SHADOWGRP -+static void -+update_gshadow(const struct sgrp *sgrp) -+{ -+ bool changed; -+ bool is_member; -+ bool was_member; -+ bool was_admin; -+ struct sgrp *nsgrp; - -- /* -- * See if the user was an administrator of this group -- */ -- was_admin = is_on_list (sgrp->sg_adm, user_name); -+ changed = false; - -- /* -- * See if the user specified this group as one of their -- * concurrent groups. -- */ -- is_member = Gflg && ( (was_member && aflg) -- || is_on_list (user_groups, sgrp->sg_name)); -+ /* -+ * See if the user was a member of this group -+ */ -+ was_member = is_on_list (sgrp->sg_mem, user_name); - -- if (!was_member && !was_admin && !is_member) { -- continue; -- } -+ /* -+ * See if the user was an administrator of this group -+ */ -+ was_admin = is_on_list (sgrp->sg_adm, user_name); - -- /* -- * If rflg+Gflg is passed in AKA -rG invert is_member, to remove targeted -- * groups while leaving the user apart of groups not mentioned -- */ -- if (Gflg && rflg) { -- is_member = !is_member; -- } -+ /* -+ * See if the user specified this group as one of their -+ * concurrent groups. -+ */ -+ is_member = Gflg && ( (was_member && aflg) -+ || is_on_list (user_groups, sgrp->sg_name)); - -- nsgrp = __sgr_dup (sgrp); -- if (NULL == nsgrp) { -- fprintf (stderr, -- _("%s: Out of memory. Cannot update %s.\n"), -- Prog, sgr_dbname ()); -- fail_exit (E_GRP_UPDATE); -- } -+ if (!was_member && !was_admin && !is_member) -+ return; - -- if (was_admin && lflg) { -- /* User was an admin of this group but the user -- * has been renamed. -- */ -- nsgrp->sg_adm = del_list (nsgrp->sg_adm, user_name); -- nsgrp->sg_adm = add_list (nsgrp->sg_adm, user_newname); -- changed = true; --#ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "changing admin name in shadow group", -- user_name, AUDIT_NO_ID, 1); --#endif -- SYSLOG ((LOG_INFO, -- "change admin '%s' to '%s' in shadow group '%s'", -- user_name, user_newname, nsgrp->sg_name)); -- } -- -- if (was_member) { -- if ((!Gflg) || is_member) { -- /* User was a member and is still a member -- * of this group. -- * But the user might have been renamed. -- */ -- if (lflg) { -- nsgrp->sg_mem = del_list (nsgrp->sg_mem, -- user_name); -- nsgrp->sg_mem = add_list (nsgrp->sg_mem, -- user_newname); -- changed = true; -+ /* -+ * If rflg+Gflg is passed in AKA -rG invert is_member, to remove targeted -+ * groups while leaving the user apart of groups not mentioned -+ */ -+ if (Gflg && rflg) { -+ is_member = !is_member; -+ } -+ -+ nsgrp = __sgr_dup (sgrp); -+ if (NULL == nsgrp) { -+ fprintf (stderr, -+ _("%s: Out of memory. Cannot update %s.\n"), -+ Prog, sgr_dbname ()); -+ fail_exit (E_GRP_UPDATE); -+ } -+ -+ if (was_admin && lflg) { -+ /* User was an admin of this group but the user -+ * has been renamed. -+ */ -+ nsgrp->sg_adm = del_list (nsgrp->sg_adm, user_name); -+ nsgrp->sg_adm = add_list (nsgrp->sg_adm, user_newname); -+ changed = true; - #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "changing member in shadow group", -- user_name, AUDIT_NO_ID, 1); -+ audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -+ "changing admin name in shadow group", -+ user_name, AUDIT_NO_ID, 1); - #endif -- SYSLOG ((LOG_INFO, -- "change '%s' to '%s' in shadow group '%s'", -- user_name, user_newname, -- nsgrp->sg_name)); -- } -- } else { -- /* User was a member but is no more a -- * member of this group. -- */ -- nsgrp->sg_mem = del_list (nsgrp->sg_mem, user_name); -+ SYSLOG ((LOG_INFO, -+ "change admin '%s' to '%s' in shadow group '%s'", -+ user_name, user_newname, nsgrp->sg_name)); -+ } -+ -+ if (was_member) { -+ if ((!Gflg) || is_member) { -+ /* User was a member and is still a member -+ * of this group. -+ * But the user might have been renamed. -+ */ -+ if (lflg) { -+ nsgrp->sg_mem = del_list (nsgrp->sg_mem, -+ user_name); -+ nsgrp->sg_mem = add_list (nsgrp->sg_mem, -+ user_newname); - changed = true; - #ifdef WITH_AUDIT - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "removing user from shadow group", -- user_name, AUDIT_NO_ID, 1); -+ "changing member in shadow group", -+ user_name, AUDIT_NO_ID, 1); - #endif - SYSLOG ((LOG_INFO, -- "delete '%s' from shadow group '%s'", -- user_name, nsgrp->sg_name)); -+ "change '%s' to '%s' in shadow group '%s'", -+ user_name, user_newname, -+ nsgrp->sg_name)); - } -- } else if (is_member) { -- /* User was not a member but is now a member this -- * group. -+ } else { -+ /* User was a member but is no more a -+ * member of this group. - */ -- nsgrp->sg_mem = add_list (nsgrp->sg_mem, user_newname); -+ nsgrp->sg_mem = del_list (nsgrp->sg_mem, user_name); - changed = true; - #ifdef WITH_AUDIT - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "adding user to shadow group", -- user_newname, AUDIT_NO_ID, 1); -+ "removing user from shadow group", -+ user_name, AUDIT_NO_ID, 1); - #endif -- SYSLOG ((LOG_INFO, "add '%s' to shadow group '%s'", -- user_newname, nsgrp->sg_name)); -+ SYSLOG ((LOG_INFO, -+ "delete '%s' from shadow group '%s'", -+ user_name, nsgrp->sg_name)); - } -- if (!changed) -- goto free_nsgrp; -- -- /* -- * Update the group entry to reflect the changes. -+ } else if (is_member) { -+ /* User was not a member but is now a member this -+ * group. - */ -- if (sgr_update (nsgrp) == 0) { -- fprintf (stderr, -- _("%s: failed to prepare the new %s entry '%s'\n"), -- Prog, sgr_dbname (), nsgrp->sg_name); -- SYSLOG ((LOG_WARN, "failed to prepare the new %s entry '%s'", -- sgr_dbname (), nsgrp->sg_name)); -- fail_exit (E_GRP_UPDATE); -- } -+ nsgrp->sg_mem = add_list (nsgrp->sg_mem, user_newname); -+ changed = true; -+#ifdef WITH_AUDIT -+ audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -+ "adding user to shadow group", -+ user_newname, AUDIT_NO_ID, 1); -+#endif -+ SYSLOG ((LOG_INFO, "add '%s' to shadow group '%s'", -+ user_newname, nsgrp->sg_name)); -+ } -+ if (!changed) -+ goto free_nsgrp; - --free_nsgrp: -- free (nsgrp); -+ /* -+ * Update the group entry to reflect the changes. -+ */ -+ if (sgr_update (nsgrp) == 0) { -+ fprintf (stderr, -+ _("%s: failed to prepare the new %s entry '%s'\n"), -+ Prog, sgr_dbname (), nsgrp->sg_name); -+ SYSLOG ((LOG_WARN, "failed to prepare the new %s entry '%s'", -+ sgr_dbname (), nsgrp->sg_name)); -+ fail_exit (E_GRP_UPDATE); - } -+ -+free_nsgrp: -+ free (nsgrp); - } - #endif /* SHADOWGRP */ - -+ - /* - * grp_update - add user to secondary group set - * --- -2.45.1 - diff --git a/shadow-utils.spec b/shadow-utils.spec index e3cd026..0786f83 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils -Version: 4.15.1 -Release: 9%{?dist} +Version: 4.16.0 +Release: 1%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -22,14 +22,10 @@ Source7: passwd.pamd Patch0: shadow-4.15.0-manfix.patch # Date parsing improvement - could be upstreamed Patch1: shadow-4.15.0-date-parsing.patch -# Several patches already available upstream. PRs:#994, #996, #997 -Patch2: shadow-4.15.1-sast-fixes.patch # Audit message changes - partially upstreamed -Patch3: shadow-4.15.1-audit-update.patch +Patch2: shadow-4.15.1-audit-update.patch # Probably non-upstreamable -Patch4: shadow-4.15.0-account-tools-setuid.patch -# https://github.com/shadow-maint/shadow/commit/ead55e9ba8958504e23e29545f90c4dd925c7462 -Patch5: shadow-4.15.0-getdef-spurious-error.patch +Patch3: shadow-4.15.0-account-tools-setuid.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -295,6 +291,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Tue Aug 13 2024 Iker Pedrosa - 2:4.16.0-1 +- Rebase to version 4.16.0 (#2293678) + * Tue Jul 23 2024 Kevin Fenzi - 2:4.15.1-9 - Revert chpasswd: use PAM again for now. diff --git a/sources b/sources index ca5a1c9..a2d890c 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (shadow-4.15.1.tar.xz) = 2667a1d781066adce42e684463329c3f32d28c07b7b79b628525bffcd61c078f6ff430be3d42976d0509d9f9a55cd80f5a50d479b85155476cee7f00f06708d8 -SHA512 (shadow-4.15.1.tar.xz.asc) = 0a39d6a45b7d8df12aade89ed9fc9d481c91297dbd34e85fe831426c1d0051cbcf8478759306b8871cd6b1835604c5836decf398d0165c50ac52fee365561446 +SHA512 (shadow-4.16.0.tar.xz) = 3986572c74cce013c733c592ef5a8113e69bba8fee74fb697fe8206bd616d29553e42822e663478db81b3e17b26b403bc69b3492dd981b87643b0e1c55035ecf +SHA512 (shadow-4.16.0.tar.xz.asc) = be98d5c157115869e23932e347b609ab342c0bc1a9d716d07ae61b497779c1a5a436534eb3ee0294687eca5831e193776a005d13b43b6979c8acd380b9372550 From 8971f52d1594b16f8166c2c8d312b2c0799ac1d9 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Wed, 28 Aug 2024 13:20:46 +0200 Subject: [PATCH 092/134] Rebase to version 4.16.0 Resolves: #2293678 Signed-off-by: Iker Pedrosa --- shadow-utils.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index 0786f83..3c6d110 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.16.0 -Release: 1%{?dist} +Release: 2%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -291,7 +291,7 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog -* Tue Aug 13 2024 Iker Pedrosa - 2:4.16.0-1 +* Wed Aug 28 2024 Iker Pedrosa - 2:4.16.0-2 - Rebase to version 4.16.0 (#2293678) * Tue Jul 23 2024 Kevin Fenzi - 2:4.15.1-9 From 4642a65eb4963253b1abd952aa727fcbb238df53 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Fri, 13 Sep 2024 09:24:39 +0200 Subject: [PATCH 093/134] Sort alphabetically configuration options Signed-off-by: Iker Pedrosa --- shadow-utils.spec | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index 3c6d110..85615d9 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -127,22 +127,22 @@ export LDFLAGS="-pie -Wl,-z,relro -Wl,-z,now" autoreconf %configure \ + --disable-account-tools-setuid \ + --enable-lastlog \ + --enable-logind=no \ + --enable-man \ --enable-shadowgrp \ - --enable-man \ + --enable-shared \ --with-audit \ - --with-libpam \ - --with-sha-crypt \ --with-bcrypt \ - --with-yescrypt \ + --with-group-name-max-length=32 \ + --with-libpam \ --with-selinux \ + --with-sha-crypt \ + --with-yescrypt \ --without-libbsd \ --without-libcrack \ - --without-sssd \ - --enable-shared \ - --with-group-name-max-length=32 \ - --enable-lastlog \ - --enable-logind=no \ - --disable-account-tools-setuid + --without-sssd %make_build %install From fe4f9dc5c0ad3270c280392bb574748f7c49bf81 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Fri, 13 Sep 2024 09:43:20 +0200 Subject: [PATCH 094/134] Disable nscd Signed-off-by: Iker Pedrosa --- shadow-utils.spec | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index 85615d9..7021037 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.16.0 -Release: 2%{?dist} +Release: 3%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -142,6 +142,7 @@ autoreconf --with-yescrypt \ --without-libbsd \ --without-libcrack \ + --without-nscd \ --without-sssd %make_build @@ -291,6 +292,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Fri Sep 13 2024 Iker Pedrosa - 2:4.16.0-3 +- Disable nscd + * Wed Aug 28 2024 Iker Pedrosa - 2:4.16.0-2 - Rebase to version 4.16.0 (#2293678) From cb321b1db18591f6a8acd44a1b8d5fc838ba3077 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Thu, 19 Sep 2024 16:52:21 +0200 Subject: [PATCH 095/134] useradd: fix write_full() return value Resolves: #2313559 Signed-off-by: Iker Pedrosa --- ...4.16.0-useradd-fix-write-full-return.patch | 34 +++++++++++++++++++ shadow-utils.spec | 7 +++- 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 shadow-4.16.0-useradd-fix-write-full-return.patch diff --git a/shadow-4.16.0-useradd-fix-write-full-return.patch b/shadow-4.16.0-useradd-fix-write-full-return.patch new file mode 100644 index 0000000..6f66333 --- /dev/null +++ b/shadow-4.16.0-useradd-fix-write-full-return.patch @@ -0,0 +1,34 @@ +From 8903b94c86c978e8abef623358fd3e4629c06967 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Mon, 9 Sep 2024 10:36:17 +0200 +Subject: [PATCH] useradd: fix write_full() return value + +write_full() returns -1 on error and useradd was checking another value. + +Closes: https://github.com/shadow-maint/shadow/issues/1072 +Fixes: f45498a6c286 ("libmisc/write_full.c: Improve write_full()") + +Reported-by: +Suggested-by: +Reviewed-by: Alejandro Colomar +Reviewed-by: Iker Pedrosa +--- + src/useradd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/useradd.c b/src/useradd.c +index 02c500d0..d64fd892 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -2042,7 +2042,7 @@ static void lastlog_reset (uid_t uid) + return; + } + if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid) +- || (write_full (fd, &ll, sizeof (ll)) != (ssize_t) sizeof (ll)) ++ || (write_full (fd, &ll, sizeof (ll)) != -1) + || (fsync (fd) != 0)) { + fprintf (stderr, + _("%s: failed to reset the lastlog entry of UID %lu: %s\n"), +-- +2.46.0 + diff --git a/shadow-utils.spec b/shadow-utils.spec index 7021037..0096c95 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.16.0 -Release: 3%{?dist} +Release: 4%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -26,6 +26,8 @@ Patch1: shadow-4.15.0-date-parsing.patch Patch2: shadow-4.15.1-audit-update.patch # Probably non-upstreamable Patch3: shadow-4.15.0-account-tools-setuid.patch +# https://github.com/shadow-maint/shadow/commit/8903b94c86c978e8abef623358fd3e4629c06967 +Patch4: shadow-4.16.0-useradd-fix-write-full-return.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -292,6 +294,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Thu Sep 19 2024 Iker Pedrosa - 2:4.16.0-4 +- useradd: fix write_full() return value. Resolves: #2313559 + * Fri Sep 13 2024 Iker Pedrosa - 2:4.16.0-3 - Disable nscd From cbfed0db1ea3fb6094d44d5a5642182d3fff2738 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Mon, 7 Oct 2024 10:00:36 +0200 Subject: [PATCH 096/134] useradd: fix write_full() return value Resolves: #2313559 Signed-off-by: Iker Pedrosa --- shadow-4.16.0-useradd-fix-write-full-return.patch | 2 +- shadow-utils.spec | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/shadow-4.16.0-useradd-fix-write-full-return.patch b/shadow-4.16.0-useradd-fix-write-full-return.patch index 6f66333..64e2ef8 100644 --- a/shadow-4.16.0-useradd-fix-write-full-return.patch +++ b/shadow-4.16.0-useradd-fix-write-full-return.patch @@ -25,7 +25,7 @@ index 02c500d0..d64fd892 100644 } if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid) - || (write_full (fd, &ll, sizeof (ll)) != (ssize_t) sizeof (ll)) -+ || (write_full (fd, &ll, sizeof (ll)) != -1) ++ || (write_full (fd, &ll, sizeof (ll)) == -1) || (fsync (fd) != 0)) { fprintf (stderr, _("%s: failed to reset the lastlog entry of UID %lu: %s\n"), diff --git a/shadow-utils.spec b/shadow-utils.spec index 0096c95..fa3ef81 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.16.0 -Release: 4%{?dist} +Release: 5%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -26,7 +26,7 @@ Patch1: shadow-4.15.0-date-parsing.patch Patch2: shadow-4.15.1-audit-update.patch # Probably non-upstreamable Patch3: shadow-4.15.0-account-tools-setuid.patch -# https://github.com/shadow-maint/shadow/commit/8903b94c86c978e8abef623358fd3e4629c06967 +# https://github.com/shadow-maint/shadow/commit/903593249630054ab5df327481f7386f718088cc Patch4: shadow-4.16.0-useradd-fix-write-full-return.patch ### Dependencies ### @@ -294,7 +294,7 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog -* Thu Sep 19 2024 Iker Pedrosa - 2:4.16.0-4 +* Mon Oct 7 2024 Iker Pedrosa - 2:4.16.0-5 - useradd: fix write_full() return value. Resolves: #2313559 * Fri Sep 13 2024 Iker Pedrosa - 2:4.16.0-3 From 4eba5ba13e9508f39d30c439ee494a7fe13c6cb1 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Wed, 16 Oct 2024 12:04:44 +0200 Subject: [PATCH 097/134] Rebuilt for libeconf soname bump Signed-off-by: Iker Pedrosa --- shadow-utils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index fa3ef81..633a2c8 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.16.0 -Release: 5%{?dist} +Release: 6%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -294,6 +294,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Wed Oct 16 2024 Iker Pedrosa - 2:4.16.0-6 +- Rebuilt for libeconf soname bump + * Mon Oct 7 2024 Iker Pedrosa - 2:4.16.0-5 - useradd: fix write_full() return value. Resolves: #2313559 From e7d5253e951ad6169b017318ef143d6b992c07e2 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Tue, 12 Nov 2024 09:34:52 +0100 Subject: [PATCH 098/134] SPDX license migration for subpackages Signed-off-by: Iker Pedrosa --- shadow-utils.spec | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index 633a2c8..31cd953 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.16.0 -Release: 6%{?dist} +Release: 7%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -91,7 +91,6 @@ are used for managing group accounts. ### Subpackages ### %package subid Summary: A library to manage subordinate uid and gid ranges -License: BSD and GPLv2+ %description subid Utility library that provides a way to manage subid ranges. @@ -99,7 +98,6 @@ Utility library that provides a way to manage subid ranges. %package subid-devel Summary: Development package for shadow-utils-subid -License: BSD and GPLv2+ Requires: shadow-utils-subid = %{epoch}:%{version}-%{release} %description subid-devel @@ -294,6 +292,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Tue Nov 12 2024 Iker Pedrosa - 2:4.16.0-7 +- SPDX license migration for subpackages + * Wed Oct 16 2024 Iker Pedrosa - 2:4.16.0-6 - Rebuilt for libeconf soname bump From 796cd4dc3b67f307697301441ed6c78f3bff5ed0 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Mon, 9 Dec 2024 14:36:59 +0100 Subject: [PATCH 099/134] Rebase to version 4.17.0-rc1 Signed-off-by: Iker Pedrosa --- .gitignore | 2 ++ ...4.16.0-useradd-fix-write-full-return.patch | 34 ------------------- ...> shadow-4.17.0-account-tools-setuid.patch | 12 +++---- ....patch => shadow-4.17.0-audit-update.patch | 18 +++++----- shadow-utils.spec | 22 ++++++------ sources | 4 +-- 6 files changed, 29 insertions(+), 63 deletions(-) delete mode 100644 shadow-4.16.0-useradd-fix-write-full-return.patch rename shadow-4.15.0-account-tools-setuid.patch => shadow-4.17.0-account-tools-setuid.patch (97%) rename shadow-4.15.1-audit-update.patch => shadow-4.17.0-audit-update.patch (99%) diff --git a/.gitignore b/.gitignore index 08e3c3f..62cae0c 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,5 @@ shadow-4.1.4.2.tar.bz2 /shadow-4.15.1.tar.xz.asc /shadow-4.16.0.tar.xz /shadow-4.16.0.tar.xz.asc +/shadow-4.17.0-rc1.tar.xz +/shadow-4.17.0-rc1.tar.xz.asc diff --git a/shadow-4.16.0-useradd-fix-write-full-return.patch b/shadow-4.16.0-useradd-fix-write-full-return.patch deleted file mode 100644 index 64e2ef8..0000000 --- a/shadow-4.16.0-useradd-fix-write-full-return.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 8903b94c86c978e8abef623358fd3e4629c06967 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Mon, 9 Sep 2024 10:36:17 +0200 -Subject: [PATCH] useradd: fix write_full() return value - -write_full() returns -1 on error and useradd was checking another value. - -Closes: https://github.com/shadow-maint/shadow/issues/1072 -Fixes: f45498a6c286 ("libmisc/write_full.c: Improve write_full()") - -Reported-by: -Suggested-by: -Reviewed-by: Alejandro Colomar -Reviewed-by: Iker Pedrosa ---- - src/useradd.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/useradd.c b/src/useradd.c -index 02c500d0..d64fd892 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -2042,7 +2042,7 @@ static void lastlog_reset (uid_t uid) - return; - } - if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid) -- || (write_full (fd, &ll, sizeof (ll)) != (ssize_t) sizeof (ll)) -+ || (write_full (fd, &ll, sizeof (ll)) == -1) - || (fsync (fd) != 0)) { - fprintf (stderr, - _("%s: failed to reset the lastlog entry of UID %lu: %s\n"), --- -2.46.0 - diff --git a/shadow-4.15.0-account-tools-setuid.patch b/shadow-4.17.0-account-tools-setuid.patch similarity index 97% rename from shadow-4.15.0-account-tools-setuid.patch rename to shadow-4.17.0-account-tools-setuid.patch index d162487..83453e0 100644 --- a/shadow-4.15.0-account-tools-setuid.patch +++ b/shadow-4.17.0-account-tools-setuid.patch @@ -91,7 +91,7 @@ diff -up shadow-4.15.0/src/groupmems.c.account-tools-setuid shadow-4.15.0/src/gr +#endif /* ACCT_TOOLS_SETUID */ #include - #include "alloc.h" + #include "alloc/x/xmalloc.h" @@ -430,6 +432,7 @@ static void process_flags (int argc, cha static void check_perms (void) { @@ -216,7 +216,7 @@ diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/new spent = *sp; if ( (NULL != crypt_method) @@ -547,7 +561,7 @@ static int add_passwd (struct passwd *pw - if (strcmp (pwd->pw_passwd, "x") != 0) { + if (!streq(pwd->pw_passwd, "x")) { return update_passwd (pwd, password); } -#else /* USE_PAM */ @@ -225,7 +225,7 @@ diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/new * If there is already a shadow entry, do not touch it. * If there is already a passwd entry with a password, do not @@ -558,14 +572,14 @@ static int add_passwd (struct passwd *pw - || (strcmp (pwd->pw_passwd, "x") != 0)) { + || !streq(pwd->pw_passwd, "x")) { return 0; } -#endif /* USE_PAM */ @@ -238,7 +238,7 @@ diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/new spent.sp_namp = pwd->pw_name; -#ifndef USE_PAM +#if !defined(ACCT_TOOLS_SETUID) && !defined(USE_PAM) - if ((crypt_method != NULL) && (0 == strcmp(crypt_method, "NONE"))) { + if ((crypt_method != NULL) && streq(crypt_method, "NONE")) { spent.sp_pwdp = (char *)password; } else { @@ -610,35 +624,41 @@ static int add_passwd (struct passwd *pw @@ -355,8 +355,8 @@ diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/new /* keep the list of user/password for later update by PAM */ nusers++; @@ -1211,6 +1240,7 @@ int main (int argc, char **argv) - usernames[nusers-1] = strdup (fields[0]); - passwords[nusers-1] = strdup (fields[1]); + usernames[nusers-1] = xstrdup(fields[0]); + passwords[nusers-1] = xstrdup(fields[1]); #endif /* USE_PAM */ +#endif /* ACCT_TOOLS_SETUID */ if (add_passwd (&newpw, fields[1]) != 0) { diff --git a/shadow-4.15.1-audit-update.patch b/shadow-4.17.0-audit-update.patch similarity index 99% rename from shadow-4.15.1-audit-update.patch rename to shadow-4.17.0-audit-update.patch index 0295ecc..fc05c51 100644 --- a/shadow-4.15.1-audit-update.patch +++ b/shadow-4.17.0-audit-update.patch @@ -552,14 +552,14 @@ diff -up shadow-4.15.1/src/groupadd.c.audit-update shadow-4.15.1/src/groupadd.c #endif /* SHADOWGRP */ } @@ -245,7 +254,7 @@ static void check_new_name (void) - fprintf (stderr, _("%s: '%s' is not a valid group name\n"), - Prog, group_name); + fprintf(stderr, _("%s: '%s' is not a valid group name\n"), + Prog, group_name); -- exit (E_BAD_ARG); -+ fail_exit (E_BAD_ARG); - } +- exit(E_BAD_ARG); ++ fail_exit (E_BAD_ARG); + } - /* + return; @@ -261,11 +270,11 @@ static void close_files (void) fprintf (stderr, _("%s: failure while writing changes to %s\n"), @@ -904,7 +904,7 @@ diff -up shadow-4.15.1/src/newgrp.c.audit-update shadow-4.15.1/src/newgrp.c +++ shadow-4.15.1/src/newgrp.c 2024-05-20 11:52:05.640758536 +0200 @@ -188,10 +188,10 @@ static void check_perms (const struct gr if (grp->gr_passwd[0] == '\0' || - strcmp (cpasswd, grp->gr_passwd) != 0) { + !streq(cpasswd, grp->gr_passwd)) { #ifdef WITH_AUDIT - SNPRINTF(audit_buf, "authentication new-gid=%lu", + SNPRINTF(audit_buf, "authentication new_gid=%lu", @@ -1249,7 +1249,7 @@ diff -up shadow-4.15.1/src/useradd.c.audit-update shadow-4.15.1/src/useradd.c #endif SYSLOG ((LOG_INFO, @@ -1556,7 +1515,7 @@ static void process_flags (int argc, cha - Prog, user_name); + } #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, - "adding user", @@ -1742,7 +1742,7 @@ diff -up shadow-4.15.1/src/usermod.c.audit-update shadow-4.15.1/src/usermod.c + "updating-passwd", user_newname, user_newid, 1); #endif SYSLOG ((LOG_INFO, "lock user '%s' password", user_newname)); - strcpy (buf, "!"); + xasprintf(&buf, "!%s", pw_pass); @@ -457,14 +457,14 @@ static char *new_pw_passwd (char *pw_pas #ifdef WITH_AUDIT diff --git a/shadow-utils.spec b/shadow-utils.spec index 31cd953..acce5d0 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,12 +1,12 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils -Version: 4.16.0 -Release: 7%{?dist} +Version: 4.17.0~rc1 +Release: 1%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow -Source0: https://github.com/shadow-maint/shadow/releases/download/v%{version}/shadow-%{version}.tar.xz -Source1: https://github.com/shadow-maint/shadow/releases/download/v%{version}/shadow-%{version}.tar.xz.asc +Source0: https://github.com/shadow-maint/shadow/releases/download/4.17.0-rc1/shadow-4.17.0-rc1.tar.xz +Source1: https://github.com/shadow-maint/shadow/releases/download/4.17.0-rc1/shadow-4.17.0-rc1.tar.xz.asc Source2: shadow-utils.useradd Source3: shadow-utils.login.defs Source4: shadow-bsd.txt @@ -23,11 +23,9 @@ Patch0: shadow-4.15.0-manfix.patch # Date parsing improvement - could be upstreamed Patch1: shadow-4.15.0-date-parsing.patch # Audit message changes - partially upstreamed -Patch2: shadow-4.15.1-audit-update.patch +Patch2: shadow-4.17.0-audit-update.patch # Probably non-upstreamable -Patch3: shadow-4.15.0-account-tools-setuid.patch -# https://github.com/shadow-maint/shadow/commit/903593249630054ab5df327481f7386f718088cc -Patch4: shadow-4.16.0-useradd-fix-write-full-return.patch +Patch3: shadow-4.17.0-account-tools-setuid.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -104,7 +102,7 @@ Requires: shadow-utils-subid = %{epoch}:%{version}-%{release} Development files for shadow-utils-subid. %prep -%autosetup -p 1 -S git -n shadow-%{version} +%autosetup -p 1 -S git -n shadow-4.17.0-rc1 iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -170,7 +168,6 @@ mv -v $RPM_BUILD_ROOT/usr/sbin/* $RPM_BUILD_ROOT%{_bindir}/ rm $RPM_BUILD_ROOT%{_bindir}/chfn rm $RPM_BUILD_ROOT%{_bindir}/chsh rm $RPM_BUILD_ROOT%{_bindir}/expiry -rm $RPM_BUILD_ROOT%{_bindir}/groups rm $RPM_BUILD_ROOT%{_bindir}/login rm $RPM_BUILD_ROOT%{_bindir}/su rm $RPM_BUILD_ROOT%{_bindir}/faillog @@ -182,8 +179,6 @@ rm $RPM_BUILD_ROOT%{_mandir}/man1/chsh.* rm $RPM_BUILD_ROOT%{_mandir}/*/man1/chsh.* rm $RPM_BUILD_ROOT%{_mandir}/man1/expiry.* rm $RPM_BUILD_ROOT%{_mandir}/*/man1/expiry.* -rm $RPM_BUILD_ROOT%{_mandir}/man1/groups.* -rm $RPM_BUILD_ROOT%{_mandir}/*/man1/groups.* rm $RPM_BUILD_ROOT%{_mandir}/man1/login.* rm $RPM_BUILD_ROOT%{_mandir}/*/man1/login.* rm $RPM_BUILD_ROOT%{_mandir}/man1/su.* @@ -292,6 +287,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Mon Dec 9 2024 Iker Pedrosa - 2:4.17.0~rc1-1 +- Rebase to version 4.17.0-rc1 + * Tue Nov 12 2024 Iker Pedrosa - 2:4.16.0-7 - SPDX license migration for subpackages diff --git a/sources b/sources index a2d890c..f611d3a 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (shadow-4.16.0.tar.xz) = 3986572c74cce013c733c592ef5a8113e69bba8fee74fb697fe8206bd616d29553e42822e663478db81b3e17b26b403bc69b3492dd981b87643b0e1c55035ecf -SHA512 (shadow-4.16.0.tar.xz.asc) = be98d5c157115869e23932e347b609ab342c0bc1a9d716d07ae61b497779c1a5a436534eb3ee0294687eca5831e193776a005d13b43b6979c8acd380b9372550 +SHA512 (shadow-4.17.0-rc1.tar.xz) = debf2d16fc50de8e118cde71ff85597829849548e3e608025c827ed0fa21dfd784e41b79dda87a06ae0a2f3869edf2c4a4ebd95e7b5b4cae04ea8790eae21f7a +SHA512 (shadow-4.17.0-rc1.tar.xz.asc) = 5ae16f8e17ee1d5453060233a3eefaae932e35f106661023af0aabdf370a1870d279a8f7944b7b87e8cecc836fe4fc9b68a5349b84e954fea692fab13d246f20 From be06553cde095f6cd65820caec503ffb7a43e2a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= Date: Sun, 22 Dec 2024 15:31:08 +0100 Subject: [PATCH 100/134] Remove potentially dangerous {C,LD}FLAGS shenanigans MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also fail linking if there are undefined symbols at link-time. Signed-off-by: Björn Esser --- shadow-utils.spec | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index acce5d0..a89e964 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.17.0~rc1 -Release: 1%{?dist} +Release: 2%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -16,6 +16,8 @@ Source7: passwd.pamd ### Globals ### %global includesubiddir %{_includedir}/shadow +# Fail linking if there are undefined symbols. +%global _ld_strict_symbol_defs 1 ### Patches ### # Misc manual page changes - non-upstreamable @@ -114,15 +116,6 @@ cp -a %{SOURCE6} man/login.defs.d/HOME_MODE.xml rm lib/getdate.c %build -%ifarch sparc64 -#sparc64 need big PIE -export CFLAGS="$RPM_OPT_FLAGS -fPIE" -export LDFLAGS="-pie -Wl,-z,relro -Wl,-z,now" -%else -export CFLAGS="$RPM_OPT_FLAGS -fpie" -export LDFLAGS="-pie -Wl,-z,relro -Wl,-z,now" -%endif - autoreconf %configure \ --disable-account-tools-setuid \ @@ -287,6 +280,10 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Sun Dec 22 2024 Björn Esser - 2:4.17.0~rc1-2 +- Remove potentially dangerous {C,LD}FLAGS shenanigans +- Fail linking if there are undefined symbols at link-time + * Mon Dec 9 2024 Iker Pedrosa - 2:4.17.0~rc1-1 - Rebase to version 4.17.0-rc1 From 35488fe25418e771073a691604dd0340874d59dd Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Thu, 26 Dec 2024 09:51:56 +0100 Subject: [PATCH 101/134] Rebase to version 4.17.0 Resolves: #2293678 Signed-off-by: Iker Pedrosa --- .gitignore | 2 ++ shadow-4.17.0-audit-update.patch | 4 ++-- shadow-utils.spec | 11 +++++++---- sources | 4 ++-- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 62cae0c..1585108 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,5 @@ shadow-4.1.4.2.tar.bz2 /shadow-4.16.0.tar.xz.asc /shadow-4.17.0-rc1.tar.xz /shadow-4.17.0-rc1.tar.xz.asc +/shadow-4.17.0.tar.xz +/shadow-4.17.0.tar.xz.asc diff --git a/shadow-4.17.0-audit-update.patch b/shadow-4.17.0-audit-update.patch index fc05c51..3ae6400 100644 --- a/shadow-4.17.0-audit-update.patch +++ b/shadow-4.17.0-audit-update.patch @@ -903,8 +903,8 @@ diff -up shadow-4.15.1/src/newgrp.c.audit-update shadow-4.15.1/src/newgrp.c --- shadow-4.15.1/src/newgrp.c.audit-update 2024-03-08 22:27:04.000000000 +0100 +++ shadow-4.15.1/src/newgrp.c 2024-05-20 11:52:05.640758536 +0200 @@ -188,10 +188,10 @@ static void check_perms (const struct gr - if (grp->gr_passwd[0] == '\0' || - !streq(cpasswd, grp->gr_passwd)) { + if (streq(grp->gr_passwd, "") || + !streq(grp->gr_passwd, cpasswd)) { #ifdef WITH_AUDIT - SNPRINTF(audit_buf, "authentication new-gid=%lu", + SNPRINTF(audit_buf, "authentication new_gid=%lu", diff --git a/shadow-utils.spec b/shadow-utils.spec index a89e964..7d1bb53 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,12 +1,12 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils -Version: 4.17.0~rc1 +Version: 4.17.0 Release: 2%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow -Source0: https://github.com/shadow-maint/shadow/releases/download/4.17.0-rc1/shadow-4.17.0-rc1.tar.xz -Source1: https://github.com/shadow-maint/shadow/releases/download/4.17.0-rc1/shadow-4.17.0-rc1.tar.xz.asc +Source0: https://github.com/shadow-maint/shadow/releases/download/4.17.0/shadow-4.17.0.tar.xz +Source1: https://github.com/shadow-maint/shadow/releases/download/4.17.0/shadow-4.17.0.tar.xz.asc Source2: shadow-utils.useradd Source3: shadow-utils.login.defs Source4: shadow-bsd.txt @@ -104,7 +104,7 @@ Requires: shadow-utils-subid = %{epoch}:%{version}-%{release} Development files for shadow-utils-subid. %prep -%autosetup -p 1 -S git -n shadow-4.17.0-rc1 +%autosetup -p 1 -S git -n shadow-4.17.0 iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -280,6 +280,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Thu Dec 26 2024 Iker Pedrosa - 2:4.17.0 +- Rebase to version 4.17.0. Resolves: #2293678 + * Sun Dec 22 2024 Björn Esser - 2:4.17.0~rc1-2 - Remove potentially dangerous {C,LD}FLAGS shenanigans - Fail linking if there are undefined symbols at link-time diff --git a/sources b/sources index f611d3a..4d4e5ae 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (shadow-4.17.0-rc1.tar.xz) = debf2d16fc50de8e118cde71ff85597829849548e3e608025c827ed0fa21dfd784e41b79dda87a06ae0a2f3869edf2c4a4ebd95e7b5b4cae04ea8790eae21f7a -SHA512 (shadow-4.17.0-rc1.tar.xz.asc) = 5ae16f8e17ee1d5453060233a3eefaae932e35f106661023af0aabdf370a1870d279a8f7944b7b87e8cecc836fe4fc9b68a5349b84e954fea692fab13d246f20 +SHA512 (shadow-4.17.0.tar.xz) = 36fb4a17cce43f5c97f669124c9419376ccbaa04fee8865fe590f525f3b2d14ce6422da6c52544e7d563ac8bebb29532ac9935c3ecd298718814118a932a00c7 +SHA512 (shadow-4.17.0.tar.xz.asc) = 53143dcdb637aa3c579ac5302904c10ad0e39611c0384061d8d7f06a03ae4612a5e42c6c1fd6dc8da0220d27fc429870f749ab9be508f58966f362e80a6fb43b From edb8f1a314e7da724556c551687f6b190d92e6e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 12 Jan 2025 14:41:48 +0100 Subject: [PATCH 102/134] Rebuilt for the bin-sbin merge (2nd attempt) https://fedoraproject.org/wiki/Changes/Unify_bin_and_sbin --- shadow-utils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index 7d1bb53..bf4d6af 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.17.0 -Release: 2%{?dist} +Release: 3%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -280,6 +280,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Sun Jan 12 2025 Zbigniew Jędrzejewski-Szmek - 2:4.17.0-3 +- Rebuilt for the bin-sbin merge (2nd attempt) + * Thu Dec 26 2024 Iker Pedrosa - 2:4.17.0 - Rebase to version 4.17.0. Resolves: #2293678 From 7b5d11c4b7d0d91c4d879b18facaefd7975544a5 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Sun, 19 Jan 2025 10:32:26 +0000 Subject: [PATCH 103/134] Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild --- shadow-utils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index bf4d6af..cdd4784 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.17.0 -Release: 3%{?dist} +Release: 4%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -280,6 +280,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Sun Jan 19 2025 Fedora Release Engineering - 2:4.17.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild + * Sun Jan 12 2025 Zbigniew Jędrzejewski-Szmek - 2:4.17.0-3 - Rebuilt for the bin-sbin merge (2nd attempt) From f872b43d352b5d97f9f7f5ee091b5cd7cb3ffa17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= Date: Sat, 1 Feb 2025 19:57:31 +0100 Subject: [PATCH 104/134] Add explicit BR: libxcrypt-devel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Esser --- shadow-utils.spec | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index cdd4784..42b8d1d 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.17.0 -Release: 4%{?dist} +Release: 5%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -53,6 +53,7 @@ BuildRequires: libeconf-devel BuildRequires: libselinux-devel >= 1.25.2-1 BuildRequires: libsemanage-devel BuildRequires: libtool +BuildRequires: libxcrypt-devel BuildRequires: libxslt BuildRequires: make BuildRequires: pam-devel @@ -280,6 +281,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Sat Feb 01 2025 Björn Esser - 2:4.17.0-5 +- Add explicit BR: libxcrypt-devel + * Sun Jan 19 2025 Fedora Release Engineering - 2:4.17.0-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild From 889277e842663629aa7f9fd1795bcc82201b4b39 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Thu, 20 Mar 2025 11:55:30 +0100 Subject: [PATCH 105/134] Rebase to version 4.17.4 Resolves: #2353491 Signed-off-by: Iker Pedrosa --- .gitignore | 2 + shadow-4.15.0-date-parsing.patch | 69 - shadow-4.17.0-audit-update.patch | 2053 ----------------- ...> shadow-4.17.4-account-tools-setuid.patch | 16 +- shadow-utils.spec | 26 +- sources | 4 +- 6 files changed, 26 insertions(+), 2144 deletions(-) delete mode 100644 shadow-4.15.0-date-parsing.patch delete mode 100644 shadow-4.17.0-audit-update.patch rename shadow-4.17.0-account-tools-setuid.patch => shadow-4.17.4-account-tools-setuid.patch (98%) diff --git a/.gitignore b/.gitignore index 1585108..ff11943 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,5 @@ shadow-4.1.4.2.tar.bz2 /shadow-4.17.0-rc1.tar.xz.asc /shadow-4.17.0.tar.xz /shadow-4.17.0.tar.xz.asc +/shadow-4.17.4.tar.xz +/shadow-4.17.4.tar.xz.asc diff --git a/shadow-4.15.0-date-parsing.patch b/shadow-4.15.0-date-parsing.patch deleted file mode 100644 index 272d2df..0000000 --- a/shadow-4.15.0-date-parsing.patch +++ /dev/null @@ -1,69 +0,0 @@ -Index: shadow-4.5/lib/getdate.y -=================================================================== ---- shadow-4.5.orig/lib/getdate.y -+++ shadow-4.5/lib/getdate.y -@@ -152,6 +152,7 @@ static int yyHaveDay; - static int yyHaveRel; - static int yyHaveTime; - static int yyHaveZone; -+static int yyHaveYear; - static int yyTimezone; - static int yyDay; - static int yyHour; -@@ -293,18 +294,21 @@ date : tUNUMBER '/' tUNUMBER { - yyDay = $3; - yyYear = $5; - } -+ yyHaveYear++; - } - | tUNUMBER tSNUMBER tSNUMBER { - /* ISO 8601 format. yyyy-mm-dd. */ - yyYear = $1; - yyMonth = -$2; - yyDay = -$3; -+ yyHaveYear++; - } - | tUNUMBER tMONTH tSNUMBER { - /* e.g. 17-JUN-1992. */ - yyDay = $1; - yyMonth = $2; - yyYear = -$3; -+ yyHaveYear++; - } - | tMONTH tUNUMBER { - yyMonth = $1; -@@ -314,6 +318,7 @@ date : tUNUMBER '/' tUNUMBER { - yyMonth = $1; - yyDay = $2; - yyYear = $4; -+ yyHaveYear++; - } - | tUNUMBER tMONTH { - yyMonth = $2; -@@ -323,6 +328,7 @@ date : tUNUMBER '/' tUNUMBER { - yyMonth = $2; - yyDay = $1; - yyYear = $3; -+ yyHaveYear++; - } - ; - -@@ -395,7 +401,8 @@ relunit : tUNUMBER tYEAR_UNIT { - - number : tUNUMBER - { -- if ((yyHaveTime != 0) && (yyHaveDate != 0) && (yyHaveRel == 0)) -+ if ((yyHaveTime != 0 || $1 >= 100) && !yyHaveYear -+ && (yyHaveDate != 0) && (yyHaveRel == 0)) - yyYear = $1; - else - { -@@ -802,7 +809,7 @@ yylex (void) - return LookupWord (buff); - } - if (c != '(') -- return *yyInput++; -+ return (unsigned char)*yyInput++; - Count = 0; - do - { diff --git a/shadow-4.17.0-audit-update.patch b/shadow-4.17.0-audit-update.patch deleted file mode 100644 index 3ae6400..0000000 --- a/shadow-4.17.0-audit-update.patch +++ /dev/null @@ -1,2053 +0,0 @@ -diff -up shadow-4.15.1/lib/audit_help.c.audit-update shadow-4.15.1/lib/audit_help.c ---- shadow-4.15.1/lib/audit_help.c.audit-update 2024-03-01 02:50:52.000000000 +0100 -+++ shadow-4.15.1/lib/audit_help.c 2024-05-20 11:52:05.639758532 +0200 -@@ -48,7 +48,7 @@ void audit_help_open (void) - * This function will log a message to the audit system using a predefined - * message format. Parameter usage is as follows: - * -- * type - type of message: AUDIT_USER_CHAUTHTOK for changing any account -+ * type - type of message: AUDIT_USER_MGMT for changing any account - * attributes. - * pgname - program's name - * op - operation. "adding user", "changing finger info", "deleting group" -@@ -68,6 +68,39 @@ void audit_logger (int type, MAYBE_UNUSE - } - } - -+/* -+ * This function will log a message to the audit system using a predefined -+ * message format. Parameter usage is as follows: -+ * -+ * type - type of message: AUDIT_USER_MGMT for changing any account -+ * attributes. -+ * pgname - program's name -+ * op - operation. "adding user", "changing finger info", "deleting group" -+ * name - user's account or group name. If not available use NULL. -+ * id - uid or gid that the operation is being performed on. This is used -+ * only when user is NULL. -+ * grp - group name associated with event -+ */ -+void audit_logger_with_group (int type, MAYBE_UNUSED const char *pgname, -+ const char *op, const char *name, unsigned int id, -+ const char *grp, shadow_audit_result result) -+{ -+ int len; -+ char enc_group[(GROUP_NAME_MAX_LENGTH*2)+1], buf[1024]; -+ if (audit_fd < 0) { -+ return; -+ } -+ len = strnlen(grp, sizeof(enc_group)/2); -+ if (audit_value_needs_encoding(grp, len)) { -+ snprintf(buf, sizeof(buf), "%s grp=%s", op, -+ audit_encode_value(enc_group, grp, len)); -+ } else { -+ snprintf(buf, sizeof(buf), "%s grp=\"%s\"", op, grp); -+ } -+ audit_log_acct_message (audit_fd, type, NULL, buf, name, id, -+ NULL, NULL, NULL, (int) result); -+} -+ - void audit_logger_message (const char *message, shadow_audit_result result) - { - if (audit_fd < 0) { -diff -up shadow-4.15.1/lib/cleanup_group.c.audit-update shadow-4.15.1/lib/cleanup_group.c ---- shadow-4.15.1/lib/cleanup_group.c.audit-update 2024-03-01 02:50:52.000000000 +0100 -+++ shadow-4.15.1/lib/cleanup_group.c 2024-05-20 11:52:05.639758532 +0200 -@@ -62,7 +62,7 @@ void cleanup_report_mod_group (void *cle - gr_dbname (), - info->action)); - #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_ACCT, log_get_progname(), -+ audit_logger (AUDIT_GRP_MGMT, log_get_progname(), - info->audit_msg, - info->name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); -@@ -80,7 +80,7 @@ void cleanup_report_mod_gshadow (void *c - sgr_dbname (), - info->action)); - #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_ACCT, log_get_progname(), -+ audit_logger (AUDIT_GRP_MGMT, log_get_progname(), - info->audit_msg, - info->name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); -@@ -101,7 +101,7 @@ void cleanup_report_add_group_group (voi - SYSLOG ((LOG_ERR, "failed to add group %s to %s", name, gr_dbname ())); - #ifdef WITH_AUDIT - audit_logger (AUDIT_ADD_GROUP, log_get_progname(), -- "adding group to /etc/group", -+ "adding-group", - name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); - #endif -@@ -120,8 +120,8 @@ void cleanup_report_add_group_gshadow (v - - SYSLOG ((LOG_ERR, "failed to add group %s to %s", name, sgr_dbname ())); - #ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_GROUP, log_get_progname(), -- "adding group to /etc/gshadow", -+ audit_logger (AUDIT_GRP_MGMT, log_get_progname(), -+ "adding-shadow-group", - name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); - #endif -@@ -143,8 +143,8 @@ void cleanup_report_del_group_group (voi - "failed to remove group %s from %s", - name, gr_dbname ())); - #ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_GROUP, log_get_progname(), -- "removing group from /etc/group", -+ audit_logger (AUDIT_DEL_GROUP, log_get_progname(), -+ "removing-group", - name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); - #endif -@@ -166,8 +166,8 @@ void cleanup_report_del_group_gshadow (v - "failed to remove group %s from %s", - name, sgr_dbname ())); - #ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_GROUP, log_get_progname(), -- "removing group from /etc/gshadow", -+ audit_logger (AUDIT_GRP_MGMT, log_get_progname(), -+ "removing-shadow-group", - name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); - #endif -@@ -187,7 +187,7 @@ void cleanup_unlock_group (MAYBE_UNUSED - log_get_progname(), gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); - #ifdef WITH_AUDIT -- audit_logger_message ("unlocking group file", -+ audit_logger_message ("unlocking-group", - SHADOW_AUDIT_FAILURE); - #endif - } -@@ -207,7 +207,7 @@ void cleanup_unlock_gshadow (MAYBE_UNUSE - log_get_progname(), sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - #ifdef WITH_AUDIT -- audit_logger_message ("unlocking gshadow file", -+ audit_logger_message ("unlocking-gshadow", - SHADOW_AUDIT_FAILURE); - #endif - } -diff -up shadow-4.15.1/lib/cleanup_user.c.audit-update shadow-4.15.1/lib/cleanup_user.c ---- shadow-4.15.1/lib/cleanup_user.c.audit-update 2024-03-01 02:50:52.000000000 +0100 -+++ shadow-4.15.1/lib/cleanup_user.c 2024-05-20 11:52:05.639758532 +0200 -@@ -44,7 +44,7 @@ void cleanup_report_mod_passwd (void *cl - pw_dbname (), - info->action)); - #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_ACCT, log_get_progname(), -+ audit_logger (AUDIT_USER_MGMT, log_get_progname(), - info->audit_msg, - info->name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); -@@ -65,7 +65,7 @@ void cleanup_report_add_user_passwd (voi - SYSLOG ((LOG_ERR, "failed to add user %s to %s", name, pw_dbname ())); - #ifdef WITH_AUDIT - audit_logger (AUDIT_ADD_USER, log_get_progname(), -- "adding user to /etc/passwd", -+ "adding-user", - name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); - #endif -@@ -84,8 +84,8 @@ void cleanup_report_add_user_shadow (voi - - SYSLOG ((LOG_ERR, "failed to add user %s to %s", name, spw_dbname ())); - #ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_USER, log_get_progname(), -- "adding user to /etc/shadow", -+ audit_logger (AUDIT_USER_MGMT, log_get_progname(), -+ "adding-shadow-user", - name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); - #endif -@@ -104,7 +104,7 @@ void cleanup_unlock_passwd (MAYBE_UNUSED - log_get_progname(), pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - #ifdef WITH_AUDIT -- audit_logger_message ("unlocking passwd file", -+ audit_logger_message ("unlocking-passwd", - SHADOW_AUDIT_FAILURE); - #endif - } -@@ -123,7 +123,7 @@ void cleanup_unlock_shadow (MAYBE_UNUSED - log_get_progname(), spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - #ifdef WITH_AUDIT -- audit_logger_message ("unlocking shadow file", -+ audit_logger_message ("unlocking-shadow", - SHADOW_AUDIT_FAILURE); - #endif - } -diff -up shadow-4.15.1/lib/prototypes.h.audit-update shadow-4.15.1/lib/prototypes.h ---- shadow-4.15.1/lib/prototypes.h.audit-update 2024-03-01 02:50:52.000000000 +0100 -+++ shadow-4.15.1/lib/prototypes.h 2024-05-20 11:52:05.639758532 +0200 -@@ -198,12 +198,21 @@ extern int audit_fd; - extern void audit_help_open (void); - /* Use AUDIT_NO_ID when a name is provided to audit_logger instead of an ID */ - #define AUDIT_NO_ID ((unsigned int) -1) -+#ifndef AUDIT_GRP_MGMT -+#define AUDIT_GRP_MGMT 1132 /* Group account was modified */ -+#endif -+#ifndef AUDIT_GRP_CHAUTHTOK -+#define AUDIT_GRP_CHAUTHTOK 1133 /* Group account password was changed */ -+#endif - typedef enum { - SHADOW_AUDIT_FAILURE = 0, - SHADOW_AUDIT_SUCCESS = 1} shadow_audit_result; - extern void audit_logger (int type, const char *pgname, const char *op, - const char *name, unsigned int id, - shadow_audit_result result); -+void audit_logger_with_group (int type, MAYBE_UNUSED const char *pgname, -+ const char *op, const char *name, unsigned int id, -+ const char *grp, shadow_audit_result result); - void audit_logger_message (const char *message, shadow_audit_result result); - #endif - -diff -up shadow-4.15.1/src/chage.c.audit-update shadow-4.15.1/src/chage.c ---- shadow-4.15.1/src/chage.c.audit-update 2024-03-08 22:27:04.000000000 +0100 -+++ shadow-4.15.1/src/chage.c 2024-05-20 11:52:05.639758532 +0200 -@@ -110,8 +110,8 @@ fail_exit (int code) - - #ifdef WITH_AUDIT - if (E_SUCCESS != code) { -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "change age", user_name, user_uid, 0); -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "change-age", user_name, user_uid, SHADOW_AUDIT_FAILURE); - } - #endif - -@@ -846,10 +846,7 @@ int main (int argc, char **argv) - fprintf (stderr, _("%s: Permission denied.\n"), Prog); - fail_exit (E_NOPERM); - } --#ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "display aging info", user_name, user_uid, 1); --#endif -+ /* Displaying fields is not of interest to audit */ - list_fields (); - fail_exit (E_SUCCESS); - } -@@ -868,39 +865,39 @@ int main (int argc, char **argv) - } - #ifdef WITH_AUDIT - else { -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "change all aging information", -- user_name, user_uid, 1); -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "change-all-aging-information", -+ user_name, user_uid, SHADOW_AUDIT_SUCCESS); - } - #endif - } else { - #ifdef WITH_AUDIT - if (Mflg) { -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "change max age", user_name, user_uid, 1); -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "change-max-age", user_name, user_uid, SHADOW_AUDIT_SUCCESS); - } - if (mflg) { -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "change min age", user_name, user_uid, 1); -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "change-min-age", user_name, user_uid, 1); - } - if (dflg) { -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "change last change date", -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "change-last-change-date", - user_name, user_uid, 1); - } - if (Wflg) { -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "change passwd warning", -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "change-passwd-warning", - user_name, user_uid, 1); - } - if (Iflg) { -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "change inactive days", -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "change-inactive-days", - user_name, user_uid, 1); - } - if (Eflg) { -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "change passwd expiration", -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "change-passwd-expiration", - user_name, user_uid, 1); - } - #endif -diff -up shadow-4.15.1/src/gpasswd.c.audit-update shadow-4.15.1/src/gpasswd.c ---- shadow-4.15.1/src/gpasswd.c.audit-update 2024-03-08 22:27:04.000000000 +0100 -+++ shadow-4.15.1/src/gpasswd.c 2024-05-20 11:52:05.640758536 +0200 -@@ -125,7 +125,7 @@ static void usage (int status) - (void) fputs (_(" -d, --delete USER remove USER from GROUP\n"), usageout); - (void) fputs (_(" -h, --help display this help message and exit\n"), usageout); - (void) fputs (_(" -Q, --root CHROOT_DIR directory to chroot into\n"), usageout); -- (void) fputs (_(" -r, --remove-password remove the GROUP's password\n"), usageout); -+ (void) fputs (_(" -r, --delete-password remove the GROUP's password\n"), usageout); - (void) fputs (_(" -R, --restrict restrict access to GROUP to its members\n"), usageout); - (void) fputs (_(" -M, --members USER,... set the list of members of GROUP\n"), usageout); - #ifdef SHADOWGRP -@@ -384,20 +384,14 @@ static void open_files (void) - - static void log_gpasswd_failure (const char *suffix) - { --#ifdef WITH_AUDIT -- char buf[1024]; --#endif -- - if (aflg) { - SYSLOG ((LOG_ERR, - "%s failed to add user %s to group %s%s", - myname, user, group, suffix)); - #ifdef WITH_AUDIT -- SNPRINTF(buf, "%s failed to add user %s to group %s%s", -- myname, user, group, suffix); -- audit_logger (AUDIT_USER_ACCT, Prog, -- buf, -- group, AUDIT_NO_ID, -+ audit_logger_with_group (AUDIT_USER_MGMT, Prog, -+ "add-user-to-group", -+ user, AUDIT_NO_ID, group, - SHADOW_AUDIT_FAILURE); - #endif - } else if (dflg) { -@@ -405,11 +399,9 @@ static void log_gpasswd_failure (const c - "%s failed to remove user %s from group %s%s", - myname, user, group, suffix)); - #ifdef WITH_AUDIT -- SNPRINTF(buf, "%s failed to remove user %s from group %s%s", -- myname, user, group, suffix); -- audit_logger (AUDIT_USER_ACCT, Prog, -- buf, -- group, AUDIT_NO_ID, -+ audit_logger_with_group (AUDIT_USER_MGMT, Prog, -+ "delete-user-from-group", -+ user, AUDIT_NO_ID, group, - SHADOW_AUDIT_FAILURE); - #endif - } else if (rflg) { -@@ -417,11 +409,9 @@ static void log_gpasswd_failure (const c - "%s failed to remove password of group %s%s", - myname, group, suffix)); - #ifdef WITH_AUDIT -- SNPRINTF(buf, "%s failed to remove password of group %s%s", -- myname, group, suffix); -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- buf, -- group, AUDIT_NO_ID, -+ audit_logger_with_group (AUDIT_GRP_CHAUTHTOK, Prog, -+ "delete-group-password", -+ myname, AUDIT_NO_ID, group, - SHADOW_AUDIT_FAILURE); - #endif - } else if (Rflg) { -@@ -429,11 +419,9 @@ static void log_gpasswd_failure (const c - "%s failed to restrict access to group %s%s", - myname, group, suffix)); - #ifdef WITH_AUDIT -- SNPRINTF(buf, "%s failed to restrict access to group %s%s", -- myname, group, suffix); -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- buf, -- group, AUDIT_NO_ID, -+ audit_logger_with_group (AUDIT_GRP_MGMT, Prog, -+ "restrict-group", -+ myname, AUDIT_NO_ID, group, - SHADOW_AUDIT_FAILURE); - #endif - } else if (Aflg || Mflg) { -@@ -443,11 +431,9 @@ static void log_gpasswd_failure (const c - "%s failed to set the administrators of group %s to %s%s", - myname, group, admins, suffix)); - #ifdef WITH_AUDIT -- SNPRINTF(buf, "%s failed to set the administrators of group %s to %s%s", -- myname, group, admins, suffix); -- audit_logger (AUDIT_USER_ACCT, Prog, -- buf, -- group, AUDIT_NO_ID, -+ audit_logger_with_group (AUDIT_GRP_MGMT, Prog, -+ "set-admins-of-group", -+ admins, AUDIT_NO_ID, group, - SHADOW_AUDIT_FAILURE); - #endif - } -@@ -457,11 +443,9 @@ static void log_gpasswd_failure (const c - "%s failed to set the members of group %s to %s%s", - myname, group, members, suffix)); - #ifdef WITH_AUDIT -- SNPRINTF(buf, "%s failed to set the members of group %s to %s%s", -- myname, group, members, suffix); -- audit_logger (AUDIT_USER_ACCT, Prog, -- buf, -- group, AUDIT_NO_ID, -+ audit_logger_with_group (AUDIT_USER_MGMT, Prog, -+ "add-users-to-group", -+ members, AUDIT_NO_ID, group, - SHADOW_AUDIT_FAILURE); - #endif - } -@@ -470,11 +454,9 @@ static void log_gpasswd_failure (const c - "%s failed to change password of group %s%s", - myname, group, suffix)); - #ifdef WITH_AUDIT -- SNPRINTF(buf, "%s failed to change password of group %s%s", -- myname, group, suffix); -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- buf, -- group, AUDIT_NO_ID, -+ audit_logger_with_group (AUDIT_GRP_CHAUTHTOK, Prog, -+ "change-password", -+ myname, AUDIT_NO_ID, group, - SHADOW_AUDIT_FAILURE); - #endif - } -@@ -514,11 +496,9 @@ static void log_gpasswd_success (const c - "user %s added by %s to group %s%s", - user, myname, group, suffix)); - #ifdef WITH_AUDIT -- SNPRINTF(buf, "user %s added by %s to group %s%s", -- user, myname, group, suffix); -- audit_logger (AUDIT_USER_ACCT, Prog, -- buf, -- group, AUDIT_NO_ID, -+ audit_logger_with_group (AUDIT_USER_MGMT, Prog, -+ "add-user-to-group", -+ user, AUDIT_NO_ID, group, - SHADOW_AUDIT_SUCCESS); - #endif - } else if (dflg) { -@@ -526,11 +506,9 @@ static void log_gpasswd_success (const c - "user %s removed by %s from group %s%s", - user, myname, group, suffix)); - #ifdef WITH_AUDIT -- SNPRINTF(buf, "user %s removed by %s from group %s%s", -- user, myname, group, suffix); -- audit_logger (AUDIT_USER_ACCT, Prog, -- buf, -- group, AUDIT_NO_ID, -+ audit_logger_with_group (AUDIT_USER_MGMT, Prog, -+ "delete-user-from-group", -+ user, AUDIT_NO_ID, group, - SHADOW_AUDIT_SUCCESS); - #endif - } else if (rflg) { -@@ -540,9 +518,9 @@ static void log_gpasswd_success (const c - #ifdef WITH_AUDIT - SNPRINTF(buf, "password of group %s removed by %s%s", - group, myname, suffix); -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- buf, -- group, AUDIT_NO_ID, -+ audit_logger_with_group (AUDIT_GRP_CHAUTHTOK, Prog, -+ "delete-group-password", -+ myname, AUDIT_NO_ID, group, - SHADOW_AUDIT_SUCCESS); - #endif - } else if (Rflg) { -@@ -552,9 +530,9 @@ static void log_gpasswd_success (const c - #ifdef WITH_AUDIT - SNPRINTF(buf, "access to group %s restricted by %s%s", - group, myname, suffix); -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- buf, -- group, AUDIT_NO_ID, -+ audit_logger_with_group (AUDIT_GRP_MGMT, Prog, -+ "restrict-group", -+ myname, AUDIT_NO_ID, group, - SHADOW_AUDIT_SUCCESS); - #endif - } else if (Aflg || Mflg) { -@@ -564,11 +542,9 @@ static void log_gpasswd_success (const c - "administrators of group %s set by %s to %s%s", - group, myname, admins, suffix)); - #ifdef WITH_AUDIT -- SNPRINTF(buf, "administrators of group %s set by %s to %s%s", -- group, myname, admins, suffix); -- audit_logger (AUDIT_USER_ACCT, Prog, -- buf, -- group, AUDIT_NO_ID, -+ audit_logger_with_group (AUDIT_GRP_MGMT, Prog, -+ "set-admins-of-group", -+ admins, AUDIT_NO_ID, group, - SHADOW_AUDIT_SUCCESS); - #endif - } -@@ -578,11 +554,9 @@ static void log_gpasswd_success (const c - "members of group %s set by %s to %s%s", - group, myname, members, suffix)); - #ifdef WITH_AUDIT -- SNPRINTF(buf, "members of group %s set by %s to %s%s", -- group, myname, members, suffix); -- audit_logger (AUDIT_USER_ACCT, Prog, -- buf, -- group, AUDIT_NO_ID, -+ audit_logger_with_group (AUDIT_USER_MGMT, Prog, -+ "add-users-to-group", -+ members, AUDIT_NO_ID, group, - SHADOW_AUDIT_SUCCESS); - #endif - } -@@ -591,11 +565,9 @@ static void log_gpasswd_success (const c - "password of group %s changed by %s%s", - group, myname, suffix)); - #ifdef WITH_AUDIT -- SNPRINTF(buf, "password of group %s changed by %s%s", -- group, myname, suffix); -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- buf, -- group, AUDIT_NO_ID, -+ audit_logger_with_group (AUDIT_GRP_CHAUTHTOK, Prog, -+ "change-password", -+ myname, AUDIT_NO_ID, group, - SHADOW_AUDIT_SUCCESS); - #endif - } -diff -up shadow-4.15.1/src/groupadd.c.audit-update shadow-4.15.1/src/groupadd.c ---- shadow-4.15.1/src/groupadd.c.audit-update 2024-03-08 22:27:04.000000000 +0100 -+++ shadow-4.15.1/src/groupadd.c 2024-05-20 11:52:05.640758536 +0200 -@@ -115,6 +115,15 @@ usage (int status) - exit (status); - } - -+static void fail_exit(int status) -+{ -+#ifdef WITH_AUDIT -+ audit_logger(AUDIT_ADD_GROUP, Prog, "add-group", group_name, -+ AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); -+#endif -+ exit (status); -+} -+ - /* - * new_grent - initialize the values in a group file entry - * -@@ -211,7 +220,7 @@ static void grp_update (void) - fprintf (stderr, - _("%s: failed to prepare the new %s entry '%s'\n"), - Prog, gr_dbname (), grp.gr_name); -- exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE); - } - #ifdef SHADOWGRP - /* -@@ -221,7 +230,7 @@ static void grp_update (void) - fprintf (stderr, - _("%s: failed to prepare the new %s entry '%s'\n"), - Prog, sgr_dbname (), sgrp.sg_name); -- exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE); - } - #endif /* SHADOWGRP */ - } -@@ -245,7 +254,7 @@ static void check_new_name (void) - fprintf(stderr, _("%s: '%s' is not a valid group name\n"), - Prog, group_name); - -- exit(E_BAD_ARG); -+ fail_exit (E_BAD_ARG); - } - - return; -@@ -261,11 +270,11 @@ static void close_files (void) - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, gr_dbname ()); -- exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE); - } - #ifdef WITH_AUDIT - audit_logger (AUDIT_ADD_GROUP, Prog, -- "adding group to /etc/group", -+ "add-group", - group_name, group_id, SHADOW_AUDIT_SUCCESS); - #endif - SYSLOG ((LOG_INFO, "group added to %s: name=%s, GID=%u", -@@ -282,11 +291,11 @@ static void close_files (void) - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, sgr_dbname ()); -- exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE); - } - #ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_GROUP, Prog, -- "adding group to /etc/gshadow", -+ audit_logger (AUDIT_GRP_MGMT, Prog, -+ "add-shadow-group", - group_name, group_id, SHADOW_AUDIT_SUCCESS); - #endif - SYSLOG ((LOG_INFO, "group added to %s: name=%s", -@@ -299,10 +308,6 @@ static void close_files (void) - #endif /* SHADOWGRP */ - - /* Report success at the system level */ --#ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_GROUP, Prog, -- "", group_name, group_id, SHADOW_AUDIT_SUCCESS); --#endif - SYSLOG ((LOG_INFO, "new group: name=%s, GID=%u", - group_name, (unsigned int) group_id)); - del_cleanup (cleanup_report_add_group); -@@ -320,7 +325,7 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, gr_dbname ()); -- exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE); - } - add_cleanup (cleanup_unlock_group, NULL); - -@@ -330,7 +335,7 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, sgr_dbname ()); -- exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE); - } - add_cleanup (cleanup_unlock_gshadow, NULL); - } -@@ -346,7 +351,7 @@ static void open_files (void) - if (gr_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, _("%s: cannot open %s: %s\n"), Prog, gr_dbname (), strerror(errno)); - SYSLOG ((LOG_WARN, "cannot open %s: %s", gr_dbname (), strerror(errno))); -- exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE); - } - - #ifdef SHADOWGRP -@@ -356,7 +361,7 @@ static void open_files (void) - _("%s: cannot open %s: %s\n"), - Prog, sgr_dbname (), strerror(errno)); - SYSLOG ((LOG_WARN, "cannot open %s: %s", sgr_dbname (), strerror(errno))); -- exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE); - } - } - #endif /* SHADOWGRP */ -@@ -493,7 +498,7 @@ static void check_flags (void) - fprintf (stderr, - _("%s: group '%s' already exists\n"), - Prog, group_name); -- exit (E_NAME_IN_USE); -+ fail_exit (E_NAME_IN_USE); - } - - if (gflg && (prefix_getgrgid (group_id) != NULL)) { -@@ -512,7 +517,7 @@ static void check_flags (void) - fprintf (stderr, - _("%s: GID '%lu' already exists\n"), - Prog, (unsigned long) group_id); -- exit (E_GID_IN_USE); -+ fail_exit (E_GID_IN_USE); - } - } - } -@@ -540,7 +545,7 @@ static void check_perms (void) - fprintf (stderr, - _("%s: Cannot determine your user name.\n"), - Prog); -- exit (1); -+ fail_exit (1); - } - - retval = pam_start (Prog, pampw->pw_name, &conv, &pamh); -@@ -560,7 +565,7 @@ static void check_perms (void) - if (NULL != pamh) { - (void) pam_end (pamh, retval); - } -- exit (1); -+ fail_exit (1); - } - (void) pam_end (pamh, retval); - #endif /* USE_PAM */ -@@ -591,7 +596,7 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: Cannot setup cleanup service.\n"), - Prog); -- exit (1); -+ fail_exit (1); - } - - /* -@@ -618,7 +623,7 @@ int main (int argc, char **argv) - - if (!gflg) { - if (find_new_gid (rflg, &group_id, NULL) < 0) { -- exit (E_GID_IN_USE); -+ fail_exit (E_GID_IN_USE); - } - } - -diff -up shadow-4.15.1/src/groupdel.c.audit-update shadow-4.15.1/src/groupdel.c ---- shadow-4.15.1/src/groupdel.c.audit-update 2024-03-08 22:27:04.000000000 +0100 -+++ shadow-4.15.1/src/groupdel.c 2024-05-20 11:52:05.640758536 +0200 -@@ -87,6 +87,15 @@ usage (int status) - exit (status); - } - -+static void fail_exit(int status) -+{ -+#ifdef WITH_AUDIT -+ audit_logger(AUDIT_GRP_MGMT, Prog, "delete-group", group_name, -+ AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); -+#endif -+ exit (status); -+} -+ - /* - * grp_update - update group file entries - * -@@ -113,7 +122,7 @@ static void grp_update (void) - fprintf (stderr, - _("%s: cannot remove entry '%s' from %s\n"), - Prog, group_name, gr_dbname ()); -- exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE); - } - - #ifdef SHADOWGRP -@@ -125,7 +134,7 @@ static void grp_update (void) - fprintf (stderr, - _("%s: cannot remove entry '%s' from %s\n"), - Prog, group_name, sgr_dbname ()); -- exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE); - } - } - #endif /* SHADOWGRP */ -@@ -144,12 +153,12 @@ static void close_files (void) - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, gr_dbname ()); -- exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE); - } - - #ifdef WITH_AUDIT - audit_logger (AUDIT_DEL_GROUP, Prog, -- "removing group from /etc/group", -+ "delete-group", - group_name, group_id, SHADOW_AUDIT_SUCCESS); - #endif - SYSLOG ((LOG_INFO, -@@ -168,12 +177,12 @@ static void close_files (void) - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, sgr_dbname ()); -- exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE); - } - - #ifdef WITH_AUDIT -- audit_logger (AUDIT_DEL_GROUP, Prog, -- "removing group from /etc/gshadow", -+ audit_logger (AUDIT_GRP_MGMT, Prog, -+ "delete-shadow-group", - group_name, group_id, SHADOW_AUDIT_SUCCESS); - #endif - SYSLOG ((LOG_INFO, -@@ -186,11 +195,6 @@ static void close_files (void) - } - #endif /* SHADOWGRP */ - -- /* Report success at the system level */ --#ifdef WITH_AUDIT -- audit_logger (AUDIT_DEL_GROUP, Prog, -- "", group_name, group_id, SHADOW_AUDIT_SUCCESS); --#endif - SYSLOG ((LOG_INFO, "group '%s' removed\n", group_name)); - del_cleanup (cleanup_report_del_group); - } -@@ -207,7 +211,7 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, gr_dbname ()); -- exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE); - } - add_cleanup (cleanup_unlock_group, NULL); - #ifdef SHADOWGRP -@@ -216,7 +220,7 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, sgr_dbname ()); -- exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE); - } - add_cleanup (cleanup_unlock_gshadow, NULL); - } -@@ -234,7 +238,7 @@ static void open_files (void) - _("%s: cannot open %s\n"), - Prog, gr_dbname ()); - SYSLOG ((LOG_WARN, "cannot open %s", gr_dbname ())); -- exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE); - } - #ifdef SHADOWGRP - if (is_shadow_grp) { -@@ -243,7 +247,7 @@ static void open_files (void) - _("%s: cannot open %s\n"), - Prog, sgr_dbname ()); - SYSLOG ((LOG_WARN, "cannot open %s", sgr_dbname ())); -- exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE); - } - } - #endif /* SHADOWGRP */ -@@ -284,7 +288,7 @@ static void group_busy (gid_t gid) - fprintf (stderr, - _("%s: cannot remove the primary group of user '%s'\n"), - Prog, pwd->pw_name); -- exit (E_GROUP_BUSY); -+ fail_exit (E_GROUP_BUSY); - } - - /* -@@ -368,7 +372,7 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: Cannot setup cleanup service.\n"), - Prog); -- exit (1); -+ fail_exit (1); - } - - process_flags (argc, argv); -@@ -382,7 +386,7 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: Cannot determine your user name.\n"), - Prog); -- exit (1); -+ fail_exit (1); - } - - retval = pam_start (Prog, pampw->pw_name, &conv, &pamh); -@@ -403,7 +407,7 @@ int main (int argc, char **argv) - if (NULL != pamh) { - (void) pam_end (pamh, retval); - } -- exit (1); -+ fail_exit (1); - } - (void) pam_end (pamh, retval); - #endif /* USE_PAM */ -@@ -423,7 +427,7 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: group '%s' does not exist\n"), - Prog, group_name); -- exit (E_NOTFOUND); -+ fail_exit (E_NOTFOUND); - } - - group_id = grp->gr_gid; -diff -up shadow-4.15.1/src/groupmod.c.audit-update shadow-4.15.1/src/groupmod.c ---- shadow-4.15.1/src/groupmod.c.audit-update 2024-03-08 22:27:04.000000000 +0100 -+++ shadow-4.15.1/src/groupmod.c 2024-05-20 11:52:05.640758536 +0200 -@@ -474,7 +474,7 @@ static void close_files (void) - exit (E_GRP_UPDATE); - } - #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_ACCT, Prog, -+ audit_logger (AUDIT_GRP_MGMT, Prog, - info_group.audit_msg, - group_name, AUDIT_NO_ID, - SHADOW_AUDIT_SUCCESS); -@@ -497,7 +497,14 @@ static void close_files (void) - exit (E_GRP_UPDATE); - } - #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_ACCT, Prog, -+ /* If both happened, log password change as its more important */ -+ if (pflg) -+ audit_logger (AUDIT_GRP_CHAUTHTOK, Prog, -+ info_gshadow.audit_msg, -+ group_name, AUDIT_NO_ID, -+ SHADOW_AUDIT_SUCCESS); -+ else -+ audit_logger (AUDIT_GRP_MGMT, Prog, - info_gshadow.audit_msg, - group_name, AUDIT_NO_ID, - SHADOW_AUDIT_SUCCESS); -@@ -520,7 +527,7 @@ static void close_files (void) - exit (E_GRP_UPDATE); - } - #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_ACCT, Prog, -+ audit_logger (AUDIT_GRP_MGMT, Prog, - info_passwd.audit_msg, - group_name, AUDIT_NO_ID, - SHADOW_AUDIT_SUCCESS); -@@ -535,8 +542,8 @@ static void close_files (void) - } - - #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_ACCT, Prog, -- "modifying group", -+ audit_logger (AUDIT_GRP_MGMT, Prog, -+ "modify-group", - group_name, AUDIT_NO_ID, - SHADOW_AUDIT_SUCCESS); - #endif -diff -up shadow-4.15.1/src/newgrp.c.audit-update shadow-4.15.1/src/newgrp.c ---- shadow-4.15.1/src/newgrp.c.audit-update 2024-03-08 22:27:04.000000000 +0100 -+++ shadow-4.15.1/src/newgrp.c 2024-05-20 11:52:05.640758536 +0200 -@@ -188,10 +188,10 @@ static void check_perms (const struct gr - if (streq(grp->gr_passwd, "") || - !streq(grp->gr_passwd, cpasswd)) { - #ifdef WITH_AUDIT -- SNPRINTF(audit_buf, "authentication new-gid=%lu", -+ SNPRINTF(audit_buf, "authentication new_gid=%lu", - (unsigned long) grp->gr_gid); - audit_logger (AUDIT_GRP_AUTH, Prog, -- audit_buf, NULL, getuid (), 0); -+ audit_buf, NULL, getuid (), SHADOW_AUDIT_FAILURE); - #endif - SYSLOG ((LOG_INFO, - "Invalid password for group '%s' from '%s'", -@@ -201,10 +201,10 @@ static void check_perms (const struct gr - goto failure; - } - #ifdef WITH_AUDIT -- SNPRINTF(audit_buf, "authentication new-gid=%lu", -+ SNPRINTF(audit_buf, "authentication new_gid=%lu", - (unsigned long) grp->gr_gid); - audit_logger (AUDIT_GRP_AUTH, Prog, -- audit_buf, NULL, getuid (), 1); -+ audit_buf, NULL, getuid (), SHADOW_AUDIT_SUCCESS); - #endif - } - -@@ -215,16 +215,6 @@ failure: - * harm. -- JWP - */ - closelog (); --#ifdef WITH_AUDIT -- if (groupname) { -- SNPRINTF(audit_buf, "changing new-group=%s", groupname); -- audit_logger (AUDIT_CHGRP_ID, Prog, -- audit_buf, NULL, getuid (), 0); -- } else { -- audit_logger (AUDIT_CHGRP_ID, Prog, -- "changing", NULL, getuid (), 0); -- } --#endif - exit (EXIT_FAILURE); - } - -@@ -298,13 +288,23 @@ static void syslog_sg (const char *name, - is_newgrp ? "newgrp" : "sg", strerror (errno)); - #ifdef WITH_AUDIT - if (group) { -- SNPRINTF(audit_buf, -- "changing new-group=%s", group); -+ char enc_group[(GROUP_NAME_MAX_LENGTH*2)+1]; -+ int len = strnlen(group, sizeof(enc_group)/2); -+ if (audit_value_needs_encoding(group, len)) { -+ snprintf (audit_buf, sizeof(audit_buf), -+ "changing new_group=%s", -+ audit_encode_value(enc_group, -+ group, len)); -+ } else { -+ snprintf (audit_buf, sizeof(audit_buf), -+ "changing new_group=\"%s\"", -+ group); -+ } - audit_logger (AUDIT_CHGRP_ID, Prog, -- audit_buf, NULL, getuid (), 0); -+ audit_buf, NULL, getuid (), SHADOW_AUDIT_FAILURE); - } else { - audit_logger (AUDIT_CHGRP_ID, Prog, -- "changing", NULL, getuid (), 0); -+ "changing", NULL, getuid (), SHADOW_AUDIT_FAILURE); - } - #endif - exit (EXIT_FAILURE); -@@ -440,7 +440,7 @@ int main (int argc, char **argv) - Prog); - #ifdef WITH_AUDIT - audit_logger (AUDIT_CHGRP_ID, Prog, -- "changing", NULL, getuid (), 0); -+ "changing", NULL, getuid (), SHADOW_AUDIT_FAILURE); - #endif - SYSLOG ((LOG_WARN, "Cannot determine the user name of the caller (UID %lu)", - (unsigned long) getuid ())); -@@ -556,12 +556,22 @@ int main (int argc, char **argv) - perror ("getgroups"); - #ifdef WITH_AUDIT - if (group) { -- SNPRINTF(audit_buf, "changing new-group=%s", group); -+ char enc_group[(GROUP_NAME_MAX_LENGTH*2)+1]; -+ int len = strnlen(group, sizeof(enc_group)/2); -+ if (audit_value_needs_encoding(group, len)) { -+ snprintf (audit_buf, sizeof(audit_buf), -+ "changing new_group=%s", -+ audit_encode_value(enc_group, -+ group, len)); -+ } else { -+ snprintf (audit_buf, sizeof(audit_buf), -+ "changing new_group=\"%s\"", group); -+ } - audit_logger (AUDIT_CHGRP_ID, Prog, -- audit_buf, NULL, getuid (), 0); -+ audit_buf, NULL, getuid (), SHADOW_AUDIT_FAILURE); - } else { - audit_logger (AUDIT_CHGRP_ID, Prog, -- "changing", NULL, getuid (), 0); -+ "changing", NULL, getuid (), SHADOW_AUDIT_FAILURE); - } - #endif - exit (EXIT_FAILURE); -@@ -715,9 +725,9 @@ int main (int argc, char **argv) - if (setgid (gid) != 0) { - perror ("setgid"); - #ifdef WITH_AUDIT -- SNPRINTF(audit_buf, "changing new-gid=%lu", (unsigned long) gid); -+ SNPRINTF(audit_buf, "changing new_gid=%lu", (unsigned long) gid); - audit_logger (AUDIT_CHGRP_ID, Prog, -- audit_buf, NULL, getuid (), 0); -+ audit_buf, NULL, getuid (), SHADOW_AUDIT_FAILURE); - #endif - exit (EXIT_FAILURE); - } -@@ -725,9 +735,9 @@ int main (int argc, char **argv) - if (setuid (getuid ()) != 0) { - perror ("setuid"); - #ifdef WITH_AUDIT -- SNPRINTF(audit_buf, "changing new-gid=%lu", (unsigned long) gid); -+ SNPRINTF(audit_buf, "changing new_gid=%lu", (unsigned long) gid); - audit_logger (AUDIT_CHGRP_ID, Prog, -- audit_buf, NULL, getuid (), 0); -+ audit_buf, NULL, getuid (), SHADOW_AUDIT_FAILURE); - #endif - exit (EXIT_FAILURE); - } -@@ -740,9 +750,9 @@ int main (int argc, char **argv) - closelog (); - execl (SHELL, "sh", "-c", command, (char *) NULL); - #ifdef WITH_AUDIT -- SNPRINTF(audit_buf, "changing new-gid=%lu", (unsigned long) gid); -+ SNPRINTF(audit_buf, "changing new_gid=%lu", (unsigned long) gid); - audit_logger (AUDIT_CHGRP_ID, Prog, -- audit_buf, NULL, getuid (), 0); -+ audit_buf, NULL, getuid (), SHADOW_AUDIT_FAILURE); - #endif - perror (SHELL); - exit ((errno == ENOENT) ? E_CMD_NOTFOUND : E_CMD_NOEXEC); -@@ -806,9 +816,9 @@ int main (int argc, char **argv) - } - - #ifdef WITH_AUDIT -- SNPRINTF(audit_buf, "changing new-gid=%lu", (unsigned long) gid); -+ SNPRINTF(audit_buf, "changing new_gid=%lu", (unsigned long) gid); - audit_logger (AUDIT_CHGRP_ID, Prog, -- audit_buf, NULL, getuid (), 1); -+ audit_buf, NULL, getuid (), SHADOW_AUDIT_SUCCESS); - #endif - /* - * Exec the login shell and go away. We are trying to get back to -@@ -832,12 +842,22 @@ int main (int argc, char **argv) - closelog (); - #ifdef WITH_AUDIT - if (NULL != group) { -- SNPRINTF(audit_buf, "changing new-group=%s", group); -+ char enc_group[(GROUP_NAME_MAX_LENGTH*2)+1]; -+ int len = strnlen(group, sizeof(enc_group)/2); -+ if (audit_value_needs_encoding(group, len)) { -+ snprintf (audit_buf, sizeof(audit_buf), -+ "changing new_group=%s", -+ audit_encode_value(enc_group, -+ group, len)); -+ } else { -+ snprintf (audit_buf, sizeof(audit_buf), -+ "changing new_group=\"%s\"", group); -+ } - audit_logger (AUDIT_CHGRP_ID, Prog, -- audit_buf, NULL, getuid (), 0); -+ audit_buf, NULL, getuid (), SHADOW_AUDIT_FAILURE); - } else { - audit_logger (AUDIT_CHGRP_ID, Prog, -- "changing", NULL, getuid (), 0); -+ "changing", NULL, getuid (), SHADOW_AUDIT_FAILURE); - } - #endif - exit (EXIT_FAILURE); -diff -up shadow-4.15.1/src/useradd.c.audit-update shadow-4.15.1/src/useradd.c ---- shadow-4.15.1/src/useradd.c.audit-update 2024-05-20 11:52:05.635758519 +0200 -+++ shadow-4.15.1/src/useradd.c 2024-05-20 11:52:05.640758536 +0200 -@@ -245,6 +245,8 @@ static FILE *fmkstemp(char *template); - */ - static void fail_exit (int code) - { -+ int type; -+ - if (home_added && rmdir(prefix_user_home) != 0) { - fprintf(stderr, - _("%s: %s was created, but could not be removed\n"), -@@ -255,38 +257,22 @@ static void fail_exit (int code) - if (spw_locked && spw_unlock() == 0) { - fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname()); - SYSLOG((LOG_ERR, "failed to unlock %s", spw_dbname())); --#ifdef WITH_AUDIT -- audit_logger(AUDIT_ADD_USER, Prog, "unlocking shadow file", -- user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); --#endif - /* continue */ - } - if (pw_locked && pw_unlock() == 0) { - fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname()); - SYSLOG((LOG_ERR, "failed to unlock %s", pw_dbname())); --#ifdef WITH_AUDIT -- audit_logger(AUDIT_ADD_USER, Prog, "unlocking passwd file", -- user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); --#endif - /* continue */ - } - if (gr_locked && gr_unlock() == 0) { - fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname()); - SYSLOG((LOG_ERR, "failed to unlock %s", gr_dbname())); --#ifdef WITH_AUDIT -- audit_logger(AUDIT_ADD_USER, Prog, "unlocking group file", -- user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); --#endif - /* continue */ - } - #ifdef SHADOWGRP - if (sgr_locked && sgr_unlock() == 0) { - fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname()); - SYSLOG((LOG_ERR, "failed to unlock %s", sgr_dbname())); --# ifdef WITH_AUDIT -- audit_logger(AUDIT_ADD_USER, Prog, "unlocking gshadow file", -- user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); --# endif - /* continue */ - } - #endif -@@ -294,27 +280,23 @@ static void fail_exit (int code) - if (sub_uid_locked && sub_uid_unlock() == 0) { - fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname()); - SYSLOG((LOG_ERR, "failed to unlock %s", sub_uid_dbname())); --# ifdef WITH_AUDIT -- audit_logger(AUDIT_ADD_USER, Prog, -- "unlocking subordinate user file", -- user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); --# endif - /* continue */ - } - if (sub_gid_locked && sub_gid_unlock() == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname())); --# ifdef WITH_AUDIT -- audit_logger(AUDIT_ADD_USER, Prog, -- "unlocking subordinate group file", -- user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); --# endif - /* continue */ - } - #endif /* ENABLE_SUBIDS */ - - #ifdef WITH_AUDIT -- audit_logger(AUDIT_ADD_USER, Prog, "adding user", -+ if (code == E_PW_UPDATE || code >= E_GRP_UPDATE) -+ type = AUDIT_USER_MGMT; -+ else -+ type = AUDIT_ADD_USER; -+ -+ audit_logger (type, Prog, -+ "add-user", - user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); - #endif - SYSLOG((LOG_INFO, "failed adding user '%s', exit code: %d", user_name, code)); -@@ -727,7 +709,7 @@ static int set_defaults (void) - } - #ifdef WITH_AUDIT - audit_logger (AUDIT_USYS_CONFIG, Prog, -- "changing useradd defaults", -+ "changing-useradd-defaults", - NULL, AUDIT_NO_ID, - SHADOW_AUDIT_SUCCESS); - #endif -@@ -1056,12 +1038,6 @@ static void grp_update (void) - _("%s: Out of memory. Cannot update %s.\n"), - Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", gr_dbname (), user_name)); --#ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_USER, Prog, -- "adding user to group", -- user_name, AUDIT_NO_ID, -- SHADOW_AUDIT_FAILURE); --#endif - fail_exit (E_GRP_UPDATE); /* XXX */ - } - -@@ -1075,18 +1051,12 @@ static void grp_update (void) - _("%s: failed to prepare the new %s entry '%s'\n"), - Prog, gr_dbname (), ngrp->gr_name); - SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", gr_dbname (), user_name)); --#ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_USER, Prog, -- "adding user to group", -- user_name, AUDIT_NO_ID, -- SHADOW_AUDIT_FAILURE); --#endif - fail_exit (E_GRP_UPDATE); - } - #ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_USER, Prog, -- "adding user to group", -- user_name, AUDIT_NO_ID, -+ audit_logger_with_group (AUDIT_USER_MGMT, Prog, -+ "add-user-to-group", -+ user_name, AUDIT_NO_ID, ngrp->gr_name, - SHADOW_AUDIT_SUCCESS); - #endif - SYSLOG ((LOG_INFO, -@@ -1131,12 +1101,6 @@ static void grp_update (void) - _("%s: Out of memory. Cannot update %s.\n"), - Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", sgr_dbname (), user_name)); --#ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_USER, Prog, -- "adding user to shadow group", -- user_name, AUDIT_NO_ID, -- SHADOW_AUDIT_FAILURE); --#endif - fail_exit (E_GRP_UPDATE); /* XXX */ - } - -@@ -1150,18 +1114,13 @@ static void grp_update (void) - _("%s: failed to prepare the new %s entry '%s'\n"), - Prog, sgr_dbname (), nsgrp->sg_name); - SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", sgr_dbname (), user_name)); --#ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_USER, Prog, -- "adding user to shadow group", -- user_name, AUDIT_NO_ID, -- SHADOW_AUDIT_FAILURE); --#endif -+ - fail_exit (E_GRP_UPDATE); - } - #ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_USER, Prog, -- "adding user to shadow group", -- user_name, AUDIT_NO_ID, -+ audit_logger_with_group (AUDIT_USER_MGMT, Prog, -+ "add-to-shadow-group", -+ user_name, AUDIT_NO_ID, nsgrp->sg_name, - SHADOW_AUDIT_SUCCESS); - #endif - SYSLOG ((LOG_INFO, -@@ -1556,7 +1515,7 @@ static void process_flags (int argc, cha - } - #ifdef WITH_AUDIT - audit_logger (AUDIT_ADD_USER, Prog, -- "adding user", -+ "add-user", - user_name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); - #endif -@@ -1656,7 +1615,7 @@ static void close_files (void) - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - #ifdef WITH_AUDIT - audit_logger (AUDIT_ADD_USER, Prog, -- "unlocking shadow file", -+ "unlocking-shadow-file", - user_name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); - #endif -@@ -1669,7 +1628,7 @@ static void close_files (void) - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - #ifdef WITH_AUDIT - audit_logger (AUDIT_ADD_USER, Prog, -- "unlocking passwd file", -+ "unlocking-passwd-file", - user_name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); - #endif -@@ -1686,7 +1645,7 @@ static void close_files (void) - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); - #ifdef WITH_AUDIT - audit_logger (AUDIT_ADD_USER, Prog, -- "unlocking subordinate user file", -+ "unlocking-subordinate-user-file", - user_name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); - #endif -@@ -1700,7 +1659,7 @@ static void close_files (void) - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); - #ifdef WITH_AUDIT - audit_logger (AUDIT_ADD_USER, Prog, -- "unlocking subordinate group file", -+ "unlocking-subordinate-group-file", - user_name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); - #endif -@@ -1963,7 +1922,7 @@ static void grp_add (void) - Prog, gr_dbname (), grp.gr_name); - #ifdef WITH_AUDIT - audit_logger (AUDIT_ADD_GROUP, Prog, -- "adding group", -+ "add-group", - grp.gr_name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); - #endif -@@ -1979,7 +1938,7 @@ static void grp_add (void) - Prog, sgr_dbname (), sgrp.sg_name); - #ifdef WITH_AUDIT - audit_logger (AUDIT_ADD_GROUP, Prog, -- "adding group", -+ "add-group", - grp.gr_name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); - #endif -@@ -1989,7 +1948,7 @@ static void grp_add (void) - SYSLOG ((LOG_INFO, "new group: name=%s, GID=%u", user_name, user_gid)); - #ifdef WITH_AUDIT - audit_logger (AUDIT_ADD_GROUP, Prog, -- "adding group", -+ "add-group", - grp.gr_name, AUDIT_NO_ID, - SHADOW_AUDIT_SUCCESS); - #endif -@@ -2191,11 +2150,6 @@ static void usr_update (unsigned long su - fprintf (stderr, - _("%s: failed to prepare the new %s entry '%s'\n"), - Prog, spw_dbname (), spent.sp_namp); --#ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_USER, Prog, -- "adding shadow password", -- user_name, user_id, SHADOW_AUDIT_FAILURE); --#endif - fail_exit (E_PW_UPDATE); - } - #ifdef ENABLE_SUBIDS -@@ -2222,7 +2176,7 @@ static void usr_update (unsigned long su - * and we can use the real ID thereafter. - */ - audit_logger (AUDIT_ADD_USER, Prog, -- "adding user", -+ "add-user", - user_name, AUDIT_NO_ID, - SHADOW_AUDIT_SUCCESS); - #endif -@@ -2317,10 +2271,6 @@ static void create_home (void) - if (mkdir(path, 0) != 0) { - fprintf(stderr, _("%s: cannot create directory %s\n"), - Prog, path); --#ifdef WITH_AUDIT -- audit_logger(AUDIT_ADD_USER, Prog, "adding home directory", -- user_name, user_id, SHADOW_AUDIT_FAILURE); --#endif - fail_exit(E_HOMEDIR); - } - if (chown(path, 0, 0) < 0) { -@@ -2345,7 +2295,7 @@ static void create_home (void) - } - home_added = true; - #ifdef WITH_AUDIT -- audit_logger(AUDIT_ADD_USER, Prog, "adding home directory", -+ audit_logger(AUDIT_USER_MGMT, Prog, "add-home-dir", - user_name, user_id, SHADOW_AUDIT_SUCCESS); - #endif - #ifdef WITH_SELINUX -@@ -2586,12 +2536,6 @@ int main (int argc, char **argv) - */ - if (prefix_getpwnam (user_name) != NULL) { /* local, no need for xgetpwnam */ - fprintf (stderr, _("%s: user '%s' already exists\n"), Prog, user_name); --#ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_USER, Prog, -- "adding user", -- user_name, AUDIT_NO_ID, -- SHADOW_AUDIT_FAILURE); --#endif - fail_exit (E_NAME_IN_USE); - } - -@@ -2607,12 +2551,6 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: group %s exists - if you want to add this user to that group, use -g.\n"), - Prog, user_name); --#ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_USER, Prog, -- "adding group", -- user_name, AUDIT_NO_ID, -- SHADOW_AUDIT_FAILURE); --#endif - fail_exit (E_NAME_IN_USE); - } - } -@@ -2642,12 +2580,6 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: UID %lu is not unique\n"), - Prog, (unsigned long) user_id); --#ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_USER, Prog, -- "adding user", -- user_name, user_id, -- SHADOW_AUDIT_FAILURE); --#endif - fail_exit (E_UID_IN_USE); - } - } -@@ -2722,9 +2654,9 @@ int main (int argc, char **argv) - _("%s: warning: the user name %s to %s SELinux user mapping failed.\n"), - Prog, user_name, user_selinux); - #ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_USER, Prog, -- "adding SELinux user mapping", -- user_name, user_id, 0); -+ audit_logger (AUDIT_ROLE_ASSIGN, Prog, -+ "add-selinux-user-mapping", -+ user_name, user_id, SHADOW_AUDIT_FAILURE); - #endif /* WITH_AUDIT */ - fail_exit (E_SE_UPDATE); - } -diff -up shadow-4.15.1/src/userdel.c.audit-update shadow-4.15.1/src/userdel.c ---- shadow-4.15.1/src/userdel.c.audit-update 2024-03-08 22:27:04.000000000 +0100 -+++ shadow-4.15.1/src/userdel.c 2024-05-20 11:52:05.641758539 +0200 -@@ -206,9 +206,9 @@ static void update_groups (void) - * Update the DBM group file with the new entry as well. - */ - #ifdef WITH_AUDIT -- audit_logger (AUDIT_DEL_USER, Prog, -- "deleting user from group", -- user_name, user_id, SHADOW_AUDIT_SUCCESS); -+ audit_logger_with_group (AUDIT_USER_MGMT, Prog, -+ "deleting-user-from-group", -+ user_name, user_id, ngrp->gr_name, SHADOW_AUDIT_SUCCESS); - #endif /* WITH_AUDIT */ - SYSLOG ((LOG_INFO, "delete '%s' from group '%s'\n", - user_name, ngrp->gr_name)); -@@ -267,9 +267,9 @@ static void update_groups (void) - exit (E_GRP_UPDATE); - } - #ifdef WITH_AUDIT -- audit_logger (AUDIT_DEL_USER, Prog, -- "deleting user from shadow group", -- user_name, user_id, SHADOW_AUDIT_SUCCESS); -+ audit_logger_with_group (AUDIT_USER_MGMT, Prog, -+ "deleting-user-from-shadow-group", -+ user_name, user_id, nsgrp->sg_name, SHADOW_AUDIT_SUCCESS); - #endif /* WITH_AUDIT */ - SYSLOG ((LOG_INFO, "delete '%s' from shadow group '%s'\n", - user_name, nsgrp->sg_name)); -@@ -345,9 +345,9 @@ static void remove_usergroup (void) - } - - #ifdef WITH_AUDIT -- audit_logger (AUDIT_DEL_GROUP, Prog, -- "deleting group", -- user_name, AUDIT_NO_ID, -+ audit_logger_with_group (AUDIT_DEL_GROUP, Prog, -+ "delete-group", -+ user_name, AUDIT_NO_ID, user_name, - SHADOW_AUDIT_SUCCESS); - #endif /* WITH_AUDIT */ - SYSLOG ((LOG_INFO, -@@ -363,9 +363,9 @@ static void remove_usergroup (void) - fail_exit (E_GRP_UPDATE); - } - #ifdef WITH_AUDIT -- audit_logger (AUDIT_DEL_GROUP, Prog, -- "deleting shadow group", -- user_name, AUDIT_NO_ID, -+ audit_logger_with_group (AUDIT_GRP_MGMT, Prog, -+ "delete-shadow-group", -+ user_name, AUDIT_NO_ID, user_name, - SHADOW_AUDIT_SUCCESS); - #endif /* WITH_AUDIT */ - SYSLOG ((LOG_INFO, -@@ -527,7 +527,7 @@ static void fail_exit (int code) - - #ifdef WITH_AUDIT - audit_logger (AUDIT_DEL_USER, Prog, -- "deleting user", -+ "delete-user", - user_name, user_id, SHADOW_AUDIT_FAILURE); - #endif /* WITH_AUDIT */ - -@@ -546,22 +546,12 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, pw_dbname ()); --#ifdef WITH_AUDIT -- audit_logger (AUDIT_DEL_USER, Prog, -- "locking password file", -- user_name, user_id, SHADOW_AUDIT_FAILURE); --#endif /* WITH_AUDIT */ - fail_exit (E_PW_UPDATE); - } - pw_locked = true; - if (pw_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, - _("%s: cannot open %s\n"), Prog, pw_dbname ()); --#ifdef WITH_AUDIT -- audit_logger (AUDIT_DEL_USER, Prog, -- "opening password file", -- user_name, user_id, SHADOW_AUDIT_FAILURE); --#endif /* WITH_AUDIT */ - fail_exit (E_PW_UPDATE); - } - if (is_shadow_pwd) { -@@ -569,11 +559,6 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, spw_dbname ()); --#ifdef WITH_AUDIT -- audit_logger (AUDIT_DEL_USER, Prog, -- "locking shadow password file", -- user_name, user_id, SHADOW_AUDIT_FAILURE); --#endif /* WITH_AUDIT */ - fail_exit (E_PW_UPDATE); - } - spw_locked = true; -@@ -581,11 +566,6 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot open %s\n"), - Prog, spw_dbname ()); --#ifdef WITH_AUDIT -- audit_logger (AUDIT_DEL_USER, Prog, -- "opening shadow password file", -- user_name, user_id, SHADOW_AUDIT_FAILURE); --#endif /* WITH_AUDIT */ - fail_exit (E_PW_UPDATE); - } - } -@@ -593,21 +573,11 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, gr_dbname ()); --#ifdef WITH_AUDIT -- audit_logger (AUDIT_DEL_USER, Prog, -- "locking group file", -- user_name, user_id, SHADOW_AUDIT_FAILURE); --#endif /* WITH_AUDIT */ - fail_exit (E_GRP_UPDATE); - } - gr_locked = true; - if (gr_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ()); --#ifdef WITH_AUDIT -- audit_logger (AUDIT_DEL_USER, Prog, -- "opening group file", -- user_name, user_id, SHADOW_AUDIT_FAILURE); --#endif /* WITH_AUDIT */ - fail_exit (E_GRP_UPDATE); - } - #ifdef SHADOWGRP -@@ -616,22 +586,12 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, sgr_dbname ()); --#ifdef WITH_AUDIT -- audit_logger (AUDIT_DEL_USER, Prog, -- "locking shadow group file", -- user_name, user_id, SHADOW_AUDIT_FAILURE); --#endif /* WITH_AUDIT */ - fail_exit (E_GRP_UPDATE); - } - sgr_locked= true; - if (sgr_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, _("%s: cannot open %s\n"), - Prog, sgr_dbname ()); --#ifdef WITH_AUDIT -- audit_logger (AUDIT_DEL_USER, Prog, -- "opening shadow group file", -- user_name, user_id, SHADOW_AUDIT_FAILURE); --#endif /* WITH_AUDIT */ - fail_exit (E_GRP_UPDATE); - } - } -@@ -642,22 +602,12 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, sub_uid_dbname ()); --#ifdef WITH_AUDIT -- audit_logger (AUDIT_DEL_USER, Prog, -- "locking subordinate user file", -- user_name, user_id, SHADOW_AUDIT_FAILURE); --#endif /* WITH_AUDIT */ - fail_exit (E_SUB_UID_UPDATE); - } - sub_uid_locked = true; - if (sub_uid_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, - _("%s: cannot open %s\n"), Prog, sub_uid_dbname ()); --#ifdef WITH_AUDIT -- audit_logger (AUDIT_DEL_USER, Prog, -- "opening subordinate user file", -- user_name, user_id, SHADOW_AUDIT_FAILURE); --#endif /* WITH_AUDIT */ - fail_exit (E_SUB_UID_UPDATE); - } - } -@@ -666,22 +616,12 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, sub_gid_dbname ()); --#ifdef WITH_AUDIT -- audit_logger (AUDIT_DEL_USER, Prog, -- "locking subordinate group file", -- user_name, user_id, SHADOW_AUDIT_FAILURE); --#endif /* WITH_AUDIT */ - fail_exit (E_SUB_GID_UPDATE); - } - sub_gid_locked = true; - if (sub_gid_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, - _("%s: cannot open %s\n"), Prog, sub_gid_dbname ()); --#ifdef WITH_AUDIT -- audit_logger (AUDIT_DEL_USER, Prog, -- "opening subordinate group file", -- user_name, user_id, SHADOW_AUDIT_FAILURE); --#endif /* WITH_AUDIT */ - fail_exit (E_SUB_GID_UPDATE); - } - } -@@ -726,7 +666,7 @@ static void update_user (void) - #endif /* ENABLE_SUBIDS */ - #ifdef WITH_AUDIT - audit_logger (AUDIT_DEL_USER, Prog, -- "deleting user entries", -+ "delete-user", - user_name, user_id, SHADOW_AUDIT_SUCCESS); - #endif /* WITH_AUDIT */ - SYSLOG ((LOG_INFO, "delete user '%s'\n", user_name)); -@@ -824,7 +764,7 @@ static int remove_mailbox (void) - SYSLOG ((LOG_ERR, "Cannot remove %s: %s", mailfile, strerror (errno))); - #ifdef WITH_AUDIT - audit_logger (AUDIT_DEL_USER, Prog, -- "deleting mail file", -+ "delete-mail-file", - user_name, user_id, SHADOW_AUDIT_FAILURE); - #endif /* WITH_AUDIT */ - free(mailfile); -@@ -840,7 +780,7 @@ static int remove_mailbox (void) - SYSLOG ((LOG_ERR, "Cannot remove %s: %s", mailfile, strerror (errno))); - #ifdef WITH_AUDIT - audit_logger (AUDIT_DEL_USER, Prog, -- "deleting mail file", -+ "delete-mail-file", - user_name, user_id, SHADOW_AUDIT_FAILURE); - #endif /* WITH_AUDIT */ - errors = 1; -@@ -849,8 +789,8 @@ static int remove_mailbox (void) - #ifdef WITH_AUDIT - else - { -- audit_logger (AUDIT_DEL_USER, Prog, -- "deleting mail file", -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "delete-mail-file", - user_name, user_id, SHADOW_AUDIT_SUCCESS); - } - #endif /* WITH_AUDIT */ -@@ -867,7 +807,7 @@ static int remove_mailbox (void) - mailfile, strerror (errno))); - #ifdef WITH_AUDIT - audit_logger (AUDIT_DEL_USER, Prog, -- "deleting mail file", -+ "delete-mail-file", - user_name, user_id, SHADOW_AUDIT_FAILURE); - #endif /* WITH_AUDIT */ - free(mailfile); -@@ -883,7 +823,7 @@ static int remove_mailbox (void) - SYSLOG ((LOG_ERR, "Cannot remove %s: %s", mailfile, strerror (errno))); - #ifdef WITH_AUDIT - audit_logger (AUDIT_DEL_USER, Prog, -- "deleting mail file", -+ "delete-mail-file", - user_name, user_id, SHADOW_AUDIT_FAILURE); - #endif /* WITH_AUDIT */ - errors = 1; -@@ -892,8 +832,8 @@ static int remove_mailbox (void) - #ifdef WITH_AUDIT - else - { -- audit_logger (AUDIT_DEL_USER, Prog, -- "deleting mail file", -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "delete-mail-file", - user_name, user_id, SHADOW_AUDIT_SUCCESS); - } - #endif /* WITH_AUDIT */ -@@ -1104,7 +1044,7 @@ int main (int argc, char **argv) - Prog, user_name); - #ifdef WITH_AUDIT - audit_logger (AUDIT_DEL_USER, Prog, -- "deleting user not found", -+ "deleting-user-not-found", - user_name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); - #endif /* WITH_AUDIT */ -@@ -1154,7 +1094,7 @@ int main (int argc, char **argv) - if (!fflg) { - #ifdef WITH_AUDIT - audit_logger (AUDIT_DEL_USER, Prog, -- "deleting user logged in", -+ "deleting-user-logged-in", - user_name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); - #endif /* WITH_AUDIT */ -@@ -1248,8 +1188,8 @@ int main (int argc, char **argv) - #ifdef WITH_AUDIT - else - { -- audit_logger (AUDIT_DEL_USER, Prog, -- "deleting home directory", -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "deleting-home-directory", - user_name, user_id, SHADOW_AUDIT_SUCCESS); - } - #endif /* WITH_AUDIT */ -@@ -1257,7 +1197,7 @@ int main (int argc, char **argv) - #ifdef WITH_AUDIT - if (0 != errors) { - audit_logger (AUDIT_DEL_USER, Prog, -- "deleting home directory", -+ "deleting-home-directory", - user_name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); - } -@@ -1270,8 +1210,8 @@ int main (int argc, char **argv) - _("%s: warning: the user name %s to SELinux user mapping removal failed.\n"), - Prog, user_name); - #ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_USER, Prog, -- "removing SELinux user mapping", -+ audit_logger (AUDIT_ROLE_REMOVE, Prog, -+ "delete-selinux-user-mapping", - user_name, user_id, SHADOW_AUDIT_FAILURE); - #endif /* WITH_AUDIT */ - fail_exit (E_SE_UPDATE); -diff -up shadow-4.15.1/src/usermod.c.audit-update shadow-4.15.1/src/usermod.c ---- shadow-4.15.1/src/usermod.c.audit-update 2024-05-20 11:52:05.638758529 +0200 -+++ shadow-4.15.1/src/usermod.c 2024-05-20 11:56:51.962509443 +0200 -@@ -440,7 +440,7 @@ static char *new_pw_passwd (char *pw_pas - - #ifdef WITH_AUDIT - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "updating passwd", user_newname, user_newid, 0); -+ "updating-passwd", user_newname, user_newid, 1); - #endif - SYSLOG ((LOG_INFO, "lock user '%s' password", user_newname)); - xasprintf(&buf, "!%s", pw_pass); -@@ -457,14 +457,14 @@ static char *new_pw_passwd (char *pw_pas - - #ifdef WITH_AUDIT - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "updating password", user_newname, user_newid, 0); -+ "updating-password", user_newname, user_newid, 1); - #endif - SYSLOG ((LOG_INFO, "unlock user '%s' password", user_newname)); - memmove(pw_pass, pw_pass + 1, strlen(pw_pass)); - } else if (pflg) { - #ifdef WITH_AUDIT - audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "changing password", user_newname, user_newid, 1); -+ "updating-password", user_newname, user_newid, 1); - #endif - SYSLOG ((LOG_INFO, "change user '%s' password", user_newname)); - pw_pass = xstrdup (user_pass); -@@ -492,8 +492,8 @@ static void new_pwent (struct passwd *pw - fail_exit (E_NAME_IN_USE); - } - #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "changing name", user_newname, user_newid, 1); -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "changing-name", user_newname, user_newid, 1); - #endif - SYSLOG ((LOG_INFO, - "change user name '%s' to '%s'", -@@ -512,8 +512,8 @@ static void new_pwent (struct passwd *pw - - if (uflg) { - #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "changing uid", user_newname, user_newid, 1); -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "changing-uid", user_newname, user_newid, 1); - #endif - SYSLOG ((LOG_INFO, - "change user '%s' UID from '%d' to '%d'", -@@ -522,8 +522,8 @@ static void new_pwent (struct passwd *pw - } - if (gflg) { - #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "changing primary group", -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "changing-primary-group", - user_newname, user_newid, 1); - #endif - SYSLOG ((LOG_INFO, -@@ -533,16 +533,16 @@ static void new_pwent (struct passwd *pw - } - if (cflg) { - #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "changing comment", user_newname, user_newid, 1); -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "changing-comment", user_newname, user_newid, 1); - #endif - pwent->pw_gecos = user_newcomment; - } - - if (dflg) { - #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "changing home directory", -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "changing-home-dir", - user_newname, user_newid, 1); - #endif - SYSLOG ((LOG_INFO, -@@ -558,8 +558,8 @@ static void new_pwent (struct passwd *pw - } - if (sflg) { - #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "changing user shell", -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "changing-shell", - user_newname, user_newid, 1); - #endif - SYSLOG ((LOG_INFO, -@@ -589,8 +589,8 @@ static void new_spent (struct spwd *spen - - if (fflg) { - #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "changing inactive days", -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "changing-inactive-days", - user_newname, user_newid, 1); - #endif - SYSLOG ((LOG_INFO, -@@ -604,8 +604,8 @@ static void new_spent (struct spwd *spen - DAY_TO_STR(new_exp, user_newexpire); - DAY_TO_STR(old_exp, user_expire); - #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "changing expiration date", -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "changing-expiration-date", - user_newname, user_newid, 1); - #endif - SYSLOG ((LOG_INFO, -@@ -690,9 +690,9 @@ fail_exit (int code) - #endif /* ENABLE_SUBIDS */ - - #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "modifying account", -- user_name, AUDIT_NO_ID, 0); -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "modify-account", -+ user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); - #endif - exit (code); - } -@@ -762,9 +762,12 @@ update_group(const struct group *grp) - user_newname); - changed = true; - #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "changing group member", -- user_newname, AUDIT_NO_ID, 1); -+ audit_logger_with_group ( -+ AUDIT_USER_MGMT, Prog, -+ "update-member-in-group", -+ user_newname, AUDIT_NO_ID, -+ ngrp->gr_name, -+ SHADOW_AUDIT_SUCCESS); - #endif - SYSLOG ((LOG_INFO, - "change '%s' to '%s' in group '%s'", -@@ -778,9 +781,11 @@ update_group(const struct group *grp) - ngrp->gr_mem = del_list (ngrp->gr_mem, user_name); - changed = true; - #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "removing group member", -- user_name, AUDIT_NO_ID, 1); -+ audit_logger_with_group (AUDIT_USER_MGMT, Prog, -+ "delete-user-from-group", -+ user_name, AUDIT_NO_ID, -+ ngrp->gr_name, -+ SHADOW_AUDIT_SUCCESS); - #endif - SYSLOG ((LOG_INFO, - "delete '%s' from group '%s'", -@@ -793,9 +798,11 @@ update_group(const struct group *grp) - ngrp->gr_mem = add_list (ngrp->gr_mem, user_newname); - changed = true; - #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "adding user to group", -- user_name, AUDIT_NO_ID, 1); -+ audit_logger_with_group (AUDIT_USER_MGMT, Prog, -+ "add-user-to-group", -+ user_name, AUDIT_NO_ID, -+ ngrp->gr_name, -+ SHADOW_AUDIT_SUCCESS); - #endif - SYSLOG ((LOG_INFO, "add '%s' to group '%s'", - user_newname, ngrp->gr_name)); -@@ -888,9 +895,10 @@ update_gshadow(const struct sgrp *sgrp) - nsgrp->sg_adm = add_list (nsgrp->sg_adm, user_newname); - changed = true; - #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "changing admin name in shadow group", -- user_name, AUDIT_NO_ID, 1); -+ audit_logger_with_group (AUDIT_GRP_MGMT, Prog, -+ "update-admin-name-in-shadow-group", -+ user_name, AUDIT_NO_ID, nsgrp->sg_name, -+ SHADOW_AUDIT_SUCCESS); - #endif - SYSLOG ((LOG_INFO, - "change admin '%s' to '%s' in shadow group '%s'", -@@ -910,9 +918,10 @@ update_gshadow(const struct sgrp *sgrp) - user_newname); - changed = true; - #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "changing member in shadow group", -- user_name, AUDIT_NO_ID, 1); -+ audit_logger_with_group (AUDIT_USER_MGMT, Prog, -+ "update-member-in-shadow-group", -+ user_name, AUDIT_NO_ID, -+ nsgrp->sg_name, 1); - #endif - SYSLOG ((LOG_INFO, - "change '%s' to '%s' in shadow group '%s'", -@@ -926,9 +935,10 @@ update_gshadow(const struct sgrp *sgrp) - nsgrp->sg_mem = del_list (nsgrp->sg_mem, user_name); - changed = true; - #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "removing user from shadow group", -- user_name, AUDIT_NO_ID, 1); -+ audit_logger_with_group (AUDIT_USER_MGMT, Prog, -+ "delete-user-from-shadow-group", -+ user_name, AUDIT_NO_ID, -+ nsgrp->sg_name, 1); - #endif - SYSLOG ((LOG_INFO, - "delete '%s' from shadow group '%s'", -@@ -941,9 +951,10 @@ update_gshadow(const struct sgrp *sgrp) - nsgrp->sg_mem = add_list (nsgrp->sg_mem, user_newname); - changed = true; - #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "adding user to shadow group", -- user_newname, AUDIT_NO_ID, 1); -+ audit_logger_with_group (AUDIT_USER_MGMT, Prog, -+ "add-user-to-shadow-group", -+ user_newname, AUDIT_NO_ID, -+ nsgrp->sg_name, 1); - #endif - SYSLOG ((LOG_INFO, "add '%s' to shadow group '%s'", - user_newname, nsgrp->sg_name)); -@@ -1852,8 +1863,8 @@ static void move_home (void) - - #ifdef WITH_AUDIT - if (uflg || gflg) { -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "changing home directory owner", -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "updating-home-dir-owner", - user_newname, user_newid, 1); - } - #endif -@@ -1871,8 +1882,8 @@ static void move_home (void) - fail_exit (E_HOMEDIR); - } - #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "moving home directory", -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "moving-home-dir", - user_newname, user_newid, 1); - #endif - return; -@@ -1899,9 +1910,9 @@ static void move_home (void) - Prog, prefix_user_home); - } - #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_CHAUTHTOK, -+ audit_logger (AUDIT_USER_MGMT, - Prog, -- "moving home directory", -+ "moving-home-dir", - user_newname, - user_newid, - 1); -@@ -2125,8 +2136,8 @@ static void move_mailbox (void) - } - #ifdef WITH_AUDIT - else { -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "changing mail file owner", -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "updating-mail-file-owner", - user_newname, user_newid, 1); - } - #endif -@@ -2149,8 +2160,8 @@ static void move_mailbox (void) - } - #ifdef WITH_AUDIT - else { -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "changing mail file name", -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "updating-mail-file-name", - user_newname, user_newid, 1); - } - -@@ -2347,8 +2358,8 @@ int main (int argc, char **argv) - _("%s: warning: the user name %s to %s SELinux user mapping failed.\n"), - Prog, user_name, user_selinux); - #ifdef WITH_AUDIT -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "modifying User mapping ", -+ audit_logger (AUDIT_ROLE_ASSIGN, Prog, -+ "changing-selinux-user-mapping ", - user_name, user_id, - SHADOW_AUDIT_FAILURE); - #endif /* WITH_AUDIT */ -@@ -2360,8 +2371,8 @@ int main (int argc, char **argv) - _("%s: warning: the user name %s to SELinux user mapping removal failed.\n"), - Prog, user_name); - #ifdef WITH_AUDIT -- audit_logger (AUDIT_ADD_USER, Prog, -- "removing SELinux user mapping", -+ audit_logger (AUDIT_ROLE_REMOVE, Prog, -+ "delete-selinux-user-mapping", - user_name, user_id, - SHADOW_AUDIT_FAILURE); - #endif /* WITH_AUDIT */ -@@ -2404,8 +2415,8 @@ int main (int argc, char **argv) - */ - #ifdef WITH_AUDIT - if (uflg || gflg) { -- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, -- "changing home directory owner", -+ audit_logger (AUDIT_USER_MGMT, Prog, -+ "updating-home-dir-owner", - user_newname, user_newid, 1); - } - #endif diff --git a/shadow-4.17.0-account-tools-setuid.patch b/shadow-4.17.4-account-tools-setuid.patch similarity index 98% rename from shadow-4.17.0-account-tools-setuid.patch rename to shadow-4.17.4-account-tools-setuid.patch index 83453e0..4c1ff92 100644 --- a/shadow-4.17.0-account-tools-setuid.patch +++ b/shadow-4.17.4-account-tools-setuid.patch @@ -11,8 +11,8 @@ diff -up shadow-4.15.0/src/chpasswd.c.account-tools-setuid shadow-4.15.0/src/chp #endif /* USE_PAM */ +#endif /* ACCT_TOOLS_SETUID */ - int errors = 0; - int line = 0; + bool errors = false; + intmax_t line = 0; @@ -469,19 +471,23 @@ int main (int argc, char **argv) process_root_flag ("-R", argc, argv); prefix = process_prefix_flag ("-P", argc, argv); @@ -56,7 +56,7 @@ diff -up shadow-4.15.0/src/chpasswd.c.account-tools-setuid shadow-4.15.0/src/chp @@ -672,9 +680,11 @@ int main (int argc, char **argv) * password database. */ - if (0 != errors) { + if (errors) { +#ifdef ACCT_TOOLS_SETUID #ifdef USE_PAM if (!use_pam) @@ -332,15 +332,15 @@ diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/new /* @@ -1052,12 +1078,14 @@ int main (int argc, char **argv) - int line = 0; + intmax_t line = 0; uid_t uid; gid_t gid; +#ifdef ACCT_TOOLS_SETUID #ifdef USE_PAM - int *lines = NULL; + intmax_t *lines = NULL; char **usernames = NULL; char **passwords = NULL; - unsigned int nusers = 0; + size_t nusers = 0; #endif /* USE_PAM */ +#endif /* ACCT_TOOLS_SETUID */ @@ -361,15 +361,15 @@ diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/new +#endif /* ACCT_TOOLS_SETUID */ if (add_passwd (&newpw, fields[1]) != 0) { fprintf (stderr, - _("%s: line %d: can't update password\n"), + _("%s: line %jd: can't update password\n"), @@ -1327,6 +1357,7 @@ int main (int argc, char **argv) nscd_flush_cache ("group"); sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP); +#ifdef ACCT_TOOLS_SETUID #ifdef USE_PAM - unsigned int i; /* Now update the passwords using PAM */ + for (size_t i = 0; i < nusers; i++) { @@ -1339,6 +1370,7 @@ int main (int argc, char **argv) } } diff --git a/shadow-utils.spec b/shadow-utils.spec index 42b8d1d..eb9aebe 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,12 +1,12 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils -Version: 4.17.0 -Release: 5%{?dist} +Version: 4.17.4 +Release: 1%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow -Source0: https://github.com/shadow-maint/shadow/releases/download/4.17.0/shadow-4.17.0.tar.xz -Source1: https://github.com/shadow-maint/shadow/releases/download/4.17.0/shadow-4.17.0.tar.xz.asc +Source0: https://github.com/shadow-maint/shadow/releases/download/4.17.4/shadow-4.17.4.tar.xz +Source1: https://github.com/shadow-maint/shadow/releases/download/4.17.4/shadow-4.17.4.tar.xz.asc Source2: shadow-utils.useradd Source3: shadow-utils.login.defs Source4: shadow-bsd.txt @@ -18,16 +18,16 @@ Source7: passwd.pamd %global includesubiddir %{_includedir}/shadow # Fail linking if there are undefined symbols. %global _ld_strict_symbol_defs 1 +# workaround: _pam_confdir definition disappeared +%if ! %{defined _pam_confdir} +%define _pam_confdir /etc/pam.d +%endif ### Patches ### # Misc manual page changes - non-upstreamable Patch0: shadow-4.15.0-manfix.patch -# Date parsing improvement - could be upstreamed -Patch1: shadow-4.15.0-date-parsing.patch -# Audit message changes - partially upstreamed -Patch2: shadow-4.17.0-audit-update.patch # Probably non-upstreamable -Patch3: shadow-4.17.0-account-tools-setuid.patch +Patch1: shadow-4.17.4-account-tools-setuid.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -105,7 +105,7 @@ Requires: shadow-utils-subid = %{epoch}:%{version}-%{release} Development files for shadow-utils-subid. %prep -%autosetup -p 1 -S git -n shadow-4.17.0 +%autosetup -p 1 -S git -n shadow-4.17.4 iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -179,8 +179,6 @@ rm $RPM_BUILD_ROOT%{_mandir}/man1/su.* rm $RPM_BUILD_ROOT%{_mandir}/*/man1/su.* rm $RPM_BUILD_ROOT%{_mandir}/man5/passwd.* rm $RPM_BUILD_ROOT%{_mandir}/*/man5/passwd.* -rm $RPM_BUILD_ROOT%{_mandir}/man5/suauth.* -rm $RPM_BUILD_ROOT%{_mandir}/*/man5/suauth.* rm $RPM_BUILD_ROOT%{_mandir}/man8/logoutd.* rm $RPM_BUILD_ROOT%{_mandir}/*/man8/logoutd.* rm $RPM_BUILD_ROOT%{_mandir}/man8/nologin.* @@ -281,6 +279,10 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Thu Mar 20 2025 Iker Pedrosa - 2:4.17.4-1 +- Rebase to version 4.17.4. Resolves: #2353491 +- Fixes problems with expiration dates + * Sat Feb 01 2025 Björn Esser - 2:4.17.0-5 - Add explicit BR: libxcrypt-devel diff --git a/sources b/sources index 4d4e5ae..6e720c5 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (shadow-4.17.0.tar.xz) = 36fb4a17cce43f5c97f669124c9419376ccbaa04fee8865fe590f525f3b2d14ce6422da6c52544e7d563ac8bebb29532ac9935c3ecd298718814118a932a00c7 -SHA512 (shadow-4.17.0.tar.xz.asc) = 53143dcdb637aa3c579ac5302904c10ad0e39611c0384061d8d7f06a03ae4612a5e42c6c1fd6dc8da0220d27fc429870f749ab9be508f58966f362e80a6fb43b +SHA512 (shadow-4.17.4.tar.xz) = 06830f654650312a79ccd6d729a51808b324d594abf1c05d56a2d0880936df292ec5c9fd6c7f4ad59a6d0f2bf5be0af42afe6386c24c2c087fd64fff301bade3 +SHA512 (shadow-4.17.4.tar.xz.asc) = 24f14397a975e4b09be087705a96544ff8ad76e0aa8c708ed4a53db3a295ad0a33fd0797fc570dcbb2446d4e103a3e43922a93168f65012eba5d3fe31549ebdd From a7f68f91584ffdd51a38b20c562e319e060ac53c Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Tue, 25 Mar 2025 16:54:24 +0100 Subject: [PATCH 106/134] Add pam dependency for _pam_confdir missing macro Resolves: #2354806 Signed-off-by: Iker Pedrosa --- shadow-utils.spec | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index eb9aebe..b835dd5 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.17.4 -Release: 1%{?dist} +Release: 2%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -18,10 +18,6 @@ Source7: passwd.pamd %global includesubiddir %{_includedir}/shadow # Fail linking if there are undefined symbols. %global _ld_strict_symbol_defs 1 -# workaround: _pam_confdir definition disappeared -%if ! %{defined _pam_confdir} -%define _pam_confdir /etc/pam.d -%endif ### Patches ### # Misc manual page changes - non-upstreamable @@ -56,6 +52,7 @@ BuildRequires: libtool BuildRequires: libxcrypt-devel BuildRequires: libxslt BuildRequires: make +BuildRequires: pam BuildRequires: pam-devel ### Provides ### @@ -279,6 +276,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Tue Mar 25 2025 Iker Pedrosa - 2:4.17.4-2 +- Add pam dependency for _pam_confdir missing macro. Resolves: #2354806 + * Thu Mar 20 2025 Iker Pedrosa - 2:4.17.4-1 - Rebase to version 4.17.4. Resolves: #2353491 - Fixes problems with expiration dates From 92eaac9b2c03814446ff08a2835f8168b3dc5a57 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Tue, 22 Apr 2025 11:31:29 +0200 Subject: [PATCH 107/134] FSWC: Migrate to lastlog2 Link: Resolves: #2361588 Signed-off-by: Iker Pedrosa --- shadow-utils.spec | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index b835dd5..def827b 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.17.4 -Release: 2%{?dist} +Release: 3%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -80,10 +80,9 @@ programs for managing user and group accounts. The pwconv command converts passwords to the shadow password format. The pwunconv command unconverts shadow passwords and generates a passwd file (a standard UNIX password file). The pwck command checks the integrity of password -and shadow files. The lastlog command prints out the last login times -for all users. The useradd, userdel, and usermod commands are used for -managing user accounts. The groupadd, groupdel, and groupmod commands -are used for managing group accounts. +and shadow files. The useradd, userdel, and usermod commands are used +for managing user accounts. The groupadd, groupdel, and groupmod +commands are used for managing group accounts. ### Subpackages ### @@ -117,7 +116,6 @@ rm lib/getdate.c autoreconf %configure \ --disable-account-tools-setuid \ - --enable-lastlog \ --enable-logind=no \ --enable-man \ --enable-shadowgrp \ @@ -224,7 +222,6 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_bindir}/sg %attr(4755,root,root) %{_bindir}/chage %attr(4755,root,root) %{_bindir}/gpasswd -%{_bindir}/lastlog %attr(4755,root,root) %{_bindir}/newgrp %attr(0755,root,root) %caps(cap_setgid=ep) %{_bindir}/newgidmap %attr(0755,root,root) %caps(cap_setuid=ep) %{_bindir}/newuidmap @@ -262,7 +259,6 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_mandir}/man8/chgpasswd.8* %{_mandir}/man8/newusers.8* %{_mandir}/man8/*conv.8* -%{_mandir}/man8/lastlog.8* %{_mandir}/man8/vipw.8* %{_mandir}/man8/vigr.8* @@ -276,6 +272,11 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Tue Apr 22 2025 Iker Pedrosa - 2:4.17.4-3 +* FSWC: Migrate to lastlog2 + Link: + Resolves: #2361588 + * Tue Mar 25 2025 Iker Pedrosa - 2:4.17.4-2 - Add pam dependency for _pam_confdir missing macro. Resolves: #2354806 From 39c75f8e5825d87385d2a1d76b03f7e2da47b4b6 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Tue, 15 Jul 2025 12:28:52 +0200 Subject: [PATCH 108/134] Rebuild for new side-tag for lastlog2 migration Signed-off-by: Iker Pedrosa --- shadow-utils.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index def827b..a3cc639 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.17.4 -Release: 3%{?dist} +Release: 4%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -272,7 +272,7 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog -* Tue Apr 22 2025 Iker Pedrosa - 2:4.17.4-3 +* Tue Jul 15 2025 Iker Pedrosa - 2:4.17.4-4 * FSWC: Migrate to lastlog2 Link: Resolves: #2361588 From e1cfa31731cd68aa2d76ebfb3142037d16d3bb1e Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Fri, 18 Jul 2025 17:33:47 +0200 Subject: [PATCH 109/134] Stop assigning subids by default Resolves: CVE-2024-56433 and #2334168 Signed-off-by: Iker Pedrosa --- shadow-utils.login.defs | 4 ++-- shadow-utils.spec | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/shadow-utils.login.defs b/shadow-utils.login.defs index e84c7ab..1e9129a 100644 --- a/shadow-utils.login.defs +++ b/shadow-utils.login.defs @@ -148,7 +148,7 @@ SYS_UID_MAX 999 # Extra per user uids SUB_UID_MIN 524288 SUB_UID_MAX 600100000 -SUB_UID_COUNT 65536 +SUB_UID_COUNT 0 # # Min/max values for automatic gid selection in groupadd(8) @@ -161,7 +161,7 @@ SYS_GID_MAX 999 # Extra per user group ids SUB_GID_MIN 524288 SUB_GID_MAX 600100000 -SUB_GID_COUNT 65536 +SUB_GID_COUNT 0 # # Max number of login(1) retries if password is bad diff --git a/shadow-utils.spec b/shadow-utils.spec index a3cc639..834ff15 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.17.4 -Release: 4%{?dist} +Release: 5%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -272,8 +272,12 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Fri Jul 18 2025 Iker Pedrosa - 2:4.17.4-5 +- Stop assigning subids by default + Resolves: CVE-2024-56433 and #2334168 + * Tue Jul 15 2025 Iker Pedrosa - 2:4.17.4-4 -* FSWC: Migrate to lastlog2 +- FSWC: Migrate to lastlog2 Link: Resolves: #2361588 From 1f100b614dcbe4ea063620707f8aaaf0c83d7ef1 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Tue, 22 Jul 2025 11:33:02 +0200 Subject: [PATCH 110/134] Rebase to version 4.18.0 Resolves: #2374710 Signed-off-by: Iker Pedrosa --- .gitignore | 2 + ...> shadow-4.18.0-account-tools-setuid.patch | 74 +++++++++---------- shadow-utils.spec | 18 ++--- sources | 4 +- 4 files changed, 50 insertions(+), 48 deletions(-) rename shadow-4.17.4-account-tools-setuid.patch => shadow-4.18.0-account-tools-setuid.patch (79%) diff --git a/.gitignore b/.gitignore index ff11943..f4e82f2 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,5 @@ shadow-4.1.4.2.tar.bz2 /shadow-4.17.0.tar.xz.asc /shadow-4.17.4.tar.xz /shadow-4.17.4.tar.xz.asc +/shadow-4.18.0.tar.xz +/shadow-4.18.0.tar.xz.asc diff --git a/shadow-4.17.4-account-tools-setuid.patch b/shadow-4.18.0-account-tools-setuid.patch similarity index 79% rename from shadow-4.17.4-account-tools-setuid.patch rename to shadow-4.18.0-account-tools-setuid.patch index 4c1ff92..9c018f7 100644 --- a/shadow-4.17.4-account-tools-setuid.patch +++ b/shadow-4.18.0-account-tools-setuid.patch @@ -1,8 +1,8 @@ -diff -up shadow-4.15.0/src/chpasswd.c.account-tools-setuid shadow-4.15.0/src/chpasswd.c ---- shadow-4.15.0/src/chpasswd.c.account-tools-setuid 2024-03-08 22:27:04.000000000 +0100 -+++ shadow-4.15.0/src/chpasswd.c 2024-03-11 11:21:57.561150382 +0100 -@@ -443,9 +443,11 @@ int main (int argc, char **argv) - char *cp; +diff -up shadow-4.18.0-rc1/src/chpasswd.c.account-tools-setuid shadow-4.18.0-rc1/src/chpasswd.c +--- shadow-4.18.0-rc1/src/chpasswd.c.account-tools-setuid 2025-06-08 15:58:36.650175673 +0200 ++++ shadow-4.18.0-rc1/src/chpasswd.c 2025-06-09 10:09:17.902939220 +0200 +@@ -448,9 +448,11 @@ int main (int argc, char **argv) + char *newpwd; const char *salt; +#ifdef ACCT_TOOLS_SETUID @@ -13,7 +13,7 @@ diff -up shadow-4.15.0/src/chpasswd.c.account-tools-setuid shadow-4.15.0/src/chp bool errors = false; intmax_t line = 0; -@@ -469,19 +471,23 @@ int main (int argc, char **argv) +@@ -474,19 +476,23 @@ int main (int argc, char **argv) process_root_flag ("-R", argc, argv); prefix = process_prefix_flag ("-P", argc, argv); @@ -77,9 +77,9 @@ diff -up shadow-4.15.0/src/chpasswd.c.account-tools-setuid shadow-4.15.0/src/chp { /* Save the changes */ close_files (); -diff -up shadow-4.15.0/src/groupmems.c.account-tools-setuid shadow-4.15.0/src/groupmems.c ---- shadow-4.15.0/src/groupmems.c.account-tools-setuid 2024-03-08 22:27:04.000000000 +0100 -+++ shadow-4.15.0/src/groupmems.c 2024-03-11 11:16:18.365408572 +0100 +diff -up shadow-4.18.0-rc1/src/groupmems.c.account-tools-setuid shadow-4.18.0-rc1/src/groupmems.c +--- shadow-4.18.0-rc1/src/groupmems.c.account-tools-setuid 2025-06-08 15:58:36.651250652 +0200 ++++ shadow-4.18.0-rc1/src/groupmems.c 2025-06-09 10:08:59.836763261 +0200 @@ -14,9 +14,11 @@ #include #include @@ -92,7 +92,7 @@ diff -up shadow-4.15.0/src/groupmems.c.account-tools-setuid shadow-4.15.0/src/gr #include #include "alloc/x/xmalloc.h" -@@ -430,6 +432,7 @@ static void process_flags (int argc, cha +@@ -417,6 +419,7 @@ static void process_flags (int argc, cha static void check_perms (void) { if (!list) { @@ -100,7 +100,7 @@ diff -up shadow-4.15.0/src/groupmems.c.account-tools-setuid shadow-4.15.0/src/gr #ifdef USE_PAM pam_handle_t *pamh = NULL; int retval; -@@ -463,7 +466,8 @@ static void check_perms (void) +@@ -450,7 +453,8 @@ static void check_perms (void) fail_exit (1); } (void) pam_end (pamh, retval); @@ -110,10 +110,10 @@ diff -up shadow-4.15.0/src/groupmems.c.account-tools-setuid shadow-4.15.0/src/gr } } -diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/newusers.c ---- shadow-4.15.0/src/newusers.c.account-tools-setuid 2024-03-08 22:27:04.000000000 +0100 -+++ shadow-4.15.0/src/newusers.c 2024-03-11 11:20:07.198909046 +0100 -@@ -59,6 +59,7 @@ +diff -up shadow-4.18.0-rc1/src/newusers.c.account-tools-setuid shadow-4.18.0-rc1/src/newusers.c +--- shadow-4.18.0-rc1/src/newusers.c.account-tools-setuid 2025-06-08 15:58:36.652250643 +0200 ++++ shadow-4.18.0-rc1/src/newusers.c 2025-06-09 10:08:59.836928828 +0200 +@@ -67,6 +67,7 @@ static const char Prog[] = "newusers"; static bool rflg = false; /* create a system account */ @@ -121,7 +121,7 @@ diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/new #ifndef USE_PAM static /*@null@*//*@observer@*/char *crypt_method = NULL; #define cflg (NULL != crypt_method) -@@ -75,6 +76,7 @@ static long bcrypt_rounds = 13; +@@ -83,6 +84,7 @@ static long bcrypt_rounds = 13; static long yescrypt_cost = 5; #endif /* USE_YESCRYPT */ #endif /* !USE_PAM */ @@ -129,7 +129,7 @@ diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/new static bool is_shadow; #ifdef SHADOWGRP -@@ -97,9 +99,11 @@ NORETURN static void fail_exit (int); +@@ -105,9 +107,11 @@ NORETURN static void fail_exit (int); static int add_group (const char *, const char *, gid_t *, gid_t); static int get_user_id (const char *, uid_t *); static int add_user (const char *, uid_t, gid_t); @@ -141,7 +141,7 @@ diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/new static int add_passwd (struct passwd *, const char *); static void process_flags (int argc, char **argv); static void check_flags (void); -@@ -121,6 +125,7 @@ static void usage (int status) +@@ -129,6 +133,7 @@ static void usage (int status) "Options:\n"), Prog); (void) fputs (_(" -b, --badname allow bad names\n"), usageout); @@ -149,7 +149,7 @@ diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/new #ifndef USE_PAM (void) fprintf (usageout, _(" -c, --crypt-method METHOD the crypt method (one of %s)\n"), -@@ -136,9 +141,11 @@ static void usage (int status) +@@ -144,9 +149,11 @@ static void usage (int status) #endif ); #endif /* !USE_PAM */ @@ -161,7 +161,7 @@ diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/new #ifndef USE_PAM #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT\n" -@@ -146,6 +153,7 @@ static void usage (int status) +@@ -154,6 +161,7 @@ static void usage (int status) usageout); #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ #endif /* !USE_PAM */ @@ -169,7 +169,7 @@ diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/new (void) fputs ("\n", usageout); exit (status); -@@ -405,6 +413,7 @@ static int add_user (const char *name, u +@@ -419,6 +427,7 @@ static int add_user (const char *name, u return (pw_update (&pwent) == 0) ? -1 : 0; } @@ -177,7 +177,7 @@ diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/new #ifndef USE_PAM /* * update_passwd - update the password in the passwd entry -@@ -457,6 +466,7 @@ static int update_passwd (struct passwd +@@ -471,6 +480,7 @@ static int update_passwd (struct passwd return 0; } #endif /* !USE_PAM */ @@ -185,7 +185,7 @@ diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/new /* * add_passwd - add or update the encrypted password -@@ -465,10 +475,13 @@ static int add_passwd (struct passwd *pw +@@ -479,10 +489,13 @@ static int add_passwd (struct passwd *pw { const struct spwd *sp; struct spwd spent; @@ -199,7 +199,7 @@ diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/new #ifndef USE_PAM void *crypt_arg = NULL; if (NULL != crypt_method) { -@@ -505,13 +518,14 @@ static int add_passwd (struct passwd *pw +@@ -520,13 +533,14 @@ static int add_passwd (struct passwd *pw return update_passwd (pwd, password); } #endif /* USE_PAM */ @@ -215,7 +215,7 @@ diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/new if (NULL != sp) { spent = *sp; if ( (NULL != crypt_method) -@@ -547,7 +561,7 @@ static int add_passwd (struct passwd *pw +@@ -563,7 +577,7 @@ static int add_passwd (struct passwd *pw if (!streq(pwd->pw_passwd, "x")) { return update_passwd (pwd, password); } @@ -224,7 +224,7 @@ diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/new /* * If there is already a shadow entry, do not touch it. * If there is already a passwd entry with a password, do not -@@ -558,14 +572,14 @@ static int add_passwd (struct passwd *pw +@@ -574,14 +588,14 @@ static int add_passwd (struct passwd *pw || !streq(pwd->pw_passwd, "x")) { return 0; } @@ -241,7 +241,7 @@ diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/new if ((crypt_method != NULL) && streq(crypt_method, "NONE")) { spent.sp_pwdp = (char *)password; } else { -@@ -610,35 +624,41 @@ static int add_passwd (struct passwd *pw +@@ -626,35 +640,41 @@ static int add_passwd (struct passwd *pw static void process_flags (int argc, char **argv) { int c; @@ -285,7 +285,7 @@ diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/new "bhr", #endif long_options, NULL)) != -1) { -@@ -646,11 +666,13 @@ static void process_flags (int argc, cha +@@ -662,11 +682,13 @@ static void process_flags (int argc, cha case 'b': allow_bad_names = true; break; @@ -299,7 +299,7 @@ diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/new case 'h': usage (EXIT_SUCCESS); break; -@@ -659,6 +681,7 @@ static void process_flags (int argc, cha +@@ -675,6 +697,7 @@ static void process_flags (int argc, cha break; case 'R': /* no-op, handled in process_root_flag () */ break; @@ -307,7 +307,7 @@ diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/new #ifndef USE_PAM #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) case 's': -@@ -698,6 +721,7 @@ static void process_flags (int argc, cha +@@ -714,6 +737,7 @@ static void process_flags (int argc, cha break; #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ #endif /* !USE_PAM */ @@ -315,7 +315,7 @@ diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/new default: usage (EXIT_FAILURE); break; -@@ -730,6 +754,7 @@ static void process_flags (int argc, cha +@@ -746,6 +770,7 @@ static void process_flags (int argc, cha */ static void check_flags (void) { @@ -323,7 +323,7 @@ diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/new #ifndef USE_PAM #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) if (sflg && !cflg) { -@@ -762,6 +787,7 @@ static void check_flags (void) +@@ -778,6 +803,7 @@ static void check_flags (void) } } #endif /* !USE_PAM */ @@ -331,7 +331,7 @@ diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/new } /* -@@ -1052,12 +1078,14 @@ int main (int argc, char **argv) +@@ -1066,12 +1092,14 @@ int main (int argc, char **argv) intmax_t line = 0; uid_t uid; gid_t gid; @@ -346,7 +346,7 @@ diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/new log_set_progname(Prog); log_set_logfd(stderr); -@@ -1195,6 +1223,7 @@ int main (int argc, char **argv) +@@ -1191,6 +1219,7 @@ int main (int argc, char **argv) } newpw = *pw; @@ -354,7 +354,7 @@ diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/new #ifdef USE_PAM /* keep the list of user/password for later update by PAM */ nusers++; -@@ -1211,6 +1240,7 @@ int main (int argc, char **argv) +@@ -1207,6 +1236,7 @@ int main (int argc, char **argv) usernames[nusers-1] = xstrdup(fields[0]); passwords[nusers-1] = xstrdup(fields[1]); #endif /* USE_PAM */ @@ -362,7 +362,7 @@ diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/new if (add_passwd (&newpw, fields[1]) != 0) { fprintf (stderr, _("%s: line %jd: can't update password\n"), -@@ -1327,6 +1357,7 @@ int main (int argc, char **argv) +@@ -1323,6 +1353,7 @@ int main (int argc, char **argv) nscd_flush_cache ("group"); sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP); @@ -370,7 +370,7 @@ diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/new #ifdef USE_PAM /* Now update the passwords using PAM */ for (size_t i = 0; i < nusers; i++) { -@@ -1339,6 +1370,7 @@ int main (int argc, char **argv) +@@ -1334,6 +1365,7 @@ int main (int argc, char **argv) } } #endif /* USE_PAM */ diff --git a/shadow-utils.spec b/shadow-utils.spec index 834ff15..5465e15 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,12 +1,12 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils -Version: 4.17.4 -Release: 5%{?dist} +Version: 4.18.0 +Release: 1%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow -Source0: https://github.com/shadow-maint/shadow/releases/download/4.17.4/shadow-4.17.4.tar.xz -Source1: https://github.com/shadow-maint/shadow/releases/download/4.17.4/shadow-4.17.4.tar.xz.asc +Source0: https://github.com/shadow-maint/shadow/releases/download/4.18.0/shadow-4.18.0.tar.xz +Source1: https://github.com/shadow-maint/shadow/releases/download/4.18.0/shadow-4.18.0.tar.xz.asc Source2: shadow-utils.useradd Source3: shadow-utils.login.defs Source4: shadow-bsd.txt @@ -23,7 +23,7 @@ Source7: passwd.pamd # Misc manual page changes - non-upstreamable Patch0: shadow-4.15.0-manfix.patch # Probably non-upstreamable -Patch1: shadow-4.17.4-account-tools-setuid.patch +Patch1: shadow-4.18.0-account-tools-setuid.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -101,7 +101,7 @@ Requires: shadow-utils-subid = %{epoch}:%{version}-%{release} Development files for shadow-utils-subid. %prep -%autosetup -p 1 -S git -n shadow-4.17.4 +%autosetup -p 1 -S git -n shadow-4.18.0 iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -109,9 +109,6 @@ cp -f doc/HOWTO.utf8 doc/HOWTO cp -a %{SOURCE4} %{SOURCE5} . cp -a %{SOURCE6} man/login.defs.d/HOME_MODE.xml -# Force regeneration of getdate.c -rm lib/getdate.c - %build autoreconf %configure \ @@ -272,6 +269,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Tue Jul 22 2025 Iker Pedrosa - 2:4.18.0-1 +- Rebase to version 4.18.0. Resolves: #2374710 + * Fri Jul 18 2025 Iker Pedrosa - 2:4.17.4-5 - Stop assigning subids by default Resolves: CVE-2024-56433 and #2334168 diff --git a/sources b/sources index 6e720c5..8e3da98 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (shadow-4.17.4.tar.xz) = 06830f654650312a79ccd6d729a51808b324d594abf1c05d56a2d0880936df292ec5c9fd6c7f4ad59a6d0f2bf5be0af42afe6386c24c2c087fd64fff301bade3 -SHA512 (shadow-4.17.4.tar.xz.asc) = 24f14397a975e4b09be087705a96544ff8ad76e0aa8c708ed4a53db3a295ad0a33fd0797fc570dcbb2446d4e103a3e43922a93168f65012eba5d3fe31549ebdd +SHA512 (shadow-4.18.0.tar.xz) = e724670362949ccb570bb300322eb280c28ad609d631072b8db15a5e6eeba9fb9ac5d3df1df270f8b894235e4995b56c0e8f9aadb34d66bb5cea9b7a4f55e6ce +SHA512 (shadow-4.18.0.tar.xz.asc) = bb82b3d54eec0f11ace57609281974b315bba1240eafdae3b6513c7d7dfbcf10c3ae855c74c9eae33539709072046787e4b3e86dfb8bbfbf4bf23446daeb3422 From 654ff210dae918a9880cc1962b75b8a4c7ebab1f Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 25 Jul 2025 18:12:54 +0000 Subject: [PATCH 111/134] Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild --- shadow-utils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index 5465e15..f2238ca 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.18.0 -Release: 1%{?dist} +Release: 2%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -269,6 +269,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Fri Jul 25 2025 Fedora Release Engineering - 2:4.18.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild + * Tue Jul 22 2025 Iker Pedrosa - 2:4.18.0-1 - Rebase to version 4.18.0. Resolves: #2374710 From b75f74d3f1b086fd5e699e55f131ae9e1beca525 Mon Sep 17 00:00:00 2001 From: Alexey Tikhonov Date: Tue, 29 Jul 2025 20:20:15 +0200 Subject: [PATCH 112/134] Revert "Stop assigning subids by default" This reverts commit e1cfa31731cd68aa2d76ebfb3142037d16d3bb1e while CVE-2024-56433 is being disputed. Resolves: #2382662 --- shadow-utils.login.defs | 4 ++-- shadow-utils.spec | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/shadow-utils.login.defs b/shadow-utils.login.defs index 1e9129a..e84c7ab 100644 --- a/shadow-utils.login.defs +++ b/shadow-utils.login.defs @@ -148,7 +148,7 @@ SYS_UID_MAX 999 # Extra per user uids SUB_UID_MIN 524288 SUB_UID_MAX 600100000 -SUB_UID_COUNT 0 +SUB_UID_COUNT 65536 # # Min/max values for automatic gid selection in groupadd(8) @@ -161,7 +161,7 @@ SYS_GID_MAX 999 # Extra per user group ids SUB_GID_MIN 524288 SUB_GID_MAX 600100000 -SUB_GID_COUNT 0 +SUB_GID_COUNT 65536 # # Max number of login(1) retries if password is bad diff --git a/shadow-utils.spec b/shadow-utils.spec index f2238ca..34baef4 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.18.0 -Release: 2%{?dist} +Release: 3%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -269,6 +269,10 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Tue Jul 29 2025 Alexey Tikhonov - 2:4.18.0-3 +- Revert "Stop assigning subids by default" + Resolves: #2382662 + * Fri Jul 25 2025 Fedora Release Engineering - 2:4.18.0-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild From 9fbb086db0bf8f6b1436d76a5224e44ca5abf41b Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Mon, 18 Aug 2025 11:48:31 +0200 Subject: [PATCH 113/134] tests/: remove them These tests need to be migrated to TMT to continue running, but nobody is maintaining them so we've decided to remove them. Closes: 2383071 Signed-off-by: Iker Pedrosa --- tests/sanity/Makefile | 77 --- tests/sanity/PURPOSE | 10 - tests/sanity/runtest.sh | 24 - tests/sanity/sanity_test.py | 1013 ----------------------------------- tests/tests.yml | 13 - 5 files changed, 1137 deletions(-) delete mode 100644 tests/sanity/Makefile delete mode 100644 tests/sanity/PURPOSE delete mode 100755 tests/sanity/runtest.sh delete mode 100755 tests/sanity/sanity_test.py delete mode 100644 tests/tests.yml diff --git a/tests/sanity/Makefile b/tests/sanity/Makefile deleted file mode 100644 index 386221b..0000000 --- a/tests/sanity/Makefile +++ /dev/null @@ -1,77 +0,0 @@ -# Copyright (c) 2006 Red Hat, Inc. All rights reserved. This copyrighted material -# is made available to anyone wishing to use, modify, copy, or -# redistribute it subject to the terms and conditions of the GNU General -# Public License v.2. -# -# This program is distributed in the hope that it will be useful, but WITHOUT ANY -# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. See the GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# Author: Jakub Hrozek - -#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# -# Example Makefile for RHTS # -# This example is geared towards a test for a specific package # -# It does most of the work for you, but may require further coding # -#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# - -# The toplevel namespace within which the test lives. -TOPLEVEL_NAMESPACE=CoreOS - -# The name of the package under test: -PACKAGE_NAME=shadow-utils - -# The path of the test below the package: -RELATIVE_PATH=sanity - -# Version of the Test. Used with make tag. -export TESTVERSION=1.1 - -# The combined namespace of the test. -export TEST=/$(TOPLEVEL_NAMESPACE)/$(PACKAGE_NAME)/$(RELATIVE_PATH) - -# A phony target is one that is not really the name of a file. -# It is just a name for some commands to be executed when you -# make an explicit request. There are two reasons to use a -# phony target: to avoid a conflict with a file of the same -# name, and to improve performance. -.PHONY: all install download clean - -# Executables to be built should be added here, they will be generated on the system under test. -BUILT_FILES= - -# Data files, .c files, scripts anything needed to either compile the test and/or run it. -FILES=$(METADATA) Makefile PURPOSE sanity_test.py runtest.sh - -run: $(FILES) build - ./runtest.sh - -build: $(BUILT_FILES) - chmod a+x ./sanity_test.py - chmod a+x ./runtest.sh - -clean: - rm -f *~ *.rpm $(BUILT_FILES) - -# Include Common Makefile -include /usr/share/rhts/lib/rhts-make.include - -# Generate the testinfo.desc here: -$(METADATA): Makefile - @touch $(METADATA) - @echo "Owner: Jakub Hrozek " > $(METADATA) - @echo "Name: $(TEST)" >> $(METADATA) - @echo "Path: $(TEST_DIR)" >> $(METADATA) - @echo "TestVersion: $(TESTVERSION)" >> $(METADATA) - @echo "License: GNU GPL" >> $(METADATA) - @echo "Description: Basic sanity test for shadow-utils" >> $(METADATA) - @echo "TestTime: 5m" >> $(METADATA) - @echo "RunFor: $(PACKAGE_NAME)" >> $(METADATA) - @echo "Requires: $(PACKAGE_NAME)" >> $(METADATA) - @echo "Requires: python" >> $(METADATA) - rhts-lint $(METADATA) - diff --git a/tests/sanity/PURPOSE b/tests/sanity/PURPOSE deleted file mode 100644 index 27062e1..0000000 --- a/tests/sanity/PURPOSE +++ /dev/null @@ -1,10 +0,0 @@ -This is a basic sanity test for the shadow-utils package. It is implemented -in python on top of the unittesting.py module. - -Its purpose is to ensure that the binaries in the shadow-utils package behave -as expected and its switches/options work correctly. - -For the most part, every binary in the shadow-utils package is represented by -a single class named Test, i.e. TestUsermod etc. There are some -exceptions, like TestUseraddWeirdNameTest though. - diff --git a/tests/sanity/runtest.sh b/tests/sanity/runtest.sh deleted file mode 100755 index cb2a2b5..0000000 --- a/tests/sanity/runtest.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash -. /usr/bin/rhts-environment.sh -. /usr/share/beakerlib/beakerlib.sh || exit 1 - -rlJournalStart -rlFileBackup --clean /etc/default/useradd- /etc/default/useradd -setenforce 0 -python sanity_test.py -v -setenforce 1 -rlFileRestore - -EXIT=$? -if [[ $EXIT -eq 0 ]]; then - RESULT="PASS" -else - RESULT="FAIL" -fi - - -rlJournalEnd - -echo "Result: $RESULT" -echo "Exit: $EXIT" -report_result $TEST $RESULT $EXIT diff --git a/tests/sanity/sanity_test.py b/tests/sanity/sanity_test.py deleted file mode 100755 index e9c45c2..0000000 --- a/tests/sanity/sanity_test.py +++ /dev/null @@ -1,1013 +0,0 @@ -#!/usr/bin/env python -""" -A script that tests functionality of the shadow-utils package. - -Author: Jakub Hrozek, -License: GNU GPL v2 -Date: 2007 - -TODO: - * tests for password aging - * if something fails, print out the command issued for easier debugging - * test long options variants along with the short ones -""" - -import unittest -import pwd -import grp -import commands -import os -import os.path -import sys -import copy -import tempfile -import rpm -import shutil - -from UserDict import UserDict - -class RedHatVersion(object): - def __init__(self, type=None, version=None, release=None): - self.type = type - self.version = version - self.release = release - self.rhel = False - - def __eq__( self, other): - """ - Don't compare if either of the values is None - so we can do comparisons like 'is it fedora?' or 'is it rhel4?' - """ - ok = (self.type == other.type) - if ok == False: return False - - if self.version and other.version: - ok = (self.version == other.version) - if ok == False: return False - - if (self.release == other.release): - ok = (self.release == other.release) - - return ok - - def __ne__( self, other): - return not self.__eq__(other) - - def __get_fedora_info(self, mi): - return [ (h['version'],h['release']) for h in mi ][0] - - def __get_rhel_info(self, mi): - # The rules for RHEL versions are braindead..releases even more - ver_rpm, rel_rpm = [ (h['version'],h['release']) for h in mi ][0] - rhel_versions = { '3AS' : 3, '4AS' : 4, '5Server' : 5, '5Client' : 5, '6' : 6 } - if ver_rpm[:3] == '5.9' or ver_rpm[:1] == '6': # rhel6 prerelease and release hack - rhel_versions[ver_rpm] = 6 - if ver_rpm in rhel_versions.keys(): - return (rhel_versions[ver_rpm], rel_rpm) - - def is_rhel(self): - return self.rhel - - def get_info(self): - """ - Returns a tuple containing (type, version, release) of RHEL or Fedora. - Type is either RHEL or Fedora. - Returns None if it cannot parse the info - """ - - ts = rpm.TransactionSet() - mi = ts.dbMatch() - mi.pattern('name', rpm.RPMMIRE_GLOB, 'redhat-release*') - - if mi: - self.rhel = True - return ('RHEL',) + self.__get_rhel_info(mi) - else: - mi = ts.dbMatch('name','fedora-release') - self.rhel = False - if mi.count() != 0: - return ('Fedora',) + self.__get_fedora_info(mi) - - return None - - -class UserInfo(UserDict): - fields = { "pw_name" : 0, "pw_passwd" : 1, "pw_uid" : 2, "pw_gid" : 3, - "pw_gecos" : 4, "pw_dir" : 5, "pw_shell" : 6 } - - def __init__(self): - UserDict.__init__(self) - for f in UserInfo.fields: self[f] = None - - def __getitem__(self, key): - return UserDict.__getitem__(self, key) - - def __setitem__(self, key, value): - UserDict.__setitem__(self, key, value) - - def __cmp__(self, other): - return UserDict.__cmp__(self, other) - - def __repr__(self): - return " ; ".join( [ "%s => %s" % (k, v) for k, v in self.data.items() ] ) - - def __parse_info(self, struct): - for f in UserInfo.fields: - self[f] = struct[UserInfo.fields[f]] - - def get_info_uid(self, uid): - self.__parse_info(pwd.getpwuid(uid)) - - def get_info_name(self, name): - try: - self.__parse_info(pwd.getpwnam(name)) - except KeyError: - return None - - def lazy_compare(self, pattern): - """ Compare pattern against self. If any field in pattern is set - to None, it is automatically considered equal with the corresponding - field in self. """ - for field in UserInfo.fields: - if pattern[field] and pattern[field] != self[field]: - return False - - return True - -class GroupInfo(UserDict): - fields = { "gr_name" : 0, "gr_passwd" : 1, - "gr_gid" : 2, "gr_mem" : 3} - - def __init__(self): - UserDict.__init__(self) - for f in GroupInfo.fields: self[f] = None - - def __getitem__(self, key): - return UserDict.__getitem__(self, key) - - def __setitem__(self, key, value): - UserDict.__setitem__(self, key, value) - - def __cmp__(self, other): - return UserDict.__cmp__(self, other) - - def __repr__(self): - return " ; ".join( [ "%s => %s" % (k, v) for k, v in self.data.items() ] ) - - def __parse_info(self, struct): - for f in GroupInfo.fields: - self[f] = struct[GroupInfo.fields[f]] - - def get_info_gid(self, gid): - self.__parse_info(grp.getgrgid(gid)) - - def get_info_name(self, name): - self.__parse_info(grp.getgrnam(name)) - - def lazy_compare(self, pattern): - """ Compare pattern against self. If any field in pattern is set - to None, it is automatically considered equal with the corresponding - field in self. """ - for field in GroupInfo.fields: - if pattern[field] and pattern[field] != self[field]: - return False - - return True - -class LoginDefsParser(UserDict): - "A quick-n-dirty way how to fetch the defaults from /etc/login.defs into a dictionary" - - def __getitem__(self, key): - try: - return UserDict.__getitem__(self, key) - except KeyError: - # if a name-value is not defined in the config file, return defaults - if key == "CREATE_MAIL_SPOOL": - return "yes" - if key == "UMASK": - return "077" - - def __init__(self, path="/etc/login.defs",split=None): - self.path = path - UserDict.__init__(self) - try: - defs = open(path) - except IOError: - print "Could not open the config file %s" % (path) - - for line in defs: - if line.startswith('#'): continue - fields = line.split(split) - if len(fields) != 2: continue # yeah, we're dirty - self.data[fields[0]] = fields[1] - - def serialize(self): - output = open(self.path, "w+") - for k,v in self.data.items(): - output.write("%s=%s" % (k, v)) - - output.write("\n") - output.close() - -class TestUserInfo(unittest.TestCase): - def testLazyCompare(self): - """ (test sanity): Test comparing two UserInfo records """ - a = UserInfo() - a["pw_name"] = "foo" - a["pw_uid"] = 555 - b = copy.deepcopy(a) - c = UserInfo() - - self.assertEqual(a.lazy_compare(b), True) - self.assertEqual(a.lazy_compare(c), True) - - c["pw_name"] = "foo" - c["pw_uid"] = None - self.assertEqual(a.lazy_compare(c), True) - self.assertEqual(c.lazy_compare(a), False) - - c["pw_name"] = "bar" - self.assertNotEqual(a.lazy_compare(c), True) - - def testGetInfoUid(self): - """ (test sanity): Test getting user info based on his UID """ - a = UserInfo() - a.get_info_uid(0) - self.assertEqual(a["pw_name"], "root") - - def testGetInfoName(self): - """ (test sanity): Test getting user info based on his name """ - a = UserInfo() - a.get_info_name("root") - self.assertEqual(a["pw_uid"], 0) - -class ShadowUtilsTestBase: - """ Handy routines """ - def getDefaults(self): - # get the default values for so we can compare against that - (status, defaults_str) = commands.getstatusoutput('useradd -D') - if status != 0: - raise RuntimeError("Could not get the default values for useradd") - return dict([ rec.split("=") for rec in defaults_str.split("\n") ]) - - def getDefaultUserInfo(self, username): - expected = UserInfo() - defaults = self.getDefaults() - - expected["pw_name"] = username - expected["pw_dir"] = defaults["HOME"] + "/" + username - expected["pw_shell"] = defaults["SHELL"] - - return expected - -class TestUseradd(ShadowUtilsTestBase, unittest.TestCase): - def setUp(self): - self.username = "test-shadow-utils-useradd" - - def tearDown(self): - commands.getstatusoutput("userdel -r %s" % (self.username)) - - def testBasicAdd(self): - """ useradd: Tests basic adding of a user """ - expected = self.getDefaultUserInfo(self.username) - - runme = "useradd %s" % (self.username) - (status, output) = commands.getstatusoutput(runme) - self.failUnlessEqual(status, 0, output) - - created = UserInfo() - created.get_info_name(self.username) - self.assertEqual(created.lazy_compare(expected), True, "FAIL: Could not add a user\nIssued command: %s" % (runme)) - - def testExistingUser(self): - """ useradd: Test that user with an existing name cannot be added """ - (status, output) = commands.getstatusoutput("useradd %s" % (self.username)) - self.failUnlessEqual(status, 0, output) - self.assertNotEqual(commands.getstatusoutput("useradd %s" % (self.username))[0], 0, "FAIL: User that already exists added") - - def testCustomUID(self): - """ useradd: Adding an user with a specific UID """ - UID = 23456 # FIXME - test for a free UID slot first - - expected = self.getDefaultUserInfo(self.username) - expected["pw_uid"] = UID - - runme = "useradd %s -u %d" % (self.username, UID) - (status, output) = commands.getstatusoutput(runme) - self.failUnlessEqual(status, 0, "Issued command: %s\n" % (runme) + "Got from useradd: %s\n" % (output)) - - created = UserInfo() - created.get_info_name(self.username) - self.assertEqual(created.lazy_compare(expected), True, "FAIL: Could not add a user with a specific UID\nIssued command: %s" % (runme)) - - def testNegativeUID(self): - """ useradd: Tests that user cannot have a negative UID assigned """ - self.assertNotEqual(commands.getstatusoutput("useradd %s --uid -5" % (self.username))[0], 0, "FAIL: User with UID < 0 added") - - def testCustomExistingUID(self): - """ useradd: Adding a user with a specific existing UID """ - UID = 32112 - - expected = self.getDefaultUserInfo(self.username) - expected["pw_uid"] = UID - - (status_u, output_u) = commands.getstatusoutput("useradd %s -u %d" % (self.username, UID)) - - # must fail without -o flag - (status_u_no_o, output_u_no_o) = commands.getstatusoutput("useradd foo -u %d" % (UID)) - - # must pass with -o flag - (status_o, output_o) = commands.getstatusoutput("useradd foo -u %d -o" % (UID)) - - # clean up - (status, output) = commands.getstatusoutput("userdel -r foo") - - self.failUnlessEqual(status_u, 0, "FAIL: cannot add an user with a specified UID\n"+output_u) - self.assertEqual(status_o, 0, "FAIL: cannot add an user with an existing UID using the -o flag\n"+output_o) - self.failUnlessEqual(status, 0, output) - self.assertNotEqual(status_u_no_o, 0, "FAIL: user with an existing UID added\n"+output_u_no_o) - - def testCustomGID(self): - """ useradd: Adding an user with a specific GID """ - GID = 100 # users group should be everywhere - should we test before? - expected = self.getDefaultUserInfo(self.username) - expected["pw_gid"] = GID - - (status, output) = commands.getstatusoutput("useradd %s -g %d" % (self.username, GID)) - self.failUnlessEqual(status, 0, output) - - created = UserInfo() - created.get_info_name(self.username) - self.assertEqual(created.lazy_compare(expected), True, "FAIL: Could not add a user with a specific GID") - - def testCustomShell(self): - """ useradd: Adding an user with a specific login shell """ - shell = "/bin/ksh" - expected = self.getDefaultUserInfo(self.username) - expected["pw_shell"] = shell - - (status, output) = commands.getstatusoutput("useradd %s -s %s" % (self.username, shell)) - self.failUnlessEqual(status, 0, output) - - created = UserInfo() - created.get_info_name(self.username) - self.assertEqual(created.lazy_compare(expected), True, "FAIL: Could not add a user with a specific shell") - - def testCustomHome(self): - """ useradd: Adding an user with a specific home directory """ - home = "/tmp/useradd-test" - os.mkdir(home) - expected = self.getDefaultUserInfo(self.username) - expected["pw_dir"] = home - - (status, output) = commands.getstatusoutput("useradd %s -d %s" % (self.username, home)) - shutil.rmtree(home) - self.failUnlessEqual(status, 0, output) - - created = UserInfo() - created.get_info_name(self.username) - self.assertEqual(created.lazy_compare(expected), True, "FAIL: Could not add a user with a specific home") - - def testSystemAccount(self): - """ useradd: Adding a system user (UID < UID_MIN from /etc/login.defs) """ - defaults = LoginDefsParser() - - # system account with no home dir - expected = self.getDefaultUserInfo(self.username) - - (status, output) = commands.getstatusoutput("useradd -r %s" % (self.username)) - self.failUnlessEqual(status, 0, output) - - created = UserInfo() - created.get_info_name(self.username) - self.assertEqual(os.path.exists(created["pw_dir"]), False, "FAIL: System user has a home dir created") - self.assertEqual(created["pw_uid"] < defaults['UID_MIN'], True, "FAIL: System user has UID > UID_MIN") - self.assertEqual(created.lazy_compare(expected), True, "FAIL: Could not add a system user") - - def testAddToMoreGroups(self): - """ useradd: Creating an user that belongs to more than one group """ - (status, output) = commands.getstatusoutput("useradd -G bin %s" % (self.username)) - self.failUnlessEqual(status, 0, output) - - gr_bin = GroupInfo() - gr_bin.get_info_name("bin") - self.assertEqual(self.username in gr_bin["gr_mem"], True, "FAIL: User not in supplementary group after usermod -G -a") - - - def testAddWithCommonName(self): - """ useradd: Specifying a comment (user for account name) """ - comment = "zzzzzz" - (status, output) = commands.getstatusoutput("useradd -c %s %s" % (comment, self.username)) - self.failUnlessEqual(status, 0, output) - - created = UserInfo() - created.get_info_name(self.username) - self.assertEqual(created["pw_gecos"], comment, "FAIL: failed to create a user with a GECOS comment") - - def testHomePermissions(self): - """ useradd: Check if permissions on newly created home dir match the umask """ - defaults = LoginDefsParser() - - (status, output) = commands.getstatusoutput("useradd %s" % (self.username)) - self.failUnlessEqual(status, 0, output) - - created = UserInfo() - created.get_info_name(self.username) - - import stat - perm = os.stat(created["pw_dir"])[stat.ST_MODE] - mode = int(oct(perm & 0777)) - - self.assertEqual(defaults["UMASK"], "077", "FAIL: umask setting is not sane - is %s, should be 077" % (defaults["UMASK"])) - self.assertEqual(int(defaults["UMASK"]) + mode , 777, "FAIL: newly-created home dir does not match the umask") - - def testCreateMailSpool(self): - """ useradd: Check whether the mail spool gets created when told to""" - # set up creating of mail spool - defaults = LoginDefsParser("/etc/default/useradd", split="=") - - create_mail = defaults["CREATE_MAIL_SPOOL"] - defaults["CREATE_MAIL_SPOOL"] = "yes" - defaults.serialize() - - login_defs = LoginDefsParser() - - (status, output) = commands.getstatusoutput("useradd %s" % (self.username)) - self.failUnlessEqual(status, 0, output) - - # clean up - defaults["CREATE_MAIL_SPOOL"] = create_mail - defaults.serialize() - self.assertEqual(os.path.exists(login_defs["MAIL_DIR"] + "/" + self.username), True, "FAIL: useradd did not create mail spool") - - def testDefaultMailSettings(self): - """ useradd: Check whether the mail spool is on by default""" - defaults = LoginDefsParser("/etc/default/useradd", split="=") - self.assertEqual(defaults["CREATE_MAIL_SPOOL"], "yes\n") - - def testNoLastlog(self): - """ useradd: Check if the -l option prevents from being added to the lastlog """ - pass # FIXME - add some code here - - -class TestUseraddWeirdNameTest(unittest.TestCase, ShadowUtilsTestBase): - """ Tests addition/removal of usernames that have proven to be problematic in the past. - The reason to separate these from the main useradd test suite is to not run the setUp - and tearDown methods """ - - def addAndRemove(self, username, success=True): - expected = self.getDefaultUserInfo(username) - expected["pw_name"] = username - - (status, output) = commands.getstatusoutput("useradd %s" % (username)) - if success: - self.failUnlessEqual(status, 0, output) - else: - self.failIfEqual(status, 0, output) - return True - - created = UserInfo() - created.get_info_name(username) - self.assertEqual(created.lazy_compare(expected), True, "FAIL: TestUseraddWeirdName::addAndRemove - could not add a user") - - # the cleanup method won't help this time - (status, output) = commands.getstatusoutput("userdel -r %s" % (username)) - self.failUnlessEqual(status, 0, output) - - def testNumericName(self): - """ useradd: Test if an user with a purely numerical name can be added (123) """ - return self.addAndRemove("123") - - def testSambaName(self): - """ useradd: Test if an user with a name with a dollar at the end can be added (joepublic$ ) """ - return self.addAndRemove("joepublic$") - - def testDotInName(self): - """ useradd: Test if an user with a name with a dot in it can be added (joe.public ) """ - return self.addAndRemove("joe.public") - - def testAtInName(self): - """ useradd: Test if an user with an '@' in name can be added (joe@public.com) - should fail """ - return self.addAndRemove("joe@public.com", False) - - def testUppercase(self): - """ useradd: Test if an user with UPPERCASE or Uppercase name can be added """ - return self.addAndRemove("JOEPUBLIC") - return self.addAndRemove("Joepublic") - -class TestUseraddDefaultsChange(unittest.TestCase, ShadowUtilsTestBase): - def testDefaultsChange(self): - """ useradd: Test overriding default settings (shell, home dir, group) with a -D option """ - save = self.getDefaults() - - new_defs = dict() - new_defs["SHELL"] = "/bin/ksh" - new_defs["GROUP"] = "1" - new_defs["HOME"] = "/tmp" - - command = "useradd -D -s%s -g%s -b%s" % (new_defs["SHELL"], new_defs["GROUP"], new_defs["HOME"]) - (status, output) = commands.getstatusoutput(command) - self.failUnlessEqual(status, 0, output) - - overriden = self.getDefaults() - [ self.assertEqual(overriden[k], new_defs[k]) for k in new_defs.keys() ] - - command = "useradd -D -s%s -g%s -b%s" % (save["SHELL"], save["GROUP"], save["HOME"]) - (status, output) = commands.getstatusoutput(command) - self.failUnlessEqual(status, 0, output) - - -class TestUserdel(unittest.TestCase, ShadowUtilsTestBase): - def setUp(self): - self.username = "test-shadow-utils-userdel" - (status, output) = commands.getstatusoutput("useradd %s" % (self.username)) - self.failUnlessEqual(status, 0, output) - - def testRemoveUserGroup(self): - """ userdel: test if userdel removes user's group when he's deleted - regression test for #201379 """ - (status, output) = commands.getstatusoutput("userdel -r %s" % (self.username)) - self.failUnlessEqual(status, 0, output) - - # This would fail if we did not have the group removed - (status, output) = commands.getstatusoutput("useradd %s" % (self.username)) - self.failUnlessEqual(status, 0, output) - - (status, output) = commands.getstatusoutput("userdel -r %s" % (self.username)) - self.failUnlessEqual(status, 0, output) - -class TestUsermod(unittest.TestCase, ShadowUtilsTestBase): - def setUp(self): - self.username = "test-shadow-utils-usermod" - (status, output) = commands.getstatusoutput("useradd %s" % (self.username)) - self.failUnlessEqual(status, 0, output) - - def tearDown(self): - (status, output) = commands.getstatusoutput("userdel -r %s" % (self.username)) - self.failUnlessEqual(status, 0, output) - - def testAppendToSupplementaryGroup(self): - """ usermod: Test if a user can be added to a supplementary group """ - add_group = "additional_group" - (status, output) = commands.getstatusoutput("groupadd %s" % (add_group)) - self.failUnlessEqual(status, 0, output) - - (status_mod, output_mod) = commands.getstatusoutput("usermod -a -G %s %s" % (add_group, self.username)) - add_group_info = GroupInfo() - add_group_info.get_info_name(add_group) - (status, output) = commands.getstatusoutput("groupdel %s" % (add_group)) - - self.failUnlessEqual(status, 0, output) - self.failUnlessEqual(status_mod, 0, output_mod) - self.assertEqual(self.username in add_group_info["gr_mem"], True, "User not in supplementary group after usermod -G --append") - - - def testAppendToSupplementaryGroupLongOption(self): - """ usermod: Test if a user can be added to a supplementary group via --append rather that -a (regression test for 222540) """ - # this is known to not work on older RHELs - test what we are running - rhv = RedHatVersion() - runs = rhv.get_info() - if rhv.is_rhel(): - if runs[1] < 5: - print "This test makes sense for RHEL5+" - return - else: - if runs[1] < 6: - print "This test makes sense for Fedora 6+" - return - - type, release, version = RedHatVersion().get_info() - if RedHatVersion().is_rhel(): - if release < 5 or (release == 5 and version < 2): - print "This test makes sense for RHEL 5.2+" - return - - add_group = "additional_group" - (status, output) = commands.getstatusoutput("groupadd %s" % (add_group)) - self.failUnlessEqual(status, 0, output) - - (status_mod, output_mod) = commands.getstatusoutput("usermod --append -G %s %s" % (add_group, self.username)) - add_group_info = GroupInfo() - add_group_info.get_info_name(add_group) - (status, output) = commands.getstatusoutput("groupdel %s" % (add_group)) - - self.failUnlessEqual(status, 0, output) - self.failUnlessEqual(status_mod, 0, output_mod) - self.assertEqual(self.username in add_group_info["gr_mem"], True, "User not in supplementary group after usermod -G --append") - - - def testNameChange(self): - """ usermod: Test if the comment field (used as the Common Name) can be changed """ - new_comment = "zzzzzz" - - (status, output) = commands.getstatusoutput("usermod -c %s %s" % (new_comment, self.username)) - self.failUnlessEqual(status, 0, output) - - created = UserInfo() - created.get_info_name(self.username) - - self.assertEqual(created["pw_gecos"], new_comment) - - def testHomeChange(self): - """ usermod: Test if user's home directory can be changed """ - new_home = "/tmp" - created = UserInfo() - created.get_info_name(self.username) - old_home = created["pw_dir"] - - (status, output) = commands.getstatusoutput("usermod -d %s %s" % (new_home, self.username)) - self.failUnlessEqual(status, 0, output) - - created.get_info_name(self.username) - self.assertEqual(created["pw_dir"], new_home) - - # revert to old home so we can userdel -r in tearDown - (status, output) = commands.getstatusoutput("usermod -d %s %s" % (old_home, self.username)) - self.failUnlessEqual(status, 0, output) - - # FIXME - test if contents of /home directories are transferred with the -m option - # FIXME - test if new home is created if does not exist before - - def testGIDChange(self): - """ usermod: Test if user's gid can be changed. """ - new_group = "root" - # test non-existing group - (status_fail, output_fail) = commands.getstatusoutput("usermod -g no-such-group %s" % (self.username)) - (status, output) = commands.getstatusoutput("usermod -g %s %s" % (new_group, self.username)) - - created = UserInfo() - created.get_info_name(self.username) - - left = GroupInfo() - if left.get_info_name(self.username) == None: - (status_del, output_del) = commands.getstatusoutput("groupdel %s" % (self.username)) - self.failUnlessEqual(status_del, 0, output_del) - - self.failIfEqual(status_fail, 0, output_fail) - self.failUnlessEqual(status, 0, output) - self.assertEqual(created["pw_gid"], 0) #0 is root group - - def testLoginChange(self): - """ usermod: Test if user's login can be changed """ - new_login = "usermod-login-change" - user = UserInfo() - user.get_info_name(self.username) - uid = user["pw_uid"] # UID won't change even when login does - - # test changing to an existing user name - (status, output) = commands.getstatusoutput("usermod -l root %s" % (self.username)) - self.failIfEqual(status, 0, output) - - (status, output) = commands.getstatusoutput("usermod -l %s %s" % (new_login, self.username)) - self.failUnlessEqual(status, 0, output) - user.get_info_name(new_login) - self.assertEqual(user["pw_uid"], uid) - - # revert so we can userdel -r on tearDown - (status, output) = commands.getstatusoutput("usermod -l %s %s" % (self.username, new_login)) - self.failUnlessEqual(status, 0, output) - - def testShellChange(self): - """ usermod: Test if user's shell can be changed """ - new_shell = "/bin/sh" - - (status, output) = commands.getstatusoutput("usermod -s %s %s" % (new_shell, self.username)) - self.failUnlessEqual(status, 0, output) - - created = UserInfo() - created.get_info_name(self.username) - self.assertEqual(created["pw_shell"], new_shell) - -class TestGroupadd(unittest.TestCase, ShadowUtilsTestBase): - def setUp(self): - self.groupname = "test-shadow-utils-groups" - - def tearDown(self): - commands.getstatusoutput("groupdel %s" % (self.groupname)) - - def testAddGroup(self): - """ groupadd: Basic adding of a group """ - - expected = GroupInfo() - expected["gr_name"] = self.groupname - - (status, output) = commands.getstatusoutput("groupadd %s" % (self.groupname)) - self.failUnlessEqual(status, 0, output) - - created = GroupInfo() - created.get_info_name(self.groupname) - self.assertEqual(created.lazy_compare(expected), True, "FAIL: Could not add a group") - - def testAddSystemGroup(self): - """ groupadd: Adding a system group with gid < MIN_GID """ - - expected = GroupInfo() - expected["gr_name"] = self.groupname - defaults = LoginDefsParser() - - (status, output) = commands.getstatusoutput("groupadd -r %s" % (self.groupname)) - self.failUnlessEqual(status, 0, output) - - created = GroupInfo() - created.get_info_name(self.groupname) - self.assertEqual(created["gr_gid"] < defaults["GID_MIN"], True, "FAIL: System group has gid >= GID_MIN") - self.assertEqual(created.lazy_compare(expected), True, "FAIL: Could not add a system group") - - def testAddExistingGid(self): - """ groupadd: Test if we group with an existing GID can be added """ - (status, output) = commands.getstatusoutput("groupadd %s" % (self.groupname)) - self.failUnlessEqual(status, 0, output) - - gname = "%s-2" % (self.groupname) - - created = GroupInfo() - created.get_info_name(self.groupname) - - # no -o option -> this should fail - (status, output) = commands.getstatusoutput("groupadd -g%s %s" % (created["gr_gid"], gname)) - self.failIfEqual(status, 0, output) - - # override with -o option, should pass now - (status, output) = commands.getstatusoutput("groupadd -g%s -o %s" % (created["gr_gid"], gname)) - self.failUnlessEqual(status, 0, output) - - # test if the new GID is really the same - same_gid = GroupInfo() - same_gid.get_info_name(gname) - self.assertEqual(same_gid["gr_gid"], created["gr_gid"]) - - # clean up - (status, output) = commands.getstatusoutput("groupdel %s" % (gname)) - self.failUnlessEqual(status, 0, output) - - - def testOverrideDefaults(self): - """ groupadd: Test if the defaults can be overriden with the -K option """ - # this is known to not work on older RHELs - test what we are running - rhv = RedHatVersion() - runs = rhv.get_info() - if rhv.is_rhel(): - if runs[1] < 5: - print "This test makes sense for RHEL5+" - return - else: - if runs[1] < 6: - print "This test makes sense for Fedora 6+" - return - - - GID_MIN = 600 - GID_MAX = 625 - - (status, output) = commands.getstatusoutput("groupadd -K GID_MIN=%d -K GID_MAX=%d %s" % - (GID_MIN, GID_MAX, self.groupname)) - self.failUnlessEqual(status, 0, output) - - created = GroupInfo() - created.get_info_name(self.groupname) - self.assertEqual(GID_MIN <= created["gr_gid"] <= GID_MAX, True, "FAIL: created an user with UID of %d" % (created["gr_gid"])) - - - def testFOption(self): - """ groupadd: Tests the -f option of groupadd """ - (status, output) = commands.getstatusoutput("groupadd %s" % (self.groupname)) - self.failUnlessEqual(status, 0, output) - - (status, output) = commands.getstatusoutput("groupadd -f %s" % (self.groupname)) - self.assertEqual(status, 0, output) - -class TestGroupaddInvalidName(unittest.TestCase, ShadowUtilsTestBase): - def testGroupaddInvalidName(self): - """ groupadd: Test adding of a group with an invalid name """ - (status, output) = commands.getstatusoutput("groupadd foo?") - self.assertNotEqual(status, 0, output) - (status, output) = commands.getstatusoutput("groupadd aaaaabbbbbcccccdddddeeeeefffffggg") #33 chars - self.assertNotEqual(status, 0, output) - -class TestGroupaddValidName(unittest.TestCase, ShadowUtilsTestBase): - def testGroupaddValidName(self): - """ groupadd: Test adding and removing of groups with maximal valid name and name ending with $ """ - (status, output) = commands.getstatusoutput("groupadd aaaaabbbbbcccccdddddeeeeefffffgg") #32 chars - self.assertEqual(status, 0, output) - (status, output) = commands.getstatusoutput("groupadd aaaaabbbbbcccccdddddeeeeefffffg\$") #32 chars - self.assertEqual(status, 0, output) - (status, output) = commands.getstatusoutput("groupdel aaaaabbbbbcccccdddddeeeeefffffgg") #32 chars - self.assertEqual(status, 0, output) - (status, output) = commands.getstatusoutput("groupdel aaaaabbbbbcccccdddddeeeeefffffg\$") #32 chars - self.assertEqual(status, 0, output) - - -class TestGroupmod(unittest.TestCase, ShadowUtilsTestBase): - def setUp(self): - self.groupname = "test-shadow-utils-groups" - (status, output) = commands.getstatusoutput("groupadd %s" % (self.groupname)) - self.failUnlessEqual(status, 0, output) - - def tearDown(self): - commands.getstatusoutput("groupdel %s" % (self.groupname)) - - def testChangeGID(self): - """ groupmod: Test changing a gid of a group """ - expected = GroupInfo() - expected["gr_name"] = self.groupname - expected["gr_gid"] = 54321 - - (status, output) = commands.getstatusoutput("groupmod -g%d %s" % (expected["gr_gid"], self.groupname)) - self.failUnlessEqual(status, 0, output) - - created = GroupInfo() - created.get_info_name(self.groupname) - self.assertEqual(created.lazy_compare(expected), True, "FAIL: Could not change GID of an existing group") - - def testChangeGIDToExistingValue(self): - """ groupmod: Test changing GID to an existing value """ - second_name = "%s-2" % (self.groupname) - - created = GroupInfo() - created.get_info_name(self.groupname) - - expected = GroupInfo() - expected["gr_name"] = self.groupname - expected["gr_gid"] = created["gr_gid"] - - (status, output) = commands.getstatusoutput("groupadd %s" % (second_name)) - self.failUnlessEqual(status, 0, output) - - # try to assingn GID of the first group to the second - this should fail without the -o option - (status, output) = commands.getstatusoutput("groupmod -g%d %s" % (created["gr_gid"], second_name)) - self.failIfEqual(status, 0, output) - - # should pass with the -o option - (status, output) = commands.getstatusoutput("groupmod -g%d -o %s" % (created["gr_gid"], second_name)) - self.failUnlessEqual(status, 0, output) - - self.assertEqual(created.lazy_compare(expected), True, "FAIL: Could not change GID of an existing group to an existing one") - - # clean up - commands.getstatusoutput("groupdel %s" % (second_name)) - self.failUnlessEqual(status, 0, output) - - def testChangeGroupName(self): - """ groupmod: Test changing a group's name """ - second_name = "%s-2" % (self.groupname) - - created = GroupInfo() - created.get_info_name(self.groupname) - - (status, output) = commands.getstatusoutput("groupmod -n%s %s" % (second_name, self.groupname)) - self.failUnlessEqual(status, 0, output) - - changed = GroupInfo() - changed.get_info_gid(created["gr_gid"]) - self.assertEqual(changed["gr_name"], second_name) - self.assertEqual(changed["gr_gid"], created["gr_gid"]) - - # change back, so the group could be deleted by tearDown - (status, output) = commands.getstatusoutput("groupmod -n%s %s" % (self.groupname, second_name)) - self.failUnlessEqual(status, 0, output) - - def testChangeGroupNameExisting(self): - """ groupmod: Test changing a group's name to an existing one """ - existing = "bin" - (status, output) = commands.getstatusoutput("groupmod -n%s %s" % (existing, self.groupname)) - self.assertNotEqual(status, 0, output) # man groupmod -> 9: group name already in use - - def testChangeNonExistingGroup(self): - """ groupmod: Test properties of a non-existing group """ - nonexistent = "foobar" - (status, output) = commands.getstatusoutput("groupmod -nspameggs %s" % (nonexistent)) - self.assertNotEqual(status, 0, status) # man groupmod -> 6: specified group doesn't exist - -class TestGroupdel(unittest.TestCase, ShadowUtilsTestBase): - def testCorrectGroupdel(self): - """ groupdel: Basic usage of groupdel """ - self.groupname = "test-shadow-utils-groups" - (status, output) = commands.getstatusoutput("groupadd %s" % (self.groupname)) - self.failUnlessEqual(status, 0, output) - (status, output) = commands.getstatusoutput("groupdel %s" % (self.groupname)) - self.assertEqual(status, 0, output) - - def testGroupdelNoSuchGroup(self): - """ groupdel: Remove non-existing group """ - (status, output) = commands.getstatusoutput("groupdel foobar") - self.assertNotEqual(status, 0, output) - - def testRemovePrimaryGroup(self): - """ groupdel: Remove a primary group of an user """ - username = "test-groupdel-primary" - (status, output) = commands.getstatusoutput("useradd %s" % (username)) - self.failUnlessEqual(status, 0, output) - - (status, output) = commands.getstatusoutput("groupdel %s" % (username)) - self.assertNotEqual(status, 0, output) - - # clean up - (status, output) = commands.getstatusoutput("userdel -r %s" % (username)) - self.failUnlessEqual(status, 0, output) - -class TestPwckGrpck(unittest.TestCase): - def setUp(self): - self.passwd_path = tempfile.mktemp(suffix="test-pwck-passwd") - self.passwd_file = open(self.passwd_path, "w") - self.group_path = tempfile.mktemp(suffix="test-pwck-grp") - self.group_file = open(self.group_path, "w") - self.gshadow_path = tempfile.mktemp(suffix="test-pwck-gshadow") - self.gshadow_file = open(self.gshadow_path, "w") - - def tearDown(self): - self.passwd_file.close() - self.group_file.close() - self.gshadow_file.close() - - os.remove(self.passwd_path) - os.remove(self.group_path) - os.remove(self.gshadow_path) - - def runPwckCheck(self, passwd, group): - self.passwd_file.truncate() - self.group_file.truncate() - - self.passwd_file.write(passwd) - self.passwd_file.flush() - self.group_file.write(group) - self.group_file.flush() - - command = "pwck -r %s %s" % (self.passwd_path, self.group_path) - return commands.getstatusoutput(command) - - def runGrpCheck(self, group, gshadow): - self.group_file.truncate() - self.gshadow_file.truncate() - - self.gshadow_file.write(gshadow) - self.gshadow_file.flush() - - self.group_file.write(group) - self.group_file.flush() - - command = "grpck -r %s %s" % (self.group_path, self.gshadow_path) - return commands.getstatusoutput(command) - - - def testValidEntries(self): - """ pwck: a valid entry """ - status, output = self.runPwckCheck("foo:x:685:0::/dev/null:/bin/bash", "") - rhv = RedHatVersion() - runs = rhv.get_info() - if rhv.is_rhel(): - if runs[1] < 6: - self.assertEqual(status, 0, output) - else: - self.assertNotEqual(status, 0, output) - - def testNumberOfFields(self): - """ pwck: invalid number of fields in the record """ - not_enough = "foo:x:685:685::/dev/null" - too_many = "foo:x:685:685::/dev/null:/bin/bash:comment" - status, output = self.runPwckCheck(not_enough, "") - self.assertNotEqual(status, 0, output) - - status, output = self.runPwckCheck(too_many, "") - self.assertNotEqual(status, 0, output) - - def testUniqueUserName(self): - """ pwck: unique user name in the record """ - duplicate_username = "foo:x:685:685::/dev/null:/bin/bash\nfoo:x:686:686::/dev/null:/bin/bash" - status, output = self.runPwckCheck(duplicate_username, "") - self.assertNotEqual(status, 0, output) - - def testValidID(self): - """ pwck: invalid UID in the records """ - invalid_ids = [ "foo:x:-1:685::/dev/null:/bin/bash", "foo:x:blah:685::/dev/null:/bin/bash", "foo:x:1234567890:685::/dev/null:/bin/bash" ] - for record in invalid_ids: - status, output = self.runPwckCheck(record, "") - self.assertNotEqual(status, 0, record) - - - def testValidPrimaryGroup(self): - """ pwck: invalid primary group """ - invalid_groups = [ "foo:x:685:-1::/dev/null:/bin/bash", "foo:x:685:blah::/dev/null:/bin/bash", "foo:x:685:1234567890::/dev/null:/bin/bash" ] - for record in invalid_groups: - status, output = self.runPwckCheck("", record) - self.assertNotEqual(status, 0, output) - - def testValidHomeDir(self): - """ pwck: invalid home dir """ - for record in [ "foo:x:685:685::123:/bin/bash", "foo:x:685:685::/path/to/nowhere:/bin/bash", "foo:x:685:1234567890::!:/bin/bash" ]: - status, output = self.runPwckCheck(record, "") - self.assertNotEqual(status, 0, output) - - def testBZ164954(self): - """ grpck: regression test for BZ164954 """ - record = "root:x:0:root\nbin:x:1:root,bin,daemon\ndaemon:x:2:root,bin,daemon\nsys:x:3:root,bin,adm\nadm:x:4:root,adm,daemon" - status, output = self.runGrpCheck("", record) - self.assertNotEqual(status, 0, output) - -if __name__ == "__main__": - broken_on_rhel4 = { "TestUseradd" : [ "testCustomUID", "testCustomGID" ] } - - if os.getuid() != 0: - print "This test must be run as root" - sys.exit(1) - - unittest.main() - diff --git a/tests/tests.yml b/tests/tests.yml deleted file mode 100644 index 09f4769..0000000 --- a/tests/tests.yml +++ /dev/null @@ -1,13 +0,0 @@ ---- -# This first play always runs on the local staging system -- hosts: localhost - roles: - - role: standard-test-beakerlib - tags: - - classic - - atomic - tests: - - sanity - required_packages: - - shadow-utils # sanity test needs shadow-utils - - python # sanity test needs python From 5d57398d35ece8d92141cbc07e712f3d4bc3fcbe Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Fri, 31 Oct 2025 12:52:35 +0100 Subject: [PATCH 114/134] Stop setting SELinux labels in chroot and prefix environments Resolves: #2249524 Signed-off-by: Iker Pedrosa --- shadow-4.18.0-selinux-chroot-prefix.patch | 10433 ++++++++++++++++++++ shadow-utils.spec | 8 +- 2 files changed, 10440 insertions(+), 1 deletion(-) create mode 100644 shadow-4.18.0-selinux-chroot-prefix.patch diff --git a/shadow-4.18.0-selinux-chroot-prefix.patch b/shadow-4.18.0-selinux-chroot-prefix.patch new file mode 100644 index 0000000..a5db17b --- /dev/null +++ b/shadow-4.18.0-selinux-chroot-prefix.patch @@ -0,0 +1,10433 @@ +From 218cc94da84459bfa5b8417d933e8898e24ecff6 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Fri, 25 Apr 2025 15:13:12 +0200 +Subject: [PATCH 01/15] lib/: add SELinux control flag in commonio_close() + +Expand commonio_close() interface to add a control flag for SELinux file +context processing. + +Signed-off-by: Iker Pedrosa +--- + lib/commonio.c | 16 ++++++++++------ + lib/commonio.h | 2 +- + lib/groupio.c | 2 +- + lib/pwio.c | 2 +- + lib/sgroupio.c | 2 +- + lib/shadowio.c | 2 +- + lib/subordinateio.c | 4 ++-- + 7 files changed, 17 insertions(+), 13 deletions(-) + +diff --git a/lib/commonio.c b/lib/commonio.c +index 7304ec00..7ee6df4d 100644 +--- a/lib/commonio.c ++++ b/lib/commonio.c +@@ -473,7 +473,7 @@ int commonio_unlock (struct commonio_db *db) + + if (db->isopen) { + db->readonly = true; +- if (commonio_close (db) == 0) { ++ if (commonio_close (db, true) == 0) { + if (db->locked) { + dec_lock_count (); + } +@@ -885,7 +885,7 @@ static int write_all (const struct commonio_db *db) + } + + +-int commonio_close (struct commonio_db *db) ++int commonio_close (struct commonio_db *db, bool process_selinux) + { + bool errors = false; + char buf[1024]; +@@ -927,7 +927,8 @@ int commonio_close (struct commonio_db *db) + } + + #ifdef WITH_SELINUX +- if (set_selinux_file_context (db->filename, S_IFREG) != 0) { ++ if (process_selinux ++ && set_selinux_file_context (db->filename, S_IFREG) != 0) { + errors = true; + } + #endif +@@ -942,7 +943,8 @@ int commonio_close (struct commonio_db *db) + db->fp = NULL; + + #ifdef WITH_SELINUX +- if (reset_selinux_file_context () != 0) { ++ if (process_selinux ++ && reset_selinux_file_context () != 0) { + errors = true; + } + #endif +@@ -961,7 +963,8 @@ int commonio_close (struct commonio_db *db) + goto fail; + + #ifdef WITH_SELINUX +- if (set_selinux_file_context (db->filename, S_IFREG) != 0) { ++ if (process_selinux ++ && set_selinux_file_context (db->filename, S_IFREG) != 0) { + errors = true; + } + #endif +@@ -999,7 +1002,8 @@ int commonio_close (struct commonio_db *db) + } + + #ifdef WITH_SELINUX +- if (reset_selinux_file_context () != 0) { ++ if (process_selinux ++ && reset_selinux_file_context () != 0) { + goto fail; + } + #endif +diff --git a/lib/commonio.h b/lib/commonio.h +index fedbefa3..dadc0500 100644 +--- a/lib/commonio.h ++++ b/lib/commonio.h +@@ -138,7 +138,7 @@ extern int commonio_append (struct commonio_db *, const void *); + extern int commonio_remove (struct commonio_db *, const char *); + extern int commonio_rewind (struct commonio_db *); + extern /*@observer@*/ /*@null@*/const void *commonio_next (struct commonio_db *); +-extern int commonio_close (struct commonio_db *); ++extern int commonio_close (struct commonio_db *, bool); + extern int commonio_unlock (struct commonio_db *); + extern void commonio_del_entry (struct commonio_db *, + const struct commonio_entry *); +diff --git a/lib/groupio.c b/lib/groupio.c +index 72391433..5076fd3d 100644 +--- a/lib/groupio.c ++++ b/lib/groupio.c +@@ -186,7 +186,7 @@ int gr_rewind (void) + + int gr_close (void) + { +- return commonio_close (&group_db); ++ return commonio_close (&group_db, true); + } + + int gr_unlock (void) +diff --git a/lib/pwio.c b/lib/pwio.c +index 415447d6..6f666ec6 100644 +--- a/lib/pwio.c ++++ b/lib/pwio.c +@@ -158,7 +158,7 @@ int pw_rewind (void) + + int pw_close (void) + { +- return commonio_close (&passwd_db); ++ return commonio_close (&passwd_db, true); + } + + int pw_unlock (void) +diff --git a/lib/sgroupio.c b/lib/sgroupio.c +index ef82976d..659dcd06 100644 +--- a/lib/sgroupio.c ++++ b/lib/sgroupio.c +@@ -278,7 +278,7 @@ int sgr_rewind (void) + + int sgr_close (void) + { +- return commonio_close (&gshadow_db); ++ return commonio_close (&gshadow_db, true); + } + + int sgr_unlock (void) +diff --git a/lib/shadowio.c b/lib/shadowio.c +index 8b1c1d2c..55d33da2 100644 +--- a/lib/shadowio.c ++++ b/lib/shadowio.c +@@ -195,7 +195,7 @@ int spw_close (void) + return 0; + } + #endif /* WITH_TCB */ +- retval = commonio_close (&shadow_db); ++ retval = commonio_close (&shadow_db, true); + #ifdef WITH_TCB + if (use_tcb && (shadowtcb_gain_priv () == SHADOWTCB_FAILURE)) { + return 0; +diff --git a/lib/subordinateio.c b/lib/subordinateio.c +index 27f888b9..3638ec61 100644 +--- a/lib/subordinateio.c ++++ b/lib/subordinateio.c +@@ -670,7 +670,7 @@ int sub_uid_remove (const char *owner, uid_t start, unsigned long count) + + int sub_uid_close (void) + { +- return commonio_close (&subordinate_uid_db); ++ return commonio_close (&subordinate_uid_db, true); + } + + int sub_uid_unlock (void) +@@ -777,7 +777,7 @@ int sub_gid_remove (const char *owner, gid_t start, unsigned long count) + + int sub_gid_close (void) + { +- return commonio_close (&subordinate_gid_db); ++ return commonio_close (&subordinate_gid_db, true); + } + + int sub_gid_unlock (void) +-- +2.50.0 + + +From 7e7dbe0e65d2795c15c42bb04c7c03b9ff86ea84 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Fri, 25 Apr 2025 15:19:29 +0200 +Subject: [PATCH 02/15] lib/, src/: add SELinux control flag in pw_close() + +Expand pw_close() interface to add a control flag for SELinux file +context processing. + +Signed-off-by: Iker Pedrosa +--- + lib/pwio.c | 4 ++-- + lib/pwio.h | 3 ++- + src/chage.c | 2 +- + src/chfn.c | 2 +- + src/chpasswd.c | 2 +- + src/chsh.c | 2 +- + src/groupmod.c | 2 +- + src/newusers.c | 2 +- + src/passwd.c | 2 +- + src/pwck.c | 2 +- + src/pwconv.c | 2 +- + src/pwunconv.c | 2 +- + src/useradd.c | 2 +- + src/userdel.c | 6 +++--- + src/usermod.c | 2 +- + 15 files changed, 19 insertions(+), 18 deletions(-) + +diff --git a/lib/pwio.c b/lib/pwio.c +index 6f666ec6..c5c1cdb1 100644 +--- a/lib/pwio.c ++++ b/lib/pwio.c +@@ -156,9 +156,9 @@ int pw_rewind (void) + return commonio_next (&passwd_db); + } + +-int pw_close (void) ++int pw_close (bool process_selinux) + { +- return commonio_close (&passwd_db, true); ++ return commonio_close (&passwd_db, process_selinux); + } + + int pw_unlock (void) +diff --git a/lib/pwio.h b/lib/pwio.h +index 882a7c7a..b051a7e7 100644 +--- a/lib/pwio.h ++++ b/lib/pwio.h +@@ -14,8 +14,9 @@ + + #include + #include ++#include + +-extern int pw_close (void); ++extern int pw_close (bool process_selinux); + extern /*@observer@*/ /*@null@*/const struct passwd *pw_locate (const char *name); + extern /*@observer@*/ /*@null@*/const struct passwd *pw_locate_uid (uid_t uid); + extern int pw_lock (void); +diff --git a/src/chage.c b/src/chage.c +index 4b9c96d6..1ebe34c5 100644 +--- a/src/chage.c ++++ b/src/chage.c +@@ -557,7 +557,7 @@ static void close_files (void) + * Close the password file. If any entries were modified, the file + * will be re-written. + */ +- if (pw_close () == 0) { ++ if (pw_close (true) == 0) { + fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); + fail_exit (E_NOPERM); +diff --git a/src/chfn.c b/src/chfn.c +index 58502929..abf88cc8 100644 +--- a/src/chfn.c ++++ b/src/chfn.c +@@ -493,7 +493,7 @@ static void update_gecos (const char *user, char *gecos) + /* + * Changes have all been made, so commit them and unlock the file. + */ +- if (pw_close () == 0) { ++ if (pw_close (true) == 0) { + fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); + fail_exit (E_NOPERM); +diff --git a/src/chpasswd.c b/src/chpasswd.c +index 315e91ce..17f3d6d5 100644 +--- a/src/chpasswd.c ++++ b/src/chpasswd.c +@@ -393,7 +393,7 @@ static void close_files (void) + spw_locked = false; + } + +- if (pw_close () == 0) { ++ if (pw_close (true) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, pw_dbname ()); +diff --git a/src/chsh.c b/src/chsh.c +index 236ff784..b5ae28da 100644 +--- a/src/chsh.c ++++ b/src/chsh.c +@@ -428,7 +428,7 @@ static void update_shell (const char *user, char *newshell) + /* + * Changes have all been made, so commit them and unlock the file. + */ +- if (pw_close () == 0) { ++ if (pw_close (true) == 0) { + fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); + fail_exit (1); +diff --git a/src/groupmod.c b/src/groupmod.c +index cce6fd49..14b7e746 100644 +--- a/src/groupmod.c ++++ b/src/groupmod.c +@@ -534,7 +534,7 @@ static void close_files (void) + #endif /* SHADOWGRP */ + + if (gflg) { +- if (pw_close () == 0) { ++ if (pw_close (true) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, pw_dbname ()); +diff --git a/src/newusers.c b/src/newusers.c +index 38cbdddb..a738f944 100644 +--- a/src/newusers.c ++++ b/src/newusers.c +@@ -939,7 +939,7 @@ static void open_files (void) + */ + static void close_files (void) + { +- if (pw_close () == 0) { ++ if (pw_close (true) == 0) { + fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); + fail_exit (EXIT_FAILURE); +diff --git a/src/passwd.c b/src/passwd.c +index cdd817a2..8bdff6dd 100644 +--- a/src/passwd.c ++++ b/src/passwd.c +@@ -586,7 +586,7 @@ static void update_noshadow (void) + Prog, pw_dbname (), npw->pw_name); + fail_exit (E_FAILURE); + } +- if (pw_close () == 0) { ++ if (pw_close (true) == 0) { + (void) fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, pw_dbname ()); +diff --git a/src/pwck.c b/src/pwck.c +index 6272839f..b1c6970f 100644 +--- a/src/pwck.c ++++ b/src/pwck.c +@@ -309,7 +309,7 @@ static void close_files (bool changed) + * changes to the files. + */ + if (changed) { +- if (pw_close () == 0) { ++ if (pw_close (true) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, pw_dbname ()); +diff --git a/src/pwconv.c b/src/pwconv.c +index 1bb92752..da3a5820 100644 +--- a/src/pwconv.c ++++ b/src/pwconv.c +@@ -281,7 +281,7 @@ int main (int argc, char **argv) + SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); + fail_exit (E_FAILURE); + } +- if (pw_close () == 0) { ++ if (pw_close (true) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, pw_dbname ()); +diff --git a/src/pwunconv.c b/src/pwunconv.c +index 2e4d3d75..8423cda4 100644 +--- a/src/pwunconv.c ++++ b/src/pwunconv.c +@@ -207,7 +207,7 @@ int main (int argc, char **argv) + + (void) spw_close (); /* was only open O_RDONLY */ + +- if (pw_close () == 0) { ++ if (pw_close (true) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, pw_dbname ()); +diff --git a/src/useradd.c b/src/useradd.c +index 36b9b8f8..8c9e9003 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -1564,7 +1564,7 @@ static void process_flags (int argc, char **argv) + */ + static void close_files (void) + { +- if (pw_close () == 0) { ++ if (pw_close (true) == 0) { + fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); + fail_exit (E_PW_UPDATE); +diff --git a/src/userdel.c b/src/userdel.c +index 72ce11fa..b5a02b3c 100644 +--- a/src/userdel.c ++++ b/src/userdel.c +@@ -390,7 +390,7 @@ static void remove_usergroup (void) + */ + static void close_files (void) + { +- if (pw_close () == 0) { ++ if (pw_close (true) == 0) { + fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); + fail_exit (E_PW_UPDATE); +@@ -1046,7 +1046,7 @@ int main (int argc, char **argv) + pw_open(O_RDONLY); + pwd = pw_locate (user_name); /* we care only about local users */ + if (NULL == pwd) { +- pw_close(); ++ pw_close(true); + fprintf (stderr, _("%s: user '%s' does not exist\n"), + Prog, user_name); + #ifdef WITH_AUDIT +@@ -1065,7 +1065,7 @@ int main (int argc, char **argv) + } else { + user_home = xstrdup(pwd->pw_dir); + } +- pw_close(); ++ pw_close(true); + } + #ifdef WITH_TCB + if (shadowtcb_set_user (user_name) == SHADOWTCB_FAILURE) { +diff --git a/src/usermod.c b/src/usermod.c +index a0f4d7dd..180b7da0 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -1469,7 +1469,7 @@ process_flags(int argc, char **argv) + */ + static void close_files (void) + { +- if (pw_close () == 0) { ++ if (pw_close (true) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, pw_dbname ()); +-- +2.50.0 + + +From abffb267659bb1f9d49af5cba69c7a9ba2489e3d Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Fri, 25 Apr 2025 15:23:11 +0200 +Subject: [PATCH 03/15] lib/, src/: add SELinux control flag in spw_close() + +Expand spw_close() interface to add a control flag for SELinux file +context processing. + +Signed-off-by: Iker Pedrosa +--- + lib/shadowio.c | 4 ++-- + lib/shadowio.h | 2 +- + src/chage.c | 2 +- + src/chpasswd.c | 2 +- + src/newusers.c | 2 +- + src/passwd.c | 4 ++-- + src/pwck.c | 4 ++-- + src/pwconv.c | 2 +- + src/pwunconv.c | 2 +- + src/useradd.c | 2 +- + src/userdel.c | 2 +- + src/usermod.c | 2 +- + 12 files changed, 15 insertions(+), 15 deletions(-) + +diff --git a/lib/shadowio.c b/lib/shadowio.c +index 55d33da2..a109576d 100644 +--- a/lib/shadowio.c ++++ b/lib/shadowio.c +@@ -185,7 +185,7 @@ int spw_rewind (void) + return commonio_next (&shadow_db); + } + +-int spw_close (void) ++int spw_close (bool process_selinux) + { + int retval = 0; + #ifdef WITH_TCB +@@ -195,7 +195,7 @@ int spw_close (void) + return 0; + } + #endif /* WITH_TCB */ +- retval = commonio_close (&shadow_db, true); ++ retval = commonio_close (&shadow_db, process_selinux); + #ifdef WITH_TCB + if (use_tcb && (shadowtcb_gain_priv () == SHADOWTCB_FAILURE)) { + return 0; +diff --git a/lib/shadowio.h b/lib/shadowio.h +index 4dbeb6d6..e64d8d60 100644 +--- a/lib/shadowio.h ++++ b/lib/shadowio.h +@@ -13,7 +13,7 @@ + + #include "defines.h" + +-extern int spw_close (void); ++extern int spw_close (bool process_selinux); + extern bool spw_file_present (void); + extern /*@observer@*/ /*@null@*/const struct spwd *spw_locate (const char *name); + extern int spw_lock (void); +diff --git a/src/chage.c b/src/chage.c +index 1ebe34c5..a59428c5 100644 +--- a/src/chage.c ++++ b/src/chage.c +@@ -546,7 +546,7 @@ static void close_files (void) + * Now close the shadow password file, which will cause all of the + * entries to be re-written. + */ +- if (spw_close () == 0) { ++ if (spw_close (true) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); +diff --git a/src/chpasswd.c b/src/chpasswd.c +index 17f3d6d5..e3d8dcef 100644 +--- a/src/chpasswd.c ++++ b/src/chpasswd.c +@@ -378,7 +378,7 @@ static void open_files (void) + static void close_files (void) + { + if (is_shadow_pwd) { +- if (spw_close () == 0) { ++ if (spw_close (true) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, spw_dbname ()); +diff --git a/src/newusers.c b/src/newusers.c +index a738f944..43672dd2 100644 +--- a/src/newusers.c ++++ b/src/newusers.c +@@ -952,7 +952,7 @@ static void close_files (void) + pw_locked = false; + + if (is_shadow) { +- if (spw_close () == 0) { ++ if (spw_close (true) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, spw_dbname ()); +diff --git a/src/passwd.c b/src/passwd.c +index 8bdff6dd..01efb285 100644 +--- a/src/passwd.c ++++ b/src/passwd.c +@@ -625,7 +625,7 @@ static void update_shadow (void) + sp = spw_locate (name); + if (NULL == sp) { + /* Try to update the password in /etc/passwd instead. */ +- (void) spw_close (); ++ (void) spw_close (true); + update_noshadow (); + if (spw_unlock () == 0) { + (void) fprintf (stderr, +@@ -681,7 +681,7 @@ static void update_shadow (void) + Prog, spw_dbname (), nsp->sp_namp); + fail_exit (E_FAILURE); + } +- if (spw_close () == 0) { ++ if (spw_close (true) == 0) { + (void) fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, spw_dbname ()); +diff --git a/src/pwck.c b/src/pwck.c +index b1c6970f..718b639f 100644 +--- a/src/pwck.c ++++ b/src/pwck.c +@@ -320,7 +320,7 @@ static void close_files (bool changed) + } + fail_exit (E_CANTUPDATE); + } +- if (spw_opened && (spw_close () == 0)) { ++ if (spw_opened && (spw_close (true) == 0)) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, spw_dbname ()); +@@ -657,7 +657,7 @@ static void check_pw_file (bool *errors, bool *changed) + } + #ifdef WITH_TCB + if (getdef_bool ("USE_TCB") && spw_locked) { +- if (spw_opened && (spw_close () == 0)) { ++ if (spw_opened && (spw_close (true) == 0)) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, spw_dbname ()); +diff --git a/src/pwconv.c b/src/pwconv.c +index da3a5820..296b527a 100644 +--- a/src/pwconv.c ++++ b/src/pwconv.c +@@ -274,7 +274,7 @@ int main (int argc, char **argv) + } + } + +- if (spw_close () == 0) { ++ if (spw_close (true) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, spw_dbname ()); +diff --git a/src/pwunconv.c b/src/pwunconv.c +index 8423cda4..e15c8c06 100644 +--- a/src/pwunconv.c ++++ b/src/pwunconv.c +@@ -205,7 +205,7 @@ int main (int argc, char **argv) + } + } + +- (void) spw_close (); /* was only open O_RDONLY */ ++ (void) spw_close (true); /* was only open O_RDONLY */ + + if (pw_close (true) == 0) { + fprintf (stderr, +diff --git a/src/useradd.c b/src/useradd.c +index 8c9e9003..8a7df6cf 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -1569,7 +1569,7 @@ static void close_files (void) + SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); + fail_exit (E_PW_UPDATE); + } +- if (is_shadow_pwd && (spw_close () == 0)) { ++ if (is_shadow_pwd && (spw_close (true) == 0)) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); +diff --git a/src/userdel.c b/src/userdel.c +index b5a02b3c..b87f2459 100644 +--- a/src/userdel.c ++++ b/src/userdel.c +@@ -403,7 +403,7 @@ static void close_files (void) + pw_locked = false; + + if (is_shadow_pwd) { +- if (spw_close () == 0) { ++ if (spw_close (true) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); +diff --git a/src/usermod.c b/src/usermod.c +index 180b7da0..d741508a 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -1476,7 +1476,7 @@ static void close_files (void) + SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); + fail_exit (E_PW_UPDATE); + } +- if (is_shadow_pwd && (spw_close () == 0)) { ++ if (is_shadow_pwd && (spw_close (true) == 0)) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, spw_dbname ()); +-- +2.50.0 + + +From 16bd1d985900fe83a1f7c9001fa3b9f18e0f06f0 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Fri, 25 Apr 2025 15:28:42 +0200 +Subject: [PATCH 04/15] lib/, src/: add SELinux control flag in gr_close() + +Expand gr_close() interface to add a control flag for SELinux file +context processing. + +Signed-off-by: Iker Pedrosa +--- + lib/groupio.c | 4 ++-- + lib/groupio.h | 3 ++- + src/chgpasswd.c | 2 +- + src/gpasswd.c | 4 ++-- + src/groupadd.c | 2 +- + src/groupdel.c | 2 +- + src/groupmems.c | 2 +- + src/groupmod.c | 2 +- + src/grpck.c | 2 +- + src/grpconv.c | 2 +- + src/grpunconv.c | 2 +- + src/newusers.c | 2 +- + src/useradd.c | 2 +- + src/userdel.c | 2 +- + src/usermod.c | 2 +- + 15 files changed, 18 insertions(+), 17 deletions(-) + +diff --git a/lib/groupio.c b/lib/groupio.c +index 5076fd3d..837e4c47 100644 +--- a/lib/groupio.c ++++ b/lib/groupio.c +@@ -184,9 +184,9 @@ int gr_rewind (void) + return commonio_next (&group_db); + } + +-int gr_close (void) ++int gr_close (bool process_selinux) + { +- return commonio_close (&group_db, true); ++ return commonio_close (&group_db, process_selinux); + } + + int gr_unlock (void) +diff --git a/lib/groupio.h b/lib/groupio.h +index 2014de0c..ef9242d0 100644 +--- a/lib/groupio.h ++++ b/lib/groupio.h +@@ -14,8 +14,9 @@ + + #include + #include ++#include + +-extern int gr_close (void); ++extern int gr_close (bool process_selinux); + extern /*@observer@*/ /*@null@*/const struct group *gr_locate (const char *name); + extern /*@observer@*/ /*@null@*/const struct group *gr_locate_gid (gid_t gid); + extern int gr_lock (void); +diff --git a/src/chgpasswd.c b/src/chgpasswd.c +index e7759657..9b686ef0 100644 +--- a/src/chgpasswd.c ++++ b/src/chgpasswd.c +@@ -397,7 +397,7 @@ static void close_files (void) + } + #endif + +- if (gr_close () == 0) { ++ if (gr_close (true) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, gr_dbname ()); +diff --git a/src/gpasswd.c b/src/gpasswd.c +index 460bd14c..1013f004 100644 +--- a/src/gpasswd.c ++++ b/src/gpasswd.c +@@ -593,7 +593,7 @@ static void log_gpasswd_success_group (MAYBE_UNUSED void *arg) + */ + static void close_files (void) + { +- if (gr_close () == 0) { ++ if (gr_close (true) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, gr_dbname ()); +@@ -724,7 +724,7 @@ static void get_group (struct group *gr) + gr->gr_passwd = xstrdup (tmpgr->gr_passwd); + gr->gr_mem = dup_list (tmpgr->gr_mem); + +- if (gr_close () == 0) { ++ if (gr_close (true) == 0) { + fprintf (stderr, + _("%s: failure while closing read-only %s\n"), + Prog, gr_dbname ()); +diff --git a/src/groupadd.c b/src/groupadd.c +index a0d5adeb..d9a9d36c 100644 +--- a/src/groupadd.c ++++ b/src/groupadd.c +@@ -274,7 +274,7 @@ check_new_name(void) + static void close_files (void) + { + /* First, write the changes in the regular group database */ +- if (gr_close () == 0) { ++ if (gr_close (true) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, gr_dbname ()); +diff --git a/src/groupdel.c b/src/groupdel.c +index 3d289fef..c52a2ae7 100644 +--- a/src/groupdel.c ++++ b/src/groupdel.c +@@ -149,7 +149,7 @@ static void grp_update (void) + static void close_files (void) + { + /* First, write the changes in the regular group database */ +- if (gr_close () == 0) { ++ if (gr_close (true) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, gr_dbname ()); +diff --git a/src/groupmems.c b/src/groupmems.c +index d37b237f..fff9ae10 100644 +--- a/src/groupmems.c ++++ b/src/groupmems.c +@@ -522,7 +522,7 @@ static void open_files (void) + + static void close_files (void) + { +- if ((gr_close () == 0) && !list) { ++ if ((gr_close (true) == 0) && !list) { + fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ())); + fail_exit (EXIT_GROUP_FILE); +diff --git a/src/groupmod.c b/src/groupmod.c +index 14b7e746..49b68c55 100644 +--- a/src/groupmod.c ++++ b/src/groupmod.c +@@ -481,7 +481,7 @@ static void process_flags (int argc, char **argv) + */ + static void close_files (void) + { +- if (gr_close () == 0) { ++ if (gr_close (true) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, gr_dbname ()); +diff --git a/src/grpck.c b/src/grpck.c +index 5fcf6fad..db8f1e68 100644 +--- a/src/grpck.c ++++ b/src/grpck.c +@@ -321,7 +321,7 @@ static void close_files (bool changed) + * changes to the files. + */ + if (changed) { +- if (gr_close () == 0) { ++ if (gr_close (true) == 0) { + fprintf (stderr, _("%s: failure while writing changes to %s\n"), + Prog, grp_file); + fail_exit (E_CANT_UPDATE); +diff --git a/src/grpconv.c b/src/grpconv.c +index 1b31cb85..e7928a4a 100644 +--- a/src/grpconv.c ++++ b/src/grpconv.c +@@ -241,7 +241,7 @@ int main (int argc, char **argv) + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ())); + fail_exit (3); + } +- if (gr_close () == 0) { ++ if (gr_close (true) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, gr_dbname ()); +diff --git a/src/grpunconv.c b/src/grpunconv.c +index ea65a329..63597da1 100644 +--- a/src/grpunconv.c ++++ b/src/grpunconv.c +@@ -193,7 +193,7 @@ int main (int argc, char **argv) + + (void) sgr_close (); /* was only open O_RDONLY */ + +- if (gr_close () == 0) { ++ if (gr_close (true) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, gr_dbname ()); +diff --git a/src/newusers.c b/src/newusers.c +index 43672dd2..29d3a536 100644 +--- a/src/newusers.c ++++ b/src/newusers.c +@@ -969,7 +969,7 @@ static void close_files (void) + spw_locked = false; + } + +- if (gr_close () == 0) { ++ if (gr_close (true) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, gr_dbname ()); +diff --git a/src/useradd.c b/src/useradd.c +index 8a7df6cf..f52e5483 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -1664,7 +1664,7 @@ static void close_group_files (void) + if (!do_grp_update) + return; + +- if (gr_close() == 0) { ++ if (gr_close(true) == 0) { + fprintf(stderr, + _("%s: failure while writing changes to %s\n"), + Prog, gr_dbname()); +diff --git a/src/userdel.c b/src/userdel.c +index b87f2459..b0e0d541 100644 +--- a/src/userdel.c ++++ b/src/userdel.c +@@ -417,7 +417,7 @@ static void close_files (void) + spw_locked = false; + } + +- if (gr_close () == 0) { ++ if (gr_close (true) == 0) { + fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ())); + fail_exit (E_GRP_UPDATE); +diff --git a/src/usermod.c b/src/usermod.c +index d741508a..d1d26eaa 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -1487,7 +1487,7 @@ static void close_files (void) + } + + if (Gflg || lflg) { +- if (gr_close () == 0) { ++ if (gr_close (true) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, gr_dbname ()); +-- +2.50.0 + + +From f4a67dd6281a513b56c15aa1a3f292ca05674f13 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Fri, 25 Apr 2025 15:32:05 +0200 +Subject: [PATCH 05/15] lib/, src/: add SELinux control flag in sgr_close() + +Expand sgr_close() interface to add a control flag for SELinux file +context processing. + +Signed-off-by: Iker Pedrosa +--- + lib/sgroupio.c | 4 ++-- + lib/sgroupio.h | 2 +- + src/chgpasswd.c | 2 +- + src/gpasswd.c | 4 ++-- + src/groupadd.c | 2 +- + src/groupdel.c | 2 +- + src/groupmems.c | 2 +- + src/groupmod.c | 2 +- + src/grpck.c | 2 +- + src/grpconv.c | 2 +- + src/grpunconv.c | 2 +- + src/newusers.c | 2 +- + src/useradd.c | 2 +- + src/userdel.c | 2 +- + src/usermod.c | 2 +- + 15 files changed, 17 insertions(+), 17 deletions(-) + +diff --git a/lib/sgroupio.c b/lib/sgroupio.c +index 659dcd06..025584ad 100644 +--- a/lib/sgroupio.c ++++ b/lib/sgroupio.c +@@ -276,9 +276,9 @@ int sgr_rewind (void) + return commonio_next (&gshadow_db); + } + +-int sgr_close (void) ++int sgr_close (bool process_selinux) + { +- return commonio_close (&gshadow_db, true); ++ return commonio_close (&gshadow_db, process_selinux); + } + + int sgr_unlock (void) +diff --git a/lib/sgroupio.h b/lib/sgroupio.h +index 3474a985..0e25fc0b 100644 +--- a/lib/sgroupio.h ++++ b/lib/sgroupio.h +@@ -12,7 +12,7 @@ + #ifndef _SGROUPIO_H + #define _SGROUPIO_H + +-extern int sgr_close (void); ++extern int sgr_close (bool process_selinux); + extern bool sgr_file_present (void); + extern /*@observer@*/ /*@null@*/const struct sgrp *sgr_locate (const char *name); + extern int sgr_lock (void); +diff --git a/src/chgpasswd.c b/src/chgpasswd.c +index 9b686ef0..47402ecc 100644 +--- a/src/chgpasswd.c ++++ b/src/chgpasswd.c +@@ -381,7 +381,7 @@ static void close_files (void) + { + #ifdef SHADOWGRP + if (is_shadow_grp) { +- if (sgr_close () == 0) { ++ if (sgr_close (true) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, sgr_dbname ()); +diff --git a/src/gpasswd.c b/src/gpasswd.c +index 1013f004..a49b9140 100644 +--- a/src/gpasswd.c ++++ b/src/gpasswd.c +@@ -607,7 +607,7 @@ static void close_files (void) + + #ifdef SHADOWGRP + if (is_shadowgrp) { +- if (sgr_close () == 0) { ++ if (sgr_close (true) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, sgr_dbname ()); +@@ -762,7 +762,7 @@ static void get_group (struct group *gr) + sg->sg_adm[0] = NULL; + + } +- if (sgr_close () == 0) { ++ if (sgr_close (true) == 0) { + fprintf (stderr, + _("%s: failure while closing read-only %s\n"), + Prog, sgr_dbname ()); +diff --git a/src/groupadd.c b/src/groupadd.c +index d9a9d36c..7cfb0eb5 100644 +--- a/src/groupadd.c ++++ b/src/groupadd.c +@@ -295,7 +295,7 @@ static void close_files (void) + /* Now, write the changes in the shadow database */ + #ifdef SHADOWGRP + if (is_shadow_grp) { +- if (sgr_close () == 0) { ++ if (sgr_close (true) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, sgr_dbname ()); +diff --git a/src/groupdel.c b/src/groupdel.c +index c52a2ae7..56123a7b 100644 +--- a/src/groupdel.c ++++ b/src/groupdel.c +@@ -173,7 +173,7 @@ static void close_files (void) + /* Then, write the changes in the shadow database */ + #ifdef SHADOWGRP + if (is_shadow_grp) { +- if (sgr_close () == 0) { ++ if (sgr_close (true) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, sgr_dbname ()); +diff --git a/src/groupmems.c b/src/groupmems.c +index fff9ae10..5976b074 100644 +--- a/src/groupmems.c ++++ b/src/groupmems.c +@@ -538,7 +538,7 @@ static void close_files (void) + + #ifdef SHADOWGRP + if (is_shadowgrp) { +- if ((sgr_close () == 0) && !list) { ++ if ((sgr_close (true) == 0) && !list) { + fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ())); + fail_exit (EXIT_GROUP_FILE); +diff --git a/src/groupmod.c b/src/groupmod.c +index 49b68c55..3c258feb 100644 +--- a/src/groupmod.c ++++ b/src/groupmod.c +@@ -504,7 +504,7 @@ static void close_files (void) + #ifdef SHADOWGRP + if ( is_shadow_grp + && (pflg || nflg || user_list)) { +- if (sgr_close () == 0) { ++ if (sgr_close (true) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, sgr_dbname ()); +diff --git a/src/grpck.c b/src/grpck.c +index db8f1e68..872f882f 100644 +--- a/src/grpck.c ++++ b/src/grpck.c +@@ -327,7 +327,7 @@ static void close_files (bool changed) + fail_exit (E_CANT_UPDATE); + } + #ifdef SHADOWGRP +- if (is_shadow && (sgr_close () == 0)) { ++ if (is_shadow && (sgr_close (true) == 0)) { + fprintf (stderr, _("%s: failure while writing changes to %s\n"), + Prog, sgr_file); + fail_exit (E_CANT_UPDATE); +diff --git a/src/grpconv.c b/src/grpconv.c +index e7928a4a..d9c59fc9 100644 +--- a/src/grpconv.c ++++ b/src/grpconv.c +@@ -234,7 +234,7 @@ int main (int argc, char **argv) + } + } + +- if (sgr_close () == 0) { ++ if (sgr_close (true) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, sgr_dbname ()); +diff --git a/src/grpunconv.c b/src/grpunconv.c +index 63597da1..03fc824e 100644 +--- a/src/grpunconv.c ++++ b/src/grpunconv.c +@@ -191,7 +191,7 @@ int main (int argc, char **argv) + } + } + +- (void) sgr_close (); /* was only open O_RDONLY */ ++ (void) sgr_close (true); /* was only open O_RDONLY */ + + if (gr_close (true) == 0) { + fprintf (stderr, +diff --git a/src/newusers.c b/src/newusers.c +index 29d3a536..19a32863 100644 +--- a/src/newusers.c ++++ b/src/newusers.c +@@ -1002,7 +1002,7 @@ static void close_files (void) + + #ifdef SHADOWGRP + if (is_shadow_grp) { +- if (sgr_close () == 0) { ++ if (sgr_close (true) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, sgr_dbname ()); +diff --git a/src/useradd.c b/src/useradd.c +index f52e5483..7f596673 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -1672,7 +1672,7 @@ static void close_group_files (void) + fail_exit(E_GRP_UPDATE); + } + #ifdef SHADOWGRP +- if (is_shadow_grp && sgr_close() == 0) { ++ if (is_shadow_grp && sgr_close(true) == 0) { + fprintf(stderr, + _("%s: failure while writing changes to %s\n"), + Prog, sgr_dbname()); +diff --git a/src/userdel.c b/src/userdel.c +index b0e0d541..1829ba4d 100644 +--- a/src/userdel.c ++++ b/src/userdel.c +@@ -431,7 +431,7 @@ static void close_files (void) + + #ifdef SHADOWGRP + if (is_shadow_grp) { +- if (sgr_close () == 0) { ++ if (sgr_close (true) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ())); +diff --git a/src/usermod.c b/src/usermod.c +index d1d26eaa..dbcb32b2 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -1498,7 +1498,7 @@ static void close_files (void) + } + #ifdef SHADOWGRP + if (is_shadow_grp) { +- if (sgr_close () == 0) { ++ if (sgr_close (true) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, sgr_dbname ()); +-- +2.50.0 + + +From f3dce7ede9c3f267e810fec3500498e76a305d8a Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Fri, 25 Apr 2025 15:35:48 +0200 +Subject: [PATCH 06/15] lib/, src/: add SELinux control flag in sub_uid_close() + +Expand sub_uid_close() interface to add a control flag for SELinux file +context processing. + +Signed-off-by: Iker Pedrosa +--- + lib/subordinateio.c | 14 +++++++------- + lib/subordinateio.h | 2 +- + lib/user_busy.c | 10 +++++----- + src/newuidmap.c | 2 +- + src/newusers.c | 2 +- + src/useradd.c | 2 +- + src/userdel.c | 2 +- + src/usermod.c | 2 +- + 8 files changed, 18 insertions(+), 18 deletions(-) + +diff --git a/lib/subordinateio.c b/lib/subordinateio.c +index 3638ec61..206a1348 100644 +--- a/lib/subordinateio.c ++++ b/lib/subordinateio.c +@@ -590,7 +590,7 @@ static bool have_range(struct commonio_db *db, + + if (doclose) { + if (db == &subordinate_uid_db) +- sub_uid_close(); ++ sub_uid_close(true); + else + sub_gid_close(); + } +@@ -668,9 +668,9 @@ int sub_uid_remove (const char *owner, uid_t start, unsigned long count) + return remove_range (&subordinate_uid_db, owner, start, count); + } + +-int sub_uid_close (void) ++int sub_uid_close (bool process_selinux) + { +- return commonio_close (&subordinate_uid_db, true); ++ return commonio_close (&subordinate_uid_db, process_selinux); + } + + int sub_uid_unlock (void) +@@ -907,7 +907,7 @@ int list_owner_ranges(const char *owner, enum subid_type id_type, struct subid_r + + out: + if (id_type == ID_TYPE_UID) +- sub_uid_close(); ++ sub_uid_close(true); + else + sub_gid_close(); + +@@ -998,7 +998,7 @@ int find_subid_owners(unsigned long id, enum subid_type id_type, uid_t **uids) + } + + if (id_type == ID_TYPE_UID) +- sub_uid_close(); ++ sub_uid_close(true); + else + sub_gid_close(); + +@@ -1068,7 +1068,7 @@ bool new_subid_range(struct subordinate_range *range, enum subid_type id_type, b + + out: + if (id_type == ID_TYPE_UID) { +- sub_uid_close(); ++ sub_uid_close(true); + sub_uid_unlock(); + } else { + sub_gid_close(); +@@ -1118,7 +1118,7 @@ bool release_subid_range(struct subordinate_range *range, enum subid_type id_typ + ret = remove_range(db, range->owner, range->start, range->count) == 1; + + if (id_type == ID_TYPE_UID) { +- sub_uid_close(); ++ sub_uid_close(true); + sub_uid_unlock(); + } else { + sub_gid_close(); +diff --git a/lib/subordinateio.h b/lib/subordinateio.h +index 3d1a0547..d16c8b9e 100644 +--- a/lib/subordinateio.h ++++ b/lib/subordinateio.h +@@ -13,7 +13,7 @@ + + #include "../libsubid/subid.h" + +-extern int sub_uid_close(void); ++extern int sub_uid_close(bool process_selinux); + extern bool have_sub_uids(const char *owner, uid_t start, unsigned long count); + extern bool sub_uid_file_present (void); + extern bool local_sub_uid_assigned(const char *owner); +diff --git a/lib/user_busy.c b/lib/user_busy.c +index d689d34d..ab1dd5a4 100644 +--- a/lib/user_busy.c ++++ b/lib/user_busy.c +@@ -180,7 +180,7 @@ static int user_busy_processes (const char *name, uid_t uid) + if (proc == NULL) { + perror ("opendir /proc"); + #ifdef ENABLE_SUBIDS +- sub_uid_close(); ++ sub_uid_close(true); + #endif + return 0; + } +@@ -188,7 +188,7 @@ static int user_busy_processes (const char *name, uid_t uid) + perror ("stat (\"/\")"); + (void) closedir (proc); + #ifdef ENABLE_SUBIDS +- sub_uid_close(); ++ sub_uid_close(true); + #endif + return 0; + } +@@ -225,7 +225,7 @@ static int user_busy_processes (const char *name, uid_t uid) + if (check_status (name, tmp_d_name, uid) != 0) { + (void) closedir (proc); + #ifdef ENABLE_SUBIDS +- sub_uid_close(); ++ sub_uid_close(true); + #endif + fprintf (log_get_logfd(), + _("%s: user %s is currently used by process %d\n"), +@@ -248,7 +248,7 @@ static int user_busy_processes (const char *name, uid_t uid) + (void) closedir (proc); + (void) closedir (task_dir); + #ifdef ENABLE_SUBIDS +- sub_uid_close(); ++ sub_uid_close(true); + #endif + fprintf (log_get_logfd(), + _("%s: user %s is currently used by process %d\n"), +@@ -264,7 +264,7 @@ static int user_busy_processes (const char *name, uid_t uid) + + (void) closedir (proc); + #ifdef ENABLE_SUBIDS +- sub_uid_close(); ++ sub_uid_close(true); + #endif /* ENABLE_SUBIDS */ + return 0; + } +diff --git a/src/newuidmap.c b/src/newuidmap.c +index 894c5ec8..90bd6de5 100644 +--- a/src/newuidmap.c ++++ b/src/newuidmap.c +@@ -158,7 +158,7 @@ int main(int argc, char **argv) + verify_ranges(pw, ranges, mappings); + + write_mapping(proc_dir_fd, ranges, mappings, "uid_map", pw->pw_uid); +- sub_uid_close(); ++ sub_uid_close(true); + + return EXIT_SUCCESS; + } +diff --git a/src/newusers.c b/src/newusers.c +index 19a32863..d71a792b 100644 +--- a/src/newusers.c ++++ b/src/newusers.c +@@ -977,7 +977,7 @@ static void close_files (void) + fail_exit (EXIT_FAILURE); + } + #ifdef ENABLE_SUBIDS +- if (is_sub_uid && (sub_uid_close () == 0)) { ++ if (is_sub_uid && (sub_uid_close (true) == 0)) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), Prog, sub_uid_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_uid_dbname ())); +diff --git a/src/useradd.c b/src/useradd.c +index 7f596673..971fec55 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -1579,7 +1579,7 @@ static void close_files (void) + close_group_files (); + + #ifdef ENABLE_SUBIDS +- if (is_sub_uid && (sub_uid_close () == 0)) { ++ if (is_sub_uid && (sub_uid_close (true) == 0)) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), Prog, sub_uid_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_uid_dbname ())); +diff --git a/src/userdel.c b/src/userdel.c +index 1829ba4d..8fe9f4e2 100644 +--- a/src/userdel.c ++++ b/src/userdel.c +@@ -449,7 +449,7 @@ static void close_files (void) + + #ifdef ENABLE_SUBIDS + if (is_sub_uid) { +- if (sub_uid_close () == 0) { ++ if (sub_uid_close (true) == 0) { + fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sub_uid_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_uid_dbname ())); + fail_exit (E_SUB_UID_UPDATE); +diff --git a/src/usermod.c b/src/usermod.c +index dbcb32b2..440c2406 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -1561,7 +1561,7 @@ static void close_files (void) + + #ifdef ENABLE_SUBIDS + if (vflg || Vflg) { +- if (sub_uid_close () == 0) { ++ if (sub_uid_close (true) == 0) { + fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sub_uid_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_uid_dbname ())); + fail_exit (E_SUB_UID_UPDATE); +-- +2.50.0 + + +From ab2a2656e442043d5b39e1320552ba9850aabd27 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Fri, 25 Apr 2025 15:38:18 +0200 +Subject: [PATCH 07/15] lib/, src/: add SELinux control flag in sub_gid_close() + +Expand sub_gid_close() interface to add a control flag for SELinux file +context processing. + +Signed-off-by: Iker Pedrosa +--- + lib/subordinateio.c | 14 +++++++------- + lib/subordinateio.h | 2 +- + src/newgidmap.c | 2 +- + src/newusers.c | 2 +- + src/useradd.c | 2 +- + src/userdel.c | 2 +- + src/usermod.c | 2 +- + 7 files changed, 13 insertions(+), 13 deletions(-) + +diff --git a/lib/subordinateio.c b/lib/subordinateio.c +index 206a1348..e2c2375a 100644 +--- a/lib/subordinateio.c ++++ b/lib/subordinateio.c +@@ -592,7 +592,7 @@ static bool have_range(struct commonio_db *db, + if (db == &subordinate_uid_db) + sub_uid_close(true); + else +- sub_gid_close(); ++ sub_gid_close(true); + } + + return ret; +@@ -775,9 +775,9 @@ int sub_gid_remove (const char *owner, gid_t start, unsigned long count) + return remove_range (&subordinate_gid_db, owner, start, count); + } + +-int sub_gid_close (void) ++int sub_gid_close (bool process_selinux) + { +- return commonio_close (&subordinate_gid_db, true); ++ return commonio_close (&subordinate_gid_db, process_selinux); + } + + int sub_gid_unlock (void) +@@ -909,7 +909,7 @@ out: + if (id_type == ID_TYPE_UID) + sub_uid_close(true); + else +- sub_gid_close(); ++ sub_gid_close(true); + + *in_ranges = ranges; + return count; +@@ -1000,7 +1000,7 @@ int find_subid_owners(unsigned long id, enum subid_type id_type, uid_t **uids) + if (id_type == ID_TYPE_UID) + sub_uid_close(true); + else +- sub_gid_close(); ++ sub_gid_close(true); + + return n; + } +@@ -1071,7 +1071,7 @@ out: + sub_uid_close(true); + sub_uid_unlock(); + } else { +- sub_gid_close(); ++ sub_gid_close(true); + sub_gid_unlock(); + } + +@@ -1121,7 +1121,7 @@ bool release_subid_range(struct subordinate_range *range, enum subid_type id_typ + sub_uid_close(true); + sub_uid_unlock(); + } else { +- sub_gid_close(); ++ sub_gid_close(true); + sub_gid_unlock(); + } + +diff --git a/lib/subordinateio.h b/lib/subordinateio.h +index d16c8b9e..63f5b1fb 100644 +--- a/lib/subordinateio.h ++++ b/lib/subordinateio.h +@@ -31,7 +31,7 @@ extern bool release_subid_range(struct subordinate_range *range, enum subid_type + extern int find_subid_owners(unsigned long id, enum subid_type id_type, uid_t **uids); + extern void free_subordinate_ranges(struct subordinate_range **ranges, int count); + +-extern int sub_gid_close(void); ++extern int sub_gid_close(bool process_selinux); + extern bool have_sub_gids(const char *owner, gid_t start, unsigned long count); + extern bool sub_gid_file_present (void); + extern bool local_sub_gid_assigned(const char *owner); +diff --git a/src/newgidmap.c b/src/newgidmap.c +index 3463e850..7ce22b5a 100644 +--- a/src/newgidmap.c ++++ b/src/newgidmap.c +@@ -230,7 +230,7 @@ int main(int argc, char **argv) + + write_setgroups(proc_dir_fd, allow_setgroups); + write_mapping(proc_dir_fd, ranges, mappings, "gid_map", pw->pw_uid); +- sub_gid_close(); ++ sub_gid_close(true); + + return EXIT_SUCCESS; + } +diff --git a/src/newusers.c b/src/newusers.c +index d71a792b..8cd11a71 100644 +--- a/src/newusers.c ++++ b/src/newusers.c +@@ -983,7 +983,7 @@ static void close_files (void) + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_uid_dbname ())); + fail_exit (EXIT_FAILURE); + } +- if (is_sub_gid && (sub_gid_close () == 0)) { ++ if (is_sub_gid && (sub_gid_close (true) == 0)) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), Prog, sub_gid_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_gid_dbname ())); +diff --git a/src/useradd.c b/src/useradd.c +index 971fec55..3d2fdb35 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -1585,7 +1585,7 @@ static void close_files (void) + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_uid_dbname ())); + fail_exit (E_SUB_UID_UPDATE); + } +- if (is_sub_gid && (sub_gid_close () == 0)) { ++ if (is_sub_gid && (sub_gid_close (true) == 0)) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), Prog, sub_gid_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_gid_dbname ())); +diff --git a/src/userdel.c b/src/userdel.c +index 8fe9f4e2..7dcbd923 100644 +--- a/src/userdel.c ++++ b/src/userdel.c +@@ -463,7 +463,7 @@ static void close_files (void) + } + + if (is_sub_gid) { +- if (sub_gid_close () == 0) { ++ if (sub_gid_close (true) == 0) { + fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sub_gid_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_gid_dbname ())); + fail_exit (E_SUB_GID_UPDATE); +diff --git a/src/usermod.c b/src/usermod.c +index 440c2406..534bdc74 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -1574,7 +1574,7 @@ static void close_files (void) + sub_uid_locked = false; + } + if (wflg || Wflg) { +- if (sub_gid_close () == 0) { ++ if (sub_gid_close (true) == 0) { + fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sub_gid_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_gid_dbname ())); + fail_exit (E_SUB_GID_UPDATE); +-- +2.50.0 + + +From 9161c63be728bfba7545bac1e4cbde8a069ad4e6 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Fri, 25 Apr 2025 15:44:06 +0200 +Subject: [PATCH 08/15] lib/: add SELinux control flag in commonio_unlock() + +Expand commonio_unlock() interface to add a control flag for SELinux +file context processing. + +Signed-off-by: Iker Pedrosa +--- + lib/commonio.c | 4 ++-- + lib/commonio.h | 2 +- + lib/groupio.c | 2 +- + lib/pwio.c | 2 +- + lib/sgroupio.c | 2 +- + lib/shadowio.c | 2 +- + lib/subordinateio.c | 4 ++-- + 7 files changed, 9 insertions(+), 9 deletions(-) + +diff --git a/lib/commonio.c b/lib/commonio.c +index 7ee6df4d..19653e7e 100644 +--- a/lib/commonio.c ++++ b/lib/commonio.c +@@ -467,13 +467,13 @@ static void dec_lock_count (void) + } + + +-int commonio_unlock (struct commonio_db *db) ++int commonio_unlock (struct commonio_db *db, bool process_selinux) + { + char lock[1029]; + + if (db->isopen) { + db->readonly = true; +- if (commonio_close (db, true) == 0) { ++ if (commonio_close (db, process_selinux) == 0) { + if (db->locked) { + dec_lock_count (); + } +diff --git a/lib/commonio.h b/lib/commonio.h +index dadc0500..8b8f5cf4 100644 +--- a/lib/commonio.h ++++ b/lib/commonio.h +@@ -139,7 +139,7 @@ extern int commonio_remove (struct commonio_db *, const char *); + extern int commonio_rewind (struct commonio_db *); + extern /*@observer@*/ /*@null@*/const void *commonio_next (struct commonio_db *); + extern int commonio_close (struct commonio_db *, bool); +-extern int commonio_unlock (struct commonio_db *); ++extern int commonio_unlock (struct commonio_db *, bool); + extern void commonio_del_entry (struct commonio_db *, + const struct commonio_entry *); + extern int commonio_sort_wrt (struct commonio_db *shadow, +diff --git a/lib/groupio.c b/lib/groupio.c +index 837e4c47..6ad4ae69 100644 +--- a/lib/groupio.c ++++ b/lib/groupio.c +@@ -191,7 +191,7 @@ int gr_close (bool process_selinux) + + int gr_unlock (void) + { +- return commonio_unlock (&group_db); ++ return commonio_unlock (&group_db, true); + } + + void __gr_set_changed (void) +diff --git a/lib/pwio.c b/lib/pwio.c +index c5c1cdb1..c5dcb904 100644 +--- a/lib/pwio.c ++++ b/lib/pwio.c +@@ -163,7 +163,7 @@ int pw_close (bool process_selinux) + + int pw_unlock (void) + { +- return commonio_unlock (&passwd_db); ++ return commonio_unlock (&passwd_db, true); + } + + /*@null@*/struct commonio_entry *__pw_get_head (void) +diff --git a/lib/sgroupio.c b/lib/sgroupio.c +index 025584ad..dbabcc36 100644 +--- a/lib/sgroupio.c ++++ b/lib/sgroupio.c +@@ -283,7 +283,7 @@ int sgr_close (bool process_selinux) + + int sgr_unlock (void) + { +- return commonio_unlock (&gshadow_db); ++ return commonio_unlock (&gshadow_db, true); + } + + void __sgr_set_changed (void) +diff --git a/lib/shadowio.c b/lib/shadowio.c +index a109576d..9866af6d 100644 +--- a/lib/shadowio.c ++++ b/lib/shadowio.c +@@ -211,7 +211,7 @@ int spw_unlock (void) + + if (!getdef_bool ("USE_TCB")) { + #endif /* WITH_TCB */ +- return commonio_unlock (&shadow_db); ++ return commonio_unlock (&shadow_db, true); + #ifdef WITH_TCB + } + if (shadowtcb_drop_priv () == SHADOWTCB_FAILURE) { +diff --git a/lib/subordinateio.c b/lib/subordinateio.c +index e2c2375a..9587e1a9 100644 +--- a/lib/subordinateio.c ++++ b/lib/subordinateio.c +@@ -675,7 +675,7 @@ int sub_uid_close (bool process_selinux) + + int sub_uid_unlock (void) + { +- return commonio_unlock (&subordinate_uid_db); ++ return commonio_unlock (&subordinate_uid_db, true); + } + + uid_t sub_uid_find_free_range(uid_t min, uid_t max, unsigned long count) +@@ -782,7 +782,7 @@ int sub_gid_close (bool process_selinux) + + int sub_gid_unlock (void) + { +- return commonio_unlock (&subordinate_gid_db); ++ return commonio_unlock (&subordinate_gid_db, true); + } + + gid_t sub_gid_find_free_range(gid_t min, gid_t max, unsigned long count) +-- +2.50.0 + + +From 9609c3ba7d4097c2ff63ee6ccfa6b74c41fbde5e Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Fri, 25 Apr 2025 15:53:17 +0200 +Subject: [PATCH 09/15] lib/, src/: add SELinux control flag in pw_unlock() + +Expand pw_unlock() interface to add a control flag for SELinux file +context processing. + +Signed-off-by: Iker Pedrosa +--- + lib/cleanup_user.c | 2 +- + lib/lockpw.c | 4 ++-- + lib/pwio.c | 4 ++-- + lib/pwio.h | 2 +- + src/chage.c | 4 ++-- + src/chfn.c | 4 ++-- + src/chpasswd.c | 4 ++-- + src/chsh.c | 4 ++-- + src/newusers.c | 4 ++-- + src/passwd.c | 4 ++-- + src/pwck.c | 4 ++-- + src/pwconv.c | 4 ++-- + src/pwunconv.c | 4 ++-- + src/useradd.c | 4 ++-- + src/userdel.c | 4 ++-- + src/usermod.c | 4 ++-- + 16 files changed, 30 insertions(+), 30 deletions(-) + +diff --git a/lib/cleanup_user.c b/lib/cleanup_user.c +index 809caaf3..a661f5e9 100644 +--- a/lib/cleanup_user.c ++++ b/lib/cleanup_user.c +@@ -98,7 +98,7 @@ void cleanup_report_add_user_shadow (void *user_name) + */ + void cleanup_unlock_passwd (MAYBE_UNUSED void *arg) + { +- if (pw_unlock () == 0) { ++ if (pw_unlock (true) == 0) { + fprintf (log_get_logfd(), + _("%s: failed to unlock %s\n"), + log_get_progname(), pw_dbname ()); +diff --git a/lib/lockpw.c b/lib/lockpw.c +index 15e7c8f4..f73c434a 100644 +--- a/lib/lockpw.c ++++ b/lib/lockpw.c +@@ -56,7 +56,7 @@ int lckpwdf (void) + */ + + if (i == 15) { +- pw_unlock (); ++ pw_unlock (true); + return -1; + } + +@@ -78,7 +78,7 @@ int ulckpwdf (void) + * Unlock both files. + */ + +- return (pw_unlock () && spw_unlock ())? 0 : -1; ++ return (pw_unlock (true) && spw_unlock ())? 0 : -1; + } + #else + extern int ISO_C_forbids_an_empty_translation_unit; +diff --git a/lib/pwio.c b/lib/pwio.c +index c5dcb904..78146c37 100644 +--- a/lib/pwio.c ++++ b/lib/pwio.c +@@ -161,9 +161,9 @@ int pw_close (bool process_selinux) + return commonio_close (&passwd_db, process_selinux); + } + +-int pw_unlock (void) ++int pw_unlock (bool process_selinux) + { +- return commonio_unlock (&passwd_db, true); ++ return commonio_unlock (&passwd_db, process_selinux); + } + + /*@null@*/struct commonio_entry *__pw_get_head (void) +diff --git a/lib/pwio.h b/lib/pwio.h +index b051a7e7..0903b8bd 100644 +--- a/lib/pwio.h ++++ b/lib/pwio.h +@@ -26,7 +26,7 @@ extern /*@observer@*/ /*@null@*/const struct passwd *pw_next (void); + extern int pw_open (int mode); + extern int pw_remove (const char *name); + extern int pw_rewind (void); +-extern int pw_unlock (void); ++extern int pw_unlock (bool process_selinux); + extern int pw_update (const struct passwd *pw); + extern int pw_sort (void); + +diff --git a/src/chage.c b/src/chage.c +index a59428c5..d3a42ccf 100644 +--- a/src/chage.c ++++ b/src/chage.c +@@ -101,7 +101,7 @@ fail_exit (int code) + } + } + if (pw_locked) { +- if (pw_unlock () == 0) { ++ if (pw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +@@ -568,7 +568,7 @@ static void close_files (void) + /* continue */ + } + spw_locked = false; +- if (pw_unlock () == 0) { ++ if (pw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +diff --git a/src/chfn.c b/src/chfn.c +index abf88cc8..dca81486 100644 +--- a/src/chfn.c ++++ b/src/chfn.c +@@ -79,7 +79,7 @@ static void get_old_fields (const char *gecos); + static void fail_exit (int code) + { + if (pw_locked) { +- if (pw_unlock () == 0) { ++ if (pw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +@@ -498,7 +498,7 @@ static void update_gecos (const char *user, char *gecos) + SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); + fail_exit (E_NOPERM); + } +- if (pw_unlock () == 0) { ++ if (pw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +diff --git a/src/chpasswd.c b/src/chpasswd.c +index e3d8dcef..5323c520 100644 +--- a/src/chpasswd.c ++++ b/src/chpasswd.c +@@ -81,7 +81,7 @@ static void close_files (void); + static void fail_exit (int code) + { + if (pw_locked) { +- if (pw_unlock () == 0) { ++ if (pw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +@@ -400,7 +400,7 @@ static void close_files (void) + SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); + fail_exit (1); + } +- if (pw_unlock () == 0) { ++ if (pw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +diff --git a/src/chsh.c b/src/chsh.c +index b5ae28da..4403d412 100644 +--- a/src/chsh.c ++++ b/src/chsh.c +@@ -78,7 +78,7 @@ static void + fail_exit (int code) + { + if (pw_locked) { +- if (pw_unlock () == 0) { ++ if (pw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +@@ -433,7 +433,7 @@ static void update_shell (const char *user, char *newshell) + SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); + fail_exit (1); + } +- if (pw_unlock () == 0) { ++ if (pw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +diff --git a/src/newusers.c b/src/newusers.c +index 8cd11a71..669b6236 100644 +--- a/src/newusers.c ++++ b/src/newusers.c +@@ -172,7 +172,7 @@ static void fail_exit (int code) + } + } + if (pw_locked) { +- if (pw_unlock () == 0) { ++ if (pw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +@@ -944,7 +944,7 @@ static void close_files (void) + SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); + fail_exit (EXIT_FAILURE); + } +- if (pw_unlock () == 0) { ++ if (pw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +diff --git a/src/passwd.c b/src/passwd.c +index 01efb285..8a55d797 100644 +--- a/src/passwd.c ++++ b/src/passwd.c +@@ -483,7 +483,7 @@ static void + fail_exit (int status) + { + if (pw_locked) { +- if (pw_unlock () == 0) { ++ if (pw_unlock (true) == 0) { + (void) fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +@@ -593,7 +593,7 @@ static void update_noshadow (void) + SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); + fail_exit (E_FAILURE); + } +- if (pw_unlock () == 0) { ++ if (pw_unlock (true) == 0) { + (void) fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, pw_dbname ()); +diff --git a/src/pwck.c b/src/pwck.c +index 718b639f..f30c5289 100644 +--- a/src/pwck.c ++++ b/src/pwck.c +@@ -96,7 +96,7 @@ static void fail_exit (int code) + } + + if (pw_locked) { +- if (pw_unlock () == 0) { ++ if (pw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + if (use_system_pw_file) { + SYSLOG ((LOG_ERR, "failed to unlock %s", +@@ -351,7 +351,7 @@ static void close_files (bool changed) + } + spw_locked = false; + if (pw_locked) { +- if (pw_unlock () == 0) { ++ if (pw_unlock (true) == 0) { + fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, pw_dbname ()); +diff --git a/src/pwconv.c b/src/pwconv.c +index 296b527a..82181bb4 100644 +--- a/src/pwconv.c ++++ b/src/pwconv.c +@@ -83,7 +83,7 @@ static void process_flags (int argc, char **argv); + static void fail_exit (int status) + { + if (pw_locked) { +- if (pw_unlock () == 0) { ++ if (pw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +@@ -299,7 +299,7 @@ int main (int argc, char **argv) + /* continue */ + } + +- if (pw_unlock () == 0) { ++ if (pw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +diff --git a/src/pwunconv.c b/src/pwunconv.c +index e15c8c06..72944fe5 100644 +--- a/src/pwunconv.c ++++ b/src/pwunconv.c +@@ -54,7 +54,7 @@ static void fail_exit (int status) + } + } + if (pw_locked) { +- if (pw_unlock () == 0) { ++ if (pw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +@@ -227,7 +227,7 @@ int main (int argc, char **argv) + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + /* continue */ + } +- if (pw_unlock () == 0) { ++ if (pw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +diff --git a/src/useradd.c b/src/useradd.c +index 3d2fdb35..aa070f2d 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -270,7 +270,7 @@ static void fail_exit (int code) + SYSLOG((LOG_ERR, "failed to unlock %s", spw_dbname())); + /* continue */ + } +- if (pw_locked && pw_unlock() == 0) { ++ if (pw_locked && pw_unlock(true) == 0) { + fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname()); + SYSLOG((LOG_ERR, "failed to unlock %s", pw_dbname())); + /* continue */ +@@ -1606,7 +1606,7 @@ static void close_files (void) + } + spw_locked = false; + } +- if (pw_unlock () == 0) { ++ if (pw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + #ifdef WITH_AUDIT +diff --git a/src/userdel.c b/src/userdel.c +index 7dcbd923..b4e87820 100644 +--- a/src/userdel.c ++++ b/src/userdel.c +@@ -395,7 +395,7 @@ static void close_files (void) + SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); + fail_exit (E_PW_UPDATE); + } +- if (pw_unlock () == 0) { ++ if (pw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +@@ -484,7 +484,7 @@ static void close_files (void) + static void fail_exit (int code) + { + if (pw_locked) { +- if (pw_unlock () == 0) { ++ if (pw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +diff --git a/src/usermod.c b/src/usermod.c +index 534bdc74..6f761404 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -655,7 +655,7 @@ fail_exit (int code) + } + } + if (pw_locked) { +- if (pw_unlock () == 0) { ++ if (pw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +@@ -1544,7 +1544,7 @@ static void close_files (void) + /* continue */ + } + } +- if (pw_unlock () == 0) { ++ if (pw_unlock (true) == 0) { + fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, pw_dbname ()); +-- +2.50.0 + + +From bdce75b7b6f7ec69cda287b081de6ca83022ee79 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Fri, 25 Apr 2025 15:57:21 +0200 +Subject: [PATCH 10/15] lib/, src/: add SELinux control flag in spw_unlock() + +Expand spw_unlock() interface to add a control flag for SELinux file +context processing. + +Signed-off-by: Iker Pedrosa +--- + lib/cleanup_user.c | 2 +- + lib/lockpw.c | 2 +- + lib/shadowio.c | 4 ++-- + lib/shadowio.h | 2 +- + src/chage.c | 4 ++-- + src/chpasswd.c | 4 ++-- + src/newusers.c | 4 ++-- + src/passwd.c | 6 +++--- + src/pwck.c | 8 ++++---- + src/pwconv.c | 4 ++-- + src/pwunconv.c | 4 ++-- + src/useradd.c | 4 ++-- + src/userdel.c | 4 ++-- + src/usermod.c | 4 ++-- + 14 files changed, 28 insertions(+), 28 deletions(-) + +diff --git a/lib/cleanup_user.c b/lib/cleanup_user.c +index a661f5e9..b3a5a66e 100644 +--- a/lib/cleanup_user.c ++++ b/lib/cleanup_user.c +@@ -117,7 +117,7 @@ void cleanup_unlock_passwd (MAYBE_UNUSED void *arg) + */ + void cleanup_unlock_shadow (MAYBE_UNUSED void *arg) + { +- if (spw_unlock () == 0) { ++ if (spw_unlock (true) == 0) { + fprintf (log_get_logfd(), + _("%s: failed to unlock %s\n"), + log_get_progname(), spw_dbname ()); +diff --git a/lib/lockpw.c b/lib/lockpw.c +index f73c434a..7c99d56e 100644 +--- a/lib/lockpw.c ++++ b/lib/lockpw.c +@@ -78,7 +78,7 @@ int ulckpwdf (void) + * Unlock both files. + */ + +- return (pw_unlock (true) && spw_unlock ())? 0 : -1; ++ return (pw_unlock (true) && spw_unlock (true))? 0 : -1; + } + #else + extern int ISO_C_forbids_an_empty_translation_unit; +diff --git a/lib/shadowio.c b/lib/shadowio.c +index 9866af6d..71089eda 100644 +--- a/lib/shadowio.c ++++ b/lib/shadowio.c +@@ -204,14 +204,14 @@ int spw_close (bool process_selinux) + return retval; + } + +-int spw_unlock (void) ++int spw_unlock (bool process_selinux) + { + #ifdef WITH_TCB + int retval = 0; + + if (!getdef_bool ("USE_TCB")) { + #endif /* WITH_TCB */ +- return commonio_unlock (&shadow_db, true); ++ return commonio_unlock (&shadow_db, process_selinux); + #ifdef WITH_TCB + } + if (shadowtcb_drop_priv () == SHADOWTCB_FAILURE) { +diff --git a/lib/shadowio.h b/lib/shadowio.h +index e64d8d60..be645d0e 100644 +--- a/lib/shadowio.h ++++ b/lib/shadowio.h +@@ -23,7 +23,7 @@ extern /*@observer@*/ /*@null@*/const struct spwd *spw_next (void); + extern int spw_open (int mode); + extern int spw_remove (const char *name); + extern int spw_rewind (void); +-extern int spw_unlock (void); ++extern int spw_unlock (bool process_selinux); + extern int spw_update (const struct spwd *sp); + extern int spw_sort (void); + +diff --git a/src/chage.c b/src/chage.c +index d3a42ccf..e77a46de 100644 +--- a/src/chage.c ++++ b/src/chage.c +@@ -94,7 +94,7 @@ static void + fail_exit (int code) + { + if (spw_locked) { +- if (spw_unlock () == 0) { ++ if (spw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + /* continue */ +@@ -562,7 +562,7 @@ static void close_files (void) + SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); + fail_exit (E_NOPERM); + } +- if (spw_unlock () == 0) { ++ if (spw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + /* continue */ +diff --git a/src/chpasswd.c b/src/chpasswd.c +index 5323c520..2656b039 100644 +--- a/src/chpasswd.c ++++ b/src/chpasswd.c +@@ -89,7 +89,7 @@ static void fail_exit (int code) + } + + if (spw_locked) { +- if (spw_unlock () == 0) { ++ if (spw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + /* continue */ +@@ -385,7 +385,7 @@ static void close_files (void) + SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); + fail_exit (1); + } +- if (spw_unlock () == 0) { ++ if (spw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + /* continue */ +diff --git a/src/newusers.c b/src/newusers.c +index 669b6236..4cbb1639 100644 +--- a/src/newusers.c ++++ b/src/newusers.c +@@ -165,7 +165,7 @@ static void usage (int status) + static void fail_exit (int code) + { + if (spw_locked) { +- if (spw_unlock () == 0) { ++ if (spw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + /* continue */ +@@ -959,7 +959,7 @@ static void close_files (void) + SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); + fail_exit (EXIT_FAILURE); + } +- if (spw_unlock () == 0) { ++ if (spw_unlock (true) == 0) { + fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, spw_dbname ()); +diff --git a/src/passwd.c b/src/passwd.c +index 8a55d797..512dc572 100644 +--- a/src/passwd.c ++++ b/src/passwd.c +@@ -491,7 +491,7 @@ fail_exit (int status) + } + + if (spw_locked) { +- if (spw_unlock () == 0) { ++ if (spw_unlock (true) == 0) { + (void) fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + /* continue */ +@@ -627,7 +627,7 @@ static void update_shadow (void) + /* Try to update the password in /etc/passwd instead. */ + (void) spw_close (true); + update_noshadow (); +- if (spw_unlock () == 0) { ++ if (spw_unlock (true) == 0) { + (void) fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, spw_dbname ()); +@@ -688,7 +688,7 @@ static void update_shadow (void) + SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); + fail_exit (E_FAILURE); + } +- if (spw_unlock () == 0) { ++ if (spw_unlock (true) == 0) { + (void) fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, spw_dbname ()); +diff --git a/src/pwck.c b/src/pwck.c +index f30c5289..9c4cc29a 100644 +--- a/src/pwck.c ++++ b/src/pwck.c +@@ -85,7 +85,7 @@ extern int allow_bad_names; + static void fail_exit (int code) + { + if (spw_locked) { +- if (spw_unlock () == 0) { ++ if (spw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); + if (use_system_spw_file) { + SYSLOG ((LOG_ERR, "failed to unlock %s", +@@ -338,7 +338,7 @@ static void close_files (bool changed) + * Don't be anti-social - unlock the files when you're done. + */ + if (spw_locked) { +- if (spw_unlock () == 0) { ++ if (spw_unlock (true) == 0) { + fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, spw_dbname ()); +@@ -581,7 +581,7 @@ static void check_pw_file (bool *errors, bool *changed) + _("%s: cannot open %s\n"), + Prog, spw_dbname ()); + *errors = true; +- if (spw_unlock () == 0) { ++ if (spw_unlock (true) == 0) { + fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, spw_dbname ()); +@@ -669,7 +669,7 @@ static void check_pw_file (bool *errors, bool *changed) + } else { + spw_opened = false; + } +- if (spw_unlock () == 0) { ++ if (spw_unlock (true) == 0) { + fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, spw_dbname ()); +diff --git a/src/pwconv.c b/src/pwconv.c +index 82181bb4..b0d668b5 100644 +--- a/src/pwconv.c ++++ b/src/pwconv.c +@@ -91,7 +91,7 @@ static void fail_exit (int status) + } + + if (spw_locked) { +- if (spw_unlock () == 0) { ++ if (spw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + /* continue */ +@@ -305,7 +305,7 @@ int main (int argc, char **argv) + /* continue */ + } + +- if (spw_unlock () == 0) { ++ if (spw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + /* continue */ +diff --git a/src/pwunconv.c b/src/pwunconv.c +index 72944fe5..7a6d2be5 100644 +--- a/src/pwunconv.c ++++ b/src/pwunconv.c +@@ -47,7 +47,7 @@ static void process_flags (int argc, char **argv); + static void fail_exit (int status) + { + if (spw_locked) { +- if (spw_unlock () == 0) { ++ if (spw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + /* continue */ +@@ -222,7 +222,7 @@ int main (int argc, char **argv) + fail_exit (3); + } + +- if (spw_unlock () == 0) { ++ if (spw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + /* continue */ +diff --git a/src/useradd.c b/src/useradd.c +index aa070f2d..9c8b774f 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -265,7 +265,7 @@ static void fail_exit (int code) + SYSLOG((LOG_ERR, "failed to remove %s", prefix_user_home)); + } + +- if (spw_locked && spw_unlock() == 0) { ++ if (spw_locked && spw_unlock(true) == 0) { + fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname()); + SYSLOG((LOG_ERR, "failed to unlock %s", spw_dbname())); + /* continue */ +@@ -1593,7 +1593,7 @@ static void close_files (void) + } + #endif /* ENABLE_SUBIDS */ + if (is_shadow_pwd) { +- if (spw_unlock () == 0) { ++ if (spw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + #ifdef WITH_AUDIT +diff --git a/src/userdel.c b/src/userdel.c +index b4e87820..478c22d5 100644 +--- a/src/userdel.c ++++ b/src/userdel.c +@@ -409,7 +409,7 @@ static void close_files (void) + SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); + fail_exit (E_PW_UPDATE); + } +- if (spw_unlock () == 0) { ++ if (spw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + /* continue */ +@@ -498,7 +498,7 @@ static void fail_exit (int code) + } + } + if (spw_locked) { +- if (spw_unlock () == 0) { ++ if (spw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + /* continue */ +diff --git a/src/usermod.c b/src/usermod.c +index 6f761404..68373f35 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -648,7 +648,7 @@ fail_exit (int code) + } + #endif + if (spw_locked) { +- if (spw_unlock () == 0) { ++ if (spw_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + /* continue */ +@@ -1534,7 +1534,7 @@ static void close_files (void) + } + + if (is_shadow_pwd) { +- if (spw_unlock () == 0) { ++ if (spw_unlock (true) == 0) { + fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, spw_dbname ()); +-- +2.50.0 + + +From 68eb3395a4bcbbdb820b6c8c17cc64fb08749d11 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Fri, 25 Apr 2025 16:00:43 +0200 +Subject: [PATCH 11/15] lib/, src/: add SELinux control flag in gr_unlock() + +Expand gr_unlock() interface to add a control flag for SELinux file +context processing. + +Signed-off-by: Iker Pedrosa +--- + lib/cleanup_group.c | 2 +- + lib/groupio.c | 4 ++-- + lib/groupio.h | 2 +- + src/chgpasswd.c | 4 ++-- + src/groupmems.c | 4 ++-- + src/grpck.c | 4 ++-- + src/grpconv.c | 4 ++-- + src/grpunconv.c | 4 ++-- + src/newusers.c | 4 ++-- + src/useradd.c | 4 ++-- + src/userdel.c | 4 ++-- + src/usermod.c | 4 ++-- + 12 files changed, 22 insertions(+), 22 deletions(-) + +diff --git a/lib/cleanup_group.c b/lib/cleanup_group.c +index 54480092..a5846152 100644 +--- a/lib/cleanup_group.c ++++ b/lib/cleanup_group.c +@@ -181,7 +181,7 @@ void cleanup_report_del_group_gshadow (void *group_name) + */ + void cleanup_unlock_group (MAYBE_UNUSED void *arg) + { +- if (gr_unlock () == 0) { ++ if (gr_unlock (true) == 0) { + fprintf (log_get_logfd(), + _("%s: failed to unlock %s\n"), + log_get_progname(), gr_dbname ()); +diff --git a/lib/groupio.c b/lib/groupio.c +index 6ad4ae69..f21aa618 100644 +--- a/lib/groupio.c ++++ b/lib/groupio.c +@@ -189,9 +189,9 @@ int gr_close (bool process_selinux) + return commonio_close (&group_db, process_selinux); + } + +-int gr_unlock (void) ++int gr_unlock (bool process_selinux) + { +- return commonio_unlock (&group_db, true); ++ return commonio_unlock (&group_db, process_selinux); + } + + void __gr_set_changed (void) +diff --git a/lib/groupio.h b/lib/groupio.h +index ef9242d0..eae13cd3 100644 +--- a/lib/groupio.h ++++ b/lib/groupio.h +@@ -26,7 +26,7 @@ extern /*@observer@*/ /*@null@*/const struct group *gr_next (void); + extern int gr_open (int mode); + extern int gr_remove (const char *name); + extern int gr_rewind (void); +-extern int gr_unlock (void); ++extern int gr_unlock (bool process_selinux); + extern int gr_update (const struct group *gr); + extern int gr_sort (void); + +diff --git a/src/chgpasswd.c b/src/chgpasswd.c +index 47402ecc..84553d81 100644 +--- a/src/chgpasswd.c ++++ b/src/chgpasswd.c +@@ -82,7 +82,7 @@ static void close_files (void); + static void fail_exit (int code) + { + if (gr_locked) { +- if (gr_unlock () == 0) { ++ if (gr_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + /* continue */ +@@ -404,7 +404,7 @@ static void close_files (void) + SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ())); + fail_exit (1); + } +- if (gr_unlock () == 0) { ++ if (gr_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + /* continue */ +diff --git a/src/groupmems.c b/src/groupmems.c +index 5976b074..0c59474f 100644 +--- a/src/groupmems.c ++++ b/src/groupmems.c +@@ -457,7 +457,7 @@ static void check_perms (void) + static void fail_exit (int code) + { + if (gr_locked) { +- if (gr_unlock () == 0) { ++ if (gr_unlock (true) == 0) { + fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, gr_dbname ()); +@@ -528,7 +528,7 @@ static void close_files (void) + fail_exit (EXIT_GROUP_FILE); + } + if (gr_locked) { +- if (gr_unlock () == 0) { ++ if (gr_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + /* continue */ +diff --git a/src/grpck.c b/src/grpck.c +index 872f882f..bd2014fc 100644 +--- a/src/grpck.c ++++ b/src/grpck.c +@@ -92,7 +92,7 @@ static void check_sgr_file (bool *errors, bool *changed); + static void fail_exit (int status) + { + if (gr_locked) { +- if (gr_unlock () == 0) { ++ if (gr_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + /* continue */ +@@ -349,7 +349,7 @@ static void close_files (bool changed) + } + #endif + if (gr_locked) { +- if (gr_unlock () == 0) { ++ if (gr_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + /* continue */ +diff --git a/src/grpconv.c b/src/grpconv.c +index d9c59fc9..3160b8b1 100644 +--- a/src/grpconv.c ++++ b/src/grpconv.c +@@ -56,7 +56,7 @@ static void process_flags (int argc, char **argv); + static void fail_exit (int status) + { + if (gr_locked) { +- if (gr_unlock () == 0) { ++ if (gr_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + /* continue */ +@@ -253,7 +253,7 @@ int main (int argc, char **argv) + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + /* continue */ + } +- if (gr_unlock () == 0) { ++ if (gr_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + /* continue */ +diff --git a/src/grpunconv.c b/src/grpunconv.c +index 03fc824e..085c48ac 100644 +--- a/src/grpunconv.c ++++ b/src/grpunconv.c +@@ -55,7 +55,7 @@ static void process_flags (int argc, char **argv); + static void fail_exit (int status) + { + if (gr_locked) { +- if (gr_unlock () == 0) { ++ if (gr_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + /* continue */ +@@ -209,7 +209,7 @@ int main (int argc, char **argv) + fail_exit (3); + } + +- if (gr_unlock () == 0) { ++ if (gr_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + /* continue */ +diff --git a/src/newusers.c b/src/newusers.c +index 4cbb1639..47f01661 100644 +--- a/src/newusers.c ++++ b/src/newusers.c +@@ -179,7 +179,7 @@ static void fail_exit (int code) + } + } + if (gr_locked) { +- if (gr_unlock () == 0) { ++ if (gr_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + /* continue */ +@@ -991,7 +991,7 @@ static void close_files (void) + } + #endif /* ENABLE_SUBIDS */ + +- if (gr_unlock () == 0) { ++ if (gr_unlock (true) == 0) { + fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, gr_dbname ()); +diff --git a/src/useradd.c b/src/useradd.c +index 9c8b774f..75cfbde2 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -275,7 +275,7 @@ static void fail_exit (int code) + SYSLOG((LOG_ERR, "failed to unlock %s", pw_dbname())); + /* continue */ + } +- if (gr_locked && gr_unlock() == 0) { ++ if (gr_locked && gr_unlock(true) == 0) { + fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname()); + SYSLOG((LOG_ERR, "failed to unlock %s", gr_dbname())); + /* continue */ +@@ -1690,7 +1690,7 @@ static void close_group_files (void) + */ + static void unlock_group_files (void) + { +- if (gr_unlock () == 0) { ++ if (gr_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + #ifdef WITH_AUDIT +diff --git a/src/userdel.c b/src/userdel.c +index 478c22d5..12696732 100644 +--- a/src/userdel.c ++++ b/src/userdel.c +@@ -422,7 +422,7 @@ static void close_files (void) + SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ())); + fail_exit (E_GRP_UPDATE); + } +- if (gr_unlock () == 0) { ++ if (gr_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + /* continue */ +@@ -491,7 +491,7 @@ static void fail_exit (int code) + } + } + if (gr_locked) { +- if (gr_unlock () == 0) { ++ if (gr_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + /* continue */ +diff --git a/src/usermod.c b/src/usermod.c +index 68373f35..2e21a70f 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -632,7 +632,7 @@ static void + fail_exit (int code) + { + if (gr_locked) { +- if (gr_unlock () == 0) { ++ if (gr_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + /* continue */ +@@ -1522,7 +1522,7 @@ static void close_files (void) + } + } + #endif +- if (gr_unlock () == 0) { ++ if (gr_unlock (true) == 0) { + fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, gr_dbname ()); +-- +2.50.0 + + +From 37b636524cfb7c9b7dce8c56484fb60795ef2b91 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Fri, 25 Apr 2025 16:03:58 +0200 +Subject: [PATCH 12/15] lib/, src/: add SELinux control flag in sgr_unlock() + +Expand sgr_unlock() interface to add a control flag for SELinux file +context processing. + +Signed-off-by: Iker Pedrosa +--- + lib/cleanup_group.c | 2 +- + lib/sgroupio.c | 4 ++-- + lib/sgroupio.h | 2 +- + src/chgpasswd.c | 4 ++-- + src/groupmems.c | 4 ++-- + src/grpck.c | 4 ++-- + src/grpconv.c | 4 ++-- + src/grpunconv.c | 4 ++-- + src/newusers.c | 4 ++-- + src/useradd.c | 4 ++-- + src/userdel.c | 4 ++-- + src/usermod.c | 4 ++-- + 12 files changed, 22 insertions(+), 22 deletions(-) + +diff --git a/lib/cleanup_group.c b/lib/cleanup_group.c +index a5846152..dc9f1eb2 100644 +--- a/lib/cleanup_group.c ++++ b/lib/cleanup_group.c +@@ -201,7 +201,7 @@ void cleanup_unlock_group (MAYBE_UNUSED void *arg) + */ + void cleanup_unlock_gshadow (MAYBE_UNUSED void *arg) + { +- if (sgr_unlock () == 0) { ++ if (sgr_unlock (true) == 0) { + fprintf (log_get_logfd(), + _("%s: failed to unlock %s\n"), + log_get_progname(), sgr_dbname ()); +diff --git a/lib/sgroupio.c b/lib/sgroupio.c +index dbabcc36..4239e23d 100644 +--- a/lib/sgroupio.c ++++ b/lib/sgroupio.c +@@ -281,9 +281,9 @@ int sgr_close (bool process_selinux) + return commonio_close (&gshadow_db, process_selinux); + } + +-int sgr_unlock (void) ++int sgr_unlock (bool process_selinux) + { +- return commonio_unlock (&gshadow_db, true); ++ return commonio_unlock (&gshadow_db, process_selinux); + } + + void __sgr_set_changed (void) +diff --git a/lib/sgroupio.h b/lib/sgroupio.h +index 0e25fc0b..256f6d54 100644 +--- a/lib/sgroupio.h ++++ b/lib/sgroupio.h +@@ -22,7 +22,7 @@ extern /*@null@*/const struct sgrp *sgr_next (void); + extern int sgr_open (int mode); + extern int sgr_remove (const char *name); + extern int sgr_rewind (void); +-extern int sgr_unlock (void); ++extern int sgr_unlock (bool process_selinux); + extern int sgr_update (const struct sgrp *sg); + extern int sgr_sort (void); + +diff --git a/src/chgpasswd.c b/src/chgpasswd.c +index 84553d81..27094f50 100644 +--- a/src/chgpasswd.c ++++ b/src/chgpasswd.c +@@ -91,7 +91,7 @@ static void fail_exit (int code) + + #ifdef SHADOWGRP + if (sgr_locked) { +- if (sgr_unlock () == 0) { ++ if (sgr_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + /* continue */ +@@ -388,7 +388,7 @@ static void close_files (void) + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ())); + fail_exit (1); + } +- if (sgr_unlock () == 0) { ++ if (sgr_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + /* continue */ +diff --git a/src/groupmems.c b/src/groupmems.c +index 0c59474f..f39724c8 100644 +--- a/src/groupmems.c ++++ b/src/groupmems.c +@@ -468,7 +468,7 @@ static void fail_exit (int code) + + #ifdef SHADOWGRP + if (sgr_locked) { +- if (sgr_unlock () == 0) { ++ if (sgr_unlock (true) == 0) { + fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, sgr_dbname ()); +@@ -544,7 +544,7 @@ static void close_files (void) + fail_exit (EXIT_GROUP_FILE); + } + if (sgr_locked) { +- if (sgr_unlock () == 0) { ++ if (sgr_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + /* continue */ +diff --git a/src/grpck.c b/src/grpck.c +index bd2014fc..bc178d52 100644 +--- a/src/grpck.c ++++ b/src/grpck.c +@@ -101,7 +101,7 @@ static void fail_exit (int status) + + #ifdef SHADOWGRP + if (sgr_locked) { +- if (sgr_unlock () == 0) { ++ if (sgr_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + /* continue */ +@@ -340,7 +340,7 @@ static void close_files (bool changed) + */ + #ifdef SHADOWGRP + if (sgr_locked) { +- if (sgr_unlock () == 0) { ++ if (sgr_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + /* continue */ +diff --git a/src/grpconv.c b/src/grpconv.c +index 3160b8b1..5958d3f5 100644 +--- a/src/grpconv.c ++++ b/src/grpconv.c +@@ -64,7 +64,7 @@ static void fail_exit (int status) + } + + if (sgr_locked) { +- if (sgr_unlock () == 0) { ++ if (sgr_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + /* continue */ +@@ -248,7 +248,7 @@ int main (int argc, char **argv) + SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ())); + fail_exit (3); + } +- if (sgr_unlock () == 0) { ++ if (sgr_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + /* continue */ +diff --git a/src/grpunconv.c b/src/grpunconv.c +index 085c48ac..5256e0bc 100644 +--- a/src/grpunconv.c ++++ b/src/grpunconv.c +@@ -63,7 +63,7 @@ static void fail_exit (int status) + } + + if (sgr_locked) { +- if (sgr_unlock () == 0) { ++ if (sgr_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + /* continue */ +@@ -215,7 +215,7 @@ int main (int argc, char **argv) + /* continue */ + } + +- if (sgr_unlock () == 0) { ++ if (sgr_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + /* continue */ +diff --git a/src/newusers.c b/src/newusers.c +index 47f01661..261a5911 100644 +--- a/src/newusers.c ++++ b/src/newusers.c +@@ -187,7 +187,7 @@ static void fail_exit (int code) + } + #ifdef SHADOWGRP + if (sgr_locked) { +- if (sgr_unlock () == 0) { ++ if (sgr_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + /* continue */ +@@ -1009,7 +1009,7 @@ static void close_files (void) + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ())); + fail_exit (EXIT_FAILURE); + } +- if (sgr_unlock () == 0) { ++ if (sgr_unlock (true) == 0) { + fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, sgr_dbname ()); +diff --git a/src/useradd.c b/src/useradd.c +index 75cfbde2..cb7ac88e 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -281,7 +281,7 @@ static void fail_exit (int code) + /* continue */ + } + #ifdef SHADOWGRP +- if (sgr_locked && sgr_unlock() == 0) { ++ if (sgr_locked && sgr_unlock(true) == 0) { + fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname()); + SYSLOG((LOG_ERR, "failed to unlock %s", sgr_dbname())); + /* continue */ +@@ -1704,7 +1704,7 @@ static void unlock_group_files (void) + gr_locked = false; + #ifdef SHADOWGRP + if (is_shadow_grp) { +- if (sgr_unlock () == 0) { ++ if (sgr_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + #ifdef WITH_AUDIT +diff --git a/src/userdel.c b/src/userdel.c +index 12696732..80ed1a48 100644 +--- a/src/userdel.c ++++ b/src/userdel.c +@@ -438,7 +438,7 @@ static void close_files (void) + fail_exit (E_GRP_UPDATE); + } + +- if (sgr_unlock () == 0) { ++ if (sgr_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + /* continue */ +@@ -506,7 +506,7 @@ static void fail_exit (int code) + } + #ifdef SHADOWGRP + if (sgr_locked) { +- if (sgr_unlock () == 0) { ++ if (sgr_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + /* continue */ +diff --git a/src/usermod.c b/src/usermod.c +index 2e21a70f..69ea8e55 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -640,7 +640,7 @@ fail_exit (int code) + } + #ifdef SHADOWGRP + if (sgr_locked) { +- if (sgr_unlock () == 0) { ++ if (sgr_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + /* continue */ +@@ -1511,7 +1511,7 @@ static void close_files (void) + #endif + #ifdef SHADOWGRP + if (is_shadow_grp) { +- if (sgr_unlock () == 0) { ++ if (sgr_unlock (true) == 0) { + fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, sgr_dbname ()); +-- +2.50.0 + + +From dee1a5a5782b8aafcc32c7f93a53ce591355d1b3 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Fri, 25 Apr 2025 16:06:57 +0200 +Subject: [PATCH 13/15] src/vipw.c: add SELinux control flag in unlock + +All unlock functions require the SELinux control flag, thus add it as an +argument. + +Signed-off-by: Iker Pedrosa +--- + src/vipw.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/src/vipw.c b/src/vipw.c +index 3c840e9f..ba323e0e 100644 +--- a/src/vipw.c ++++ b/src/vipw.c +@@ -62,7 +62,7 @@ static const char *Prog; + static const char *filename, *fileeditname; + static bool filelocked = false; + static bool createedit = false; +-static int (*unlock) (void); ++static int (*unlock) (bool); + static bool quiet = false; + #ifdef WITH_TCB + static const char *user = NULL; +@@ -74,7 +74,7 @@ static bool tcb_mode = false; + static void usage (int status); + static int create_backup_file (FILE *, const char *, struct stat *); + static void vipwexit (const char *msg, int syserr, int ret); +-static void vipwedit (const char *, int (*)(void), int (*)(void)); ++static void vipwedit (const char *, int (*)(void), int (*)(bool)); + + /* + * usage - display usage message and exit +@@ -164,7 +164,7 @@ static void vipwexit (const char *msg, int syserr, int ret) + } + } + if (filelocked) { +- if ((*unlock) () == 0) { ++ if ((*unlock) (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, fileeditname); + SYSLOG ((LOG_ERR, "failed to unlock %s", fileeditname)); + /* continue */ +@@ -195,7 +195,7 @@ static void vipwexit (const char *msg, int syserr, int ret) + * + */ + static void +-vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (void)) ++vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (bool)) + { + int status; + char *to_rename; +@@ -467,7 +467,7 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (void)) + } + #endif /* WITH_TCB */ + +- if ((*file_unlock) () == 0) { ++ if ((*file_unlock) (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, fileeditname); + SYSLOG ((LOG_ERR, "failed to unlock %s", fileeditname)); + /* continue */ +-- +2.50.0 + + +From f297173f0247b9288c424e765e972eb13d4c9ded Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Fri, 25 Apr 2025 16:10:09 +0200 +Subject: [PATCH 14/15] lib/, src/: add SELinux control flag in + sub_uid_unlock() + +Expand sub_uid_unlock() interface to add a control flag for SELinux file +context processing. + +Signed-off-by: Iker Pedrosa +--- + lib/subordinateio.c | 12 ++++++------ + lib/subordinateio.h | 2 +- + src/newusers.c | 4 ++-- + src/useradd.c | 4 ++-- + src/userdel.c | 4 ++-- + src/usermod.c | 4 ++-- + 6 files changed, 15 insertions(+), 15 deletions(-) + +diff --git a/lib/subordinateio.c b/lib/subordinateio.c +index 9587e1a9..eaa2dc99 100644 +--- a/lib/subordinateio.c ++++ b/lib/subordinateio.c +@@ -673,9 +673,9 @@ int sub_uid_close (bool process_selinux) + return commonio_close (&subordinate_uid_db, process_selinux); + } + +-int sub_uid_unlock (void) ++int sub_uid_unlock (bool process_selinux) + { +- return commonio_unlock (&subordinate_uid_db, true); ++ return commonio_unlock (&subordinate_uid_db, process_selinux); + } + + uid_t sub_uid_find_free_range(uid_t min, uid_t max, unsigned long count) +@@ -1022,7 +1022,7 @@ bool new_subid_range(struct subordinate_range *range, enum subid_type id_type, b + } + if (!sub_uid_open(O_CREAT | O_RDWR)) { + printf("Failed opening subuids (errno %d)\n", errno); +- sub_uid_unlock(); ++ sub_uid_unlock(true); + return false; + } + db = &subordinate_uid_db; +@@ -1069,7 +1069,7 @@ bool new_subid_range(struct subordinate_range *range, enum subid_type id_type, b + out: + if (id_type == ID_TYPE_UID) { + sub_uid_close(true); +- sub_uid_unlock(); ++ sub_uid_unlock(true); + } else { + sub_gid_close(true); + sub_gid_unlock(); +@@ -1094,7 +1094,7 @@ bool release_subid_range(struct subordinate_range *range, enum subid_type id_typ + } + if (!sub_uid_open(O_CREAT | O_RDWR)) { + printf("Failed opening subuids (errno %d)\n", errno); +- sub_uid_unlock(); ++ sub_uid_unlock(true); + return false; + } + db = &subordinate_uid_db; +@@ -1119,7 +1119,7 @@ bool release_subid_range(struct subordinate_range *range, enum subid_type id_typ + + if (id_type == ID_TYPE_UID) { + sub_uid_close(true); +- sub_uid_unlock(); ++ sub_uid_unlock(true); + } else { + sub_gid_close(true); + sub_gid_unlock(); +diff --git a/lib/subordinateio.h b/lib/subordinateio.h +index 63f5b1fb..7914613d 100644 +--- a/lib/subordinateio.h ++++ b/lib/subordinateio.h +@@ -21,7 +21,7 @@ extern int sub_uid_lock (void); + extern int sub_uid_setdbname (const char *filename); + extern /*@observer@*/const char *sub_uid_dbname (void); + extern int sub_uid_open (int mode); +-extern int sub_uid_unlock (void); ++extern int sub_uid_unlock (bool process_selinux); + extern int sub_uid_add (const char *owner, uid_t start, unsigned long count); + extern int sub_uid_remove (const char *owner, uid_t start, unsigned long count); + extern uid_t sub_uid_find_free_range(uid_t min, uid_t max, unsigned long count); +diff --git a/src/newusers.c b/src/newusers.c +index 261a5911..65bedf9b 100644 +--- a/src/newusers.c ++++ b/src/newusers.c +@@ -196,7 +196,7 @@ static void fail_exit (int code) + #endif + #ifdef ENABLE_SUBIDS + if (sub_uid_locked) { +- if (sub_uid_unlock () == 0) { ++ if (sub_uid_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); + /* continue */ +@@ -1021,7 +1021,7 @@ static void close_files (void) + #endif + #ifdef ENABLE_SUBIDS + if (is_sub_uid) { +- if (sub_uid_unlock () == 0) { ++ if (sub_uid_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); + /* continue */ +diff --git a/src/useradd.c b/src/useradd.c +index cb7ac88e..f65d24d1 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -288,7 +288,7 @@ static void fail_exit (int code) + } + #endif + #ifdef ENABLE_SUBIDS +- if (sub_uid_locked && sub_uid_unlock() == 0) { ++ if (sub_uid_locked && sub_uid_unlock(true) == 0) { + fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname()); + SYSLOG((LOG_ERR, "failed to unlock %s", sub_uid_dbname())); + /* continue */ +@@ -1623,7 +1623,7 @@ static void close_files (void) + + #ifdef ENABLE_SUBIDS + if (is_sub_uid) { +- if (sub_uid_unlock () == 0) { ++ if (sub_uid_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); + #ifdef WITH_AUDIT +diff --git a/src/userdel.c b/src/userdel.c +index 80ed1a48..68e53b85 100644 +--- a/src/userdel.c ++++ b/src/userdel.c +@@ -454,7 +454,7 @@ static void close_files (void) + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_uid_dbname ())); + fail_exit (E_SUB_UID_UPDATE); + } +- if (sub_uid_unlock () == 0) { ++ if (sub_uid_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); + /* continue */ +@@ -515,7 +515,7 @@ static void fail_exit (int code) + #endif /* SHADOWGRP */ + #ifdef ENABLE_SUBIDS + if (sub_uid_locked) { +- if (sub_uid_unlock () == 0) { ++ if (sub_uid_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); + /* continue */ +diff --git a/src/usermod.c b/src/usermod.c +index 69ea8e55..fc6cc51c 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -663,7 +663,7 @@ fail_exit (int code) + } + #ifdef ENABLE_SUBIDS + if (sub_uid_locked) { +- if (sub_uid_unlock () == 0) { ++ if (sub_uid_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); + /* continue */ +@@ -1566,7 +1566,7 @@ static void close_files (void) + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_uid_dbname ())); + fail_exit (E_SUB_UID_UPDATE); + } +- if (sub_uid_unlock () == 0) { ++ if (sub_uid_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); + /* continue */ +-- +2.50.0 + + +From 7b2bbdd0347c34bc5e094caf26c55694fb5935e7 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Fri, 25 Apr 2025 16:12:40 +0200 +Subject: [PATCH 15/15] lib/, src/: add SELinux control flag in + sub_gid_unlock() + +Expand sub_gid_unlock() interface to add a control flag for SELinux file +context processing. + +Signed-off-by: Iker Pedrosa +--- + lib/subordinateio.c | 12 ++++++------ + lib/subordinateio.h | 2 +- + src/newusers.c | 4 ++-- + src/useradd.c | 4 ++-- + src/userdel.c | 4 ++-- + src/usermod.c | 4 ++-- + 6 files changed, 15 insertions(+), 15 deletions(-) + +diff --git a/lib/subordinateio.c b/lib/subordinateio.c +index eaa2dc99..d1ab03f3 100644 +--- a/lib/subordinateio.c ++++ b/lib/subordinateio.c +@@ -780,9 +780,9 @@ int sub_gid_close (bool process_selinux) + return commonio_close (&subordinate_gid_db, process_selinux); + } + +-int sub_gid_unlock (void) ++int sub_gid_unlock (bool process_selinux) + { +- return commonio_unlock (&subordinate_gid_db, true); ++ return commonio_unlock (&subordinate_gid_db, process_selinux); + } + + gid_t sub_gid_find_free_range(gid_t min, gid_t max, unsigned long count) +@@ -1034,7 +1034,7 @@ bool new_subid_range(struct subordinate_range *range, enum subid_type id_type, b + } + if (!sub_gid_open(O_CREAT | O_RDWR)) { + printf("Failed opening subgids (errno %d)\n", errno); +- sub_gid_unlock(); ++ sub_gid_unlock(true); + return false; + } + db = &subordinate_gid_db; +@@ -1072,7 +1072,7 @@ out: + sub_uid_unlock(true); + } else { + sub_gid_close(true); +- sub_gid_unlock(); ++ sub_gid_unlock(true); + } + + return ret; +@@ -1106,7 +1106,7 @@ bool release_subid_range(struct subordinate_range *range, enum subid_type id_typ + } + if (!sub_gid_open(O_CREAT | O_RDWR)) { + printf("Failed opening subgids (errno %d)\n", errno); +- sub_gid_unlock(); ++ sub_gid_unlock(true); + return false; + } + db = &subordinate_gid_db; +@@ -1122,7 +1122,7 @@ bool release_subid_range(struct subordinate_range *range, enum subid_type id_typ + sub_uid_unlock(true); + } else { + sub_gid_close(true); +- sub_gid_unlock(); ++ sub_gid_unlock(true); + } + + return ret; +diff --git a/lib/subordinateio.h b/lib/subordinateio.h +index 7914613d..1ca4b66d 100644 +--- a/lib/subordinateio.h ++++ b/lib/subordinateio.h +@@ -39,7 +39,7 @@ extern int sub_gid_lock (void); + extern int sub_gid_setdbname (const char *filename); + extern /*@observer@*/const char *sub_gid_dbname (void); + extern int sub_gid_open (int mode); +-extern int sub_gid_unlock (void); ++extern int sub_gid_unlock (bool process_selinux); + extern int sub_gid_add (const char *owner, gid_t start, unsigned long count); + extern int sub_gid_remove (const char *owner, gid_t start, unsigned long count); + extern uid_t sub_gid_find_free_range(gid_t min, gid_t max, unsigned long count); +diff --git a/src/newusers.c b/src/newusers.c +index 65bedf9b..4eb6065c 100644 +--- a/src/newusers.c ++++ b/src/newusers.c +@@ -203,7 +203,7 @@ static void fail_exit (int code) + } + } + if (sub_gid_locked) { +- if (sub_gid_unlock () == 0) { ++ if (sub_gid_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); + /* continue */ +@@ -1029,7 +1029,7 @@ static void close_files (void) + sub_uid_locked = false; + } + if (is_sub_gid) { +- if (sub_gid_unlock () == 0) { ++ if (sub_gid_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); + /* continue */ +diff --git a/src/useradd.c b/src/useradd.c +index f65d24d1..98c2d284 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -293,7 +293,7 @@ static void fail_exit (int code) + SYSLOG((LOG_ERR, "failed to unlock %s", sub_uid_dbname())); + /* continue */ + } +- if (sub_gid_locked && sub_gid_unlock() == 0) { ++ if (sub_gid_locked && sub_gid_unlock(true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname())); + /* continue */ +@@ -1637,7 +1637,7 @@ static void close_files (void) + sub_uid_locked = false; + } + if (is_sub_gid) { +- if (sub_gid_unlock () == 0) { ++ if (sub_gid_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); + #ifdef WITH_AUDIT +diff --git a/src/userdel.c b/src/userdel.c +index 68e53b85..524c96a6 100644 +--- a/src/userdel.c ++++ b/src/userdel.c +@@ -468,7 +468,7 @@ static void close_files (void) + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_gid_dbname ())); + fail_exit (E_SUB_GID_UPDATE); + } +- if (sub_gid_unlock () == 0) { ++ if (sub_gid_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); + /* continue */ +@@ -522,7 +522,7 @@ static void fail_exit (int code) + } + } + if (sub_gid_locked) { +- if (sub_gid_unlock () == 0) { ++ if (sub_gid_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); + /* continue */ +diff --git a/src/usermod.c b/src/usermod.c +index fc6cc51c..68000a0e 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -670,7 +670,7 @@ fail_exit (int code) + } + } + if (sub_gid_locked) { +- if (sub_gid_unlock () == 0) { ++ if (sub_gid_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); + /* continue */ +@@ -1579,7 +1579,7 @@ static void close_files (void) + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_gid_dbname ())); + fail_exit (E_SUB_GID_UPDATE); + } +- if (sub_gid_unlock () == 0) { ++ if (sub_gid_unlock (true) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); + /* continue */ +-- +2.50.0 + +diff -up shadow-4.18.0/src/newusers.c.test-chroot2 shadow-4.18.0/src/newusers.c +--- shadow-4.18.0/src/newusers.c.test-chroot2 2025-07-08 11:22:16.257291774 +0200 ++++ shadow-4.18.0/src/newusers.c 2025-07-08 11:23:28.210122190 +0200 +@@ -60,6 +60,10 @@ + #include "string/strtok/stpsep.h" + #include "string/strtok/strsep2arr.h" + ++struct option_flags { ++ bool chroot; ++}; ++ + + /* + * Global variables +@@ -103,7 +107,7 @@ static bool sub_gid_locked = false; + + /* local function prototypes */ + NORETURN static void usage (int status); +-NORETURN static void fail_exit (int); ++NORETURN static void fail_exit (int, bool); + static int add_group (const char *, const char *, gid_t *, gid_t); + static int get_user_id (const char *, uid_t *); + static int add_user (const char *, uid_t, gid_t); +@@ -113,11 +117,11 @@ static int update_passwd (struct passwd + #endif /* !USE_PAM */ + #endif /* !ACCT_TOOLS_SETUID */ + static int add_passwd (struct passwd *, const char *); +-static void process_flags (int argc, char **argv); ++static void process_flags (int argc, char **argv, struct option_flags *flags); + static void check_flags (void); + static void check_perms (void); +-static void open_files (void); +-static void close_files (void); ++static void open_files (bool process_selinux); ++static void close_files (struct option_flags *flags); + + extern int allow_bad_names; + +@@ -170,24 +174,24 @@ static void usage (int status) + /* + * fail_exit - undo as much as possible + */ +-static void fail_exit (int code) ++static void fail_exit (int code, bool process_selinux) + { + if (spw_locked) { +- if (spw_unlock (true) == 0) { ++ if (spw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + /* continue */ + } + } + if (pw_locked) { +- if (pw_unlock (true) == 0) { ++ if (pw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ + } + } + if (gr_locked) { +- if (gr_unlock (true) == 0) { ++ if (gr_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + /* continue */ +@@ -195,7 +199,7 @@ static void fail_exit (int code) + } + #ifdef SHADOWGRP + if (sgr_locked) { +- if (sgr_unlock (true) == 0) { ++ if (sgr_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + /* continue */ +@@ -204,14 +208,14 @@ static void fail_exit (int code) + #endif + #ifdef ENABLE_SUBIDS + if (sub_uid_locked) { +- if (sub_uid_unlock (true) == 0) { ++ if (sub_uid_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); + /* continue */ + } + } + if (sub_gid_locked) { +- if (sub_gid_unlock (true) == 0) { ++ if (sub_gid_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); + /* continue */ +@@ -637,7 +641,7 @@ static int add_passwd (struct passwd *pw + * + * It will not return if an error is encountered. + */ +-static void process_flags (int argc, char **argv) ++static void process_flags (int argc, char **argv, struct option_flags *flags) + { + int c; + #ifndef ACCT_TOOLS_SETUID +@@ -696,6 +700,7 @@ static void process_flags (int argc, cha + rflg = true; + break; + case 'R': /* no-op, handled in process_root_flag () */ ++ flags->chroot = true; + break; + #ifndef ACCT_TOOLS_SETUID + #ifndef USE_PAM +@@ -755,7 +760,7 @@ static void process_flags (int argc, cha + + SNPRINTF(buf, "%s: %s", Prog, argv[1]); + perror (buf); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, !flags->chroot); + } + } + +@@ -859,7 +864,7 @@ static void check_perms (void) + /* + * open_files - lock and open the password, group and shadow databases + */ +-static void open_files (void) ++static void open_files (bool process_selinux) + { + /* + * Lock the password files and open them for update. This will bring +@@ -871,7 +876,7 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, pw_dbname ()); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } + pw_locked = true; + if (is_shadow) { +@@ -879,7 +884,7 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, spw_dbname ()); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } + spw_locked = true; + } +@@ -887,7 +892,7 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, gr_dbname ()); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } + gr_locked = true; + #ifdef SHADOWGRP +@@ -896,7 +901,7 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, sgr_dbname ()); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } + sgr_locked = true; + } +@@ -907,7 +912,7 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, sub_uid_dbname ()); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } + sub_uid_locked = true; + } +@@ -916,7 +921,7 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, sub_gid_dbname ()); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } + sub_gid_locked = true; + } +@@ -924,20 +929,20 @@ static void open_files (void) + + if (pw_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, _("%s: cannot open %s\n"), Prog, pw_dbname ()); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } + if (is_shadow && (spw_open (O_CREAT | O_RDWR) == 0)) { + fprintf (stderr, _("%s: cannot open %s\n"), Prog, spw_dbname ()); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } + if (gr_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ()); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } + #ifdef SHADOWGRP + if (is_shadow_grp && (sgr_open (O_CREAT | O_RDWR) == 0)) { + fprintf (stderr, _("%s: cannot open %s\n"), Prog, sgr_dbname ()); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } + #endif + #ifdef ENABLE_SUBIDS +@@ -946,7 +951,7 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot open %s\n"), + Prog, sub_uid_dbname ()); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } + } + if (is_sub_gid) { +@@ -954,7 +959,7 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot open %s\n"), + Prog, sub_gid_dbname ()); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } + } + #endif /* ENABLE_SUBIDS */ +@@ -963,14 +968,18 @@ static void open_files (void) + /* + * close_files - close and unlock the password, group and shadow databases + */ +-static void close_files (void) ++static void close_files (struct option_flags *flags) + { +- if (pw_close (true) == 0) { ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot; ++ ++ if (pw_close (process_selinux) == 0) { + fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } +- if (pw_unlock (true) == 0) { ++ if (pw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +@@ -978,14 +987,14 @@ static void close_files (void) + pw_locked = false; + + if (is_shadow) { +- if (spw_close (true) == 0) { ++ if (spw_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } +- if (spw_unlock (true) == 0) { ++ if (spw_unlock (process_selinux) == 0) { + fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, spw_dbname ()); +@@ -995,29 +1004,29 @@ static void close_files (void) + spw_locked = false; + } + +- if (gr_close (true) == 0) { ++ if (gr_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ())); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } + #ifdef ENABLE_SUBIDS +- if (is_sub_uid && (sub_uid_close (true) == 0)) { ++ if (is_sub_uid && (sub_uid_close (process_selinux) == 0)) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), Prog, sub_uid_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_uid_dbname ())); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } +- if (is_sub_gid && (sub_gid_close (true) == 0)) { ++ if (is_sub_gid && (sub_gid_close (process_selinux) == 0)) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), Prog, sub_gid_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_gid_dbname ())); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } + #endif /* ENABLE_SUBIDS */ + +- if (gr_unlock (true) == 0) { ++ if (gr_unlock (process_selinux) == 0) { + fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, gr_dbname ()); +@@ -1028,14 +1037,14 @@ static void close_files (void) + + #ifdef SHADOWGRP + if (is_shadow_grp) { +- if (sgr_close (true) == 0) { ++ if (sgr_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ())); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } +- if (sgr_unlock (true) == 0) { ++ if (sgr_unlock (process_selinux) == 0) { + fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, sgr_dbname ()); +@@ -1047,7 +1056,7 @@ static void close_files (void) + #endif + #ifdef ENABLE_SUBIDS + if (is_sub_uid) { +- if (sub_uid_unlock (true) == 0) { ++ if (sub_uid_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); + /* continue */ +@@ -1055,7 +1064,7 @@ static void close_files (void) + sub_uid_locked = false; + } + if (is_sub_gid) { +- if (sub_gid_unlock (true) == 0) { ++ if (sub_gid_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); + /* continue */ +@@ -1100,6 +1109,8 @@ int main (int argc, char **argv) + size_t nusers = 0; + #endif /* USE_PAM */ + #endif /* ACCT_TOOLS_SETUID */ ++ struct option_flags flags; ++ bool process_selinux; + + log_set_progname(Prog); + log_set_logfd(stderr); +@@ -1113,7 +1124,8 @@ int main (int argc, char **argv) + + OPENLOG ("newusers"); + +- process_flags (argc, argv); ++ process_flags (argc, argv, &flags); ++ process_selinux = !flags.chroot; + + check_perms (); + +@@ -1127,7 +1139,7 @@ int main (int argc, char **argv) + is_sub_gid = sub_gid_file_present () && !rflg; + #endif /* ENABLE_SUBIDS */ + +- open_files (); ++ open_files (process_selinux); + + /* + * Read each line. The line has the same format as a password file +@@ -1143,13 +1155,13 @@ int main (int argc, char **argv) + if (stpsep(buf, "\n") == NULL && feof(stdin) == 0) { + fprintf (stderr, _("%s: line %jd: line too long\n"), + Prog, line); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } + + if (STRSEP2ARR(buf, ":", fields) == -1) { + fprintf (stderr, _("%s: line %jd: invalid line\n"), + Prog, line); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } + + /* +@@ -1161,14 +1173,14 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: cannot update the entry of user %s (not in the passwd database)\n"), + Prog, fields[0]); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } + + if (NULL == pw && get_user_id(fields[2], &uid) != 0) { + fprintf (stderr, + _("%s: line %jd: can't create user\n"), + Prog, line); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } + + /* +@@ -1188,7 +1200,7 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: line %jd: can't create group\n"), + Prog, line); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } + + /* +@@ -1203,7 +1215,7 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: line %jd: can't create user\n"), + Prog, line); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } + + /* +@@ -1215,7 +1227,7 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: line %jd: user '%s' does not exist in %s\n"), + Prog, line, fields[0], pw_dbname ()); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } + newpw = *pw; + +@@ -1230,7 +1242,7 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: line %jd: %s\n"), + Prog, line, strerror(errno)); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } + lines[nusers-1] = line; + usernames[nusers-1] = xstrdup(fields[0]); +@@ -1241,7 +1253,7 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: line %jd: can't update password\n"), + Prog, line); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } + if (!streq(fields[4], "")) { + newpw.pw_gecos = fields[4]; +@@ -1264,7 +1276,7 @@ int main (int argc, char **argv) + fprintf(stderr, + _("%s: line %jd: homedir must be an absolute path\n"), + Prog, line); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } + if (mkdir (newpw.pw_dir, mode) != 0) { + fprintf (stderr, +@@ -1272,7 +1284,7 @@ int main (int argc, char **argv) + Prog, line, newpw.pw_dir, + strerror (errno)); + if (errno != EEXIST) { +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } + } + if (chown(newpw.pw_dir, newpw.pw_uid, newpw.pw_gid) != 0) +@@ -1281,7 +1293,7 @@ int main (int argc, char **argv) + _("%s: line %jd: chown %s failed: %s\n"), + Prog, line, newpw.pw_dir, + strerror (errno)); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } + } + +@@ -1292,7 +1304,7 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: line %jd: can't update entry\n"), + Prog, line); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } + + #ifdef ENABLE_SUBIDS +@@ -1307,14 +1319,14 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: can't find subordinate user range\n"), + Prog); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } + if (sub_uid_add(fields[0], sub_uid_start, sub_uid_count) == 0) + { + fprintf (stderr, + _("%s: failed to prepare new %s entry\n"), + Prog, sub_uid_dbname ()); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } + } + +@@ -1328,13 +1340,13 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: can't find subordinate group range\n"), + Prog); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } + if (sub_gid_add(fields[0], sub_gid_start, sub_gid_count) == 0) { + fprintf (stderr, + _("%s: failed to prepare new %s entry\n"), + Prog, sub_uid_dbname ()); +- fail_exit (EXIT_FAILURE); ++ fail_exit (EXIT_FAILURE, process_selinux); + } + } + #endif /* ENABLE_SUBIDS */ +@@ -1347,7 +1359,7 @@ int main (int argc, char **argv) + * changes to be written out all at once, and then unlocked + * afterwards. + */ +- close_files (); ++ close_files (&flags); + + nscd_flush_cache ("passwd"); + nscd_flush_cache ("group"); +diff -up shadow-4.18.0/src/useradd.c.test-chroot2 shadow-4.18.0/src/useradd.c +--- shadow-4.18.0/src/useradd.c.test-chroot2 2025-07-08 11:22:16.257383838 +0200 ++++ shadow-4.18.0/src/useradd.c 2025-07-08 11:22:16.261386737 +0200 +@@ -92,6 +92,15 @@ + #ifndef LASTLOG_FILE + #define LASTLOG_FILE "/var/log/lastlog" + #endif ++ ++/* ++ * Structures ++ */ ++struct option_flags { ++ bool chroot; ++ bool prefix; ++}; ++ + /* + * Global variables + */ +@@ -219,40 +228,41 @@ static bool home_added = false; + #define DLOG_INIT "LOG_INIT" + + /* local function prototypes */ +-NORETURN static void fail_exit (int); +-static void get_defaults (void); ++NORETURN static void fail_exit (int, bool); ++static void get_defaults (struct option_flags *); + static void show_defaults (void); + static int set_defaults (void); +-static int get_groups (char *); +-static struct group * get_local_group (char * grp_name); ++static int get_groups (char *, struct option_flags *); ++static struct group * get_local_group (char * grp_name, bool process_selinux); + NORETURN static void usage (int status); + static void new_pwent (struct passwd *); + + static void new_spent (struct spwd *); +-static void grp_update (void); ++static void grp_update (bool); + +-static void process_flags (int argc, char **argv); +-static void close_files (void); +-static void close_group_files (void); +-static void unlock_group_files (void); +-static void open_files (void); +-static void open_group_files (void); +-static void open_shadow (void); ++static void process_flags (int argc, char **argv, struct option_flags *flags); ++static void close_files (struct option_flags *flags); ++static void close_group_files (bool process_selinux); ++static void unlock_group_files (bool process_selinux); ++static void open_files (bool process_selinux); ++static void open_group_files (bool process_selinux); ++static void open_shadow (bool process_selinux); + static void faillog_reset (uid_t); + #ifdef ENABLE_LASTLOG + static void lastlog_reset (uid_t); + #endif /* ENABLE_LASTLOG */ + static void tallylog_reset (const char *); +-static void usr_update (unsigned long subuid_count, unsigned long subgid_count); +-static void create_home (void); +-static void create_mail (void); ++static void usr_update (unsigned long subuid_count, unsigned long subgid_count, ++ struct option_flags *flags); ++static void create_home (struct option_flags *flags); ++static void create_mail (struct option_flags *flags); + static void check_uid_range(int rflg, uid_t user_id); + + + /* + * fail_exit - undo as much as possible + */ +-static void fail_exit (int code) ++static void fail_exit (int code, bool process_selinux) + { + #ifdef WITH_AUDIT + int type; +@@ -265,35 +275,35 @@ static void fail_exit (int code) + SYSLOG((LOG_ERR, "failed to remove %s", prefix_user_home)); + } + +- if (spw_locked && spw_unlock(true) == 0) { ++ if (spw_locked && spw_unlock(process_selinux) == 0) { + fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname()); + SYSLOG((LOG_ERR, "failed to unlock %s", spw_dbname())); + /* continue */ + } +- if (pw_locked && pw_unlock(true) == 0) { ++ if (pw_locked && pw_unlock(process_selinux) == 0) { + fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname()); + SYSLOG((LOG_ERR, "failed to unlock %s", pw_dbname())); + /* continue */ + } +- if (gr_locked && gr_unlock(true) == 0) { ++ if (gr_locked && gr_unlock(process_selinux) == 0) { + fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname()); + SYSLOG((LOG_ERR, "failed to unlock %s", gr_dbname())); + /* continue */ + } + #ifdef SHADOWGRP +- if (sgr_locked && sgr_unlock(true) == 0) { ++ if (sgr_locked && sgr_unlock(process_selinux) == 0) { + fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname()); + SYSLOG((LOG_ERR, "failed to unlock %s", sgr_dbname())); + /* continue */ + } + #endif + #ifdef ENABLE_SUBIDS +- if (sub_uid_locked && sub_uid_unlock(true) == 0) { ++ if (sub_uid_locked && sub_uid_unlock(process_selinux) == 0) { + fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname()); + SYSLOG((LOG_ERR, "failed to unlock %s", sub_uid_dbname())); + /* continue */ + } +- if (sub_gid_locked && sub_gid_unlock(true) == 0) { ++ if (sub_gid_locked && sub_gid_unlock(process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname())); + /* continue */ +@@ -322,7 +332,7 @@ static void fail_exit (int code) + * file does not exist. + */ + static void +-get_defaults(void) ++get_defaults(struct option_flags *flags) + { + FILE *fp; + char *default_file = USER_DEFAULTS_FILE; +@@ -377,7 +387,7 @@ get_defaults(void) + ccp = cp; + + if (streq(buf, DGROUPS)) { +- if (get_groups (cp) != 0) { ++ if (get_groups (cp, flags) != 0) { + fprintf (stderr, + _("%s: the '%s=' configuration in %s has an invalid group, ignoring the bad group\n"), + Prog, DGROUPS, default_file); +@@ -736,11 +746,14 @@ err_free_new: + * converts it to a NULL-terminated array. Any unknown group + * names are reported as errors. + */ +-static int get_groups (char *list) ++static int get_groups (char *list, struct option_flags *flags) + { + struct group *grp; + bool errors = false; + int ngroups = 0; ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot && !flags->prefix; + + /* + * Free previous group list before creating a new one. +@@ -758,7 +771,7 @@ static int get_groups (char *list) + /* + * Open the group files + */ +- open_group_files (); ++ open_group_files (process_selinux); + + /* + * So long as there is some data to be converted, strip off +@@ -777,7 +790,7 @@ static int get_groups (char *list) + * Names starting with digits are treated as numerical + * GID values, otherwise the string is looked up as is. + */ +- grp = get_local_group(g); ++ grp = get_local_group(g, process_selinux); + + /* + * There must be a match, either by GID value or by +@@ -815,8 +828,8 @@ static int get_groups (char *list) + gr_free (grp); + } + +- close_group_files (); +- unlock_group_files (); ++ close_group_files (process_selinux); ++ unlock_group_files (process_selinux); + + user_groups[ngroups] = NULL; + +@@ -837,7 +850,7 @@ static int get_groups (char *list) + * If the name exists the group information is returned, otherwise NULL is + * returned. + */ +-static struct group * get_local_group(char * grp_name) ++static struct group * get_local_group(char * grp_name, bool process_selinux) + { + gid_t gid; + struct group *result_grp = NULL; +@@ -854,7 +867,7 @@ static struct group * get_local_group(ch + fprintf (stderr, + _("%s: Out of memory. Cannot find group '%s'.\n"), + Prog, grp_name); +- fail_exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE, process_selinux); + } + } + +@@ -986,7 +999,7 @@ static void new_spent (struct spwd *spen + * close_files() should be called afterwards to commit the changes + * and unlocking the group files. + */ +-static void grp_update (void) ++static void grp_update (bool process_selinux) + { + const struct group *grp; + struct group *ngrp; +@@ -1022,7 +1035,7 @@ static void grp_update (void) + _("%s: Out of memory. Cannot update %s.\n"), + Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", gr_dbname (), user_name)); +- fail_exit (E_GRP_UPDATE); /* XXX */ ++ fail_exit (E_GRP_UPDATE, process_selinux); /* XXX */ + } + + /* +@@ -1035,7 +1048,7 @@ static void grp_update (void) + _("%s: failed to prepare the new %s entry '%s'\n"), + Prog, gr_dbname (), ngrp->gr_name); + SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", gr_dbname (), user_name)); +- fail_exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE, process_selinux); + } + #ifdef WITH_AUDIT + audit_logger_with_group (AUDIT_USER_MGMT, +@@ -1085,7 +1098,7 @@ static void grp_update (void) + _("%s: Out of memory. Cannot update %s.\n"), + Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", sgr_dbname (), user_name)); +- fail_exit (E_GRP_UPDATE); /* XXX */ ++ fail_exit (E_GRP_UPDATE, process_selinux); /* XXX */ + } + + /* +@@ -1099,7 +1112,7 @@ static void grp_update (void) + Prog, sgr_dbname (), nsgrp->sg_namp); + SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", sgr_dbname (), user_name)); + +- fail_exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE, process_selinux); + } + #ifdef WITH_AUDIT + audit_logger_with_group (AUDIT_USER_MGMT, +@@ -1121,7 +1134,7 @@ static void grp_update (void) + * the values that the user will be created with accordingly. The + * values are checked for sanity. + */ +-static void process_flags (int argc, char **argv) ++static void process_flags (int argc, char **argv, struct option_flags *flags) + { + const struct group *grp; + bool anyflag = false; +@@ -1296,7 +1309,7 @@ static void process_flags (int argc, cha + gflg = true; + break; + case 'G': +- if (get_groups (optarg) != 0) { ++ if (get_groups (optarg, flags) != 0) { + exit (E_NOTFOUND); + } + if (NULL != user_groups[0]) { +@@ -1356,8 +1369,10 @@ static void process_flags (int argc, cha + rflg = true; + break; + case 'R': /* no-op, handled in process_root_flag () */ ++ flags->chroot = true; + break; + case 'P': /* no-op, handled in process_prefix_flag () */ ++ flags->prefix = true; + break; + case 's': + if ( ( !VALID (optarg) ) +@@ -1562,38 +1577,42 @@ static void process_flags (int argc, cha + * close_files() closes all of the files that were opened for this + * new user. This causes any modified entries to be written out. + */ +-static void close_files (void) ++static void close_files (struct option_flags *flags) + { +- if (pw_close (true) == 0) { ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot && !flags->prefix; ++ ++ if (pw_close (process_selinux) == 0) { + fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); +- fail_exit (E_PW_UPDATE); ++ fail_exit (E_PW_UPDATE, process_selinux); + } +- if (is_shadow_pwd && (spw_close (true) == 0)) { ++ if (is_shadow_pwd && (spw_close (process_selinux) == 0)) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); +- fail_exit (E_PW_UPDATE); ++ fail_exit (E_PW_UPDATE, process_selinux); + } + +- close_group_files (); ++ close_group_files (process_selinux); + + #ifdef ENABLE_SUBIDS +- if (is_sub_uid && (sub_uid_close (true) == 0)) { ++ if (is_sub_uid && (sub_uid_close (process_selinux) == 0)) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), Prog, sub_uid_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_uid_dbname ())); +- fail_exit (E_SUB_UID_UPDATE); ++ fail_exit (E_SUB_UID_UPDATE, process_selinux); + } +- if (is_sub_gid && (sub_gid_close (true) == 0)) { ++ if (is_sub_gid && (sub_gid_close (process_selinux) == 0)) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), Prog, sub_gid_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_gid_dbname ())); +- fail_exit (E_SUB_GID_UPDATE); ++ fail_exit (E_SUB_GID_UPDATE, process_selinux); + } + #endif /* ENABLE_SUBIDS */ + if (is_shadow_pwd) { +- if (spw_unlock (true) == 0) { ++ if (spw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + #ifdef WITH_AUDIT +@@ -1606,7 +1625,7 @@ static void close_files (void) + } + spw_locked = false; + } +- if (pw_unlock (true) == 0) { ++ if (pw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + #ifdef WITH_AUDIT +@@ -1619,11 +1638,11 @@ static void close_files (void) + } + pw_locked = false; + +- unlock_group_files (); ++ unlock_group_files (process_selinux); + + #ifdef ENABLE_SUBIDS + if (is_sub_uid) { +- if (sub_uid_unlock (true) == 0) { ++ if (sub_uid_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); + #ifdef WITH_AUDIT +@@ -1637,7 +1656,7 @@ static void close_files (void) + sub_uid_locked = false; + } + if (is_sub_gid) { +- if (sub_gid_unlock (true) == 0) { ++ if (sub_gid_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); + #ifdef WITH_AUDIT +@@ -1659,25 +1678,25 @@ static void close_files (void) + * close_group_files() closes all of the files that were opened related + * with groups. This causes any modified entries to be written out. + */ +-static void close_group_files (void) ++static void close_group_files (bool process_selinux) + { + if (!do_grp_update) + return; + +- if (gr_close(true) == 0) { ++ if (gr_close(process_selinux) == 0) { + fprintf(stderr, + _("%s: failure while writing changes to %s\n"), + Prog, gr_dbname()); + SYSLOG((LOG_ERR, "failure while writing changes to %s", gr_dbname())); +- fail_exit(E_GRP_UPDATE); ++ fail_exit(E_GRP_UPDATE, process_selinux); + } + #ifdef SHADOWGRP +- if (is_shadow_grp && sgr_close(true) == 0) { ++ if (is_shadow_grp && sgr_close(process_selinux) == 0) { + fprintf(stderr, + _("%s: failure while writing changes to %s\n"), + Prog, sgr_dbname()); + SYSLOG((LOG_ERR, "failure while writing changes to %s", sgr_dbname())); +- fail_exit(E_GRP_UPDATE); ++ fail_exit(E_GRP_UPDATE, process_selinux); + } + #endif /* SHADOWGRP */ + } +@@ -1688,9 +1707,9 @@ static void close_group_files (void) + * unlock_group_files() unlocks all of the files that were locked related + * with groups. This causes any modified entries to be written out. + */ +-static void unlock_group_files (void) ++static void unlock_group_files (bool process_selinux) + { +- if (gr_unlock (true) == 0) { ++ if (gr_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + #ifdef WITH_AUDIT +@@ -1704,7 +1723,7 @@ static void unlock_group_files (void) + gr_locked = false; + #ifdef SHADOWGRP + if (is_shadow_grp) { +- if (sgr_unlock (true) == 0) { ++ if (sgr_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + #ifdef WITH_AUDIT +@@ -1725,7 +1744,7 @@ static void unlock_group_files (void) + * + * open_files() opens the two password files. + */ +-static void open_files (void) ++static void open_files (bool process_selinux) + { + if (pw_lock () == 0) { + fprintf (stderr, +@@ -1736,12 +1755,12 @@ static void open_files (void) + pw_locked = true; + if (pw_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, _("%s: cannot open %s\n"), Prog, pw_dbname ()); +- fail_exit (E_PW_UPDATE); ++ fail_exit (E_PW_UPDATE, process_selinux); + } + + /* shadow file will be opened by open_shadow(); */ + +- open_group_files (); ++ open_group_files (process_selinux); + + #ifdef ENABLE_SUBIDS + if (is_sub_uid) { +@@ -1749,14 +1768,14 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, sub_uid_dbname ()); +- fail_exit (E_SUB_UID_UPDATE); ++ fail_exit (E_SUB_UID_UPDATE, process_selinux); + } + sub_uid_locked = true; + if (sub_uid_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, + _("%s: cannot open %s\n"), + Prog, sub_uid_dbname ()); +- fail_exit (E_SUB_UID_UPDATE); ++ fail_exit (E_SUB_UID_UPDATE, process_selinux); + } + } + if (is_sub_gid) { +@@ -1764,31 +1783,31 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, sub_gid_dbname ()); +- fail_exit (E_SUB_GID_UPDATE); ++ fail_exit (E_SUB_GID_UPDATE, process_selinux); + } + sub_gid_locked = true; + if (sub_gid_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, + _("%s: cannot open %s\n"), + Prog, sub_gid_dbname ()); +- fail_exit (E_SUB_GID_UPDATE); ++ fail_exit (E_SUB_GID_UPDATE, process_selinux); + } + } + #endif /* ENABLE_SUBIDS */ + } + +-static void open_group_files (void) ++static void open_group_files (bool process_selinux) + { + if (gr_lock () == 0) { + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, gr_dbname ()); +- fail_exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE, process_selinux); + } + gr_locked = true; + if (gr_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ()); +- fail_exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE, process_selinux); + } + + #ifdef SHADOWGRP +@@ -1797,20 +1816,20 @@ static void open_group_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, sgr_dbname ()); +- fail_exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE, process_selinux); + } + sgr_locked = true; + if (sgr_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, + _("%s: cannot open %s\n"), + Prog, sgr_dbname ()); +- fail_exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE, process_selinux); + } + } + #endif /* SHADOWGRP */ + } + +-static void open_shadow (void) ++static void open_shadow (bool process_selinux) + { + if (!is_shadow_pwd) { + return; +@@ -1819,14 +1838,14 @@ static void open_shadow (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, spw_dbname ()); +- fail_exit (E_PW_UPDATE); ++ fail_exit (E_PW_UPDATE, process_selinux); + } + spw_locked = true; + if (spw_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, + _("%s: cannot open %s\n"), + Prog, spw_dbname ()); +- fail_exit (E_PW_UPDATE); ++ fail_exit (E_PW_UPDATE, process_selinux); + } + } + +@@ -1880,7 +1899,7 @@ static void new_sgent (struct sgrp *sgen + * grp_add() writes the new records to the group files. + */ + +-static void grp_add (void) ++static void grp_add (bool process_selinux) + { + struct group grp; + +@@ -1909,7 +1928,7 @@ static void grp_add (void) + grp.gr_name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); + #endif +- fail_exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE, process_selinux); + } + #ifdef SHADOWGRP + /* +@@ -1925,7 +1944,7 @@ static void grp_add (void) + grp.gr_name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); + #endif +- fail_exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE, process_selinux); + } + #endif /* SHADOWGRP */ + SYSLOG ((LOG_INFO, "new group: name=%s, GID=%u", user_name, user_gid)); +@@ -2074,11 +2093,16 @@ static void tallylog_reset (const char * + * usr_update() creates the password file entries for this user + * and will update the group entries if required. + */ +-static void usr_update (unsigned long subuid_count, unsigned long subgid_count) ++static void ++usr_update (unsigned long subuid_count, unsigned long subgid_count, ++ struct option_flags *flags) + { + struct passwd pwent; + struct spwd spent; + char *tty; ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot && !flags->prefix; + + /* + * Fill in the password structure with any new fields, making +@@ -2119,7 +2143,7 @@ static void usr_update (unsigned long su + fprintf (stderr, + _("%s: failed to prepare the new %s entry '%s'\n"), + Prog, pw_dbname (), pwent.pw_name); +- fail_exit (E_PW_UPDATE); ++ fail_exit (E_PW_UPDATE, process_selinux); + } + + /* +@@ -2129,7 +2153,7 @@ static void usr_update (unsigned long su + fprintf (stderr, + _("%s: failed to prepare the new %s entry '%s'\n"), + Prog, spw_dbname (), spent.sp_namp); +- fail_exit (E_PW_UPDATE); ++ fail_exit (E_PW_UPDATE, process_selinux); + } + #ifdef ENABLE_SUBIDS + if (is_sub_uid && !local_sub_uid_assigned(user_name) && +@@ -2137,14 +2161,14 @@ static void usr_update (unsigned long su + fprintf (stderr, + _("%s: failed to prepare the new %s entry\n"), + Prog, sub_uid_dbname ()); +- fail_exit (E_SUB_UID_UPDATE); ++ fail_exit (E_SUB_UID_UPDATE, process_selinux); + } + if (is_sub_gid && !local_sub_gid_assigned(user_name) && + (sub_gid_add(user_name, sub_gid_start, subgid_count) == 0)) { + fprintf (stderr, + _("%s: failed to prepare the new %s entry\n"), + Prog, sub_uid_dbname ()); +- fail_exit (E_SUB_GID_UPDATE); ++ fail_exit (E_SUB_GID_UPDATE, process_selinux); + } + #endif /* ENABLE_SUBIDS */ + +@@ -2163,7 +2187,7 @@ static void usr_update (unsigned long su + * Do any group file updates for this user. + */ + if (do_grp_update) { +- grp_update (); ++ grp_update (process_selinux); + } + } + +@@ -2174,11 +2198,14 @@ static void usr_update (unsigned long su + * already exist. It will be created mode 755 owned by the user + * with the user's default group. + */ +-static void create_home (void) ++static void create_home (struct option_flags *flags) + { + char path[strlen(prefix_user_home) + 2]; + char *bhome, *cp; + mode_t mode; ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot && !flags->prefix; + + if (access (prefix_user_home, F_OK) == 0) + return; +@@ -2189,15 +2216,17 @@ static void create_home (void) + fprintf(stderr, + _("%s: error while duplicating string %s\n"), + Prog, user_home); +- fail_exit(E_HOMEDIR); ++ fail_exit(E_HOMEDIR, process_selinux); + } + + #ifdef WITH_SELINUX +- if (set_selinux_file_context(prefix_user_home, S_IFDIR) != 0) { +- fprintf(stderr, +- _("%s: cannot set SELinux context for home directory %s\n"), +- Prog, user_home); +- fail_exit(E_HOMEDIR); ++ if (process_selinux) { ++ if (set_selinux_file_context(prefix_user_home, S_IFDIR) != 0) { ++ fprintf(stderr, ++ _("%s: cannot set SELinux context for home directory %s\n"), ++ Prog, user_home); ++ fail_exit(E_HOMEDIR, process_selinux); ++ } + } + #endif + +@@ -2227,14 +2256,14 @@ static void create_home (void) + fprintf(stderr, + _("%s: error while duplicating string in BTRFS check %s\n"), + Prog, path); +- fail_exit(E_HOMEDIR); ++ fail_exit(E_HOMEDIR, process_selinux); + } + stpcpy(&btrfs_check[strlen(path) - strlen(cp) - 1], ""); + if (is_btrfs(btrfs_check) <= 0) { + fprintf(stderr, + _("%s: home directory \"%s\" must be mounted on BTRFS\n"), + Prog, path); +- fail_exit(E_HOMEDIR); ++ fail_exit(E_HOMEDIR, process_selinux); + } + free(btrfs_check); + // make subvolume to mount for user instead of directory +@@ -2242,7 +2271,7 @@ static void create_home (void) + fprintf(stderr, + _("%s: failed to create BTRFS subvolume: %s\n"), + Prog, path); +- fail_exit(E_HOMEDIR); ++ fail_exit(E_HOMEDIR, process_selinux); + } + } + else +@@ -2250,7 +2279,7 @@ static void create_home (void) + if (mkdir(path, 0) != 0) { + fprintf(stderr, _("%s: cannot create directory %s\n"), + Prog, path); +- fail_exit(E_HOMEDIR); ++ fail_exit(E_HOMEDIR, process_selinux); + } + if (chown(path, 0, 0) < 0) { + fprintf(stderr, +@@ -2278,12 +2307,14 @@ static void create_home (void) + user_name, user_id, SHADOW_AUDIT_SUCCESS); + #endif + #ifdef WITH_SELINUX +- /* Reset SELinux to create files with default contexts */ +- if (reset_selinux_file_context() != 0) { +- fprintf(stderr, +- _("%s: cannot reset SELinux file creation context\n"), +- Prog); +- fail_exit(E_HOMEDIR); ++ if (process_selinux) { ++ /* Reset SELinux to create files with default contexts */ ++ if (reset_selinux_file_context() != 0) { ++ fprintf(stderr, ++ _("%s: cannot reset SELinux file creation context\n"), ++ Prog); ++ fail_exit(E_HOMEDIR, process_selinux); ++ } + } + #endif + } +@@ -2295,7 +2326,7 @@ static void create_home (void) + * exist. It will be created mode 660 owned by the user and group + * 'mail' + */ +-static void create_mail (void) ++static void create_mail (struct option_flags *flags) + { + int fd; + char *file; +@@ -2303,6 +2334,9 @@ static void create_mail (void) + mode_t mode; + const char *spool; + struct group *gr; ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot && !flags->prefix; + + if (!strcaseeq(create_mail_spool, "yes")) + return; +@@ -2322,11 +2356,13 @@ static void create_mail (void) + file = xaprintf("%s/%s", spool, user_name); + + #ifdef WITH_SELINUX +- if (set_selinux_file_context(file, S_IFREG) != 0) { +- fprintf(stderr, +- _("%s: cannot set SELinux context for mailbox file %s\n"), +- Prog, file); +- fail_exit(E_MAILBOXFILE); ++ if (process_selinux) { ++ if (set_selinux_file_context(file, S_IFREG) != 0) { ++ fprintf(stderr, ++ _("%s: cannot set SELinux context for mailbox file %s\n"), ++ Prog, file); ++ fail_exit(E_MAILBOXFILE, process_selinux); ++ } + } + #endif + +@@ -2362,12 +2398,14 @@ static void create_mail (void) + perror (_("Closing mailbox file")); + } + #ifdef WITH_SELINUX +- /* Reset SELinux to create files with default contexts */ +- if (reset_selinux_file_context() != 0) { +- fprintf(stderr, +- _("%s: cannot reset SELinux file creation context\n"), +- Prog); +- fail_exit(E_MAILBOXFILE); ++ if (process_selinux) { ++ /* Reset SELinux to create files with default contexts */ ++ if (reset_selinux_file_context() != 0) { ++ fprintf(stderr, ++ _("%s: cannot reset SELinux file creation context\n"), ++ Prog); ++ fail_exit(E_MAILBOXFILE, process_selinux); ++ } + } + #endif + } +@@ -2409,6 +2447,8 @@ int main (int argc, char **argv) + #endif + unsigned long subuid_count = 0; + unsigned long subgid_count = 0; ++ struct option_flags flags; ++ bool process_selinux; + + log_set_progname(Prog); + log_set_logfd(stderr); +@@ -2439,9 +2479,10 @@ int main (int argc, char **argv) + is_shadow_grp = sgr_file_present (); + #endif + +- get_defaults (); ++ get_defaults (&flags); + +- process_flags (argc, argv); ++ process_flags (argc, argv, &flags); ++ process_selinux = !flags.chroot && !flags.prefix; + + #ifdef ENABLE_SUBIDS + uid_min = getdef_ulong ("UID_MIN", 1000UL); +@@ -2470,7 +2511,7 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: Cannot determine your user name.\n"), + Prog); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + + retval = pam_start (Prog, pampw?pampw->pw_name:"root", &conv, &pamh); +@@ -2491,7 +2532,7 @@ int main (int argc, char **argv) + if (NULL != pamh) { + (void) pam_end (pamh, retval); + } +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + (void) pam_end (pamh, retval); + #endif /* USE_PAM */ +@@ -2515,7 +2556,7 @@ int main (int argc, char **argv) + */ + if (prefix_getpwnam (user_name) != NULL) { /* local, no need for xgetpwnam */ + fprintf (stderr, _("%s: user '%s' already exists\n"), Prog, user_name); +- fail_exit (E_NAME_IN_USE); ++ fail_exit (E_NAME_IN_USE, process_selinux); + } + + /* +@@ -2530,7 +2571,7 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: group %s exists - if you want to add this user to that group, use -g.\n"), + Prog, user_name); +- fail_exit (E_NAME_IN_USE); ++ fail_exit (E_NAME_IN_USE, process_selinux); + } + } + +@@ -2543,7 +2584,7 @@ int main (int argc, char **argv) + * - flush nscd caches for passwd and group services, + * - then close and update the files. + */ +- open_files (); ++ open_files (process_selinux); + + if (!oflg) { + /* first, seek for a valid uid to use for this user. +@@ -2552,14 +2593,14 @@ int main (int argc, char **argv) + if (!uflg) { + if (find_new_uid (rflg, &user_id, NULL) < 0) { + fprintf (stderr, _("%s: can't create user\n"), Prog); +- fail_exit (E_UID_IN_USE); ++ fail_exit (E_UID_IN_USE, process_selinux); + } + } else { + if (prefix_getpwuid (user_id) != NULL) { + fprintf (stderr, + _("%s: UID %lu is not unique\n"), + Prog, (unsigned long) user_id); +- fail_exit (E_UID_IN_USE); ++ fail_exit (E_UID_IN_USE, process_selinux); + } + } + } +@@ -2572,11 +2613,11 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: Failed to create tcb directory for %s\n"), + Prog, user_name); +- fail_exit (E_UID_IN_USE); ++ fail_exit (E_UID_IN_USE, process_selinux); + } + } + #endif +- open_shadow (); ++ open_shadow (process_selinux); + + /* do we have to add a group for that user? This is why we need to + * open the group files in the open_files() function --gafton */ +@@ -2585,9 +2626,9 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: can't create group\n"), + Prog); +- fail_exit (4); ++ fail_exit (4, process_selinux); + } +- grp_add (); ++ grp_add (process_selinux); + } + + #ifdef ENABLE_SUBIDS +@@ -2596,7 +2637,7 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: can't create subordinate user IDs\n"), + Prog); +- fail_exit(E_SUB_UID_UPDATE); ++ fail_exit(E_SUB_UID_UPDATE, process_selinux); + } + } + if (is_sub_gid && subgid_count != 0) { +@@ -2604,14 +2645,14 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: can't create subordinate group IDs\n"), + Prog); +- fail_exit(E_SUB_GID_UPDATE); ++ fail_exit(E_SUB_GID_UPDATE, process_selinux); + } + } + #endif /* ENABLE_SUBIDS */ + +- usr_update (subuid_count, subgid_count); ++ usr_update (subuid_count, subgid_count, &flags); + +- close_files (); ++ close_files (&flags); + + nscd_flush_cache ("passwd"); + nscd_flush_cache ("group"); +@@ -2637,13 +2678,13 @@ int main (int argc, char **argv) + "add-selinux-user-mapping", + user_name, user_id, SHADOW_AUDIT_FAILURE); + #endif /* WITH_AUDIT */ +- fail_exit (E_SE_UPDATE); ++ fail_exit (E_SE_UPDATE, process_selinux); + } + } + #endif /* WITH_SELINUX */ + + if (mflg) { +- create_home (); ++ create_home (&flags); + if (home_added) { + copy_tree (def_template, prefix_user_home, false, true, + (uid_t)-1, user_id, (gid_t)-1, user_gid); +@@ -2660,7 +2701,7 @@ int main (int argc, char **argv) + + /* Do not create mail directory for system accounts */ + if (!rflg) { +- create_mail (); ++ create_mail (&flags); + } + + if (run_parts ("/etc/shadow-maint/useradd-post.d", user_name, +diff -up shadow-4.18.0/src/userdel.c.test-chroot2 shadow-4.18.0/src/userdel.c +--- shadow-4.18.0/src/userdel.c.test-chroot2 2025-07-08 11:22:16.257469516 +0200 ++++ shadow-4.18.0/src/userdel.c 2025-07-08 11:22:16.263226317 +0200 +@@ -73,6 +73,14 @@ + #endif /* ENABLE_SUBIDS */ + + /* ++ * Structures ++ */ ++struct option_flags { ++ bool chroot; ++ bool prefix; ++}; ++ ++/* + * Global variables + */ + static const char Prog[] = "userdel"; +@@ -87,7 +95,6 @@ static bool rflg = false; + #ifdef WITH_SELINUX + static bool Zflg = false; + #endif +-static bool Rflg = false; + + static bool is_shadow_pwd; + +@@ -109,12 +116,12 @@ static const char* prefix = ""; + + /* local function prototypes */ + static void usage (int status); +-static void update_groups (void); +-static void remove_usergroup (void); +-static void close_files (void); +-static void fail_exit (int); +-static void open_files (void); +-static void update_user (void); ++static void update_groups (bool process_selinux); ++static void remove_usergroup (bool process_selinux); ++static void close_files (struct option_flags *flags); ++static void fail_exit (int, bool); ++static void open_files (bool process_selinux); ++static void update_user (bool process_selinux); + static void user_cancel (const char *); + + #ifdef EXTRA_CHECK_HOME_DIR +@@ -162,7 +169,7 @@ static void usage (int status) + * name is their user name) and delete them too (only if USERGROUPS_ENAB + * is enabled). + */ +-static void update_groups (void) ++static void update_groups (bool process_selinux) + { + const struct group *grp; + struct group *ngrp; +@@ -219,7 +226,7 @@ static void update_groups (void) + } + + if (getdef_bool ("USERGROUPS_ENAB")) { +- remove_usergroup (); ++ remove_usergroup (process_selinux); + } + + #ifdef SHADOWGRP +@@ -291,7 +298,7 @@ static void update_groups (void) + * + it has no other members + * + it is not the primary group of any other user + */ +-static void remove_usergroup (void) ++static void remove_usergroup (bool process_selinux) + { + const struct group *grp; + const struct passwd *pwd = NULL; +@@ -346,7 +353,7 @@ static void remove_usergroup (void) + fprintf (stderr, + _("%s: cannot remove entry '%s' from %s\n"), + Prog, user_name, gr_dbname ()); +- fail_exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE, process_selinux); + } + + #ifdef WITH_AUDIT +@@ -365,7 +372,7 @@ static void remove_usergroup (void) + fprintf (stderr, + _("%s: cannot remove entry '%s' from %s\n"), + Prog, user_name, sgr_dbname ()); +- fail_exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE, process_selinux); + } + #ifdef WITH_AUDIT + audit_logger_with_group (AUDIT_GRP_MGMT, +@@ -388,14 +395,18 @@ static void remove_usergroup (void) + * close_files() closes all of the files that were opened for this + * new user. This causes any modified entries to be written out. + */ +-static void close_files (void) ++static void close_files (struct option_flags *flags) + { +- if (pw_close (true) == 0) { ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot && !flags->prefix; ++ ++ if (pw_close (process_selinux) == 0) { + fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); +- fail_exit (E_PW_UPDATE); ++ fail_exit (E_PW_UPDATE, process_selinux); + } +- if (pw_unlock (true) == 0) { ++ if (pw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +@@ -403,13 +414,13 @@ static void close_files (void) + pw_locked = false; + + if (is_shadow_pwd) { +- if (spw_close (true) == 0) { ++ if (spw_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); +- fail_exit (E_PW_UPDATE); ++ fail_exit (E_PW_UPDATE, process_selinux); + } +- if (spw_unlock (true) == 0) { ++ if (spw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + /* continue */ +@@ -417,12 +428,12 @@ static void close_files (void) + spw_locked = false; + } + +- if (gr_close (true) == 0) { ++ if (gr_close (process_selinux) == 0) { + fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ())); +- fail_exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE, process_selinux); + } +- if (gr_unlock (true) == 0) { ++ if (gr_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + /* continue */ +@@ -431,14 +442,14 @@ static void close_files (void) + + #ifdef SHADOWGRP + if (is_shadow_grp) { +- if (sgr_close (true) == 0) { ++ if (sgr_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ())); +- fail_exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE, process_selinux); + } + +- if (sgr_unlock (true) == 0) { ++ if (sgr_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + /* continue */ +@@ -449,12 +460,12 @@ static void close_files (void) + + #ifdef ENABLE_SUBIDS + if (is_sub_uid) { +- if (sub_uid_close (true) == 0) { ++ if (sub_uid_close (process_selinux) == 0) { + fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sub_uid_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_uid_dbname ())); +- fail_exit (E_SUB_UID_UPDATE); ++ fail_exit (E_SUB_UID_UPDATE, process_selinux); + } +- if (sub_uid_unlock (true) == 0) { ++ if (sub_uid_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); + /* continue */ +@@ -463,12 +474,12 @@ static void close_files (void) + } + + if (is_sub_gid) { +- if (sub_gid_close (true) == 0) { ++ if (sub_gid_close (process_selinux) == 0) { + fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sub_gid_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_gid_dbname ())); +- fail_exit (E_SUB_GID_UPDATE); ++ fail_exit (E_SUB_GID_UPDATE, process_selinux); + } +- if (sub_gid_unlock (true) == 0) { ++ if (sub_gid_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); + /* continue */ +@@ -481,24 +492,24 @@ static void close_files (void) + /* + * fail_exit - exit with a failure code after unlocking the files + */ +-static void fail_exit (int code) ++static void fail_exit (int code, bool process_selinux) + { + if (pw_locked) { +- if (pw_unlock (true) == 0) { ++ if (pw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ + } + } + if (gr_locked) { +- if (gr_unlock (true) == 0) { ++ if (gr_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + /* continue */ + } + } + if (spw_locked) { +- if (spw_unlock (true) == 0) { ++ if (spw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + /* continue */ +@@ -506,7 +517,7 @@ static void fail_exit (int code) + } + #ifdef SHADOWGRP + if (sgr_locked) { +- if (sgr_unlock (true) == 0) { ++ if (sgr_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + /* continue */ +@@ -515,14 +526,14 @@ static void fail_exit (int code) + #endif /* SHADOWGRP */ + #ifdef ENABLE_SUBIDS + if (sub_uid_locked) { +- if (sub_uid_unlock (true) == 0) { ++ if (sub_uid_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); + /* continue */ + } + } + if (sub_gid_locked) { +- if (sub_gid_unlock (true) == 0) { ++ if (sub_gid_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); + /* continue */ +@@ -545,45 +556,45 @@ static void fail_exit (int code) + * open_files() opens the two password files. + */ + +-static void open_files (void) ++static void open_files (bool process_selinux) + { + if (pw_lock () == 0) { + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, pw_dbname ()); +- fail_exit (E_PW_UPDATE); ++ fail_exit (E_PW_UPDATE, process_selinux); + } + pw_locked = true; + if (pw_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, + _("%s: cannot open %s\n"), Prog, pw_dbname ()); +- fail_exit (E_PW_UPDATE); ++ fail_exit (E_PW_UPDATE, process_selinux); + } + if (is_shadow_pwd) { + if (spw_lock () == 0) { + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, spw_dbname ()); +- fail_exit (E_PW_UPDATE); ++ fail_exit (E_PW_UPDATE, process_selinux); + } + spw_locked = true; + if (spw_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, + _("%s: cannot open %s\n"), + Prog, spw_dbname ()); +- fail_exit (E_PW_UPDATE); ++ fail_exit (E_PW_UPDATE, process_selinux); + } + } + if (gr_lock () == 0) { + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, gr_dbname ()); +- fail_exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE, process_selinux); + } + gr_locked = true; + if (gr_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ()); +- fail_exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE, process_selinux); + } + #ifdef SHADOWGRP + if (is_shadow_grp) { +@@ -591,13 +602,13 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, sgr_dbname ()); +- fail_exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE, process_selinux); + } + sgr_locked= true; + if (sgr_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, _("%s: cannot open %s\n"), + Prog, sgr_dbname ()); +- fail_exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE, process_selinux); + } + } + #endif /* SHADOWGRP */ +@@ -607,13 +618,13 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, sub_uid_dbname ()); +- fail_exit (E_SUB_UID_UPDATE); ++ fail_exit (E_SUB_UID_UPDATE, process_selinux); + } + sub_uid_locked = true; + if (sub_uid_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, + _("%s: cannot open %s\n"), Prog, sub_uid_dbname ()); +- fail_exit (E_SUB_UID_UPDATE); ++ fail_exit (E_SUB_UID_UPDATE, process_selinux); + } + } + if (is_sub_gid) { +@@ -621,13 +632,13 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, sub_gid_dbname ()); +- fail_exit (E_SUB_GID_UPDATE); ++ fail_exit (E_SUB_GID_UPDATE, process_selinux); + } + sub_gid_locked = true; + if (sub_gid_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, + _("%s: cannot open %s\n"), Prog, sub_gid_dbname ()); +- fail_exit (E_SUB_GID_UPDATE); ++ fail_exit (E_SUB_GID_UPDATE, process_selinux); + } + } + #endif /* ENABLE_SUBIDS */ +@@ -639,13 +650,13 @@ static void open_files (void) + * update_user() deletes the password file entries for this user + * and will update the group entries as required. + */ +-static void update_user (void) ++static void update_user (bool process_selinux) + { + if (pw_remove (user_name) == 0) { + fprintf (stderr, + _("%s: cannot remove entry '%s' from %s\n"), + Prog, user_name, pw_dbname ()); +- fail_exit (E_PW_UPDATE); ++ fail_exit (E_PW_UPDATE, process_selinux); + } + if ( is_shadow_pwd + && (spw_locate (user_name) != NULL) +@@ -653,20 +664,20 @@ static void update_user (void) + fprintf (stderr, + _("%s: cannot remove entry '%s' from %s\n"), + Prog, user_name, spw_dbname ()); +- fail_exit (E_PW_UPDATE); ++ fail_exit (E_PW_UPDATE, process_selinux); + } + #ifdef ENABLE_SUBIDS + if (is_sub_uid && sub_uid_remove(user_name, 0, ULONG_MAX) == 0) { + fprintf (stderr, + _("%s: cannot remove entry %lu from %s\n"), + Prog, (unsigned long)user_id, sub_uid_dbname ()); +- fail_exit (E_SUB_UID_UPDATE); ++ fail_exit (E_SUB_UID_UPDATE, process_selinux); + } + if (is_sub_gid && sub_gid_remove(user_name, 0, ULONG_MAX) == 0) { + fprintf (stderr, + _("%s: cannot remove entry %lu from %s\n"), + Prog, (unsigned long)user_id, sub_gid_dbname ()); +- fail_exit (E_SUB_GID_UPDATE); ++ fail_exit (E_SUB_GID_UPDATE, process_selinux); + } + #endif /* ENABLE_SUBIDS */ + #ifdef WITH_AUDIT +@@ -905,6 +916,8 @@ int main (int argc, char **argv) + int retval; + #endif /* USE_PAM */ + #endif /* ACCT_TOOLS_SETUID */ ++ struct option_flags flags; ++ bool process_selinux; + + log_set_progname(Prog); + log_set_logfd(stderr); +@@ -954,9 +967,10 @@ int main (int argc, char **argv) + rflg = true; + break; + case 'R': /* no-op, handled in process_root_flag () */ +- Rflg = true; ++ flags.chroot = true; + break; + case 'P': /* no-op, handled in process_prefix_flag () */ ++ flags.prefix = true; + break; + #ifdef WITH_SELINUX + case 'Z': +@@ -982,6 +996,7 @@ int main (int argc, char **argv) + } + } + } ++ process_selinux = !flags.chroot && !flags.prefix; + + if ((optind + 1) != argc) { + usage (E_USAGE); +@@ -1046,7 +1061,7 @@ int main (int argc, char **argv) + pw_open(O_RDONLY); + pwd = pw_locate (user_name); /* we care only about local users */ + if (NULL == pwd) { +- pw_close(true); ++ pw_close(process_selinux); + fprintf (stderr, _("%s: user '%s' does not exist\n"), + Prog, user_name); + #ifdef WITH_AUDIT +@@ -1065,7 +1080,7 @@ int main (int argc, char **argv) + } else { + user_home = xstrdup(pwd->pw_dir); + } +- pw_close(true); ++ pw_close(process_selinux); + } + #ifdef WITH_TCB + if (shadowtcb_set_user (user_name) == SHADOWTCB_FAILURE) { +@@ -1077,7 +1092,7 @@ int main (int argc, char **argv) + * Note: This is a best effort basis. The user may log in between, + * a cron job may be started on her behalf, etc. + */ +- if (streq(prefix, "") && !Rflg && user_busy(user_name, user_id) != 0) { ++ if (streq(prefix, "") && !flags.chroot && user_busy(user_name, user_id) != 0) { + if (!fflg) { + #ifdef WITH_AUDIT + audit_logger (AUDIT_DEL_USER, Prog, +@@ -1093,9 +1108,9 @@ int main (int argc, char **argv) + * Do the hard stuff - open the files, create the user entries, + * create the home directory, then close and update the files. + */ +- open_files (); +- update_user (); +- update_groups (); ++ open_files (process_selinux); ++ update_user (process_selinux); ++ update_groups (process_selinux); + + if (rflg) { + if (remove_mailbox ()) { +@@ -1203,7 +1218,7 @@ int main (int argc, char **argv) + "delete-selinux-user-mapping", + user_name, user_id, SHADOW_AUDIT_FAILURE); + #endif /* WITH_AUDIT */ +- fail_exit (E_SE_UPDATE); ++ fail_exit (E_SE_UPDATE, process_selinux); + } + } + #endif /* WITH_SELINUX */ +@@ -1214,7 +1229,7 @@ int main (int argc, char **argv) + */ + if (streq(prefix, "")) + user_cancel (user_name); +- close_files (); ++ close_files (&flags); + + if (run_parts ("/etc/shadow-maint/userdel-post.d", user_name, "userdel")) { + exit(1); +diff -up shadow-4.18.0/src/usermod.c.test-chroot2 shadow-4.18.0/src/usermod.c +--- shadow-4.18.0/src/usermod.c.test-chroot2 2025-07-08 11:22:16.257549046 +0200 ++++ shadow-4.18.0/src/usermod.c 2025-07-08 11:22:16.262408337 +0200 +@@ -97,6 +97,14 @@ + #define VALID(s) (!strpbrk(s, ":\n")) + + /* ++ * Structures ++ */ ++struct option_flags { ++ bool chroot; ++ bool prefix; ++}; ++ ++/* + * Global variables + */ + static const char Prog[] = "usermod"; +@@ -182,23 +190,23 @@ static bool sub_gid_locked = false; + /* local function prototypes */ + static int get_groups (char *); + NORETURN static void usage (int status); +-static void new_pwent (struct passwd *); +-static void new_spent (struct spwd *); +-NORETURN static void fail_exit (int); +-static void update_group_file(void); +-static void update_group(const struct group *grp); ++static void new_pwent (struct passwd *, bool); ++static void new_spent (struct spwd *, bool); ++NORETURN static void fail_exit (int, bool); ++static void update_group_file(bool); ++static void update_group(const struct group *grp, bool process_selinux); + + #ifdef SHADOWGRP +-static void update_gshadow_file(void); +-static void update_gshadow(const struct sgrp *sgrp); ++static void update_gshadow_file(bool process_selinux); ++static void update_gshadow(const struct sgrp *sgrp, bool process_selinux); + #endif +-static void grp_update (void); ++static void grp_update (bool process_selinux); + +-static void process_flags (int, char **); +-static void close_files (void); +-static void open_files (void); +-static void usr_update (void); +-static void move_home (void); ++static void process_flags (int, char **, struct option_flags *); ++static void close_files (struct option_flags *); ++static void open_files (bool process_selinux); ++static void usr_update (struct option_flags *flags); ++static void move_home (bool process_selinux); + #ifdef ENABLE_LASTLOG + static void update_lastlog (void); + #endif /* ENABLE_LASTLOG */ +@@ -466,7 +474,7 @@ static char *new_pw_passwd (char *pw_pas + * new_pwent() takes all of the values that have been entered and fills + * in a (struct passwd) with them. + */ +-static void new_pwent (struct passwd *pwent) ++static void new_pwent (struct passwd *pwent, bool process_selinux) + { + if (lflg) { + if (pw_locate (user_newname) != NULL) { +@@ -477,7 +485,7 @@ static void new_pwent (struct passwd *pw + fprintf (stderr, + _("%s: user '%s' already exists in %s\n"), + Prog, user_newname, pw_dbname ()); +- fail_exit (E_NAME_IN_USE); ++ fail_exit (E_NAME_IN_USE, process_selinux); + } + #ifdef WITH_AUDIT + audit_logger (AUDIT_USER_MGMT, Prog, +@@ -563,14 +571,14 @@ static void new_pwent (struct passwd *pw + * new_spent() takes all of the values that have been entered and fills + * in a (struct spwd) with them. + */ +-static void new_spent (struct spwd *spent) ++static void new_spent (struct spwd *spent, bool process_selinux) + { + if (lflg) { + if (spw_locate (user_newname) != NULL) { + fprintf (stderr, + _("%s: user '%s' already exists in %s\n"), + Prog, user_newname, spw_dbname ()); +- fail_exit (E_NAME_IN_USE); ++ fail_exit (E_NAME_IN_USE, process_selinux); + } + spent->sp_namp = xstrdup (user_newname); + } +@@ -629,10 +637,10 @@ static void new_spent (struct spwd *spen + */ + NORETURN + static void +-fail_exit (int code) ++fail_exit (int code, bool process_selinux) + { + if (gr_locked) { +- if (gr_unlock (true) == 0) { ++ if (gr_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + /* continue */ +@@ -640,7 +648,7 @@ fail_exit (int code) + } + #ifdef SHADOWGRP + if (sgr_locked) { +- if (sgr_unlock (true) == 0) { ++ if (sgr_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + /* continue */ +@@ -648,14 +656,14 @@ fail_exit (int code) + } + #endif + if (spw_locked) { +- if (spw_unlock (true) == 0) { ++ if (spw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + /* continue */ + } + } + if (pw_locked) { +- if (pw_unlock (true) == 0) { ++ if (pw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +@@ -663,14 +671,14 @@ fail_exit (int code) + } + #ifdef ENABLE_SUBIDS + if (sub_uid_locked) { +- if (sub_uid_unlock (true) == 0) { ++ if (sub_uid_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); + /* continue */ + } + } + if (sub_gid_locked) { +- if (sub_gid_unlock (true) == 0) { ++ if (sub_gid_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); + /* continue */ +@@ -688,7 +696,7 @@ fail_exit (int code) + + + static void +-update_group_file(void) ++update_group_file(bool process_selinux) + { + const struct group *grp; + +@@ -697,12 +705,12 @@ update_group_file(void) + * the user is a member of. + */ + while ((grp = gr_next()) != NULL) +- update_group(grp); ++ update_group(grp, process_selinux); + } + + + static void +-update_group(const struct group *grp) ++update_group(const struct group *grp, bool process_selinux) + { + bool changed; + bool is_member; +@@ -735,7 +743,7 @@ update_group(const struct group *grp) + fprintf (stderr, + _("%s: Out of memory. Cannot update %s.\n"), + Prog, gr_dbname ()); +- fail_exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE, process_selinux); + } + + if (was_member) { +@@ -804,7 +812,7 @@ update_group(const struct group *grp) + _("%s: failed to prepare the new %s entry '%s'\n"), + Prog, gr_dbname (), ngrp->gr_name); + SYSLOG ((LOG_WARN, "failed to prepare the new %s entry '%s'", gr_dbname (), ngrp->gr_name)); +- fail_exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE, process_selinux); + } + + free_ngrp: +@@ -814,7 +822,7 @@ free_ngrp: + + #ifdef SHADOWGRP + static void +-update_gshadow_file(void) ++update_gshadow_file(bool process_selinux) + { + const struct sgrp *sgrp; + +@@ -823,14 +831,14 @@ update_gshadow_file(void) + * that the user is a member of. + */ + while ((sgrp = sgr_next()) != NULL) +- update_gshadow(sgrp); ++ update_gshadow(sgrp, process_selinux); + } + #endif /* SHADOWGRP */ + + + #ifdef SHADOWGRP + static void +-update_gshadow(const struct sgrp *sgrp) ++update_gshadow(const struct sgrp *sgrp, bool process_selinux) + { + bool changed; + bool is_member; +@@ -873,7 +881,7 @@ update_gshadow(const struct sgrp *sgrp) + fprintf (stderr, + _("%s: Out of memory. Cannot update %s.\n"), + Prog, sgr_dbname ()); +- fail_exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE, process_selinux); + } + + if (was_admin && lflg) { +@@ -960,7 +968,7 @@ update_gshadow(const struct sgrp *sgrp) + Prog, sgr_dbname (), nsgrp->sg_namp); + SYSLOG ((LOG_WARN, "failed to prepare the new %s entry '%s'", + sgr_dbname (), nsgrp->sg_namp)); +- fail_exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE, process_selinux); + } + + free_nsgrp: +@@ -975,12 +983,12 @@ free_nsgrp: + * grp_update() takes the secondary group set given in user_groups and + * adds the user to each group given by that set. + */ +-static void grp_update (void) ++static void grp_update (bool process_selinux) + { +- update_group_file(); ++ update_group_file(process_selinux); + #ifdef SHADOWGRP + if (is_shadow_grp) { +- update_gshadow_file(); ++ update_gshadow_file(process_selinux); + } + #endif + } +@@ -993,7 +1001,7 @@ static void grp_update (void) + * are checked for sanity. + */ + static void +-process_flags(int argc, char **argv) ++process_flags(int argc, char **argv, struct option_flags *flags) + { + struct stat st; + bool anyflag = false; +@@ -1158,8 +1166,10 @@ process_flags(int argc, char **argv) + rflg = true; + break; + case 'R': /* no-op, handled in process_root_flag () */ ++ flags->chroot = true; + break; + case 'P': /* no-op, handled in process_prefix_flag () */ ++ flags->prefix = true; + break; + case 's': + if ( ( !VALID (optarg) ) +@@ -1467,51 +1477,55 @@ process_flags(int argc, char **argv) + * close_files() closes all of the files that were opened for this new + * user. This causes any modified entries to be written out. + */ +-static void close_files (void) ++static void close_files (struct option_flags *flags) + { +- if (pw_close (true) == 0) { ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot && !flags->prefix; ++ ++ if (pw_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); +- fail_exit (E_PW_UPDATE); ++ fail_exit (E_PW_UPDATE, process_selinux); + } +- if (is_shadow_pwd && (spw_close (true) == 0)) { ++ if (is_shadow_pwd && (spw_close (process_selinux) == 0)) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, + "failure while writing changes to %s", + spw_dbname ())); +- fail_exit (E_PW_UPDATE); ++ fail_exit (E_PW_UPDATE, process_selinux); + } + + if (Gflg || lflg) { +- if (gr_close (true) == 0) { ++ if (gr_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, + "failure while writing changes to %s", + gr_dbname ())); +- fail_exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE, process_selinux); + } + #ifdef SHADOWGRP + if (is_shadow_grp) { +- if (sgr_close (true) == 0) { ++ if (sgr_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, + "failure while writing changes to %s", + sgr_dbname ())); +- fail_exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE, process_selinux); + } + } + #endif + #ifdef SHADOWGRP + if (is_shadow_grp) { +- if (sgr_unlock (true) == 0) { ++ if (sgr_unlock (process_selinux) == 0) { + fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, sgr_dbname ()); +@@ -1522,7 +1536,7 @@ static void close_files (void) + } + } + #endif +- if (gr_unlock (true) == 0) { ++ if (gr_unlock (process_selinux) == 0) { + fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, gr_dbname ()); +@@ -1534,7 +1548,7 @@ static void close_files (void) + } + + if (is_shadow_pwd) { +- if (spw_unlock (true) == 0) { ++ if (spw_unlock (process_selinux) == 0) { + fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, spw_dbname ()); +@@ -1544,7 +1558,7 @@ static void close_files (void) + /* continue */ + } + } +- if (pw_unlock (true) == 0) { ++ if (pw_unlock (process_selinux) == 0) { + fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, pw_dbname ()); +@@ -1561,12 +1575,12 @@ static void close_files (void) + + #ifdef ENABLE_SUBIDS + if (vflg || Vflg) { +- if (sub_uid_close (true) == 0) { ++ if (sub_uid_close (process_selinux) == 0) { + fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sub_uid_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_uid_dbname ())); +- fail_exit (E_SUB_UID_UPDATE); ++ fail_exit (E_SUB_UID_UPDATE, process_selinux); + } +- if (sub_uid_unlock (true) == 0) { ++ if (sub_uid_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); + /* continue */ +@@ -1574,12 +1588,12 @@ static void close_files (void) + sub_uid_locked = false; + } + if (wflg || Wflg) { +- if (sub_gid_close (true) == 0) { ++ if (sub_gid_close (process_selinux) == 0) { + fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sub_gid_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_gid_dbname ())); +- fail_exit (E_SUB_GID_UPDATE); ++ fail_exit (E_SUB_GID_UPDATE, process_selinux); + } +- if (sub_gid_unlock (true) == 0) { ++ if (sub_gid_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); + /* continue */ +@@ -1604,33 +1618,33 @@ static void close_files (void) + * + * open_files() opens the two password files. + */ +-static void open_files (void) ++static void open_files (bool process_selinux) + { + if (pw_lock () == 0) { + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, pw_dbname ()); +- fail_exit (E_PW_UPDATE); ++ fail_exit (E_PW_UPDATE, process_selinux); + } + pw_locked = true; + if (pw_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, + _("%s: cannot open %s\n"), + Prog, pw_dbname ()); +- fail_exit (E_PW_UPDATE); ++ fail_exit (E_PW_UPDATE, process_selinux); + } + if (is_shadow_pwd && (spw_lock () == 0)) { + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, spw_dbname ()); +- fail_exit (E_PW_UPDATE); ++ fail_exit (E_PW_UPDATE, process_selinux); + } + spw_locked = true; + if (is_shadow_pwd && (spw_open (O_CREAT | O_RDWR) == 0)) { + fprintf (stderr, + _("%s: cannot open %s\n"), + Prog, spw_dbname ()); +- fail_exit (E_PW_UPDATE); ++ fail_exit (E_PW_UPDATE, process_selinux); + } + + if (Gflg || lflg) { +@@ -1642,28 +1656,28 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, gr_dbname ()); +- fail_exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE, process_selinux); + } + gr_locked = true; + if (gr_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, + _("%s: cannot open %s\n"), + Prog, gr_dbname ()); +- fail_exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE, process_selinux); + } + #ifdef SHADOWGRP + if (is_shadow_grp && (sgr_lock () == 0)) { + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, sgr_dbname ()); +- fail_exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE, process_selinux); + } + sgr_locked = true; + if (is_shadow_grp && (sgr_open (O_CREAT | O_RDWR) == 0)) { + fprintf (stderr, + _("%s: cannot open %s\n"), + Prog, sgr_dbname ()); +- fail_exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE, process_selinux); + } + #endif + } +@@ -1673,14 +1687,14 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, sub_uid_dbname ()); +- fail_exit (E_SUB_UID_UPDATE); ++ fail_exit (E_SUB_UID_UPDATE, process_selinux); + } + sub_uid_locked = true; + if (sub_uid_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, + _("%s: cannot open %s\n"), + Prog, sub_uid_dbname ()); +- fail_exit (E_SUB_UID_UPDATE); ++ fail_exit (E_SUB_UID_UPDATE, process_selinux); + } + } + if (wflg || Wflg) { +@@ -1688,14 +1702,14 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, sub_gid_dbname ()); +- fail_exit (E_SUB_GID_UPDATE); ++ fail_exit (E_SUB_GID_UPDATE, process_selinux); + } + sub_gid_locked = true; + if (sub_gid_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, + _("%s: cannot open %s\n"), + Prog, sub_gid_dbname ()); +- fail_exit (E_SUB_GID_UPDATE); ++ fail_exit (E_SUB_GID_UPDATE, process_selinux); + } + } + #endif /* ENABLE_SUBIDS */ +@@ -1707,13 +1721,15 @@ static void open_files (void) + * usr_update() creates the password file entries for this user and + * will update the group entries if required. + */ +-static void usr_update (void) ++static void usr_update (struct option_flags *flags) + { + struct passwd pwent; + const struct passwd *pwd; +- + struct spwd spent; + const struct spwd *spwd = NULL; ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot && !flags->prefix; + + /* + * Locate the entry in /etc/passwd, which MUST exist. +@@ -1723,10 +1739,10 @@ static void usr_update (void) + fprintf (stderr, + _("%s: user '%s' does not exist in %s\n"), + Prog, user_name, pw_dbname ()); +- fail_exit (E_NOTFOUND); ++ fail_exit (E_NOTFOUND, process_selinux); + } + pwent = *pwd; +- new_pwent (&pwent); ++ new_pwent (&pwent, process_selinux); + + + /* If the shadow file does not exist, it won't be created */ +@@ -1735,7 +1751,7 @@ static void usr_update (void) + if (NULL != spwd) { + /* Update the shadow entry if it exists */ + spent = *spwd; +- new_spent (&spent); ++ new_spent (&spent, process_selinux); + } else if ( ( pflg + && streq(pwent.pw_passwd, SHADOW_PASSWD_STRING)) + || eflg || fflg) { +@@ -1766,7 +1782,7 @@ static void usr_update (void) + spent.sp_inact = -1; + spent.sp_expire = -1; + spent.sp_flag = SHADOW_SP_FLAG_UNSET; +- new_spent (&spent); ++ new_spent (&spent, process_selinux); + spwd = &spent; /* entry needs to be committed */ + } + } +@@ -1777,13 +1793,13 @@ static void usr_update (void) + fprintf (stderr, + _("%s: failed to prepare the new %s entry '%s'\n"), + Prog, pw_dbname (), pwent.pw_name); +- fail_exit (E_PW_UPDATE); ++ fail_exit (E_PW_UPDATE, process_selinux); + } + if (lflg && (pw_remove (user_name) == 0)) { + fprintf (stderr, + _("%s: cannot remove entry '%s' from %s\n"), + Prog, user_name, pw_dbname ()); +- fail_exit (E_PW_UPDATE); ++ fail_exit (E_PW_UPDATE, process_selinux); + } + } + if ((NULL != spwd) && (lflg || eflg || fflg || pflg || Lflg || Uflg)) { +@@ -1791,13 +1807,13 @@ static void usr_update (void) + fprintf (stderr, + _("%s: failed to prepare the new %s entry '%s'\n"), + Prog, spw_dbname (), spent.sp_namp); +- fail_exit (E_PW_UPDATE); ++ fail_exit (E_PW_UPDATE, process_selinux); + } + if (lflg && (spw_remove (user_name) == 0)) { + fprintf (stderr, + _("%s: cannot remove entry '%s' from %s\n"), + Prog, user_name, spw_dbname ()); +- fail_exit (E_PW_UPDATE); ++ fail_exit (E_PW_UPDATE, process_selinux); + } + } + } +@@ -1808,7 +1824,7 @@ static void usr_update (void) + * move_home() moves the user's home directory to a new location. The + * files will be copied if the directory cannot simply be renamed. + */ +-static void move_home (void) ++static void move_home (bool process_selinux) + { + struct stat sb; + +@@ -1820,7 +1836,7 @@ static void move_home (void) + fprintf (stderr, + _("%s: directory %s exists\n"), + Prog, user_newhome); +- fail_exit (E_HOMEDIR); ++ fail_exit (E_HOMEDIR, process_selinux); + } + + if (stat (prefix_user_home, &sb) == 0) { +@@ -1834,7 +1850,7 @@ static void move_home (void) + "not a directory. It is not removed and no " + "home directories are created.\n"), + Prog, user_home); +- fail_exit (E_HOMEDIR); ++ fail_exit (E_HOMEDIR, process_selinux); + } + + #ifdef WITH_AUDIT +@@ -1855,7 +1871,7 @@ static void move_home (void) + fprintf (stderr, + _("%s: Failed to change ownership of the home directory"), + Prog); +- fail_exit (E_HOMEDIR); ++ fail_exit (E_HOMEDIR, process_selinux); + } + #ifdef WITH_AUDIT + audit_logger (AUDIT_USER_MGMT, Prog, +@@ -1870,7 +1886,7 @@ static void move_home (void) + fprintf (stderr, + _("%s: error: cannot move subvolume from %s to %s - different device\n"), + Prog, prefix_user_home, prefix_user_newhome); +- fail_exit (E_HOMEDIR); ++ fail_exit (E_HOMEDIR, process_selinux); + } + #endif + +@@ -1901,7 +1917,7 @@ static void move_home (void) + fprintf (stderr, + _("%s: cannot rename directory %s to %s\n"), + Prog, prefix_user_home, prefix_user_newhome); +- fail_exit (E_HOMEDIR); ++ fail_exit (E_HOMEDIR, process_selinux); + } + } else { + fprintf (stderr, +@@ -2160,6 +2176,8 @@ int main (int argc, char **argv) + int retval; + #endif /* USE_PAM */ + #endif /* ACCT_TOOLS_SETUID */ ++ struct option_flags flags; ++ bool process_selinux; + + log_set_progname(Prog); + log_set_logfd(stderr); +@@ -2189,7 +2207,8 @@ int main (int argc, char **argv) + is_sub_gid = sub_gid_file_present (); + #endif /* ENABLE_SUBIDS */ + +- process_flags (argc, argv); ++ process_flags (argc, argv, &flags); ++ process_selinux = !flags.chroot && !flags.prefix; + + /* + * The home directory, the username and the user's UID should not +@@ -2251,13 +2270,13 @@ int main (int argc, char **argv) + * Do the hard stuff - open the files, change the user entries, + * change the home directory, then close and update the files. + */ +- open_files (); ++ open_files (process_selinux); + if ( cflg || dflg || eflg || fflg || gflg || Lflg || lflg || pflg + || sflg || uflg || Uflg) { +- usr_update (); ++ usr_update (&flags); + } + if (Gflg || lflg) { +- grp_update (); ++ grp_update (process_selinux); + } + #ifdef ENABLE_SUBIDS + if (Vflg) { +@@ -2273,7 +2292,7 @@ int main (int argc, char **argv) + (uintmax_t) ptr->range.first, + (uintmax_t) ptr->range.last, + sub_uid_dbname()); +- fail_exit (E_SUB_UID_UPDATE); ++ fail_exit (E_SUB_UID_UPDATE, process_selinux); + } + } + } +@@ -2290,7 +2309,7 @@ int main (int argc, char **argv) + (uintmax_t) ptr->range.first, + (uintmax_t) ptr->range.last, + sub_uid_dbname()); +- fail_exit (E_SUB_UID_UPDATE); ++ fail_exit (E_SUB_UID_UPDATE, process_selinux); + } + } + } +@@ -2307,7 +2326,7 @@ int main (int argc, char **argv) + (uintmax_t) ptr->range.first, + (uintmax_t) ptr->range.last, + sub_gid_dbname()); +- fail_exit (E_SUB_GID_UPDATE); ++ fail_exit (E_SUB_GID_UPDATE, process_selinux); + } + } + } +@@ -2324,12 +2343,12 @@ int main (int argc, char **argv) + (uintmax_t) ptr->range.first, + (uintmax_t) ptr->range.last, + sub_gid_dbname()); +- fail_exit (E_SUB_GID_UPDATE); ++ fail_exit (E_SUB_GID_UPDATE, process_selinux); + } + } + } + #endif /* ENABLE_SUBIDS */ +- close_files (); ++ close_files (&flags); + + #ifdef WITH_TCB + if ( (lflg || uflg) +@@ -2355,7 +2374,7 @@ int main (int argc, char **argv) + user_name, user_id, + SHADOW_AUDIT_FAILURE); + #endif /* WITH_AUDIT */ +- fail_exit (E_SE_UPDATE); ++ fail_exit (E_SE_UPDATE, process_selinux); + } + } else { + if (del_seuser (user_name) != 0) { +@@ -2368,14 +2387,14 @@ int main (int argc, char **argv) + user_name, user_id, + SHADOW_AUDIT_FAILURE); + #endif /* WITH_AUDIT */ +- fail_exit (E_SE_UPDATE); ++ fail_exit (E_SE_UPDATE, process_selinux); + } + } + } + #endif /* WITH_SELINUX */ + + if (mflg) { +- move_home (); ++ move_home (process_selinux); + } + + #ifndef NO_MOVE_MAILBOX +@@ -2420,7 +2439,7 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: Failed to change ownership of the home directory"), + Prog); +- fail_exit (E_HOMEDIR); ++ fail_exit (E_HOMEDIR, process_selinux); + } + } + } + +diff -up shadow-4.18.0/lib/cleanup_group.c.test-chroot3 shadow-4.18.0/lib/cleanup_group.c +--- shadow-4.18.0/lib/cleanup_group.c.test-chroot3 2025-07-04 11:15:02.302179208 +0200 ++++ shadow-4.18.0/lib/cleanup_group.c 2025-07-04 11:15:02.311510389 +0200 +@@ -179,9 +179,11 @@ void cleanup_report_del_group_gshadow (v + * + * It should be registered after the group file is successfully locked. + */ +-void cleanup_unlock_group (MAYBE_UNUSED void *arg) ++void cleanup_unlock_group (void *process_selinux) + { +- if (gr_unlock (true) == 0) { ++ bool process = *((bool *) process_selinux); ++ ++ if (gr_unlock (process) == 0) { + fprintf (log_get_logfd(), + _("%s: failed to unlock %s\n"), + log_get_progname(), gr_dbname ()); +@@ -199,9 +201,11 @@ void cleanup_unlock_group (MAYBE_UNUSED + * + * It should be registered after the gshadow file is successfully locked. + */ +-void cleanup_unlock_gshadow (MAYBE_UNUSED void *arg) ++void cleanup_unlock_gshadow (void *process_selinux) + { +- if (sgr_unlock (true) == 0) { ++ bool process = *((bool *) process_selinux); ++ ++ if (sgr_unlock (process) == 0) { + fprintf (log_get_logfd(), + _("%s: failed to unlock %s\n"), + log_get_progname(), sgr_dbname ()); +diff -up shadow-4.18.0/lib/cleanup_user.c.test-chroot3 shadow-4.18.0/lib/cleanup_user.c +--- shadow-4.18.0/lib/cleanup_user.c.test-chroot3 2025-07-04 11:15:02.297132547 +0200 ++++ shadow-4.18.0/lib/cleanup_user.c 2025-07-04 11:15:02.311622726 +0200 +@@ -96,9 +96,11 @@ void cleanup_report_add_user_shadow (voi + * + * It should be registered after the passwd database is successfully locked. + */ +-void cleanup_unlock_passwd (MAYBE_UNUSED void *arg) ++void cleanup_unlock_passwd (void *process_selinux) + { +- if (pw_unlock (true) == 0) { ++ bool process = *((bool *) process_selinux); ++ ++ if (pw_unlock (process) == 0) { + fprintf (log_get_logfd(), + _("%s: failed to unlock %s\n"), + log_get_progname(), pw_dbname ()); +@@ -115,9 +117,11 @@ void cleanup_unlock_passwd (MAYBE_UNUSED + * + * It should be registered after the shadow database is successfully locked. + */ +-void cleanup_unlock_shadow (MAYBE_UNUSED void *arg) ++void cleanup_unlock_shadow (void *process_selinux) + { +- if (spw_unlock (true) == 0) { ++ bool process = *((bool *) process_selinux); ++ ++ if (spw_unlock (process) == 0) { + fprintf (log_get_logfd(), + _("%s: failed to unlock %s\n"), + log_get_progname(), spw_dbname ()); +diff -up shadow-4.18.0/lib/prototypes.h.test-chroot3 shadow-4.18.0/lib/prototypes.h +--- shadow-4.18.0/lib/prototypes.h.test-chroot3 2025-06-24 22:28:01.058453223 +0200 ++++ shadow-4.18.0/lib/prototypes.h 2025-07-04 11:15:02.311703893 +0200 +@@ -92,11 +92,11 @@ void cleanup_report_del_group_gshadow (v + void cleanup_report_mod_passwd (void *cleanup_info); + void cleanup_report_mod_group (void *cleanup_info); + void cleanup_report_mod_gshadow (void *cleanup_info); +-void cleanup_unlock_group (/*@null@*/void *MAYBE_UNUSED); ++void cleanup_unlock_group (void *process_selinux); + #ifdef SHADOWGRP +-void cleanup_unlock_gshadow (/*@null@*/void *MAYBE_UNUSED); ++void cleanup_unlock_gshadow (void *process_selinux); + #endif +-void cleanup_unlock_passwd (/*@null@*/void *MAYBE_UNUSED); ++void cleanup_unlock_passwd (void *process_selinux); + + /* console.c */ + extern bool console (const char *); +diff -up shadow-4.18.0/src/chgpasswd.c.test-chroot3 shadow-4.18.0/src/chgpasswd.c +--- shadow-4.18.0/src/chgpasswd.c.test-chroot3 2025-07-04 11:15:02.302260729 +0200 ++++ shadow-4.18.0/src/chgpasswd.c 2025-07-04 11:15:02.312527205 +0200 +@@ -38,6 +38,12 @@ + #include "string/strcmp/streq.h" + #include "string/strtok/stpsep.h" + ++/* ++ * Structures ++ */ ++struct option_flags { ++ bool chroot; ++}; + + /* + * Global variables +@@ -68,21 +74,21 @@ static bool sgr_locked = false; + static bool gr_locked = false; + + /* local function prototypes */ +-NORETURN static void fail_exit (int code); ++NORETURN static void fail_exit (int code, bool process_selinux); + NORETURN static void usage (int status); +-static void process_flags (int argc, char **argv); ++static void process_flags (int argc, char **argv, struct option_flags *flags); + static void check_flags (void); + static void check_perms (void); +-static void open_files (void); +-static void close_files (void); ++static void open_files (bool process_selinux); ++static void close_files (struct option_flags *flags); + + /* + * fail_exit - exit with a failure code after unlocking the files + */ +-static void fail_exit (int code) ++static void fail_exit (int code, bool process_selinux) + { + if (gr_locked) { +- if (gr_unlock (true) == 0) { ++ if (gr_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + /* continue */ +@@ -91,7 +97,7 @@ static void fail_exit (int code) + + #ifdef SHADOWGRP + if (sgr_locked) { +- if (sgr_unlock (true) == 0) { ++ if (sgr_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + /* continue */ +@@ -149,7 +155,7 @@ usage (int status) + * + * It will not return if an error is encountered. + */ +-static void process_flags (int argc, char **argv) ++static void process_flags (int argc, char **argv, struct option_flags *flags) + { + int c; + #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) +@@ -187,6 +193,7 @@ static void process_flags (int argc, cha + md5flg = true; + break; + case 'R': /* no-op, handled in process_root_flag () */ ++ flags->chroot = true; + break; + #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) + case 's': +@@ -336,7 +343,7 @@ static void check_perms (void) + /* + * open_files - lock and open the group databases + */ +-static void open_files (void) ++static void open_files (bool process_selinux) + { + /* + * Lock the group file and open it for reading and writing. This will +@@ -346,13 +353,13 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, gr_dbname ()); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + gr_locked = true; + if (gr_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, + _("%s: cannot open %s\n"), Prog, gr_dbname ()); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + + #ifdef SHADOWGRP +@@ -362,13 +369,13 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, sgr_dbname ()); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + sgr_locked = true; + if (sgr_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, _("%s: cannot open %s\n"), + Prog, sgr_dbname ()); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + } + #endif +@@ -377,18 +384,21 @@ static void open_files (void) + /* + * close_files - close and unlock the group databases + */ +-static void close_files (void) ++static void close_files (struct option_flags *flags) + { ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot; + #ifdef SHADOWGRP + if (is_shadow_grp) { +- if (sgr_close (true) == 0) { ++ if (sgr_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ())); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } +- if (sgr_unlock (true) == 0) { ++ if (sgr_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + /* continue */ +@@ -397,14 +407,14 @@ static void close_files (void) + } + #endif + +- if (gr_close (true) == 0) { ++ if (gr_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ())); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } +- if (gr_unlock (true) == 0) { ++ if (gr_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + /* continue */ +@@ -428,6 +438,8 @@ int main (int argc, char **argv) + struct group newgr; + bool errors = false; + intmax_t line = 0; ++ struct option_flags flags; ++ bool process_selinux; + + log_set_progname(Prog); + log_set_logfd(stderr); +@@ -444,7 +456,8 @@ int main (int argc, char **argv) + + process_root_flag ("-R", argc, argv); + +- process_flags (argc, argv); ++ process_flags (argc, argv, &flags); ++ process_selinux = !flags.chroot; + + OPENLOG (Prog); + +@@ -454,7 +467,7 @@ int main (int argc, char **argv) + is_shadow_grp = sgr_file_present (); + #endif + +- open_files (); ++ open_files (process_selinux); + + /* + * Read each line, separating the group name from the password. The +@@ -523,7 +536,7 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: failed to crypt password with salt '%s': %s\n"), + Prog, salt, strerror (errno)); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + } + +@@ -624,10 +637,10 @@ int main (int argc, char **argv) + if (errors) { + fprintf (stderr, + _("%s: error detected, changes ignored\n"), Prog); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + +- close_files (); ++ close_files (&flags); + + nscd_flush_cache ("group"); + sssd_flush_cache (SSSD_DB_GROUP); +diff -up shadow-4.18.0/src/groupadd.c.test-chroot3 shadow-4.18.0/src/groupadd.c +--- shadow-4.18.0/src/groupadd.c.test-chroot3 2025-07-04 11:15:02.284218582 +0200 ++++ shadow-4.18.0/src/groupadd.c 2025-07-04 11:15:02.311806157 +0200 +@@ -54,6 +54,14 @@ + #define E_GRP_UPDATE 10 /* can't update group file */ + + /* ++ * Structures ++ */ ++struct option_flags { ++ bool chroot; ++ bool prefix; ++}; ++ ++/* + * Global variables + */ + static const char Prog[] = "groupadd"; +@@ -85,9 +93,9 @@ static void new_sgent (struct sgrp *sgen + #endif + static void grp_update (void); + static void check_new_name (void); +-static void close_files (void); +-static void open_files (void); +-static void process_flags (int argc, char **argv); ++static void close_files (struct option_flags *flags); ++static void open_files (struct option_flags *flags); ++static void process_flags (int argc, char **argv, struct option_flags *flags); + static void check_flags (void); + static void check_perms (void); + +@@ -271,10 +279,14 @@ check_new_name(void) + * close_files() closes all of the files that were opened for this new + * group. This causes any modified entries to be written out. + */ +-static void close_files (void) ++static void close_files (struct option_flags *flags) + { ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot && !flags->prefix; ++ + /* First, write the changes in the regular group database */ +- if (gr_close (true) == 0) { ++ if (gr_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, gr_dbname ()); +@@ -289,13 +301,13 @@ static void close_files (void) + gr_dbname (), group_name, (unsigned int) group_id)); + del_cleanup (cleanup_report_add_group_group); + +- cleanup_unlock_group (NULL); ++ cleanup_unlock_group (&process_selinux); + del_cleanup (cleanup_unlock_group); + + /* Now, write the changes in the shadow database */ + #ifdef SHADOWGRP + if (is_shadow_grp) { +- if (sgr_close (true) == 0) { ++ if (sgr_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, sgr_dbname ()); +@@ -310,7 +322,7 @@ static void close_files (void) + sgr_dbname (), group_name)); + del_cleanup (cleanup_report_add_group_gshadow); + +- cleanup_unlock_gshadow (NULL); ++ cleanup_unlock_gshadow (&process_selinux); + del_cleanup (cleanup_unlock_gshadow); + } + #endif /* SHADOWGRP */ +@@ -326,8 +338,12 @@ static void close_files (void) + * + * open_files() opens the two group files. + */ +-static void open_files (void) ++static void open_files (struct option_flags *flags) + { ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot && !flags->prefix; ++ + /* First, lock the databases */ + if (gr_lock () == 0) { + fprintf (stderr, +@@ -335,7 +351,7 @@ static void open_files (void) + Prog, gr_dbname ()); + fail_exit (E_GRP_UPDATE); + } +- add_cleanup (cleanup_unlock_group, NULL); ++ add_cleanup (cleanup_unlock_group, &process_selinux); + + #ifdef SHADOWGRP + if (is_shadow_grp) { +@@ -345,7 +361,7 @@ static void open_files (void) + Prog, sgr_dbname ()); + fail_exit (E_GRP_UPDATE); + } +- add_cleanup (cleanup_unlock_gshadow, NULL); ++ add_cleanup (cleanup_unlock_gshadow, &process_selinux); + } + #endif /* SHADOWGRP */ + +@@ -380,7 +396,7 @@ static void open_files (void) + * + * It will not return if an error is encountered. + */ +-static void process_flags (int argc, char **argv) ++static void process_flags (int argc, char **argv, struct option_flags *flags) + { + /* + * Parse the command line options. +@@ -455,8 +471,10 @@ static void process_flags (int argc, cha + rflg = true; + break; + case 'R': /* no-op, handled in process_root_flag () */ ++ flags->chroot = true; + break; + case 'P': /* no-op, handled in process_prefix_flag () */ ++ flags->prefix = true; + break; + case 'U': + user_list = optarg; +@@ -583,6 +601,8 @@ static void check_perms (void) + */ + int main (int argc, char **argv) + { ++ struct option_flags flags; ++ + log_set_progname(Prog); + log_set_logfd(stderr); + +@@ -608,7 +628,7 @@ int main (int argc, char **argv) + /* + * Parse the command line options. + */ +- process_flags (argc, argv); ++ process_flags (argc, argv, &flags); + + check_perms (); + +@@ -625,7 +645,7 @@ int main (int argc, char **argv) + * Do the hard stuff - open the files, create the group entries, + * then close and update the files. + */ +- open_files (); ++ open_files (&flags); + + if (!gflg) { + if (find_new_gid (rflg, &group_id, NULL) < 0) { +@@ -634,7 +654,7 @@ int main (int argc, char **argv) + } + + grp_update (); +- close_files (); ++ close_files (&flags); + if (run_parts ("/etc/shadow-maint/groupadd-post.d", group_name, + Prog)) { + exit(1); +diff -up shadow-4.18.0/src/groupdel.c.test-chroot3 shadow-4.18.0/src/groupdel.c +--- shadow-4.18.0/src/groupdel.c.test-chroot3 2025-07-04 11:15:02.284261326 +0200 ++++ shadow-4.18.0/src/groupdel.c 2025-07-04 11:15:02.312079796 +0200 +@@ -33,6 +33,12 @@ + #endif + #include "shadowlog.h" + #include "run_part.h" ++ ++struct option_flags { ++ bool chroot; ++ bool prefix; ++}; ++ + /* + * Global variables + */ +@@ -61,10 +67,10 @@ static bool is_shadow_grp; + /* local function prototypes */ + NORETURN static void usage (int status); + static void grp_update (void); +-static void close_files (void); +-static void open_files (void); ++static void close_files (struct option_flags *flags); ++static void open_files (struct option_flags *flags); + static void group_busy (gid_t gid); +-static void process_flags (int argc, char **argv); ++static void process_flags (int argc, char **argv, struct option_flags *flags); + + /* + * usage - display usage message and exit +@@ -146,10 +152,14 @@ static void grp_update (void) + * close_files() closes all of the files that were opened for this + * new group. This causes any modified entries to be written out. + */ +-static void close_files (void) ++static void close_files (struct option_flags *flags) + { ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot && !flags->prefix; ++ + /* First, write the changes in the regular group database */ +- if (gr_close (true) == 0) { ++ if (gr_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, gr_dbname ()); +@@ -166,14 +176,14 @@ static void close_files (void) + group_name, gr_dbname ())); + del_cleanup (cleanup_report_del_group_group); + +- cleanup_unlock_group (NULL); ++ cleanup_unlock_group (&process_selinux); + del_cleanup (cleanup_unlock_group); + + + /* Then, write the changes in the shadow database */ + #ifdef SHADOWGRP + if (is_shadow_grp) { +- if (sgr_close (true) == 0) { ++ if (sgr_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, sgr_dbname ()); +@@ -190,7 +200,7 @@ static void close_files (void) + group_name, sgr_dbname ())); + del_cleanup (cleanup_report_del_group_gshadow); + +- cleanup_unlock_gshadow (NULL); ++ cleanup_unlock_gshadow (&process_selinux); + del_cleanup (cleanup_unlock_gshadow); + } + #endif /* SHADOWGRP */ +@@ -204,8 +214,12 @@ static void close_files (void) + * + * open_files() opens the two group files. + */ +-static void open_files (void) ++static void open_files (struct option_flags *flags) + { ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot && !flags->prefix; ++ + /* First, lock the databases */ + if (gr_lock () == 0) { + fprintf (stderr, +@@ -213,7 +227,7 @@ static void open_files (void) + Prog, gr_dbname ()); + fail_exit (E_GRP_UPDATE); + } +- add_cleanup (cleanup_unlock_group, NULL); ++ add_cleanup (cleanup_unlock_group, &process_selinux); + #ifdef SHADOWGRP + if (is_shadow_grp) { + if (sgr_lock () == 0) { +@@ -222,7 +236,7 @@ static void open_files (void) + Prog, sgr_dbname ()); + fail_exit (E_GRP_UPDATE); + } +- add_cleanup (cleanup_unlock_gshadow, NULL); ++ add_cleanup (cleanup_unlock_gshadow, &process_selinux); + } + #endif + +@@ -296,7 +310,7 @@ static void group_busy (gid_t gid) + * + * It will not return if an error is encountered. + */ +-static void process_flags (int argc, char **argv) ++static void process_flags (int argc, char **argv, struct option_flags *flags) + { + /* + * Parse the command line options. +@@ -317,8 +331,10 @@ static void process_flags (int argc, cha + usage (E_SUCCESS); + /*@notreached@*/break; + case 'R': /* no-op, handled in process_root_flag () */ ++ flags->chroot = true; + break; + case 'P': /* no-op, handled in process_prefix_flag () */ ++ flags->prefix = true; + break; + case 'f': + check_group_busy = false; +@@ -352,6 +368,7 @@ int main (int argc, char **argv) + int retval; + #endif /* USE_PAM */ + #endif /* ACCT_TOOLS_SETUID */ ++ struct option_flags flags; + + log_set_progname(Prog); + log_set_logfd(stderr); +@@ -375,7 +392,7 @@ int main (int argc, char **argv) + fail_exit (1); + } + +- process_flags (argc, argv); ++ process_flags (argc, argv, &flags); + + #ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM +@@ -449,11 +466,11 @@ int main (int argc, char **argv) + * Do the hard stuff - open the files, delete the group entries, + * then close and update the files. + */ +- open_files (); ++ open_files (&flags); + + grp_update (); + +- close_files (); ++ close_files (&flags); + + if (run_parts ("/etc/shadow-maint/groupdel-post.d", group_name, + Prog)) { +diff -up shadow-4.18.0/src/groupmems.c.test-chroot3 shadow-4.18.0/src/groupmems.c +--- shadow-4.18.0/src/groupmems.c.test-chroot3 2025-07-04 11:15:02.302301588 +0200 ++++ shadow-4.18.0/src/groupmems.c 2025-07-04 11:15:57.404278255 +0200 +@@ -47,6 +47,13 @@ + #define EXIT_INVALID_GROUP 9 /* specified group does not exist */ + + /* ++ * Structures ++ */ ++struct option_flags { ++ bool chroot; ++}; ++ ++/* + * Global variables + */ + static const char Prog[] = "groupmems"; +@@ -68,15 +75,17 @@ static bool sgr_locked = false; + /* local function prototypes */ + static char *whoami (void); + static void add_user (const char *user, +- const struct group *grp); ++ const struct group *grp, ++ bool process_selinux); + static void remove_user (const char *user, +- const struct group *grp); +-static void purge_members (const struct group *grp); ++ const struct group *grp, ++ bool process_selinux); ++static void purge_members (const struct group *grp, bool process_selinux); + static void display_members (const char *const *members); + NORETURN static void usage (int status); +-static void process_flags (int argc, char **argv); +-static void check_perms (void); +-NORETURN static void fail_exit (int code); ++static void process_flags (int argc, char **argv, struct option_flags *flags); ++static void check_perms (bool process_selinux); ++NORETURN static void fail_exit (int code, bool process_selinux); + #define isroot() (getuid () == 0) + + static char *whoami (void) +@@ -99,7 +108,8 @@ static char *whoami (void) + * add_user - Add a user to the specified group + */ + static void add_user (const char *user, +- const struct group *grp) ++ const struct group *grp, ++ bool process_selinux) + { + struct group *newgrp; + +@@ -108,7 +118,7 @@ static void add_user (const char *user, + fprintf (stderr, + _("%s: user '%s' is already a member of '%s'\n"), + Prog, user, grp->gr_name); +- fail_exit (EXIT_MEMBER_EXISTS); ++ fail_exit (EXIT_MEMBER_EXISTS, process_selinux); + } + + newgrp = __gr_dup(grp); +@@ -116,7 +126,7 @@ static void add_user (const char *user, + fprintf (stderr, + _("%s: Out of memory. Cannot update %s.\n"), + Prog, gr_dbname ()); +- fail_exit (13); ++ fail_exit (13, process_selinux); + } + + /* Add the user to the /etc/group group */ +@@ -146,7 +156,7 @@ static void add_user (const char *user, + fprintf (stderr, + _("%s: Out of memory. Cannot update %s.\n"), + Prog, sgr_dbname ()); +- fail_exit (13); ++ fail_exit (13, process_selinux); + } + /* Add the user to the members */ + newsg->sg_mem = add_list (newsg->sg_mem, user); +@@ -157,7 +167,7 @@ static void add_user (const char *user, + fprintf (stderr, + _("%s: failed to prepare the new %s entry '%s'\n"), + Prog, sgr_dbname (), newsg->sg_namp); +- fail_exit (13); ++ fail_exit (13, process_selinux); + } + } + #endif +@@ -166,7 +176,7 @@ static void add_user (const char *user, + fprintf (stderr, + _("%s: failed to prepare the new %s entry '%s'\n"), + Prog, gr_dbname (), newgrp->gr_name); +- fail_exit (13); ++ fail_exit (13, process_selinux); + } + } + +@@ -174,7 +184,8 @@ static void add_user (const char *user, + * remove_user - Remove a user from a given group + */ + static void remove_user (const char *user, +- const struct group *grp) ++ const struct group *grp, ++ bool process_selinux) + { + struct group *newgrp; + +@@ -183,7 +194,7 @@ static void remove_user (const char *use + fprintf (stderr, + _("%s: user '%s' is not a member of '%s'\n"), + Prog, user, grp->gr_name); +- fail_exit (EXIT_NOT_MEMBER); ++ fail_exit (EXIT_NOT_MEMBER, process_selinux); + } + + newgrp = __gr_dup (grp); +@@ -191,7 +202,7 @@ static void remove_user (const char *use + fprintf (stderr, + _("%s: Out of memory. Cannot update %s.\n"), + Prog, gr_dbname ()); +- fail_exit (13); ++ fail_exit (13, process_selinux); + } + + /* Remove the user from the /etc/group group */ +@@ -221,7 +232,7 @@ static void remove_user (const char *use + fprintf (stderr, + _("%s: Out of memory. Cannot update %s.\n"), + Prog, sgr_dbname ()); +- fail_exit (13); ++ fail_exit (13, process_selinux); + } + /* Remove the user from the members */ + newsg->sg_mem = del_list (newsg->sg_mem, user); +@@ -233,7 +244,7 @@ static void remove_user (const char *use + fprintf (stderr, + _("%s: failed to prepare the new %s entry '%s'\n"), + Prog, sgr_dbname (), newsg->sg_namp); +- fail_exit (13); ++ fail_exit (13, process_selinux); + } + } + #endif +@@ -242,14 +253,14 @@ static void remove_user (const char *use + fprintf (stderr, + _("%s: failed to prepare the new %s entry '%s'\n"), + Prog, gr_dbname (), newgrp->gr_name); +- fail_exit (13); ++ fail_exit (13, process_selinux); + } + } + + /* + * purge_members - Remove every members of the specified group + */ +-static void purge_members (const struct group *grp) ++static void purge_members (const struct group *grp, bool process_selinux) + { + struct group *newgrp = __gr_dup (grp); + +@@ -257,7 +268,7 @@ static void purge_members (const struct + fprintf (stderr, + _("%s: Out of memory. Cannot update %s.\n"), + Prog, gr_dbname ()); +- fail_exit (13); ++ fail_exit (13, process_selinux); + } + + /* Remove all the members of the /etc/group group */ +@@ -288,7 +299,7 @@ static void purge_members (const struct + fprintf (stderr, + _("%s: Out of memory. Cannot update %s.\n"), + Prog, sgr_dbname ()); +- fail_exit (13); ++ fail_exit (13, process_selinux); + } + /* Remove all the members of the /etc/gshadow + * group */ +@@ -302,7 +313,7 @@ static void purge_members (const struct + fprintf (stderr, + _("%s: failed to prepare the new %s entry '%s'\n"), + Prog, sgr_dbname (), newsg->sg_namp); +- fail_exit (13); ++ fail_exit (13, process_selinux); + } + } + #endif +@@ -311,7 +322,7 @@ static void purge_members (const struct + fprintf (stderr, + _("%s: failed to prepare the new %s entry '%s'\n"), + Prog, gr_dbname (), newgrp->gr_name); +- fail_exit (13); ++ fail_exit (13, process_selinux); + } + } + +@@ -356,7 +367,7 @@ usage (int status) + /* + * process_flags - perform command line argument setting + */ +-static void process_flags (int argc, char **argv) ++static void process_flags (int argc, char **argv, struct option_flags *flags) + { + int c; + static struct option long_options[] = { +@@ -396,6 +407,7 @@ static void process_flags (int argc, cha + ++exclusive; + break; + case 'R': /* no-op, handled in process_root_flag () */ ++ flags->chroot = true; + break; + default: + usage (EXIT_USAGE); +@@ -411,12 +423,12 @@ static void process_flags (int argc, cha + && (getpwnam (adduser) == NULL)) { + fprintf (stderr, _("%s: user '%s' does not exist\n"), + Prog, adduser); +- fail_exit (EXIT_INVALID_USER); ++ fail_exit (EXIT_INVALID_USER, !flags->chroot); + } + + } + +-static void check_perms (void) ++static void check_perms (bool process_selinux) + { + if (!list) { + #ifdef ACCT_TOOLS_SETUID +@@ -430,7 +442,7 @@ static void check_perms (void) + fprintf (stderr, + _("%s: Cannot determine your user name.\n"), + Prog); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + + retval = pam_start (Prog, pampw->pw_name, &conv, &pamh); +@@ -450,7 +462,7 @@ static void check_perms (void) + if (NULL != pamh) { + (void) pam_end (pamh, retval); + } +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + (void) pam_end (pamh, retval); + #endif /* USE_PAM */ +@@ -458,10 +470,10 @@ static void check_perms (void) + } + } + +-static void fail_exit (int code) ++static void fail_exit (int code, bool process_selinux) + { + if (gr_locked) { +- if (gr_unlock (true) == 0) { ++ if (gr_unlock (process_selinux) == 0) { + fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, gr_dbname ()); +@@ -472,7 +484,7 @@ static void fail_exit (int code) + + #ifdef SHADOWGRP + if (sgr_locked) { +- if (sgr_unlock (true) == 0) { ++ if (sgr_unlock (process_selinux) == 0) { + fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, sgr_dbname ()); +@@ -485,14 +497,14 @@ static void fail_exit (int code) + exit (code); + } + +-static void open_files (void) ++static void open_files (bool process_selinux) + { + if (!list) { + if (gr_lock () == 0) { + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, gr_dbname ()); +- fail_exit (EXIT_GROUP_FILE); ++ fail_exit (EXIT_GROUP_FILE, process_selinux); + } + gr_locked = true; + +@@ -502,7 +514,7 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, sgr_dbname ()); +- fail_exit (EXIT_GROUP_FILE); ++ fail_exit (EXIT_GROUP_FILE, process_selinux); + } + sgr_locked = true; + } +@@ -511,28 +523,32 @@ static void open_files (void) + + if (gr_open (list ? O_RDONLY : O_CREAT | O_RDWR) == 0) { + fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ()); +- fail_exit (EXIT_GROUP_FILE); ++ fail_exit (EXIT_GROUP_FILE, process_selinux); + } + + #ifdef SHADOWGRP + if (is_shadowgrp) { + if (sgr_open (list ? O_RDONLY : O_CREAT | O_RDWR) == 0) { + fprintf (stderr, _("%s: cannot open %s\n"), Prog, sgr_dbname ()); +- fail_exit (EXIT_GROUP_FILE); ++ fail_exit (EXIT_GROUP_FILE, process_selinux); + } + } + #endif + } + +-static void close_files (void) ++static void close_files (struct option_flags *flags) + { +- if ((gr_close (true) == 0) && !list) { ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot; ++ ++ if ((gr_close (process_selinux) == 0) && !list) { + fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ())); +- fail_exit (EXIT_GROUP_FILE); ++ fail_exit (EXIT_GROUP_FILE, process_selinux); + } + if (gr_locked) { +- if (gr_unlock (true) == 0) { ++ if (gr_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + /* continue */ +@@ -542,13 +558,13 @@ static void close_files (void) + + #ifdef SHADOWGRP + if (is_shadowgrp) { +- if ((sgr_close (true) == 0) && !list) { ++ if ((sgr_close (process_selinux) == 0) && !list) { + fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ())); +- fail_exit (EXIT_GROUP_FILE); ++ fail_exit (EXIT_GROUP_FILE, process_selinux); + } + if (sgr_locked) { +- if (sgr_unlock (true) == 0) { ++ if (sgr_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + /* continue */ +@@ -563,6 +579,8 @@ int main (int argc, char **argv) + { + char *name; + const struct group *grp; ++ struct option_flags flags; ++ bool process_selinux; + + log_set_progname(Prog); + log_set_logfd(stderr); +@@ -579,44 +597,45 @@ int main (int argc, char **argv) + is_shadowgrp = sgr_file_present (); + #endif + +- process_flags (argc, argv); ++ process_flags (argc, argv, &flags); ++ process_selinux = !flags.chroot; + + if (NULL == thisgroup) { + name = whoami (); + if (!list && (NULL == name)) { + fprintf (stderr, _("%s: your groupname does not match your username\n"), Prog); +- fail_exit (EXIT_NOT_PRIMARY); ++ fail_exit (EXIT_NOT_PRIMARY, process_selinux); + } + } else { + name = thisgroup; + if (!list && !isroot ()) { + fprintf (stderr, _("%s: only root can use the -g/--group option\n"), Prog); +- fail_exit (EXIT_NOT_ROOT); ++ fail_exit (EXIT_NOT_ROOT, process_selinux); + } + } + +- check_perms (); ++ check_perms (process_selinux); + +- open_files (); ++ open_files (process_selinux); + + grp = gr_locate (name); + if (NULL == grp) { + fprintf (stderr, _("%s: group '%s' does not exist in %s\n"), + Prog, name, gr_dbname ()); +- fail_exit (EXIT_INVALID_GROUP); ++ fail_exit (EXIT_INVALID_GROUP, process_selinux); + } + + if (list) { + display_members ((const char *const *)grp->gr_mem); + } else if (NULL != adduser) { +- add_user (adduser, grp); ++ add_user (adduser, grp, process_selinux); + } else if (NULL != deluser) { +- remove_user (deluser, grp); ++ remove_user (deluser, grp, process_selinux); + } else if (purge) { +- purge_members (grp); ++ purge_members (grp, process_selinux); + } + +- close_files (); ++ close_files (&flags); + + exit (EXIT_SUCCESS); + } +diff -up shadow-4.18.0/src/groupmod.c.test-chroot3 shadow-4.18.0/src/groupmod.c +--- shadow-4.18.0/src/groupmod.c.test-chroot3 2025-07-04 11:15:02.284354823 +0200 ++++ shadow-4.18.0/src/groupmod.c 2025-07-04 11:15:02.311945828 +0200 +@@ -61,6 +61,10 @@ + #define E_PAM_USERNAME 12 /* can't determine your username for use with pam */ + #define E_PAM_ERROR 13 /* pam returned an error, see Syslog facility id groupmod */ + ++struct option_flags { ++ bool chroot; ++ bool prefix; ++}; + + /* + * Global variables +@@ -102,11 +106,11 @@ static void new_sgent (struct sgrp *); + static void grp_update (void); + static void check_new_gid (void); + static void check_new_name (void); +-static void process_flags (int, char **); +-static void lock_files (void); ++static void process_flags (int, char **, struct option_flags *); ++static void lock_files (struct option_flags *flags); + static void prepare_failure_reports (void); + static void open_files (void); +-static void close_files (void); ++static void close_files (struct option_flags *flags); + static void update_primary_groups (gid_t ogid, gid_t ngid); + + +@@ -405,7 +409,7 @@ check_new_name(void) + * values that the user will be created with accordingly. The values + * are checked for sanity. + */ +-static void process_flags (int argc, char **argv) ++static void process_flags (int argc, char **argv, struct option_flags *flags) + { + int c; + static struct option long_options[] = { +@@ -451,8 +455,10 @@ static void process_flags (int argc, cha + pflg = true; + break; + case 'R': /* no-op, handled in process_root_flag () */ ++ flags->chroot = true; + break; + case 'P': /* no-op, handled in process_prefix_flag () */ ++ flags->prefix = true; + break; + case 'U': + user_list = optarg; +@@ -479,9 +485,13 @@ static void process_flags (int argc, cha + * close_files() closes all of the files that were opened for this new + * group. This causes any modified entries to be written out. + */ +-static void close_files (void) ++static void close_files (struct option_flags *flags) + { +- if (gr_close (true) == 0) { ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot && !flags->prefix; ++ ++ if (gr_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, gr_dbname ()); +@@ -498,13 +508,13 @@ static void close_files (void) + gr_dbname (), info_group.action)); + del_cleanup (cleanup_report_mod_group); + +- cleanup_unlock_group (NULL); ++ cleanup_unlock_group (&process_selinux); + del_cleanup (cleanup_unlock_group); + + #ifdef SHADOWGRP + if ( is_shadow_grp + && (pflg || nflg || user_list)) { +- if (sgr_close (true) == 0) { ++ if (sgr_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, sgr_dbname ()); +@@ -528,13 +538,13 @@ static void close_files (void) + sgr_dbname (), info_gshadow.action)); + del_cleanup (cleanup_report_mod_gshadow); + +- cleanup_unlock_gshadow (NULL); ++ cleanup_unlock_gshadow (&process_selinux); + del_cleanup (cleanup_unlock_gshadow); + } + #endif /* SHADOWGRP */ + + if (gflg) { +- if (pw_close (true) == 0) { ++ if (pw_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, pw_dbname ()); +@@ -551,7 +561,7 @@ static void close_files (void) + pw_dbname (), info_passwd.action)); + del_cleanup (cleanup_report_mod_passwd); + +- cleanup_unlock_passwd (NULL); ++ cleanup_unlock_passwd (&process_selinux); + del_cleanup (cleanup_unlock_passwd); + } + +@@ -657,15 +667,19 @@ static void prepare_failure_reports (voi + * + * lock_files() locks the group, gshadow, and passwd databases. + */ +-static void lock_files (void) ++static void lock_files (struct option_flags *flags) + { ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot && !flags->prefix; ++ + if (gr_lock () == 0) { + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, gr_dbname ()); + exit (E_GRP_UPDATE); + } +- add_cleanup (cleanup_unlock_group, NULL); ++ add_cleanup (cleanup_unlock_group, &process_selinux); + + #ifdef SHADOWGRP + if ( is_shadow_grp +@@ -676,7 +690,7 @@ static void lock_files (void) + Prog, sgr_dbname ()); + exit (E_GRP_UPDATE); + } +- add_cleanup (cleanup_unlock_gshadow, NULL); ++ add_cleanup (cleanup_unlock_gshadow, &process_selinux); + } + #endif + +@@ -687,7 +701,7 @@ static void lock_files (void) + Prog, pw_dbname ()); + exit (E_GRP_UPDATE); + } +- add_cleanup (cleanup_unlock_passwd, NULL); ++ add_cleanup (cleanup_unlock_passwd, &process_selinux); + } + } + +@@ -771,6 +785,7 @@ int main (int argc, char **argv) + int retval; + #endif /* USE_PAM */ + #endif /* ACCT_TOOLS_SETUID */ ++ struct option_flags flags; + + log_set_progname(Prog); + log_set_logfd(stderr); +@@ -794,7 +809,7 @@ int main (int argc, char **argv) + exit (E_CLEANUP_SERVICE); + } + +- process_flags (argc, argv); ++ process_flags (argc, argv, &flags); + + #ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM +@@ -859,7 +874,7 @@ int main (int argc, char **argv) + check_new_name (); + } + +- lock_files (); ++ lock_files (&flags); + + /* + * Now if the group is not changed, it's our fault. +@@ -875,7 +890,7 @@ int main (int argc, char **argv) + + grp_update (); + +- close_files (); ++ close_files (&flags); + + nscd_flush_cache ("group"); + sssd_flush_cache (SSSD_DB_GROUP); +diff -up shadow-4.18.0/src/grpck.c.test-chroot3 shadow-4.18.0/src/grpck.c +--- shadow-4.18.0/src/grpck.c.test-chroot3 2025-07-04 11:15:02.302354224 +0200 ++++ shadow-4.18.0/src/grpck.c 2025-07-04 11:15:02.313643179 +0200 +@@ -44,6 +44,13 @@ + #define E_CANT_UPDATE 5 + + /* ++ * Structures ++ */ ++struct option_flags { ++ bool chroot; ++}; ++ ++/* + * Global variables + */ + static const char Prog[] = "grpck"; +@@ -64,19 +71,20 @@ static bool sort_mode = false; + static bool silence_warnings = false; + + /* local function prototypes */ +-static void fail_exit (int status); ++static void fail_exit (int status, bool process_selinux); + NORETURN static void usage (int status); + static void delete_member (char **, const char *); +-static void process_flags (int argc, char **argv); +-static void open_files (void); +-static void close_files (bool changed); ++static void process_flags (int argc, char **argv, struct option_flags *flags); ++static void open_files (bool process_selinux); ++static void close_files (bool changed, struct option_flags *flags); + static int check_members (const char *groupname, + char **members, + const char *fmt_info, + const char *fmt_prompt, + const char *fmt_syslog, + bool *errors); +-static void check_grp_file (bool *errors, bool *changed); ++static void check_grp_file (bool *errors, bool *changed, ++ struct option_flags *flags); + #ifdef SHADOWGRP + static void compare_members_lists (const char *groupname, + char **members, +@@ -89,10 +97,10 @@ static void check_sgr_file (bool *errors + /* + * fail_exit - exit with an error code after unlocking files + */ +-static void fail_exit (int status) ++static void fail_exit (int status, bool process_selinux) + { + if (gr_locked) { +- if (gr_unlock (true) == 0) { ++ if (gr_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + /* continue */ +@@ -101,7 +109,7 @@ static void fail_exit (int status) + + #ifdef SHADOWGRP + if (sgr_locked) { +- if (sgr_unlock (true) == 0) { ++ if (sgr_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + /* continue */ +@@ -172,7 +180,7 @@ static void delete_member (char **list, + * + * It will not return if an error is encountered. + */ +-static void process_flags (int argc, char **argv) ++static void process_flags (int argc, char **argv, struct option_flags *flags) + { + int c; + static struct option long_options[] = { +@@ -201,6 +209,7 @@ static void process_flags (int argc, cha + read_only = true; + break; + case 'R': /* no-op, handled in process_root_flag () */ ++ flags->chroot = true; + break; + case 's': + sort_mode = true; +@@ -257,7 +266,7 @@ static void process_flags (int argc, cha + * In read-only mode, the databases are not locked and are opened + * only for reading. + */ +-static void open_files (void) ++static void open_files (bool process_selinux) + { + /* + * Lock the files if we aren't in "read-only" mode +@@ -267,7 +276,7 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, grp_file); +- fail_exit (E_CANT_LOCK); ++ fail_exit (E_CANT_LOCK, process_selinux); + } + gr_locked = true; + #ifdef SHADOWGRP +@@ -276,7 +285,7 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, sgr_file); +- fail_exit (E_CANT_LOCK); ++ fail_exit (E_CANT_LOCK, process_selinux); + } + sgr_locked = true; + } +@@ -293,7 +302,7 @@ static void open_files (void) + if (use_system_grp_file) { + SYSLOG ((LOG_WARN, "cannot open %s", grp_file)); + } +- fail_exit (E_CANT_OPEN); ++ fail_exit (E_CANT_OPEN, process_selinux); + } + #ifdef SHADOWGRP + if (is_shadow && (sgr_open (read_only ? O_RDONLY : O_CREAT | O_RDWR) == 0)) { +@@ -302,7 +311,7 @@ static void open_files (void) + if (use_system_sgr_file) { + SYSLOG ((LOG_WARN, "cannot open %s", sgr_file)); + } +- fail_exit (E_CANT_OPEN); ++ fail_exit (E_CANT_OPEN, process_selinux); + } + #endif + } +@@ -314,23 +323,27 @@ static void open_files (void) + * changes are committed in the databases. The databases are + * unlocked anyway. + */ +-static void close_files (bool changed) ++static void close_files (bool changed, struct option_flags *flags) + { ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot; ++ + /* + * All done. If there were no change we can just abandon any + * changes to the files. + */ + if (changed) { +- if (gr_close (true) == 0) { ++ if (gr_close (process_selinux) == 0) { + fprintf (stderr, _("%s: failure while writing changes to %s\n"), + Prog, grp_file); +- fail_exit (E_CANT_UPDATE); ++ fail_exit (E_CANT_UPDATE, process_selinux); + } + #ifdef SHADOWGRP +- if (is_shadow && (sgr_close (true) == 0)) { ++ if (is_shadow && (sgr_close (process_selinux) == 0)) { + fprintf (stderr, _("%s: failure while writing changes to %s\n"), + Prog, sgr_file); +- fail_exit (E_CANT_UPDATE); ++ fail_exit (E_CANT_UPDATE, process_selinux); + } + #endif + } +@@ -340,7 +353,7 @@ static void close_files (bool changed) + */ + #ifdef SHADOWGRP + if (sgr_locked) { +- if (sgr_unlock (true) == 0) { ++ if (sgr_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + /* continue */ +@@ -349,7 +362,7 @@ static void close_files (bool changed) + } + #endif + if (gr_locked) { +- if (gr_unlock (true) == 0) { ++ if (gr_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + /* continue */ +@@ -455,13 +468,16 @@ static void compare_members_lists (const + /* + * check_grp_file - check the content of the group file + */ +-static void check_grp_file (bool *errors, bool *changed) ++static void check_grp_file (bool *errors, bool *changed, struct option_flags *flags) + { + struct commonio_entry *gre, *tgre; + struct group *grp; + #ifdef SHADOWGRP + const struct sgrp *sgr; + #endif ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot; + + /* + * Loop through the entire group file. +@@ -627,7 +643,7 @@ static void check_grp_file (bool *errors + fprintf (stderr, + _("%s: failed to prepare the new %s entry '%s'\n"), + Prog, sgr_dbname (), sg.sg_namp); +- fail_exit (E_CANT_UPDATE); ++ fail_exit (E_CANT_UPDATE, process_selinux); + } + /* remove password from /etc/group */ + gr = *grp; +@@ -636,7 +652,7 @@ static void check_grp_file (bool *errors + fprintf (stderr, + _("%s: failed to prepare the new %s entry '%s'\n"), + Prog, gr_dbname (), gr.gr_name); +- fail_exit (E_CANT_UPDATE); ++ fail_exit (E_CANT_UPDATE, process_selinux); + } + } + } else { +@@ -819,6 +835,8 @@ int main (int argc, char **argv) + { + bool errors = false; + bool changed = false; ++ struct option_flags flags; ++ bool process_selinux; + + log_set_progname(Prog); + log_set_logfd(stderr); +@@ -832,9 +850,10 @@ int main (int argc, char **argv) + OPENLOG (Prog); + + /* Parse the command line arguments */ +- process_flags (argc, argv); ++ process_flags (argc, argv, &flags); ++ process_selinux = !flags.chroot; + +- open_files (); ++ open_files (process_selinux); + + if (sort_mode) { + gr_sort (); +@@ -845,7 +864,7 @@ int main (int argc, char **argv) + changed = true; + #endif + } else { +- check_grp_file (&errors, &changed); ++ check_grp_file (&errors, &changed, &flags); + #ifdef SHADOWGRP + if (is_shadow) { + check_sgr_file (&errors, &changed); +@@ -854,7 +873,7 @@ int main (int argc, char **argv) + } + + /* Commit the change in the database if needed */ +- close_files (changed); ++ close_files (changed, &flags); + + if (!read_only) { + nscd_flush_cache ("group"); + +diff -up shadow-4.18.0/src/chage.c.test-chroot4 shadow-4.18.0/src/chage.c +--- shadow-4.18.0/src/chage.c.test-chroot4 2025-07-04 11:17:37.593707379 +0200 ++++ shadow-4.18.0/src/chage.c 2025-07-04 11:17:37.613081862 +0200 +@@ -42,6 +42,10 @@ + #include "tcbfuncs.h" + #endif + ++struct option_flags { ++ bool chroot; ++ bool prefix; ++}; + + /* + * Global variables +@@ -79,29 +83,29 @@ NORETURN static void usage (int status); + static int new_fields (void); + static void print_day_as_date (long day); + static void list_fields (void); +-static void process_flags (int argc, char **argv); ++static void process_flags (int argc, char **argv, struct option_flags *flags); + static void check_flags (int argc, int opt_index); +-static void check_perms (void); +-static void open_files (bool readonly); +-static void close_files (void); +-NORETURN static void fail_exit (int code); ++static void check_perms (struct option_flags *flags); ++static void open_files (bool readonly, struct option_flags *flags); ++static void close_files (struct option_flags *flags); ++NORETURN static void fail_exit (int code, bool process_selinux); + + /* + * fail_exit - do some cleanup and exit with the given error code + */ + NORETURN + static void +-fail_exit (int code) ++fail_exit (int code, bool process_selinux) + { + if (spw_locked) { +- if (spw_unlock (true) == 0) { ++ if (spw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + /* continue */ + } + } + if (pw_locked) { +- if (pw_unlock (true) == 0) { ++ if (pw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +@@ -338,7 +342,7 @@ static void list_fields (void) + * + * It will not return if an error is encountered. + */ +-static void process_flags (int argc, char **argv) ++static void process_flags (int argc, char **argv, struct option_flags *flags) + { + /* + * Parse the command line options. +@@ -419,8 +423,10 @@ static void process_flags (int argc, cha + } + break; + case 'R': /* no-op, handled in process_root_flag () */ ++ flags->chroot = true; + break; + case 'P': /* no-op, handled in process_prefix_flag () */ ++ flags->prefix = true; + break; + case 'W': + Wflg = true; +@@ -472,8 +478,12 @@ static void check_flags (int argc, int o + * + * It will not return if the user is not allowed. + */ +-static void check_perms (void) ++static void check_perms (struct option_flags *flags) + { ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot && !flags->prefix; ++ + /* + * An unprivileged user can ask for their own aging information, but + * only root can change it, or list another user's aging +@@ -482,7 +492,7 @@ static void check_perms (void) + + if (!amroot && !lflg) { + fprintf (stderr, _("%s: Permission denied.\n"), Prog); +- fail_exit (E_NOPERM); ++ fail_exit (E_NOPERM, process_selinux); + } + } + +@@ -492,8 +502,12 @@ static void check_perms (void) + * In read-only mode, the databases are not locked and are opened + * only for reading. + */ +-static void open_files (bool readonly) ++static void open_files (bool readonly, struct option_flags *flags) + { ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot && !flags->prefix; ++ + /* + * Lock and open the password file. This loads all of the password + * file entries into memory. Then we get a pointer to the password +@@ -504,14 +518,14 @@ static void open_files (bool readonly) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, pw_dbname ()); +- fail_exit (E_NOPERM); ++ fail_exit (E_NOPERM, process_selinux); + } + pw_locked = true; + } + if (pw_open (readonly ? O_RDONLY: O_CREAT | O_RDWR) == 0) { + fprintf (stderr, _("%s: cannot open %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_WARN, "cannot open %s", pw_dbname ())); +- fail_exit (E_NOPERM); ++ fail_exit (E_NOPERM, process_selinux); + } + + /* +@@ -525,7 +539,7 @@ static void open_files (bool readonly) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, spw_dbname ()); +- fail_exit (E_NOPERM); ++ fail_exit (E_NOPERM, process_selinux); + } + spw_locked = true; + } +@@ -533,42 +547,46 @@ static void open_files (bool readonly) + fprintf (stderr, + _("%s: cannot open %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_WARN, "cannot open %s", spw_dbname ())); +- fail_exit (E_NOPERM); ++ fail_exit (E_NOPERM, process_selinux); + } + } + + /* + * close_files - close and unlock the password/shadow databases + */ +-static void close_files (void) ++static void close_files (struct option_flags *flags) + { ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot && !flags->prefix; ++ + /* + * Now close the shadow password file, which will cause all of the + * entries to be re-written. + */ +- if (spw_close (true) == 0) { ++ if (spw_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); +- fail_exit (E_NOPERM); ++ fail_exit (E_NOPERM, process_selinux); + } + + /* + * Close the password file. If any entries were modified, the file + * will be re-written. + */ +- if (pw_close (true) == 0) { ++ if (pw_close (process_selinux) == 0) { + fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); +- fail_exit (E_NOPERM); ++ fail_exit (E_NOPERM, process_selinux); + } +- if (spw_unlock (true) == 0) { ++ if (spw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + /* continue */ + } + spw_locked = false; +- if (pw_unlock (true) == 0) { ++ if (pw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +@@ -582,7 +600,8 @@ static void close_files (void) + * It will not return in case of error + */ + static void update_age (/*@null@*/const struct spwd *sp, +- /*@notnull@*/const struct passwd *pw) ++ /*@notnull@*/const struct passwd *pw, ++ bool process_selinux) + { + struct spwd spwent; + +@@ -603,7 +622,7 @@ static void update_age (/*@null@*/const + if (pw_update (&pwent) == 0) { + fprintf (stderr, + _("%s: failed to prepare the new %s entry '%s'\n"), Prog, pw_dbname (), pwent.pw_name); +- fail_exit (E_NOPERM); ++ fail_exit (E_NOPERM, process_selinux); + } + } else { + spwent.sp_namp = xstrdup (sp->sp_namp); +@@ -626,7 +645,7 @@ static void update_age (/*@null@*/const + if (spw_update (&spwent) == 0) { + fprintf (stderr, + _("%s: failed to prepare the new %s entry '%s'\n"), Prog, spw_dbname (), spwent.sp_namp); +- fail_exit (E_NOPERM); ++ fail_exit (E_NOPERM, process_selinux); + } + + } +@@ -712,6 +731,8 @@ int main (int argc, char **argv) + uid_t ruid; + gid_t rgid; + const struct passwd *pw; ++ struct option_flags flags; ++ bool process_selinux; + + sanitize_env (); + check_fds (); +@@ -740,9 +761,10 @@ int main (int argc, char **argv) + } + #endif + +- process_flags (argc, argv); ++ process_flags (argc, argv, &flags); ++ process_selinux = !flags.chroot && !flags.prefix; + +- check_perms (); ++ check_perms (&flags); + + if (!spw_file_present ()) { + fprintf (stderr, +@@ -753,13 +775,13 @@ int main (int argc, char **argv) + exit (E_SHADOW_NOTFOUND); + } + +- open_files (lflg); ++ open_files (lflg, &flags); + /* Drop privileges */ + if (lflg && ( (setregid (rgid, rgid) != 0) + || (setreuid (ruid, ruid) != 0))) { + fprintf (stderr, _("%s: failed to drop privileges (%s)\n"), + Prog, strerror (errno)); +- fail_exit (E_NOPERM); ++ fail_exit (E_NOPERM, process_selinux); + } + + pw = pw_locate (argv[optind]); +@@ -767,13 +789,13 @@ int main (int argc, char **argv) + fprintf (stderr, _("%s: user '%s' does not exist in %s\n"), + Prog, argv[optind], pw_dbname ()); + closelog (); +- fail_exit (E_NOPERM); ++ fail_exit (E_NOPERM, process_selinux); + } + + STRTCPY(user_name, pw->pw_name); + #ifdef WITH_TCB + if (shadowtcb_set_user (pw->pw_name) == SHADOWTCB_FAILURE) { +- fail_exit (E_NOPERM); ++ fail_exit (E_NOPERM, process_selinux); + } + #endif + user_uid = pw->pw_uid; +@@ -788,11 +810,11 @@ int main (int argc, char **argv) + if (lflg) { + if (!amroot && (ruid != user_uid)) { + fprintf (stderr, _("%s: Permission denied.\n"), Prog); +- fail_exit (E_NOPERM); ++ fail_exit (E_NOPERM, process_selinux); + } + /* Displaying fields is not of interest to audit */ + list_fields (); +- fail_exit (E_SUCCESS); ++ fail_exit (E_SUCCESS, process_selinux); + } + + /* +@@ -805,7 +827,7 @@ int main (int argc, char **argv) + if (new_fields () == 0) { + fprintf (stderr, _("%s: error changing fields\n"), + Prog); +- fail_exit (E_NOPERM); ++ fail_exit (E_NOPERM, process_selinux); + } + #ifdef WITH_AUDIT + else { +@@ -847,9 +869,9 @@ int main (int argc, char **argv) + #endif + } + +- update_age (sp, pw); ++ update_age (sp, pw, process_selinux); + +- close_files (); ++ close_files (&flags); + + SYSLOG ((LOG_INFO, "changed password expiry for %s", user_name)); + +diff -up shadow-4.18.0/src/chfn.c.test-chroot4 shadow-4.18.0/src/chfn.c +--- shadow-4.18.0/src/chfn.c.test-chroot4 2025-07-04 11:17:37.590501245 +0200 ++++ shadow-4.18.0/src/chfn.c 2025-07-04 11:17:37.613576062 +0200 +@@ -39,6 +39,9 @@ + #include "string/strdup/xstrdup.h" + #include "string/strtok/stpsep.h" + ++struct option_flags { ++ bool chroot; ++}; + + /* + * Global variables. +@@ -63,23 +66,23 @@ static bool pw_locked = false; + */ + + /* local function prototypes */ +-NORETURN static void fail_exit (int code); ++NORETURN static void fail_exit (int code, bool process_selinux); + NORETURN static void usage (int status); + static bool may_change_field (int); + static void new_fields (void); + static char *copy_field (char *, char *, char *); +-static void process_flags (int argc, char **argv); ++static void process_flags (int argc, char **argv, struct option_flags *flags); + static void check_perms (const struct passwd *pw); +-static void update_gecos (const char *user, char *gecos); ++static void update_gecos (const char *user, char *gecos, struct option_flags *flags); + static void get_old_fields (const char *gecos); + + /* + * fail_exit - exit with an error and do some cleanup + */ +-static void fail_exit (int code) ++static void fail_exit (int code, bool process_selinux) + { + if (pw_locked) { +- if (pw_unlock (true) == 0) { ++ if (pw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +@@ -250,7 +253,7 @@ static char *copy_field (char *in, char + * + * It will not return if an error is encountered. + */ +-static void process_flags (int argc, char **argv) ++static void process_flags (int argc, char **argv, struct option_flags *flags) + { + int c; /* flag currently being processed */ + static struct option long_options[] = { +@@ -316,6 +319,7 @@ static void process_flags (int argc, cha + STRTCPY(roomno, optarg); + break; + case 'R': /* no-op, handled in process_root_flag () */ ++ flags->chroot = true; + break; + case 'u': + usage (E_SUCCESS); +@@ -423,10 +427,13 @@ static void check_perms (const struct pa + * + * Commit the user's entry after changing her gecos field. + */ +-static void update_gecos (const char *user, char *gecos) ++static void update_gecos (const char *user, char *gecos, struct option_flags *flags) + { + const struct passwd *pw; /* The user's password file entry */ + struct passwd pwent; /* modified password file entry */ ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot; + + /* + * Before going any further, raise the ulimit to prevent colliding +@@ -437,7 +444,7 @@ static void update_gecos (const char *us + if (setuid (0) != 0) { + fputs (_("Cannot change ID to root.\n"), stderr); + SYSLOG ((LOG_ERR, "can't setuid(0)")); +- fail_exit (E_NOPERM); ++ fail_exit (E_NOPERM, process_selinux); + } + pwd_init (); + +@@ -449,13 +456,13 @@ static void update_gecos (const char *us + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, pw_dbname ()); +- fail_exit (E_NOPERM); ++ fail_exit (E_NOPERM, process_selinux); + } + pw_locked = true; + if (pw_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, + _("%s: cannot open %s\n"), Prog, pw_dbname ()); +- fail_exit (E_NOPERM); ++ fail_exit (E_NOPERM, process_selinux); + } + + /* +@@ -469,7 +476,7 @@ static void update_gecos (const char *us + fprintf (stderr, + _("%s: user '%s' does not exist in %s\n"), + Prog, user, pw_dbname ()); +- fail_exit (E_NOPERM); ++ fail_exit (E_NOPERM, process_selinux); + } + + /* +@@ -487,18 +494,18 @@ static void update_gecos (const char *us + fprintf (stderr, + _("%s: failed to prepare the new %s entry '%s'\n"), + Prog, pw_dbname (), pwent.pw_name); +- fail_exit (E_NOPERM); ++ fail_exit (E_NOPERM, process_selinux); + } + + /* + * Changes have all been made, so commit them and unlock the file. + */ +- if (pw_close (true) == 0) { ++ if (pw_close (process_selinux) == 0) { + fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); +- fail_exit (E_NOPERM); ++ fail_exit (E_NOPERM, process_selinux); + } +- if (pw_unlock (true) == 0) { ++ if (pw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +@@ -562,7 +569,7 @@ static void get_old_fields (const char * + * + * It will not return if a field is not valid. + */ +-static void check_fields (void) ++static void check_fields (bool process_selinux) + { + int err; + err = valid_field (fullnm, ":,=\n"); +@@ -570,7 +577,7 @@ static void check_fields (void) + fprintf (stderr, _("%s: name with non-ASCII characters: '%s'\n"), Prog, fullnm); + } else if (err < 0) { + fprintf (stderr, _("%s: invalid name: '%s'\n"), Prog, fullnm); +- fail_exit (E_NOPERM); ++ fail_exit (E_NOPERM, process_selinux); + } + err = valid_field (roomno, ":,=\n"); + if (err > 0) { +@@ -578,17 +585,17 @@ static void check_fields (void) + } else if (err < 0) { + fprintf (stderr, _("%s: invalid room number: '%s'\n"), + Prog, roomno); +- fail_exit (E_NOPERM); ++ fail_exit (E_NOPERM, process_selinux); + } + if (valid_field (workph, ":,=\n") != 0) { + fprintf (stderr, _("%s: invalid work phone: '%s'\n"), + Prog, workph); +- fail_exit (E_NOPERM); ++ fail_exit (E_NOPERM, process_selinux); + } + if (valid_field (homeph, ":,=\n") != 0) { + fprintf (stderr, _("%s: invalid home phone: '%s'\n"), + Prog, homeph); +- fail_exit (E_NOPERM); ++ fail_exit (E_NOPERM, process_selinux); + } + err = valid_field (slop, ":\n"); + if (err > 0) { +@@ -597,7 +604,7 @@ static void check_fields (void) + fprintf (stderr, + _("%s: '%s' contains illegal characters\n"), + Prog, slop); +- fail_exit (E_NOPERM); ++ fail_exit (E_NOPERM, process_selinux); + } + } + +@@ -622,6 +629,8 @@ int main (int argc, char **argv) + char new_gecos[BUFSIZ]; + char *user; + const struct passwd *pw; ++ struct option_flags flags; ++ bool process_selinux; + + sanitize_env (); + check_fds (); +@@ -644,7 +653,7 @@ int main (int argc, char **argv) + OPENLOG (Prog); + + /* parse the command line options */ +- process_flags (argc, argv); ++ process_flags (argc, argv, &flags); + + /* + * Get the name of the user to check. It is either the command line +@@ -653,14 +662,14 @@ int main (int argc, char **argv) + if (optind < argc) { + if (!is_valid_user_name (argv[optind])) { + fprintf (stderr, _("%s: Provided user name is not a valid name\n"), Prog); +- fail_exit (E_NOPERM); ++ fail_exit (E_NOPERM, process_selinux); + } + user = argv[optind]; + pw = xgetpwnam (user); + if (NULL == pw) { + fprintf (stderr, _("%s: user '%s' does not exist\n"), Prog, + user); +- fail_exit (E_NOPERM); ++ fail_exit (E_NOPERM, process_selinux); + } + } else { + pw = get_my_pwent (); +@@ -670,7 +679,7 @@ int main (int argc, char **argv) + Prog); + SYSLOG ((LOG_WARN, "Cannot determine the user name of the caller (UID %lu)", + (unsigned long) getuid ())); +- fail_exit (E_NOPERM); ++ fail_exit (E_NOPERM, process_selinux); + } + user = xstrdup (pw->pw_name); + } +@@ -695,7 +704,7 @@ int main (int argc, char **argv) + /* + * Check all of the fields for valid information + */ +- check_fields (); ++ check_fields (process_selinux); + + /* + * Build the new GECOS field by plastering all the pieces together, +@@ -704,14 +713,14 @@ int main (int argc, char **argv) + if ((strlen (fullnm) + strlen (roomno) + strlen (workph) + + strlen (homeph) + strlen (slop)) > (unsigned int) 80) { + fprintf (stderr, _("%s: fields too long\n"), Prog); +- fail_exit (E_NOPERM); ++ fail_exit (E_NOPERM, process_selinux); + } + SNPRINTF(new_gecos, "%s,%s,%s,%s%s%s", + fullnm, roomno, workph, homeph, + (!streq(slop, "")) ? "," : "", slop); + + /* Rewrite the user's gecos in the passwd file */ +- update_gecos (user, new_gecos); ++ update_gecos (user, new_gecos, &flags); + + SYSLOG ((LOG_INFO, "changed user '%s' information", user)); + +diff -up shadow-4.18.0/src/chpasswd.c.test-chroot4 shadow-4.18.0/src/chpasswd.c +--- shadow-4.18.0/src/chpasswd.c.test-chroot4 2025-07-04 11:17:37.593768325 +0200 ++++ shadow-4.18.0/src/chpasswd.c 2025-07-04 11:18:06.785652711 +0200 +@@ -38,6 +38,11 @@ + + #define IS_CRYPT_METHOD(str) ((crypt_method != NULL && streq(crypt_method, str)) ? true : false) + ++struct option_flags { ++ bool chroot; ++ bool prefix; ++}; ++ + /* + * Global variables + */ +@@ -67,21 +72,21 @@ static bool pw_locked = false; + static bool spw_locked = false; + + /* local function prototypes */ +-NORETURN static void fail_exit (int code); ++NORETURN static void fail_exit (int code, bool process_selinux); + NORETURN static void usage (int status); +-static void process_flags (int argc, char **argv); ++static void process_flags (int argc, char **argv, struct option_flags *flags); + static void check_flags (void); + static void check_perms (void); +-static void open_files (void); +-static void close_files (void); ++static void open_files (struct option_flags *flags); ++static void close_files (struct option_flags *flags); + + /* + * fail_exit - exit with a failure code after unlocking the files + */ +-static void fail_exit (int code) ++static void fail_exit (int code, bool process_selinux) + { + if (pw_locked) { +- if (pw_unlock (true) == 0) { ++ if (pw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +@@ -89,7 +94,7 @@ static void fail_exit (int code) + } + + if (spw_locked) { +- if (spw_unlock (true) == 0) { ++ if (spw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + /* continue */ +@@ -147,7 +152,7 @@ usage (int status) + * + * It will not return if an error is encountered. + */ +-static void process_flags (int argc, char **argv) ++static void process_flags (int argc, char **argv, struct option_flags *flags) + { + int c; + #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) +@@ -187,8 +192,10 @@ static void process_flags (int argc, cha + md5flg = true; + break; + case 'R': /* no-op, handled in process_root_flag () */ ++ flags->chroot = true; + break; + case 'P': /* no-op, handled in process_prefix_flag () */ ++ flags->prefix = true; + break; + #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) + case 's': +@@ -335,8 +342,12 @@ static void check_perms (void) + /* + * open_files - lock and open the password databases + */ +-static void open_files (void) ++static void open_files (struct option_flags *flags) + { ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot && !flags->prefix; ++ + /* + * Lock the password file and open it for reading and writing. This + * will bring all of the entries into memory where they may be updated. +@@ -345,13 +356,13 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, pw_dbname ()); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + pw_locked = true; + if (pw_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, + _("%s: cannot open %s\n"), Prog, pw_dbname ()); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + + /* Do the same for the shadowed database, if it exist */ +@@ -360,14 +371,14 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, spw_dbname ()); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + spw_locked = true; + if (spw_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, + _("%s: cannot open %s\n"), + Prog, spw_dbname ()); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + } + } +@@ -375,17 +386,21 @@ static void open_files (void) + /* + * close_files - close and unlock the password databases + */ +-static void close_files (void) ++static void close_files (struct option_flags *flags) + { ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot && !flags->prefix; ++ + if (is_shadow_pwd) { +- if (spw_close (true) == 0) { ++ if (spw_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } +- if (spw_unlock (true) == 0) { ++ if (spw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + /* continue */ +@@ -393,14 +408,14 @@ static void close_files (void) + spw_locked = false; + } + +- if (pw_close (true) == 0) { ++ if (pw_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } +- if (pw_unlock (true) == 0) { ++ if (pw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +@@ -456,6 +471,8 @@ int main (int argc, char **argv) + + bool errors = false; + intmax_t line = 0; ++ struct option_flags flags; ++ bool process_selinux; + + log_set_progname(Prog); + log_set_logfd(stderr); +@@ -470,7 +487,8 @@ int main (int argc, char **argv) + } + #endif /* WITH_SELINUX */ + +- process_flags (argc, argv); ++ process_flags (argc, argv, &flags); ++ process_selinux = !flags.chroot && !flags.prefix; + + salt = get_salt(); + process_root_flag ("-R", argc, argv); +@@ -496,7 +514,7 @@ int main (int argc, char **argv) + { + is_shadow_pwd = spw_file_present (); + +- open_files (); ++ open_files (&flags); + } + + /* +@@ -573,7 +591,7 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: failed to crypt password with salt '%s': %s\n"), + Prog, salt, strerror (errno)); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + } + +@@ -690,7 +708,7 @@ int main (int argc, char **argv) + _("%s: error detected, changes ignored\n"), + Prog); + } +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + + #ifdef ACCT_TOOLS_SETUID +@@ -700,7 +718,7 @@ int main (int argc, char **argv) + #endif /* ACCT_TOOLS_SETUID */ + { + /* Save the changes */ +- close_files (); ++ close_files (&flags); + } + + nscd_flush_cache ("passwd"); +diff -up shadow-4.18.0/src/grpconv.c.test-chroot4 shadow-4.18.0/src/grpconv.c +--- shadow-4.18.0/src/grpconv.c.test-chroot4 2025-07-04 11:17:37.598073521 +0200 ++++ shadow-4.18.0/src/grpconv.c 2025-07-04 11:17:37.612354766 +0200 +@@ -39,6 +39,12 @@ + #include "shadowlog.h" + #include "sssd.h" + ++/* ++ * Structures ++ */ ++struct option_flags { ++ bool chroot; ++}; + + /* + * Global variables +@@ -49,14 +55,14 @@ static bool gr_locked = false; + static bool sgr_locked = false; + + /* local function prototypes */ +-static void fail_exit (int status); ++static void fail_exit (int status, bool process_selinux); + static void usage (int status); +-static void process_flags (int argc, char **argv); ++static void process_flags (int argc, char **argv, struct option_flags *flags); + +-static void fail_exit (int status) ++static void fail_exit (int status, bool process_selinux) + { + if (gr_locked) { +- if (gr_unlock (true) == 0) { ++ if (gr_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + /* continue */ +@@ -64,7 +70,7 @@ static void fail_exit (int status) + } + + if (sgr_locked) { +- if (sgr_unlock (true) == 0) { ++ if (sgr_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + /* continue */ +@@ -93,7 +99,7 @@ static void usage (int status) + * + * It will not return if an error is encountered. + */ +-static void process_flags (int argc, char **argv) ++static void process_flags (int argc, char **argv, struct option_flags *flags) + { + /* + * Parse the command line options. +@@ -112,6 +118,7 @@ static void process_flags (int argc, cha + usage (E_SUCCESS); + /*@notreached@*/break; + case 'R': /* no-op, handled in process_root_flag () */ ++ flags->chroot = true; + break; + default: + usage (E_USAGE); +@@ -129,6 +136,8 @@ int main (int argc, char **argv) + struct group grent; + const struct sgrp *sg; + struct sgrp sgent; ++ struct option_flags flags; ++ bool process_selinux; + + log_set_progname(Prog); + log_set_logfd(stderr); +@@ -141,30 +150,31 @@ int main (int argc, char **argv) + + OPENLOG (Prog); + +- process_flags (argc, argv); ++ process_flags (argc, argv, &flags); ++ process_selinux = !flags.chroot; + + if (gr_lock () == 0) { + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, gr_dbname ()); +- fail_exit (5); ++ fail_exit (5, process_selinux); + } + gr_locked = true; + if (gr_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ()); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + + if (sgr_lock () == 0) { + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, sgr_dbname ()); +- fail_exit (5); ++ fail_exit (5, process_selinux); + } + sgr_locked = true; + if (sgr_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, _("%s: cannot open %s\n"), Prog, sgr_dbname ()); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + + /* +@@ -183,7 +193,7 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: cannot remove entry '%s' from %s\n"), + Prog, sg->sg_namp, sgr_dbname ()); +- fail_exit (3); ++ fail_exit (3, process_selinux); + } + (void) sgr_rewind (); + } +@@ -221,7 +231,7 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: failed to prepare the new %s entry '%s'\n"), + Prog, sgr_dbname (), sgent.sg_namp); +- fail_exit (3); ++ fail_exit (3, process_selinux); + } + /* remove password from /etc/group */ + grent = *gr; +@@ -230,30 +240,30 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: failed to prepare the new %s entry '%s'\n"), + Prog, gr_dbname (), grent.gr_name); +- fail_exit (3); ++ fail_exit (3, process_selinux); + } + } + +- if (sgr_close (true) == 0) { ++ if (sgr_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ())); +- fail_exit (3); ++ fail_exit (3, process_selinux); + } +- if (gr_close (true) == 0) { ++ if (gr_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ())); +- fail_exit (3); ++ fail_exit (3, process_selinux); + } +- if (sgr_unlock (true) == 0) { ++ if (sgr_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + /* continue */ + } +- if (gr_unlock (true) == 0) { ++ if (gr_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + /* continue */ +diff -up shadow-4.18.0/src/grpunconv.c.test-chroot4 shadow-4.18.0/src/grpunconv.c +--- shadow-4.18.0/src/grpunconv.c.test-chroot4 2025-07-04 11:17:37.598110132 +0200 ++++ shadow-4.18.0/src/grpunconv.c 2025-07-04 11:17:37.612706894 +0200 +@@ -38,6 +38,12 @@ + #include "sgroupio.h" + #include "shadowlog.h" + ++/* ++ * Structures ++ */ ++struct option_flags { ++ bool chroot; ++}; + + /* + * Global variables +@@ -48,14 +54,14 @@ static bool gr_locked = false; + static bool sgr_locked = false; + + /* local function prototypes */ +-static void fail_exit (int status); ++static void fail_exit (int status, bool process_selinux); + static void usage (int status); +-static void process_flags (int argc, char **argv); ++static void process_flags (int argc, char **argv, struct option_flags *flags); + +-static void fail_exit (int status) ++static void fail_exit (int status, bool process_selinux) + { + if (gr_locked) { +- if (gr_unlock (true) == 0) { ++ if (gr_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + /* continue */ +@@ -63,7 +69,7 @@ static void fail_exit (int status) + } + + if (sgr_locked) { +- if (sgr_unlock (true) == 0) { ++ if (sgr_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + /* continue */ +@@ -92,7 +98,7 @@ static void usage (int status) + * + * It will not return if an error is encountered. + */ +-static void process_flags (int argc, char **argv) ++static void process_flags (int argc, char **argv, struct option_flags *flags) + { + /* + * Parse the command line options. +@@ -111,6 +117,7 @@ static void process_flags (int argc, cha + usage (E_SUCCESS); + /*@notreached@*/break; + case 'R': /* no-op, handled in process_root_flag () */ ++ flags->chroot = true; + break; + default: + usage (E_USAGE); +@@ -127,6 +134,8 @@ int main (int argc, char **argv) + const struct group *gr; + struct group grent; + const struct sgrp *sg; ++ struct option_flags flags; ++ bool process_selinux; + + log_set_progname(Prog); + log_set_logfd(stderr); +@@ -139,7 +148,8 @@ int main (int argc, char **argv) + + OPENLOG (Prog); + +- process_flags (argc, argv); ++ process_flags (argc, argv, &flags); ++ process_selinux = !flags.chroot; + + if (sgr_file_present () == 0) { + exit (0); /* no /etc/gshadow, nothing to do */ +@@ -149,26 +159,26 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, gr_dbname ()); +- fail_exit (5); ++ fail_exit (5, process_selinux); + } + gr_locked = true; + if (gr_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, + _("%s: cannot open %s\n"), Prog, gr_dbname ()); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + + if (sgr_lock () == 0) { + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, sgr_dbname ()); +- fail_exit (5); ++ fail_exit (5, process_selinux); + } + sgr_locked = true; + if (sgr_open (O_RDONLY) == 0) { + fprintf (stderr, + _("%s: cannot open %s\n"), Prog, sgr_dbname ()); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + + /* +@@ -186,19 +196,19 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: failed to prepare the new %s entry '%s'\n"), + Prog, gr_dbname (), grent.gr_name); +- fail_exit (3); ++ fail_exit (3, process_selinux); + } + } + } + +- (void) sgr_close (true); /* was only open O_RDONLY */ ++ (void) sgr_close (process_selinux); /* was only open O_RDONLY */ + +- if (gr_close (true) == 0) { ++ if (gr_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ())); +- fail_exit (3); ++ fail_exit (3, process_selinux); + } + + if (unlink (SGROUP_FILE) != 0) { +@@ -206,16 +216,16 @@ int main (int argc, char **argv) + _("%s: cannot delete %s\n"), + Prog, SGROUP_FILE); + SYSLOG ((LOG_ERR, "cannot delete %s", SGROUP_FILE)); +- fail_exit (3); ++ fail_exit (3, process_selinux); + } + +- if (gr_unlock (true) == 0) { ++ if (gr_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + /* continue */ + } + +- if (sgr_unlock (true) == 0) { ++ if (sgr_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + /* continue */ + +From e7634eac3da8b6a2a046b7e8ab6148d07618c7f5 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Thu, 3 Jul 2025 11:59:32 +0200 +Subject: [PATCH 01/12] src/chsh.c: chroot or prefix SELinux file context + +Do not process SELinux file context during file closure when chroot or +prefix options are selected. + +Signed-off-by: Iker Pedrosa +--- + src/chsh.c | 25 +++++++++++++++++-------- + 1 file changed, 17 insertions(+), 8 deletions(-) + +diff --git a/src/chsh.c b/src/chsh.c +index 4403d412..f460e329 100644 +--- a/src/chsh.c ++++ b/src/chsh.c +@@ -47,6 +47,9 @@ + #define ETCDIR "/etc" + #endif + ++struct option_flags { ++ bool chroot; ++}; + + /* + * Global variables +@@ -66,9 +69,10 @@ NORETURN static void usage (int status); + static void new_fields (void); + static bool shell_is_listed (const char *); + static bool is_restricted_shell (const char *); +-static void process_flags (int argc, char **argv); ++static void process_flags (int argc, char **argv, struct option_flags *flags); + static void check_perms (const struct passwd *pw); +-static void update_shell (const char *user, char *loginsh); ++static void update_shell (const char *user, char *loginsh, ++ struct option_flags *flags); + + /* + * fail_exit - do some cleanup and exit with the given error code +@@ -217,7 +221,7 @@ static bool shell_is_listed (const char *sh) + * + * It will not return if an error is encountered. + */ +-static void process_flags (int argc, char **argv) ++static void process_flags (int argc, char **argv, struct option_flags *flags) + { + int c; + static struct option long_options[] = { +@@ -234,6 +238,7 @@ static void process_flags (int argc, char **argv) + usage (E_SUCCESS); + /*@notreached@*/break; + case 'R': /* no-op, handled in process_root_flag () */ ++ flags->chroot = true; + break; + case 's': + sflg = true; +@@ -359,10 +364,13 @@ static void check_perms (const struct passwd *pw) + * + * It will not return in case of error. + */ +-static void update_shell (const char *user, char *newshell) ++static void update_shell (const char *user, char *newshell, struct option_flags *flags) + { + const struct passwd *pw; /* Password entry from /etc/passwd */ + struct passwd pwent; /* New password entry */ ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot; + + /* + * Before going any further, raise the ulimit to prevent +@@ -428,12 +436,12 @@ static void update_shell (const char *user, char *newshell) + /* + * Changes have all been made, so commit them and unlock the file. + */ +- if (pw_close (true) == 0) { ++ if (pw_close (process_selinux) == 0) { + fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); + fail_exit (1); + } +- if (pw_unlock (true) == 0) { ++ if (pw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +@@ -451,6 +459,7 @@ int main (int argc, char **argv) + { + char *user; /* User name */ + const struct passwd *pw; /* Password entry from /etc/passwd */ ++ struct option_flags flags; + + sanitize_env (); + check_fds (); +@@ -472,7 +481,7 @@ int main (int argc, char **argv) + OPENLOG (Prog); + + /* parse the command line options */ +- process_flags (argc, argv); ++ process_flags (argc, argv, &flags); + + /* + * Get the name of the user to check. It is either the command line +@@ -555,7 +564,7 @@ int main (int argc, char **argv) + } + } + +- update_shell (user, loginsh); ++ update_shell (user, loginsh, &flags); + + SYSLOG ((LOG_INFO, "changed user '%s' shell to '%s'", user, loginsh)); + +-- +2.50.0 + + +From cbcf54b3e5c77a4992bca0ae4f32f0060d120884 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Thu, 3 Jul 2025 12:03:30 +0200 +Subject: [PATCH 02/12] src/chsh.c: SELinux file context for fail_exit() + +Do not process SELinux file context when running fail_exit() when chroot +or prefix options are selected. + +Signed-off-by: Iker Pedrosa +--- + src/chsh.c | 45 +++++++++++++++++++++++++-------------------- + 1 file changed, 25 insertions(+), 20 deletions(-) + +diff --git a/src/chsh.c b/src/chsh.c +index f460e329..77cd30e5 100644 +--- a/src/chsh.c ++++ b/src/chsh.c +@@ -64,13 +64,13 @@ static bool pw_locked = false; + /* external identifiers */ + + /* local function prototypes */ +-NORETURN static void fail_exit (int code); ++NORETURN static void fail_exit (int code, bool process_selinux); + NORETURN static void usage (int status); + static void new_fields (void); + static bool shell_is_listed (const char *); + static bool is_restricted_shell (const char *); + static void process_flags (int argc, char **argv, struct option_flags *flags); +-static void check_perms (const struct passwd *pw); ++static void check_perms (const struct passwd *pw, struct option_flags *flags); + static void update_shell (const char *user, char *loginsh, + struct option_flags *flags); + +@@ -79,10 +79,10 @@ static void update_shell (const char *user, char *loginsh, + */ + NORETURN + static void +-fail_exit (int code) ++fail_exit (int code, bool process_selinux) + { + if (pw_locked) { +- if (pw_unlock (true) == 0) { ++ if (pw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +@@ -268,13 +268,16 @@ static void process_flags (int argc, char **argv, struct option_flags *flags) + * + * It will not return if the user is not allowed. + */ +-static void check_perms (const struct passwd *pw) ++static void check_perms (const struct passwd *pw, struct option_flags *flags) + { + #ifdef USE_PAM + pam_handle_t *pamh = NULL; + int retval; + struct passwd *pampw; + #endif ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot; + + /* + * Non-privileged users are only allowed to change the shell if the +@@ -285,7 +288,7 @@ static void check_perms (const struct passwd *pw) + fprintf (stderr, + _("You may not change the shell for '%s'.\n"), + pw->pw_name); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + + /* +@@ -297,7 +300,7 @@ static void check_perms (const struct passwd *pw) + fprintf (stderr, + _("You may not change the shell for '%s'.\n"), + pw->pw_name); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + #ifdef WITH_SELINUX + /* +@@ -310,7 +313,7 @@ static void check_perms (const struct passwd *pw) + fprintf (stderr, + _("You may not change the shell for '%s'.\n"), + pw->pw_name); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + #endif + +@@ -381,7 +384,7 @@ static void update_shell (const char *user, char *newshell, struct option_flags + if (setuid (0) != 0) { + SYSLOG ((LOG_ERR, "can't setuid(0)")); + fputs (_("Cannot change ID to root.\n"), stderr); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + pwd_init (); + +@@ -392,13 +395,13 @@ static void update_shell (const char *user, char *newshell, struct option_flags + if (pw_lock () == 0) { + fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), + Prog, pw_dbname ()); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + pw_locked = true; + if (pw_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, _("%s: cannot open %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_WARN, "cannot open %s", pw_dbname ())); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + + /* +@@ -412,7 +415,7 @@ static void update_shell (const char *user, char *newshell, struct option_flags + fprintf (stderr, + _("%s: user '%s' does not exist in %s\n"), + Prog, user, pw_dbname ()); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + + /* +@@ -430,7 +433,7 @@ static void update_shell (const char *user, char *newshell, struct option_flags + fprintf (stderr, + _("%s: failed to prepare the new %s entry '%s'\n"), + Prog, pw_dbname (), pwent.pw_name); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + + /* +@@ -439,7 +442,7 @@ static void update_shell (const char *user, char *newshell, struct option_flags + if (pw_close (process_selinux) == 0) { + fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + if (pw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); +@@ -460,6 +463,7 @@ int main (int argc, char **argv) + char *user; /* User name */ + const struct passwd *pw; /* Password entry from /etc/passwd */ + struct option_flags flags; ++ bool process_selinux; + + sanitize_env (); + check_fds (); +@@ -482,6 +486,7 @@ int main (int argc, char **argv) + + /* parse the command line options */ + process_flags (argc, argv, &flags); ++ process_selinux = !flags.chroot; + + /* + * Get the name of the user to check. It is either the command line +@@ -490,14 +495,14 @@ int main (int argc, char **argv) + if (optind < argc) { + if (!is_valid_user_name (argv[optind])) { + fprintf (stderr, _("%s: Provided user name is not a valid name\n"), Prog); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + user = argv[optind]; + pw = xgetpwnam (user); + if (NULL == pw) { + fprintf (stderr, + _("%s: user '%s' does not exist\n"), Prog, user); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + } else { + pw = get_my_pwent (); +@@ -507,12 +512,12 @@ int main (int argc, char **argv) + Prog); + SYSLOG ((LOG_WARN, "Cannot determine the user name of the caller (UID %lu)", + (unsigned long) getuid ())); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + user = xstrdup (pw->pw_name); + } + +- check_perms (pw); ++ check_perms (pw, &flags); + + /* + * Now get the login shell. Either get it from the password +@@ -539,7 +544,7 @@ int main (int argc, char **argv) + */ + if (valid_field (loginsh, ":,=\n") != 0) { + fprintf (stderr, _("%s: Invalid entry: %s\n"), Prog, loginsh); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + if (!streq(loginsh, "") + && (loginsh[0] != '/' +@@ -550,7 +555,7 @@ int main (int argc, char **argv) + fprintf (stderr, _("%s: Warning: %s is an invalid shell\n"), Prog, loginsh); + } else { + fprintf (stderr, _("%s: %s is an invalid shell\n"), Prog, loginsh); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + } + +-- +2.50.0 + + +From 58600326353a2198df7f8753e2ad8ffa216b68cc Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Thu, 3 Jul 2025 12:35:44 +0200 +Subject: [PATCH 03/12] src/passwd.c: chroot or prefix SELinux file context + +Do not process SELinux file context during file closure when chroot or +prefix options are selected. + +Signed-off-by: Iker Pedrosa +--- + src/passwd.c | 41 ++++++++++++++++++++++++++++------------- + 1 file changed, 28 insertions(+), 13 deletions(-) + +diff --git a/src/passwd.c b/src/passwd.c +index 512dc572..6d6f319e 100644 +--- a/src/passwd.c ++++ b/src/passwd.c +@@ -53,6 +53,12 @@ + #define E_PWDBUSY 5 /* passwd file busy, try again later */ + #define E_BAD_ARG 6 /* invalid argument to option */ + #define E_PAM_ERR 10 /* PAM returned an error */ ++ ++struct option_flags { ++ bool chroot; ++ bool prefix; ++}; ++ + /* + * Global variables + */ +@@ -131,9 +137,9 @@ static void print_status (const struct passwd *); + NORETURN static void fail_exit (int); + NORETURN static void oom (void); + static char *update_crypt_pw (char *); +-static void update_noshadow (void); ++static void update_noshadow (struct option_flags *flags); + +-static void update_shadow (void); ++static void update_shadow (struct option_flags *flags); + + /* + * usage - print command usage and exit +@@ -549,10 +555,13 @@ static char *update_crypt_pw (char *cp) + } + + +-static void update_noshadow (void) ++static void update_noshadow (struct option_flags *flags) + { + const struct passwd *pw; + struct passwd *npw; ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot && !flags->prefix; + + if (pw_lock () == 0) { + (void) fprintf (stderr, +@@ -586,14 +595,14 @@ static void update_noshadow (void) + Prog, pw_dbname (), npw->pw_name); + fail_exit (E_FAILURE); + } +- if (pw_close (true) == 0) { ++ if (pw_close (process_selinux) == 0) { + (void) fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); + fail_exit (E_FAILURE); + } +- if (pw_unlock (true) == 0) { ++ if (pw_unlock (process_selinux) == 0) { + (void) fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, pw_dbname ()); +@@ -603,10 +612,13 @@ static void update_noshadow (void) + pw_locked = false; + } + +-static void update_shadow (void) ++static void update_shadow (struct option_flags *flags) + { + const struct spwd *sp; + struct spwd *nsp; ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot && !flags->prefix; + + if (spw_lock () == 0) { + (void) fprintf (stderr, +@@ -625,9 +637,9 @@ static void update_shadow (void) + sp = spw_locate (name); + if (NULL == sp) { + /* Try to update the password in /etc/passwd instead. */ +- (void) spw_close (true); +- update_noshadow (); +- if (spw_unlock (true) == 0) { ++ (void) spw_close (process_selinux); ++ update_noshadow (flags); ++ if (spw_unlock (process_selinux) == 0) { + (void) fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, spw_dbname ()); +@@ -681,14 +693,14 @@ static void update_shadow (void) + Prog, spw_dbname (), nsp->sp_namp); + fail_exit (E_FAILURE); + } +- if (spw_close (true) == 0) { ++ if (spw_close (process_selinux) == 0) { + (void) fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); + fail_exit (E_FAILURE); + } +- if (spw_unlock (true) == 0) { ++ if (spw_unlock (process_selinux) == 0) { + (void) fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, spw_dbname ()); +@@ -733,6 +745,7 @@ main(int argc, char **argv) + char *cp; /* Miscellaneous character pointing */ + + const struct spwd *sp; /* Shadow file entry for user */ ++ struct option_flags flags; + + sanitize_env (); + check_fds (); +@@ -849,8 +862,10 @@ main(int argc, char **argv) + } + break; + case 'R': /* no-op, handled in process_root_flag () */ ++ flags.chroot = true; + break; + case 'P': /* no-op, handled in process_prefix_flag () */ ++ flags.prefix = true; + break; + case 'S': + Sflg = true; /* ok for users */ +@@ -1107,9 +1122,9 @@ main(int argc, char **argv) + exit (E_NOPERM); + } + if (spw_file_present ()) { +- update_shadow (); ++ update_shadow (&flags); + } else { +- update_noshadow (); ++ update_noshadow (&flags); + } + + nscd_flush_cache ("passwd"); +-- +2.50.0 + + +From d5a9144c809e808600c7dc730970efc04bc032fd Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Thu, 3 Jul 2025 12:48:18 +0200 +Subject: [PATCH 04/12] src/passwd.c: SELinux file context for fail_exit() + +Do not process SELinux file context when running fail_exit() when chroot +or prefix options are selected. + +Signed-off-by: Iker Pedrosa +--- + src/passwd.c | 46 ++++++++++++++++++++++++---------------------- + 1 file changed, 24 insertions(+), 22 deletions(-) + +diff --git a/src/passwd.c b/src/passwd.c +index 6d6f319e..78859c96 100644 +--- a/src/passwd.c ++++ b/src/passwd.c +@@ -134,9 +134,9 @@ static int new_password (const struct passwd *); + static void check_password (const struct passwd *, const struct spwd *); + static /*@observer@*/const char *pw_status (const char *); + static void print_status (const struct passwd *); +-NORETURN static void fail_exit (int); +-NORETURN static void oom (void); +-static char *update_crypt_pw (char *); ++NORETURN static void fail_exit (int, bool); ++NORETURN static void oom (bool process_selinux); ++static char *update_crypt_pw (char *, bool); + static void update_noshadow (struct option_flags *flags); + + static void update_shadow (struct option_flags *flags); +@@ -486,10 +486,10 @@ static void print_status (const struct passwd *pw) + + NORETURN + static void +-fail_exit (int status) ++fail_exit (int status, bool process_selinux) + { + if (pw_locked) { +- if (pw_unlock (true) == 0) { ++ if (pw_unlock (process_selinux) == 0) { + (void) fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +@@ -497,7 +497,7 @@ fail_exit (int status) + } + + if (spw_locked) { +- if (spw_unlock (true) == 0) { ++ if (spw_unlock (process_selinux) == 0) { + (void) fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + /* continue */ +@@ -509,13 +509,13 @@ fail_exit (int status) + + NORETURN + static void +-oom (void) ++oom (bool process_selinux) + { + (void) fprintf (stderr, _("%s: out of memory\n"), Prog); +- fail_exit (E_FAILURE); ++ fail_exit (E_FAILURE, process_selinux); + } + +-static char *update_crypt_pw (char *cp) ++static char *update_crypt_pw (char *cp, bool process_selinux) + { + if (!use_pam) + { +@@ -533,7 +533,7 @@ static char *update_crypt_pw (char *cp) + _("%s: unlocking the password would result in a passwordless account.\n" + "You should set a password with usermod -p to unlock the password of this account.\n"), + Prog); +- fail_exit (E_FAILURE); ++ fail_exit (E_FAILURE, process_selinux); + } else { + cp++; + } +@@ -575,32 +575,32 @@ static void update_noshadow (struct option_flags *flags) + _("%s: cannot open %s\n"), + Prog, pw_dbname ()); + SYSLOG ((LOG_WARN, "cannot open %s", pw_dbname ())); +- fail_exit (E_MISSING); ++ fail_exit (E_MISSING, process_selinux); + } + pw = pw_locate (name); + if (NULL == pw) { + (void) fprintf (stderr, + _("%s: user '%s' does not exist in %s\n"), + Prog, name, pw_dbname ()); +- fail_exit (E_NOPERM); ++ fail_exit (E_NOPERM, process_selinux); + } + npw = __pw_dup (pw); + if (NULL == npw) { +- oom (); ++ oom (process_selinux); + } +- npw->pw_passwd = update_crypt_pw (npw->pw_passwd); ++ npw->pw_passwd = update_crypt_pw (npw->pw_passwd, process_selinux); + if (pw_update (npw) == 0) { + (void) fprintf (stderr, + _("%s: failed to prepare the new %s entry '%s'\n"), + Prog, pw_dbname (), npw->pw_name); +- fail_exit (E_FAILURE); ++ fail_exit (E_FAILURE, process_selinux); + } + if (pw_close (process_selinux) == 0) { + (void) fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); +- fail_exit (E_FAILURE); ++ fail_exit (E_FAILURE, process_selinux); + } + if (pw_unlock (process_selinux) == 0) { + (void) fprintf (stderr, +@@ -632,7 +632,7 @@ static void update_shadow (struct option_flags *flags) + _("%s: cannot open %s\n"), + Prog, spw_dbname ()); + SYSLOG ((LOG_WARN, "cannot open %s", spw_dbname ())); +- fail_exit (E_FAILURE); ++ fail_exit (E_FAILURE, process_selinux); + } + sp = spw_locate (name); + if (NULL == sp) { +@@ -651,9 +651,9 @@ static void update_shadow (struct option_flags *flags) + } + nsp = __spw_dup (sp); + if (NULL == nsp) { +- oom (); ++ oom (process_selinux); + } +- nsp->sp_pwdp = update_crypt_pw (nsp->sp_pwdp); ++ nsp->sp_pwdp = update_crypt_pw (nsp->sp_pwdp, process_selinux); + if (xflg) { + nsp->sp_max = age_max; + } +@@ -691,14 +691,14 @@ static void update_shadow (struct option_flags *flags) + (void) fprintf (stderr, + _("%s: failed to prepare the new %s entry '%s'\n"), + Prog, spw_dbname (), nsp->sp_namp); +- fail_exit (E_FAILURE); ++ fail_exit (E_FAILURE, process_selinux); + } + if (spw_close (process_selinux) == 0) { + (void) fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); +- fail_exit (E_FAILURE); ++ fail_exit (E_FAILURE, process_selinux); + } + if (spw_unlock (process_selinux) == 0) { + (void) fprintf (stderr, +@@ -746,6 +746,7 @@ main(int argc, char **argv) + + const struct spwd *sp; /* Shadow file entry for user */ + struct option_flags flags; ++ bool process_selinux; + + sanitize_env (); + check_fds (); +@@ -912,6 +913,7 @@ main(int argc, char **argv) + } + } + } ++ process_selinux = !flags.chroot && !flags.prefix; + + /* + * Now I have to get the user name. The name will be gotten from the +@@ -931,7 +933,7 @@ main(int argc, char **argv) + if (optind < argc) { + if (!is_valid_user_name (argv[optind])) { + fprintf (stderr, _("%s: Provided user name is not a valid name\n"), Prog); +- fail_exit (E_NOPERM); ++ fail_exit (E_NOPERM, process_selinux); + } + name = argv[optind]; + } else { +-- +2.50.0 + + +From a736c2af5702e98081bace5fde10a264f443d318 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Thu, 3 Jul 2025 12:55:35 +0200 +Subject: [PATCH 05/12] src/pwck.c: chroot or prefix SELinux file context + +Do not process SELinux file context during file closure when chroot or +prefix options are selected. + +Signed-off-by: Iker Pedrosa +--- + src/pwck.c | 46 ++++++++++++++++++++++++++++++---------------- + 1 file changed, 30 insertions(+), 16 deletions(-) + +diff --git a/src/pwck.c b/src/pwck.c +index 9c4cc29a..d0f2f1c9 100644 +--- a/src/pwck.c ++++ b/src/pwck.c +@@ -48,6 +48,10 @@ + #define E_CANTUPDATE 5 + #define E_CANTSORT 6 + ++struct option_flags { ++ bool chroot; ++}; ++ + /* + * Global variables + */ +@@ -71,10 +75,11 @@ static bool quiet = false; /* don't report warnings, only errors */ + /* local function prototypes */ + static void fail_exit (int code); + NORETURN static void usage (int status); +-static void process_flags (int argc, char **argv); ++static void process_flags (int argc, char **argv, struct option_flags *flags); + static void open_files (void); +-static void close_files (bool changed); +-static void check_pw_file (bool *errors, bool *changed); ++static void close_files (bool changed, struct option_flags *flags); ++static void check_pw_file (bool *errors, bool *changed, ++ struct option_flags *flags); + static void check_spw_file (bool *errors, bool *changed); + + extern int allow_bad_names; +@@ -155,7 +160,7 @@ usage (int status) + * + * It will not return if an error is encountered. + */ +-static void process_flags (int argc, char **argv) ++static void process_flags (int argc, char **argv, struct option_flags *flags) + { + int c; + static struct option long_options[] = { +@@ -188,6 +193,7 @@ static void process_flags (int argc, char **argv) + read_only = true; + break; + case 'R': /* no-op, handled in process_root_flag () */ ++ flags->chroot = true; + break; + case 's': + sort_mode = true; +@@ -302,14 +308,18 @@ static void open_files (void) + * changes are committed in the databases. The databases are + * unlocked anyway. + */ +-static void close_files (bool changed) ++static void close_files (bool changed, struct option_flags *flags) + { ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot; ++ + /* + * All done. If there were no change we can just abandon any + * changes to the files. + */ + if (changed) { +- if (pw_close (true) == 0) { ++ if (pw_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, pw_dbname ()); +@@ -320,7 +330,7 @@ static void close_files (bool changed) + } + fail_exit (E_CANTUPDATE); + } +- if (spw_opened && (spw_close (true) == 0)) { ++ if (spw_opened && (spw_close (process_selinux) == 0)) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, spw_dbname ()); +@@ -338,7 +348,7 @@ static void close_files (bool changed) + * Don't be anti-social - unlock the files when you're done. + */ + if (spw_locked) { +- if (spw_unlock (true) == 0) { ++ if (spw_unlock (process_selinux) == 0) { + fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, spw_dbname ()); +@@ -351,7 +361,7 @@ static void close_files (bool changed) + } + spw_locked = false; + if (pw_locked) { +- if (pw_unlock (true) == 0) { ++ if (pw_unlock (process_selinux) == 0) { + fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, pw_dbname ()); +@@ -368,13 +378,16 @@ static void close_files (bool changed) + /* + * check_pw_file - check the content of the passwd file + */ +-static void check_pw_file (bool *errors, bool *changed) ++static void check_pw_file (bool *errors, bool *changed, struct option_flags *flags) + { + struct commonio_entry *pfe, *tpfe; + struct passwd *pwd; + const struct spwd *spw; + uid_t min_sys_id = getdef_ulong ("SYS_UID_MIN", 101UL); + uid_t max_sys_id = getdef_ulong ("SYS_UID_MAX", 999UL); ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot; + + /* + * Loop through the entire password file. +@@ -581,7 +594,7 @@ static void check_pw_file (bool *errors, bool *changed) + _("%s: cannot open %s\n"), + Prog, spw_dbname ()); + *errors = true; +- if (spw_unlock (true) == 0) { ++ if (spw_unlock (process_selinux) == 0) { + fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, spw_dbname ()); +@@ -657,7 +670,7 @@ static void check_pw_file (bool *errors, bool *changed) + } + #ifdef WITH_TCB + if (getdef_bool ("USE_TCB") && spw_locked) { +- if (spw_opened && (spw_close (true) == 0)) { ++ if (spw_opened && (spw_close (process_selinux) == 0)) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, spw_dbname ()); +@@ -669,7 +682,7 @@ static void check_pw_file (bool *errors, bool *changed) + } else { + spw_opened = false; + } +- if (spw_unlock (true) == 0) { ++ if (spw_unlock (process_selinux) == 0) { + fprintf (stderr, + _("%s: failed to unlock %s\n"), + Prog, spw_dbname ()); +@@ -840,6 +853,7 @@ int main (int argc, char **argv) + { + bool errors = false; + bool changed = false; ++ struct option_flags flags; + + log_set_progname(Prog); + log_set_logfd(stderr); +@@ -853,7 +867,7 @@ int main (int argc, char **argv) + OPENLOG (Prog); + + /* Parse the command line arguments */ +- process_flags (argc, argv); ++ process_flags (argc, argv, &flags); + + open_files (); + +@@ -874,14 +888,14 @@ int main (int argc, char **argv) + } + changed = true; + } else { +- check_pw_file (&errors, &changed); ++ check_pw_file (&errors, &changed, &flags); + + if (is_shadow) { + check_spw_file (&errors, &changed); + } + } + +- close_files (changed); ++ close_files (changed, &flags); + + if (!read_only) { + nscd_flush_cache ("passwd"); +-- +2.50.0 + + +From 09957a9748ae6cd28e0826d4cacd939ac288ca1b Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Thu, 3 Jul 2025 12:58:58 +0200 +Subject: [PATCH 06/12] src/pwck.c: SELinux file context for fail_exit() + +Do not process SELinux file context when running fail_exit() when chroot +or prefix options are selected. + +Signed-off-by: Iker Pedrosa +--- + src/pwck.c | 39 ++++++++++++++++++++++----------------- + 1 file changed, 22 insertions(+), 17 deletions(-) + +diff --git a/src/pwck.c b/src/pwck.c +index d0f2f1c9..f1e9c085 100644 +--- a/src/pwck.c ++++ b/src/pwck.c +@@ -73,10 +73,10 @@ static bool sort_mode = false; + static bool quiet = false; /* don't report warnings, only errors */ + + /* local function prototypes */ +-static void fail_exit (int code); ++static void fail_exit (int code, bool process_selinux); + NORETURN static void usage (int status); + static void process_flags (int argc, char **argv, struct option_flags *flags); +-static void open_files (void); ++static void open_files (struct option_flags *flags); + static void close_files (bool changed, struct option_flags *flags); + static void check_pw_file (bool *errors, bool *changed, + struct option_flags *flags); +@@ -87,10 +87,10 @@ extern int allow_bad_names; + /* + * fail_exit - do some cleanup and exit with the given error code + */ +-static void fail_exit (int code) ++static void fail_exit (int code, bool process_selinux) + { + if (spw_locked) { +- if (spw_unlock (true) == 0) { ++ if (spw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); + if (use_system_spw_file) { + SYSLOG ((LOG_ERR, "failed to unlock %s", +@@ -101,7 +101,7 @@ static void fail_exit (int code) + } + + if (pw_locked) { +- if (pw_unlock (true) == 0) { ++ if (pw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + if (use_system_pw_file) { + SYSLOG ((LOG_ERR, "failed to unlock %s", +@@ -246,12 +246,15 @@ static void process_flags (int argc, char **argv, struct option_flags *flags) + * In read-only mode, the databases are not locked and are opened + * only for reading. + */ +-static void open_files (void) ++static void open_files (struct option_flags *flags) + { + bool use_tcb = false; + #ifdef WITH_TCB + use_tcb = getdef_bool ("USE_TCB"); + #endif /* WITH_TCB */ ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot; + + /* + * Lock the files if we aren't in "read-only" mode +@@ -261,7 +264,7 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, pw_dbname ()); +- fail_exit (E_CANTLOCK); ++ fail_exit (E_CANTLOCK, process_selinux); + } + pw_locked = true; + if (is_shadow && !use_tcb) { +@@ -269,7 +272,7 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, spw_dbname ()); +- fail_exit (E_CANTLOCK); ++ fail_exit (E_CANTLOCK, process_selinux); + } + spw_locked = true; + } +@@ -285,7 +288,7 @@ static void open_files (void) + if (use_system_pw_file) { + SYSLOG ((LOG_WARN, "cannot open %s", pw_dbname ())); + } +- fail_exit (E_CANTOPEN); ++ fail_exit (E_CANTOPEN, process_selinux); + } + if (is_shadow && !use_tcb) { + if (spw_open (read_only ? O_RDONLY : O_RDWR) == 0) { +@@ -295,7 +298,7 @@ static void open_files (void) + SYSLOG ((LOG_WARN, "cannot open %s", + spw_dbname ())); + } +- fail_exit (E_CANTOPEN); ++ fail_exit (E_CANTOPEN, process_selinux); + } + spw_opened = true; + } +@@ -328,7 +331,7 @@ static void close_files (bool changed, struct option_flags *flags) + "failure while writing changes to %s", + pw_dbname ())); + } +- fail_exit (E_CANTUPDATE); ++ fail_exit (E_CANTUPDATE, process_selinux); + } + if (spw_opened && (spw_close (process_selinux) == 0)) { + fprintf (stderr, +@@ -339,7 +342,7 @@ static void close_files (bool changed, struct option_flags *flags) + "failure while writing changes to %s", + spw_dbname ())); + } +- fail_exit (E_CANTUPDATE); ++ fail_exit (E_CANTUPDATE, process_selinux); + } + spw_opened = false; + } +@@ -644,7 +647,7 @@ static void check_pw_file (bool *errors, bool *changed, struct option_flags *fla + fprintf (stderr, + _("%s: failed to prepare the new %s entry '%s'\n"), + Prog, spw_dbname (), sp.sp_namp); +- fail_exit (E_CANTUPDATE); ++ fail_exit (E_CANTUPDATE, process_selinux); + } + /* remove password from /etc/passwd */ + pw = *pwd; +@@ -653,7 +656,7 @@ static void check_pw_file (bool *errors, bool *changed, struct option_flags *fla + fprintf (stderr, + _("%s: failed to prepare the new %s entry '%s'\n"), + Prog, pw_dbname (), pw.pw_name); +- fail_exit (E_CANTUPDATE); ++ fail_exit (E_CANTUPDATE, process_selinux); + } + } + } else { +@@ -854,6 +857,7 @@ int main (int argc, char **argv) + bool errors = false; + bool changed = false; + struct option_flags flags; ++ bool process_selinux; + + log_set_progname(Prog); + log_set_logfd(stderr); +@@ -868,22 +872,23 @@ int main (int argc, char **argv) + + /* Parse the command line arguments */ + process_flags (argc, argv, &flags); ++ process_selinux = !flags.chroot; + +- open_files (); ++ open_files (&flags); + + if (sort_mode) { + if (pw_sort () != 0) { + fprintf (stderr, + _("%s: cannot sort entries in %s\n"), + Prog, pw_dbname ()); +- fail_exit (E_CANTSORT); ++ fail_exit (E_CANTSORT, process_selinux); + } + if (is_shadow) { + if (spw_sort () != 0) { + fprintf (stderr, + _("%s: cannot sort entries in %s\n"), + Prog, spw_dbname ()); +- fail_exit (E_CANTSORT); ++ fail_exit (E_CANTSORT, process_selinux); + } + } + changed = true; +-- +2.50.0 + + +From 0c39283e9298fc130c55516fd0a4a0c6b6003bc9 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Thu, 3 Jul 2025 13:04:26 +0200 +Subject: [PATCH 07/12] src/pwconv.c: chroot or prefix SELinux file context + +Do not process SELinux file context during file closure when chroot or +prefix options are selected. + +Signed-off-by: Iker Pedrosa +--- + src/pwconv.c | 23 ++++++++++++++++------- + 1 file changed, 16 insertions(+), 7 deletions(-) + +diff --git a/src/pwconv.c b/src/pwconv.c +index b0d668b5..6c81cc6e 100644 +--- a/src/pwconv.c ++++ b/src/pwconv.c +@@ -67,6 +67,11 @@ + #define E_MISSING 4 /* unexpected failure, passwd file missing */ + #define E_PWDBUSY 5 /* passwd file(s) busy */ + #define E_BADENTRY 6 /* bad shadow entry */ ++ ++struct option_flags { ++ bool chroot; ++}; ++ + /* + * Global variables + */ +@@ -78,7 +83,7 @@ static bool pw_locked = false; + /* local function prototypes */ + static void fail_exit (int status); + static void usage (int status); +-static void process_flags (int argc, char **argv); ++static void process_flags (int argc, char **argv, struct option_flags *flags); + + static void fail_exit (int status) + { +@@ -120,7 +125,7 @@ static void usage (int status) + * + * It will not return if an error is encountered. + */ +-static void process_flags (int argc, char **argv) ++static void process_flags (int argc, char **argv, struct option_flags *flags) + { + /* + * Parse the command line options. +@@ -139,6 +144,7 @@ static void process_flags (int argc, char **argv) + usage (E_SUCCESS); + /*@notreached@*/break; + case 'R': /* no-op, handled in process_root_flag () */ ++ flags->chroot = true; + break; + default: + usage (E_USAGE); +@@ -156,6 +162,8 @@ int main (int argc, char **argv) + struct passwd pwent; + const struct spwd *sp; + struct spwd spent; ++ struct option_flags flags; ++ bool process_selinux; + + log_set_progname(Prog); + log_set_logfd(stderr); +@@ -168,7 +176,8 @@ int main (int argc, char **argv) + + OPENLOG (Prog); + +- process_flags (argc, argv); ++ process_flags (argc, argv, &flags); ++ process_selinux = !flags.chroot; + + #ifdef WITH_TCB + if (getdef_bool("USE_TCB")) { +@@ -274,14 +283,14 @@ int main (int argc, char **argv) + } + } + +- if (spw_close (true) == 0) { ++ if (spw_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); + fail_exit (E_FAILURE); + } +- if (pw_close (true) == 0) { ++ if (pw_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, pw_dbname ()); +@@ -299,13 +308,13 @@ int main (int argc, char **argv) + /* continue */ + } + +- if (pw_unlock (true) == 0) { ++ if (pw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ + } + +- if (spw_unlock (true) == 0) { ++ if (spw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + /* continue */ +-- +2.50.0 + + +From 997a523d41bb513f37ca88cab35cba9281f036b6 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Thu, 3 Jul 2025 13:05:52 +0200 +Subject: [PATCH 08/12] src/pwconv.c: SELinux file context for fail_exit() + +Do not process SELinux file context when running fail_exit() when chroot +or prefix options are selected. + +Signed-off-by: Iker Pedrosa +--- + src/pwconv.c | 26 +++++++++++++------------- + 1 file changed, 13 insertions(+), 13 deletions(-) + +diff --git a/src/pwconv.c b/src/pwconv.c +index 6c81cc6e..1dc1fd86 100644 +--- a/src/pwconv.c ++++ b/src/pwconv.c +@@ -81,14 +81,14 @@ static bool spw_locked = false; + static bool pw_locked = false; + + /* local function prototypes */ +-static void fail_exit (int status); ++static void fail_exit (int status, bool process_selinux); + static void usage (int status); + static void process_flags (int argc, char **argv, struct option_flags *flags); + +-static void fail_exit (int status) ++static void fail_exit (int status, bool process_selinux) + { + if (pw_locked) { +- if (pw_unlock (true) == 0) { ++ if (pw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +@@ -96,7 +96,7 @@ static void fail_exit (int status) + } + + if (spw_locked) { +- if (spw_unlock (true) == 0) { ++ if (spw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + /* continue */ +@@ -190,26 +190,26 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, pw_dbname ()); +- fail_exit (E_PWDBUSY); ++ fail_exit (E_PWDBUSY, process_selinux); + } + pw_locked = true; + if (pw_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, + _("%s: cannot open %s\n"), Prog, pw_dbname ()); +- fail_exit (E_MISSING); ++ fail_exit (E_MISSING, process_selinux); + } + + if (spw_lock () == 0) { + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, spw_dbname ()); +- fail_exit (E_PWDBUSY); ++ fail_exit (E_PWDBUSY, process_selinux); + } + spw_locked = true; + if (spw_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, + _("%s: cannot open %s\n"), Prog, spw_dbname ()); +- fail_exit (E_FAILURE); ++ fail_exit (E_FAILURE, process_selinux); + } + + /* +@@ -228,7 +228,7 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: cannot remove entry '%s' from %s\n"), + Prog, sp->sp_namp, spw_dbname ()); +- fail_exit (E_FAILURE); ++ fail_exit (E_FAILURE, process_selinux); + } + (void) spw_rewind(); + } +@@ -269,7 +269,7 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: failed to prepare the new %s entry '%s'\n"), + Prog, spw_dbname (), spent.sp_namp); +- fail_exit (E_FAILURE); ++ fail_exit (E_FAILURE, process_selinux); + } + + /* remove password from /etc/passwd */ +@@ -279,7 +279,7 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: failed to prepare the new %s entry '%s'\n"), + Prog, pw_dbname (), pwent.pw_name); +- fail_exit (E_FAILURE); ++ fail_exit (E_FAILURE, process_selinux); + } + } + +@@ -288,14 +288,14 @@ int main (int argc, char **argv) + _("%s: failure while writing changes to %s\n"), + Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); +- fail_exit (E_FAILURE); ++ fail_exit (E_FAILURE, process_selinux); + } + if (pw_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); +- fail_exit (E_FAILURE); ++ fail_exit (E_FAILURE, process_selinux); + } + + /* /etc/passwd- (backup file) */ +-- +2.50.0 + + +From 13e902a1b368049cb4c6853a7470f66efbac6e72 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Thu, 3 Jul 2025 13:08:10 +0200 +Subject: [PATCH 09/12] src/pwunconv.c: chroot or prefix SELinux file context + +Do not process SELinux file context during file closure when chroot or +prefix options are selected. + +Signed-off-by: Iker Pedrosa +--- + src/pwunconv.c | 21 ++++++++++++++------- + 1 file changed, 14 insertions(+), 7 deletions(-) + +diff --git a/src/pwunconv.c b/src/pwunconv.c +index 7a6d2be5..d46bde6d 100644 +--- a/src/pwunconv.c ++++ b/src/pwunconv.c +@@ -30,6 +30,9 @@ + #include "sssd.h" + #include "string/strcmp/streq.h" + ++struct option_flags { ++ bool chroot; ++}; + + /* + * Global variables +@@ -42,7 +45,7 @@ static bool pw_locked = false; + /* local function prototypes */ + static void fail_exit (int status); + static void usage (int status); +-static void process_flags (int argc, char **argv); ++static void process_flags (int argc, char **argv, struct option_flags *flags); + + static void fail_exit (int status) + { +@@ -82,7 +85,7 @@ static void usage (int status) + * + * It will not return if an error is encountered. + */ +-static void process_flags (int argc, char **argv) ++static void process_flags (int argc, char **argv, struct option_flags *flags) + { + /* + * Parse the command line options. +@@ -101,6 +104,7 @@ static void process_flags (int argc, char **argv) + usage (E_SUCCESS); + /*@notreached@*/break; + case 'R': /* no-op, handled in process_root_flag () */ ++ flags->chroot = true; + break; + default: + usage (E_USAGE); +@@ -117,6 +121,8 @@ int main (int argc, char **argv) + const struct passwd *pw; + struct passwd pwent; + const struct spwd *spwd; ++ struct option_flags flags; ++ bool process_selinux; + + log_set_progname(Prog); + log_set_logfd(stderr); +@@ -129,7 +135,8 @@ int main (int argc, char **argv) + + OPENLOG (Prog); + +- process_flags (argc, argv); ++ process_flags (argc, argv, &flags); ++ process_selinux = !flags.chroot; + + #ifdef WITH_TCB + if (getdef_bool("USE_TCB")) { +@@ -205,9 +212,9 @@ int main (int argc, char **argv) + } + } + +- (void) spw_close (true); /* was only open O_RDONLY */ ++ (void) spw_close (process_selinux); /* was only open O_RDONLY */ + +- if (pw_close (true) == 0) { ++ if (pw_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, pw_dbname ()); +@@ -222,12 +229,12 @@ int main (int argc, char **argv) + fail_exit (3); + } + +- if (spw_unlock (true) == 0) { ++ if (spw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + /* continue */ + } +- if (pw_unlock (true) == 0) { ++ if (pw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +-- +2.50.0 + + +From 849e748fe08129684da13acba13a247f0aa98eff Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Thu, 3 Jul 2025 13:09:12 +0200 +Subject: [PATCH 10/12] src/pwunconv.c: SELinux file context for fail_exit() + +Do not process SELinux file context when running fail_exit() when chroot +or prefix options are selected. + +Signed-off-by: Iker Pedrosa +--- + src/pwunconv.c | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +diff --git a/src/pwunconv.c b/src/pwunconv.c +index d46bde6d..d3e10f68 100644 +--- a/src/pwunconv.c ++++ b/src/pwunconv.c +@@ -43,21 +43,21 @@ static bool spw_locked = false; + static bool pw_locked = false; + + /* local function prototypes */ +-static void fail_exit (int status); ++static void fail_exit (int status, bool process_selinux); + static void usage (int status); + static void process_flags (int argc, char **argv, struct option_flags *flags); + +-static void fail_exit (int status) ++static void fail_exit (int status, bool process_selinux) + { + if (spw_locked) { +- if (spw_unlock (true) == 0) { ++ if (spw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + /* continue */ + } + } + if (pw_locked) { +- if (pw_unlock (true) == 0) { ++ if (pw_unlock (process_selinux) == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + /* continue */ +@@ -154,28 +154,28 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, pw_dbname ()); +- fail_exit (5); ++ fail_exit (5, process_selinux); + } + pw_locked = true; + if (pw_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, + _("%s: cannot open %s\n"), + Prog, pw_dbname ()); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + + if (spw_lock () == 0) { + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, spw_dbname ()); +- fail_exit (5); ++ fail_exit (5, process_selinux); + } + spw_locked = true; + if (spw_open (O_RDONLY) == 0) { + fprintf (stderr, + _("%s: cannot open %s\n"), + Prog, spw_dbname ()); +- fail_exit (1); ++ fail_exit (1, process_selinux); + } + + (void) pw_rewind (); +@@ -208,7 +208,7 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: failed to prepare the new %s entry '%s'\n"), + Prog, pw_dbname (), pwent.pw_name); +- fail_exit (3); ++ fail_exit (3, process_selinux); + } + } + +@@ -219,14 +219,14 @@ int main (int argc, char **argv) + _("%s: failure while writing changes to %s\n"), + Prog, pw_dbname ()); + SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); +- fail_exit (3); ++ fail_exit (3, process_selinux); + } + + if (unlink (SHADOW) != 0) { + fprintf (stderr, + _("%s: cannot delete %s\n"), Prog, SHADOW); + SYSLOG ((LOG_ERR, "cannot delete %s", SHADOW)); +- fail_exit (3); ++ fail_exit (3, process_selinux); + } + + if (spw_unlock (process_selinux) == 0) { +-- +2.50.0 + + +From b1bcf1cf8245b195cff7586770ad861f89cb7c92 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Thu, 3 Jul 2025 14:29:55 +0200 +Subject: [PATCH 11/12] src/gpasswd.c: chroot or prefix SELinux file context + +Do not process SELinux file context during file closure when chroot or +prefix options are selected. + +Signed-off-by: Iker Pedrosa +--- + src/gpasswd.c | 44 ++++++++++++++++++++++++++++---------------- + 1 file changed, 28 insertions(+), 16 deletions(-) + +diff --git a/src/gpasswd.c b/src/gpasswd.c +index a49b9140..94b2bb32 100644 +--- a/src/gpasswd.c ++++ b/src/gpasswd.c +@@ -40,6 +40,9 @@ + #include "string/strcpy/strtcpy.h" + #include "string/strdup/xstrdup.h" + ++struct option_flags { ++ bool chroot; ++}; + + /* + * Global variables +@@ -87,17 +90,17 @@ NORETURN static void failure(void); + static void usage (int status); + static void catch_signals (int killed); + static bool is_valid_user_list (const char *users); +-static void process_flags (int argc, char **argv); ++static void process_flags (int argc, char **argv, struct option_flags *flags); + static void check_flags (int argc, int opt_index); + static void open_files (void); +-static void close_files (void); ++static void close_files (struct option_flags *flags); + #ifdef SHADOWGRP +-static void get_group (struct group *gr, struct sgrp *sg); ++static void get_group (struct group *gr, struct sgrp *sg, struct option_flags *flags); + static void check_perms (const struct group *gr, const struct sgrp *sg); + static void update_group (struct group *gr, struct sgrp *sg); + static void change_passwd (struct group *gr, struct sgrp *sg); + #else +-static void get_group (struct group *gr); ++static void get_group (struct group *gr, struct option_flags *flags); + static void check_perms (const struct group *gr); + static void update_group (struct group *gr); + static void change_passwd (struct group *gr); +@@ -211,7 +214,7 @@ static void failure(void) + /* + * process_flags - process the command line options and arguments + */ +-static void process_flags (int argc, char **argv) ++static void process_flags (int argc, char **argv, struct option_flags *flags) + { + int c; + static struct option long_options[] = { +@@ -272,6 +275,7 @@ static void process_flags (int argc, char **argv) + Mflg = true; + break; + case 'Q': /* no-op, handled in process_root_flag () */ ++ flags->chroot = true; + break; + case 'r': /* remove group password */ + rflg = true; +@@ -591,9 +595,13 @@ static void log_gpasswd_success_group (MAYBE_UNUSED void *arg) + * + * It will call exit in case of error. + */ +-static void close_files (void) ++static void close_files (struct option_flags *flags) + { +- if (gr_close (true) == 0) { ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot; ++ ++ if (gr_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, gr_dbname ()); +@@ -607,7 +615,7 @@ static void close_files (void) + + #ifdef SHADOWGRP + if (is_shadowgrp) { +- if (sgr_close (true) == 0) { ++ if (sgr_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, sgr_dbname ()); +@@ -695,15 +703,18 @@ static void update_group (struct group *gr) + * Note: If !is_shadowgrp, *sg will not be initialized. + */ + #ifdef SHADOWGRP +-static void get_group (struct group *gr, struct sgrp *sg) ++static void get_group (struct group *gr, struct sgrp *sg, struct option_flags *flags) + #else +-static void get_group (struct group *gr) ++static void get_group (struct group *gr, struct option_flags *flags) + #endif + { + struct group const*tmpgr = NULL; + #ifdef SHADOWGRP + struct sgrp const*tmpsg = NULL; + #endif ++ bool process_selinux; ++ ++ process_selinux = !flags->chroot; + + if (gr_open (O_RDONLY) == 0) { + fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ()); +@@ -724,7 +735,7 @@ static void get_group (struct group *gr) + gr->gr_passwd = xstrdup (tmpgr->gr_passwd); + gr->gr_mem = dup_list (tmpgr->gr_mem); + +- if (gr_close (true) == 0) { ++ if (gr_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while closing read-only %s\n"), + Prog, gr_dbname ()); +@@ -762,7 +773,7 @@ static void get_group (struct group *gr) + sg->sg_adm[0] = NULL; + + } +- if (sgr_close (true) == 0) { ++ if (sgr_close (process_selinux) == 0) { + fprintf (stderr, + _("%s: failure while closing read-only %s\n"), + Prog, sgr_dbname ()); +@@ -864,6 +875,7 @@ int main (int argc, char **argv) + struct sgrp sgent; + #endif + struct passwd *pw = NULL; ++ struct option_flags flags; + + #ifdef WITH_AUDIT + audit_help_open (); +@@ -924,15 +936,15 @@ int main (int argc, char **argv) + } + + /* Parse the options */ +- process_flags (argc, argv); ++ process_flags (argc, argv, &flags); + + /* + * Replicate the group so it can be modified later on. + */ + #ifdef SHADOWGRP +- get_group (&grent, &sgent); ++ get_group (&grent, &sgent, &flags); + #else +- get_group (&grent); ++ get_group (&grent, &flags); + #endif + + /* +@@ -1095,7 +1107,7 @@ int main (int argc, char **argv) + update_group (&grent); + #endif + +- close_files (); ++ close_files (&flags); + + nscd_flush_cache ("group"); + sssd_flush_cache (SSSD_DB_GROUP); +-- +2.50.0 + + +From 2c250fae8866a682bac686dcaa198b325d198cf9 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Fri, 4 Jul 2025 10:03:42 +0200 +Subject: [PATCH 12/12] man/: update `--root` flag with no SELinux support + +Signed-off-by: Iker Pedrosa +--- + man/chage.1.xml | 1 + + man/chfn.1.xml | 1 + + man/chgpasswd.8.xml | 1 + + man/chpasswd.8.xml | 1 + + man/chsh.1.xml | 1 + + man/faillog.8.xml | 1 + + man/gpasswd.1.xml | 1 + + man/groupadd.8.xml | 1 + + man/groupdel.8.xml | 1 + + man/groupmems.8.xml | 1 + + man/groupmod.8.xml | 1 + + man/grpck.8.xml | 1 + + man/lastlog.8.xml | 1 + + man/newusers.8.xml | 1 + + man/passwd.1.xml | 1 + + man/pwck.8.xml | 1 + + man/pwconv.8.xml | 1 + + man/useradd.8.xml | 1 + + man/userdel.8.xml | 1 + + man/usermod.8.xml | 1 + + man/vipw.8.xml | 1 + + 21 files changed, 21 insertions(+) + +diff --git a/man/chage.1.xml b/man/chage.1.xml +index 4ccdf483..a3fff291 100644 +--- a/man/chage.1.xml ++++ b/man/chage.1.xml +@@ -205,6 +205,7 @@ + directory and use the configuration files from the + CHROOT_DIR directory. + Only absolute paths are supported. ++ No SELINUX support. + + + +diff --git a/man/chfn.1.xml b/man/chfn.1.xml +index 2fa49feb..d199ef03 100644 +--- a/man/chfn.1.xml ++++ b/man/chfn.1.xml +@@ -138,6 +138,7 @@ + Apply changes in the CHROOT_DIR + directory and use the configuration files from the + CHROOT_DIR directory. ++ No SELINUX support. + + + +diff --git a/man/chgpasswd.8.xml b/man/chgpasswd.8.xml +index f4a83c24..184c1696 100644 +--- a/man/chgpasswd.8.xml ++++ b/man/chgpasswd.8.xml +@@ -134,6 +134,7 @@ + directory and use the configuration files from the + CHROOT_DIR directory. + Only absolute paths are supported. ++ No SELINUX support. + + + +diff --git a/man/chpasswd.8.xml b/man/chpasswd.8.xml +index cffd9df1..440c8342 100644 +--- a/man/chpasswd.8.xml ++++ b/man/chpasswd.8.xml +@@ -176,6 +176,7 @@ + directory and use the configuration files from the + CHROOT_DIR directory. + Only absolute paths are supported. ++ No SELINUX support. + + + +diff --git a/man/chsh.1.xml b/man/chsh.1.xml +index db2d0ceb..8f253731 100644 +--- a/man/chsh.1.xml ++++ b/man/chsh.1.xml +@@ -89,6 +89,7 @@ + directory and use the configuration files from the + CHROOT_DIR directory. + Only absolute paths are supported. ++ No SELINUX support. + + + +diff --git a/man/faillog.8.xml b/man/faillog.8.xml +index effe43a9..7d453fd2 100644 +--- a/man/faillog.8.xml ++++ b/man/faillog.8.xml +@@ -162,6 +162,7 @@ + directory and use the configuration files from the + CHROOT_DIR directory. + Only absolute paths are supported. ++ No SELINUX support. + + + +diff --git a/man/gpasswd.1.xml b/man/gpasswd.1.xml +index 9b89d915..f918442f 100644 +--- a/man/gpasswd.1.xml ++++ b/man/gpasswd.1.xml +@@ -165,6 +165,7 @@ + directory and use the configuration files from the + CHROOT_DIR directory. + Only absolute paths are supported. ++ No SELINUX support. + + + +diff --git a/man/groupadd.8.xml b/man/groupadd.8.xml +index 9abf159a..2dea7ae5 100644 +--- a/man/groupadd.8.xml ++++ b/man/groupadd.8.xml +@@ -206,6 +206,7 @@ + directory and use the configuration files from the + CHROOT_DIR directory. + Only absolute paths are supported. ++ No SELINUX support. + + + +diff --git a/man/groupdel.8.xml b/man/groupdel.8.xml +index 8d41b883..31f29994 100644 +--- a/man/groupdel.8.xml ++++ b/man/groupdel.8.xml +@@ -94,6 +94,7 @@ + directory and use the configuration files from the + CHROOT_DIR directory. + Only absolute paths are supported. ++ No SELINUX support. + + + +diff --git a/man/groupmems.8.xml b/man/groupmems.8.xml +index cbc84622..0def6c99 100644 +--- a/man/groupmems.8.xml ++++ b/man/groupmems.8.xml +@@ -147,6 +147,7 @@ + directory and use the configuration files from the + CHROOT_DIR directory. + Only absolute paths are supported. ++ No SELINUX support. + + + +diff --git a/man/groupmod.8.xml b/man/groupmod.8.xml +index 2d51f271..ca287441 100644 +--- a/man/groupmod.8.xml ++++ b/man/groupmod.8.xml +@@ -169,6 +169,7 @@ + directory and use the configuration files from the + CHROOT_DIR directory. + Only absolute paths are supported. ++ No SELINUX support. + + + +diff --git a/man/grpck.8.xml b/man/grpck.8.xml +index 31aa6ca3..9feb190e 100644 +--- a/man/grpck.8.xml ++++ b/man/grpck.8.xml +@@ -154,6 +154,7 @@ + directory and use the configuration files from the + CHROOT_DIR directory. + Only absolute paths are supported. ++ No SELINUX support. + + + +diff --git a/man/lastlog.8.xml b/man/lastlog.8.xml +index cefe5ac2..b0589203 100644 +--- a/man/lastlog.8.xml ++++ b/man/lastlog.8.xml +@@ -109,6 +109,7 @@ + directory and use the configuration files from the + CHROOT_DIR directory. + Only absolute paths are supported. ++ No SELINUX support. + + + +diff --git a/man/newusers.8.xml b/man/newusers.8.xml +index 6812c750..e0380608 100644 +--- a/man/newusers.8.xml ++++ b/man/newusers.8.xml +@@ -313,6 +313,7 @@ + directory and use the configuration files from the + CHROOT_DIR directory. + Only absolute paths are supported. ++ No SELINUX support. + + + +diff --git a/man/passwd.1.xml b/man/passwd.1.xml +index 65dca040..def35609 100644 +--- a/man/passwd.1.xml ++++ b/man/passwd.1.xml +@@ -279,6 +279,7 @@ + directory and use the configuration files from the + CHROOT_DIR directory. + Only absolute paths are supported. ++ No SELINUX support. + + + +diff --git a/man/pwck.8.xml b/man/pwck.8.xml +index 4eb820d6..998bb44a 100644 +--- a/man/pwck.8.xml ++++ b/man/pwck.8.xml +@@ -202,6 +202,7 @@ + directory and use the configuration files from the + CHROOT_DIR directory. + Only absolute paths are supported. ++ No SELINUX support. + + + +diff --git a/man/pwconv.8.xml b/man/pwconv.8.xml +index c4aedef6..9be3f7c5 100644 +--- a/man/pwconv.8.xml ++++ b/man/pwconv.8.xml +@@ -183,6 +183,7 @@ + directory and use the configuration files from the + CHROOT_DIR directory. + Only absolute paths are supported. ++ No SELINUX support. + + + +diff --git a/man/useradd.8.xml b/man/useradd.8.xml +index fd9ff697..e6db7f6d 100644 +--- a/man/useradd.8.xml ++++ b/man/useradd.8.xml +@@ -515,6 +515,7 @@ + directory and use the configuration files from the + CHROOT_DIR directory. + Only absolute paths are supported. ++ No SELINUX support. + + + +diff --git a/man/userdel.8.xml b/man/userdel.8.xml +index 32851f11..de8eff24 100644 +--- a/man/userdel.8.xml ++++ b/man/userdel.8.xml +@@ -120,6 +120,7 @@ + directory and use the configuration files from the + CHROOT_DIR directory. + Only absolute paths are supported. ++ No SELINUX support. + + + +diff --git a/man/usermod.8.xml b/man/usermod.8.xml +index 61b5e3a9..2c704ab5 100644 +--- a/man/usermod.8.xml ++++ b/man/usermod.8.xml +@@ -337,6 +337,7 @@ + directory and use the configuration files from the + CHROOT_DIR directory. + Only absolute paths are supported. ++ No SELINUX support. + + + +diff --git a/man/vipw.8.xml b/man/vipw.8.xml +index fb80582b..975fba37 100644 +--- a/man/vipw.8.xml ++++ b/man/vipw.8.xml +@@ -120,6 +120,7 @@ + directory and use the configuration files from the + CHROOT_DIR directory. + Only absolute paths are supported. ++ No SELINUX support. + + + +-- +2.50.0 + diff --git a/shadow-utils.spec b/shadow-utils.spec index 34baef4..e406acd 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.18.0 -Release: 3%{?dist} +Release: 4%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -24,6 +24,8 @@ Source7: passwd.pamd Patch0: shadow-4.15.0-manfix.patch # Probably non-upstreamable Patch1: shadow-4.18.0-account-tools-setuid.patch +# https://github.com/shadow-maint/shadow/commit/db0e0b9112332a45131912021317ab5ab4fd6e40 +Patch2: shadow-4.18.0-selinux-chroot-prefix.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -269,6 +271,10 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Fri Oct 31 2025 Iker Pedrosa - 2:4.18.0-4 +- Stop setting SELinux labels in chroot and prefix environments + Resolves: #2249524 + * Tue Jul 29 2025 Alexey Tikhonov - 2:4.18.0-3 - Revert "Stop assigning subids by default" Resolves: #2382662 From 20b52960271fc47cb5b8bbcd2a20954bc10f402b Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Tue, 25 Nov 2025 10:30:54 +0100 Subject: [PATCH 115/134] Test CI Signed-off-by: Iker Pedrosa --- shadow-utils.spec | 7 ++++++- test.patch | 26 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 test.patch diff --git a/shadow-utils.spec b/shadow-utils.spec index e406acd..cf4fbf3 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.18.0 -Release: 4%{?dist} +Release: 5%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -26,6 +26,8 @@ Patch0: shadow-4.15.0-manfix.patch Patch1: shadow-4.18.0-account-tools-setuid.patch # https://github.com/shadow-maint/shadow/commit/db0e0b9112332a45131912021317ab5ab4fd6e40 Patch2: shadow-4.18.0-selinux-chroot-prefix.patch +# Test patch +Patch3: test.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -271,6 +273,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Tue Nov 25 2025 Iker Pedrosa - 2:4.18.0-5 +- Test CI + * Fri Oct 31 2025 Iker Pedrosa - 2:4.18.0-4 - Stop setting SELinux labels in chroot and prefix environments Resolves: #2249524 diff --git a/test.patch b/test.patch new file mode 100644 index 0000000..346d1b1 --- /dev/null +++ b/test.patch @@ -0,0 +1,26 @@ +From 012684d388881727d6ce457d710a03d6df216409 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Tue, 25 Nov 2025 09:52:03 +0100 +Subject: [PATCH] Test + +Signed-off-by: Iker Pedrosa +--- + src/useradd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/useradd.c b/src/useradd.c +index f7e46d6b..e2e95693 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -2440,7 +2440,7 @@ int main (int argc, char **argv) + #endif + unsigned long subuid_count = 0; + unsigned long subgid_count = 0; +- struct option_flags flags; ++ struct option_flags flags = {0}; + bool process_selinux; + + log_set_progname(Prog); +-- +2.52.0 + From 71c7bce53c2f1bb06b9eb5c9a23c9fecb17eeb61 Mon Sep 17 00:00:00 2001 From: Adam Williamson Date: Tue, 25 Nov 2025 10:08:41 -0800 Subject: [PATCH 116/134] Revert changes from -5 (they were only meant for testing) --- shadow-utils.spec | 7 ++++--- test.patch | 26 -------------------------- 2 files changed, 4 insertions(+), 29 deletions(-) delete mode 100644 test.patch diff --git a/shadow-utils.spec b/shadow-utils.spec index cf4fbf3..483eb21 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.18.0 -Release: 5%{?dist} +Release: 6%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -26,8 +26,6 @@ Patch0: shadow-4.15.0-manfix.patch Patch1: shadow-4.18.0-account-tools-setuid.patch # https://github.com/shadow-maint/shadow/commit/db0e0b9112332a45131912021317ab5ab4fd6e40 Patch2: shadow-4.18.0-selinux-chroot-prefix.patch -# Test patch -Patch3: test.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -273,6 +271,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Tue Nov 25 2025 Adam Williamson - 2:4.18.0-6 +- Revert changes from -5 (they were only meant for testing) + * Tue Nov 25 2025 Iker Pedrosa - 2:4.18.0-5 - Test CI diff --git a/test.patch b/test.patch deleted file mode 100644 index 346d1b1..0000000 --- a/test.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 012684d388881727d6ce457d710a03d6df216409 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Tue, 25 Nov 2025 09:52:03 +0100 -Subject: [PATCH] Test - -Signed-off-by: Iker Pedrosa ---- - src/useradd.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/useradd.c b/src/useradd.c -index f7e46d6b..e2e95693 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -2440,7 +2440,7 @@ int main (int argc, char **argv) - #endif - unsigned long subuid_count = 0; - unsigned long subgid_count = 0; -- struct option_flags flags; -+ struct option_flags flags = {0}; - bool process_selinux; - - log_set_progname(Prog); --- -2.52.0 - From 8953fddc447d650561e9786be46815400352e4af Mon Sep 17 00:00:00 2001 From: Adam Williamson Date: Tue, 25 Nov 2025 12:50:30 -0800 Subject: [PATCH 117/134] Also revert changes from -4 (last known good was -3) --- shadow-4.18.0-selinux-chroot-prefix.patch | 10433 -------------------- shadow-utils.spec | 5 +- 2 files changed, 3 insertions(+), 10435 deletions(-) delete mode 100644 shadow-4.18.0-selinux-chroot-prefix.patch diff --git a/shadow-4.18.0-selinux-chroot-prefix.patch b/shadow-4.18.0-selinux-chroot-prefix.patch deleted file mode 100644 index a5db17b..0000000 --- a/shadow-4.18.0-selinux-chroot-prefix.patch +++ /dev/null @@ -1,10433 +0,0 @@ -From 218cc94da84459bfa5b8417d933e8898e24ecff6 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Fri, 25 Apr 2025 15:13:12 +0200 -Subject: [PATCH 01/15] lib/: add SELinux control flag in commonio_close() - -Expand commonio_close() interface to add a control flag for SELinux file -context processing. - -Signed-off-by: Iker Pedrosa ---- - lib/commonio.c | 16 ++++++++++------ - lib/commonio.h | 2 +- - lib/groupio.c | 2 +- - lib/pwio.c | 2 +- - lib/sgroupio.c | 2 +- - lib/shadowio.c | 2 +- - lib/subordinateio.c | 4 ++-- - 7 files changed, 17 insertions(+), 13 deletions(-) - -diff --git a/lib/commonio.c b/lib/commonio.c -index 7304ec00..7ee6df4d 100644 ---- a/lib/commonio.c -+++ b/lib/commonio.c -@@ -473,7 +473,7 @@ int commonio_unlock (struct commonio_db *db) - - if (db->isopen) { - db->readonly = true; -- if (commonio_close (db) == 0) { -+ if (commonio_close (db, true) == 0) { - if (db->locked) { - dec_lock_count (); - } -@@ -885,7 +885,7 @@ static int write_all (const struct commonio_db *db) - } - - --int commonio_close (struct commonio_db *db) -+int commonio_close (struct commonio_db *db, bool process_selinux) - { - bool errors = false; - char buf[1024]; -@@ -927,7 +927,8 @@ int commonio_close (struct commonio_db *db) - } - - #ifdef WITH_SELINUX -- if (set_selinux_file_context (db->filename, S_IFREG) != 0) { -+ if (process_selinux -+ && set_selinux_file_context (db->filename, S_IFREG) != 0) { - errors = true; - } - #endif -@@ -942,7 +943,8 @@ int commonio_close (struct commonio_db *db) - db->fp = NULL; - - #ifdef WITH_SELINUX -- if (reset_selinux_file_context () != 0) { -+ if (process_selinux -+ && reset_selinux_file_context () != 0) { - errors = true; - } - #endif -@@ -961,7 +963,8 @@ int commonio_close (struct commonio_db *db) - goto fail; - - #ifdef WITH_SELINUX -- if (set_selinux_file_context (db->filename, S_IFREG) != 0) { -+ if (process_selinux -+ && set_selinux_file_context (db->filename, S_IFREG) != 0) { - errors = true; - } - #endif -@@ -999,7 +1002,8 @@ int commonio_close (struct commonio_db *db) - } - - #ifdef WITH_SELINUX -- if (reset_selinux_file_context () != 0) { -+ if (process_selinux -+ && reset_selinux_file_context () != 0) { - goto fail; - } - #endif -diff --git a/lib/commonio.h b/lib/commonio.h -index fedbefa3..dadc0500 100644 ---- a/lib/commonio.h -+++ b/lib/commonio.h -@@ -138,7 +138,7 @@ extern int commonio_append (struct commonio_db *, const void *); - extern int commonio_remove (struct commonio_db *, const char *); - extern int commonio_rewind (struct commonio_db *); - extern /*@observer@*/ /*@null@*/const void *commonio_next (struct commonio_db *); --extern int commonio_close (struct commonio_db *); -+extern int commonio_close (struct commonio_db *, bool); - extern int commonio_unlock (struct commonio_db *); - extern void commonio_del_entry (struct commonio_db *, - const struct commonio_entry *); -diff --git a/lib/groupio.c b/lib/groupio.c -index 72391433..5076fd3d 100644 ---- a/lib/groupio.c -+++ b/lib/groupio.c -@@ -186,7 +186,7 @@ int gr_rewind (void) - - int gr_close (void) - { -- return commonio_close (&group_db); -+ return commonio_close (&group_db, true); - } - - int gr_unlock (void) -diff --git a/lib/pwio.c b/lib/pwio.c -index 415447d6..6f666ec6 100644 ---- a/lib/pwio.c -+++ b/lib/pwio.c -@@ -158,7 +158,7 @@ int pw_rewind (void) - - int pw_close (void) - { -- return commonio_close (&passwd_db); -+ return commonio_close (&passwd_db, true); - } - - int pw_unlock (void) -diff --git a/lib/sgroupio.c b/lib/sgroupio.c -index ef82976d..659dcd06 100644 ---- a/lib/sgroupio.c -+++ b/lib/sgroupio.c -@@ -278,7 +278,7 @@ int sgr_rewind (void) - - int sgr_close (void) - { -- return commonio_close (&gshadow_db); -+ return commonio_close (&gshadow_db, true); - } - - int sgr_unlock (void) -diff --git a/lib/shadowio.c b/lib/shadowio.c -index 8b1c1d2c..55d33da2 100644 ---- a/lib/shadowio.c -+++ b/lib/shadowio.c -@@ -195,7 +195,7 @@ int spw_close (void) - return 0; - } - #endif /* WITH_TCB */ -- retval = commonio_close (&shadow_db); -+ retval = commonio_close (&shadow_db, true); - #ifdef WITH_TCB - if (use_tcb && (shadowtcb_gain_priv () == SHADOWTCB_FAILURE)) { - return 0; -diff --git a/lib/subordinateio.c b/lib/subordinateio.c -index 27f888b9..3638ec61 100644 ---- a/lib/subordinateio.c -+++ b/lib/subordinateio.c -@@ -670,7 +670,7 @@ int sub_uid_remove (const char *owner, uid_t start, unsigned long count) - - int sub_uid_close (void) - { -- return commonio_close (&subordinate_uid_db); -+ return commonio_close (&subordinate_uid_db, true); - } - - int sub_uid_unlock (void) -@@ -777,7 +777,7 @@ int sub_gid_remove (const char *owner, gid_t start, unsigned long count) - - int sub_gid_close (void) - { -- return commonio_close (&subordinate_gid_db); -+ return commonio_close (&subordinate_gid_db, true); - } - - int sub_gid_unlock (void) --- -2.50.0 - - -From 7e7dbe0e65d2795c15c42bb04c7c03b9ff86ea84 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Fri, 25 Apr 2025 15:19:29 +0200 -Subject: [PATCH 02/15] lib/, src/: add SELinux control flag in pw_close() - -Expand pw_close() interface to add a control flag for SELinux file -context processing. - -Signed-off-by: Iker Pedrosa ---- - lib/pwio.c | 4 ++-- - lib/pwio.h | 3 ++- - src/chage.c | 2 +- - src/chfn.c | 2 +- - src/chpasswd.c | 2 +- - src/chsh.c | 2 +- - src/groupmod.c | 2 +- - src/newusers.c | 2 +- - src/passwd.c | 2 +- - src/pwck.c | 2 +- - src/pwconv.c | 2 +- - src/pwunconv.c | 2 +- - src/useradd.c | 2 +- - src/userdel.c | 6 +++--- - src/usermod.c | 2 +- - 15 files changed, 19 insertions(+), 18 deletions(-) - -diff --git a/lib/pwio.c b/lib/pwio.c -index 6f666ec6..c5c1cdb1 100644 ---- a/lib/pwio.c -+++ b/lib/pwio.c -@@ -156,9 +156,9 @@ int pw_rewind (void) - return commonio_next (&passwd_db); - } - --int pw_close (void) -+int pw_close (bool process_selinux) - { -- return commonio_close (&passwd_db, true); -+ return commonio_close (&passwd_db, process_selinux); - } - - int pw_unlock (void) -diff --git a/lib/pwio.h b/lib/pwio.h -index 882a7c7a..b051a7e7 100644 ---- a/lib/pwio.h -+++ b/lib/pwio.h -@@ -14,8 +14,9 @@ - - #include - #include -+#include - --extern int pw_close (void); -+extern int pw_close (bool process_selinux); - extern /*@observer@*/ /*@null@*/const struct passwd *pw_locate (const char *name); - extern /*@observer@*/ /*@null@*/const struct passwd *pw_locate_uid (uid_t uid); - extern int pw_lock (void); -diff --git a/src/chage.c b/src/chage.c -index 4b9c96d6..1ebe34c5 100644 ---- a/src/chage.c -+++ b/src/chage.c -@@ -557,7 +557,7 @@ static void close_files (void) - * Close the password file. If any entries were modified, the file - * will be re-written. - */ -- if (pw_close () == 0) { -+ if (pw_close (true) == 0) { - fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); - fail_exit (E_NOPERM); -diff --git a/src/chfn.c b/src/chfn.c -index 58502929..abf88cc8 100644 ---- a/src/chfn.c -+++ b/src/chfn.c -@@ -493,7 +493,7 @@ static void update_gecos (const char *user, char *gecos) - /* - * Changes have all been made, so commit them and unlock the file. - */ -- if (pw_close () == 0) { -+ if (pw_close (true) == 0) { - fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); - fail_exit (E_NOPERM); -diff --git a/src/chpasswd.c b/src/chpasswd.c -index 315e91ce..17f3d6d5 100644 ---- a/src/chpasswd.c -+++ b/src/chpasswd.c -@@ -393,7 +393,7 @@ static void close_files (void) - spw_locked = false; - } - -- if (pw_close () == 0) { -+ if (pw_close (true) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, pw_dbname ()); -diff --git a/src/chsh.c b/src/chsh.c -index 236ff784..b5ae28da 100644 ---- a/src/chsh.c -+++ b/src/chsh.c -@@ -428,7 +428,7 @@ static void update_shell (const char *user, char *newshell) - /* - * Changes have all been made, so commit them and unlock the file. - */ -- if (pw_close () == 0) { -+ if (pw_close (true) == 0) { - fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); - fail_exit (1); -diff --git a/src/groupmod.c b/src/groupmod.c -index cce6fd49..14b7e746 100644 ---- a/src/groupmod.c -+++ b/src/groupmod.c -@@ -534,7 +534,7 @@ static void close_files (void) - #endif /* SHADOWGRP */ - - if (gflg) { -- if (pw_close () == 0) { -+ if (pw_close (true) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, pw_dbname ()); -diff --git a/src/newusers.c b/src/newusers.c -index 38cbdddb..a738f944 100644 ---- a/src/newusers.c -+++ b/src/newusers.c -@@ -939,7 +939,7 @@ static void open_files (void) - */ - static void close_files (void) - { -- if (pw_close () == 0) { -+ if (pw_close (true) == 0) { - fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); - fail_exit (EXIT_FAILURE); -diff --git a/src/passwd.c b/src/passwd.c -index cdd817a2..8bdff6dd 100644 ---- a/src/passwd.c -+++ b/src/passwd.c -@@ -586,7 +586,7 @@ static void update_noshadow (void) - Prog, pw_dbname (), npw->pw_name); - fail_exit (E_FAILURE); - } -- if (pw_close () == 0) { -+ if (pw_close (true) == 0) { - (void) fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, pw_dbname ()); -diff --git a/src/pwck.c b/src/pwck.c -index 6272839f..b1c6970f 100644 ---- a/src/pwck.c -+++ b/src/pwck.c -@@ -309,7 +309,7 @@ static void close_files (bool changed) - * changes to the files. - */ - if (changed) { -- if (pw_close () == 0) { -+ if (pw_close (true) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, pw_dbname ()); -diff --git a/src/pwconv.c b/src/pwconv.c -index 1bb92752..da3a5820 100644 ---- a/src/pwconv.c -+++ b/src/pwconv.c -@@ -281,7 +281,7 @@ int main (int argc, char **argv) - SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); - fail_exit (E_FAILURE); - } -- if (pw_close () == 0) { -+ if (pw_close (true) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, pw_dbname ()); -diff --git a/src/pwunconv.c b/src/pwunconv.c -index 2e4d3d75..8423cda4 100644 ---- a/src/pwunconv.c -+++ b/src/pwunconv.c -@@ -207,7 +207,7 @@ int main (int argc, char **argv) - - (void) spw_close (); /* was only open O_RDONLY */ - -- if (pw_close () == 0) { -+ if (pw_close (true) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, pw_dbname ()); -diff --git a/src/useradd.c b/src/useradd.c -index 36b9b8f8..8c9e9003 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -1564,7 +1564,7 @@ static void process_flags (int argc, char **argv) - */ - static void close_files (void) - { -- if (pw_close () == 0) { -+ if (pw_close (true) == 0) { - fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); - fail_exit (E_PW_UPDATE); -diff --git a/src/userdel.c b/src/userdel.c -index 72ce11fa..b5a02b3c 100644 ---- a/src/userdel.c -+++ b/src/userdel.c -@@ -390,7 +390,7 @@ static void remove_usergroup (void) - */ - static void close_files (void) - { -- if (pw_close () == 0) { -+ if (pw_close (true) == 0) { - fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); - fail_exit (E_PW_UPDATE); -@@ -1046,7 +1046,7 @@ int main (int argc, char **argv) - pw_open(O_RDONLY); - pwd = pw_locate (user_name); /* we care only about local users */ - if (NULL == pwd) { -- pw_close(); -+ pw_close(true); - fprintf (stderr, _("%s: user '%s' does not exist\n"), - Prog, user_name); - #ifdef WITH_AUDIT -@@ -1065,7 +1065,7 @@ int main (int argc, char **argv) - } else { - user_home = xstrdup(pwd->pw_dir); - } -- pw_close(); -+ pw_close(true); - } - #ifdef WITH_TCB - if (shadowtcb_set_user (user_name) == SHADOWTCB_FAILURE) { -diff --git a/src/usermod.c b/src/usermod.c -index a0f4d7dd..180b7da0 100644 ---- a/src/usermod.c -+++ b/src/usermod.c -@@ -1469,7 +1469,7 @@ process_flags(int argc, char **argv) - */ - static void close_files (void) - { -- if (pw_close () == 0) { -+ if (pw_close (true) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, pw_dbname ()); --- -2.50.0 - - -From abffb267659bb1f9d49af5cba69c7a9ba2489e3d Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Fri, 25 Apr 2025 15:23:11 +0200 -Subject: [PATCH 03/15] lib/, src/: add SELinux control flag in spw_close() - -Expand spw_close() interface to add a control flag for SELinux file -context processing. - -Signed-off-by: Iker Pedrosa ---- - lib/shadowio.c | 4 ++-- - lib/shadowio.h | 2 +- - src/chage.c | 2 +- - src/chpasswd.c | 2 +- - src/newusers.c | 2 +- - src/passwd.c | 4 ++-- - src/pwck.c | 4 ++-- - src/pwconv.c | 2 +- - src/pwunconv.c | 2 +- - src/useradd.c | 2 +- - src/userdel.c | 2 +- - src/usermod.c | 2 +- - 12 files changed, 15 insertions(+), 15 deletions(-) - -diff --git a/lib/shadowio.c b/lib/shadowio.c -index 55d33da2..a109576d 100644 ---- a/lib/shadowio.c -+++ b/lib/shadowio.c -@@ -185,7 +185,7 @@ int spw_rewind (void) - return commonio_next (&shadow_db); - } - --int spw_close (void) -+int spw_close (bool process_selinux) - { - int retval = 0; - #ifdef WITH_TCB -@@ -195,7 +195,7 @@ int spw_close (void) - return 0; - } - #endif /* WITH_TCB */ -- retval = commonio_close (&shadow_db, true); -+ retval = commonio_close (&shadow_db, process_selinux); - #ifdef WITH_TCB - if (use_tcb && (shadowtcb_gain_priv () == SHADOWTCB_FAILURE)) { - return 0; -diff --git a/lib/shadowio.h b/lib/shadowio.h -index 4dbeb6d6..e64d8d60 100644 ---- a/lib/shadowio.h -+++ b/lib/shadowio.h -@@ -13,7 +13,7 @@ - - #include "defines.h" - --extern int spw_close (void); -+extern int spw_close (bool process_selinux); - extern bool spw_file_present (void); - extern /*@observer@*/ /*@null@*/const struct spwd *spw_locate (const char *name); - extern int spw_lock (void); -diff --git a/src/chage.c b/src/chage.c -index 1ebe34c5..a59428c5 100644 ---- a/src/chage.c -+++ b/src/chage.c -@@ -546,7 +546,7 @@ static void close_files (void) - * Now close the shadow password file, which will cause all of the - * entries to be re-written. - */ -- if (spw_close () == 0) { -+ if (spw_close (true) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); -diff --git a/src/chpasswd.c b/src/chpasswd.c -index 17f3d6d5..e3d8dcef 100644 ---- a/src/chpasswd.c -+++ b/src/chpasswd.c -@@ -378,7 +378,7 @@ static void open_files (void) - static void close_files (void) - { - if (is_shadow_pwd) { -- if (spw_close () == 0) { -+ if (spw_close (true) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, spw_dbname ()); -diff --git a/src/newusers.c b/src/newusers.c -index a738f944..43672dd2 100644 ---- a/src/newusers.c -+++ b/src/newusers.c -@@ -952,7 +952,7 @@ static void close_files (void) - pw_locked = false; - - if (is_shadow) { -- if (spw_close () == 0) { -+ if (spw_close (true) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, spw_dbname ()); -diff --git a/src/passwd.c b/src/passwd.c -index 8bdff6dd..01efb285 100644 ---- a/src/passwd.c -+++ b/src/passwd.c -@@ -625,7 +625,7 @@ static void update_shadow (void) - sp = spw_locate (name); - if (NULL == sp) { - /* Try to update the password in /etc/passwd instead. */ -- (void) spw_close (); -+ (void) spw_close (true); - update_noshadow (); - if (spw_unlock () == 0) { - (void) fprintf (stderr, -@@ -681,7 +681,7 @@ static void update_shadow (void) - Prog, spw_dbname (), nsp->sp_namp); - fail_exit (E_FAILURE); - } -- if (spw_close () == 0) { -+ if (spw_close (true) == 0) { - (void) fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, spw_dbname ()); -diff --git a/src/pwck.c b/src/pwck.c -index b1c6970f..718b639f 100644 ---- a/src/pwck.c -+++ b/src/pwck.c -@@ -320,7 +320,7 @@ static void close_files (bool changed) - } - fail_exit (E_CANTUPDATE); - } -- if (spw_opened && (spw_close () == 0)) { -+ if (spw_opened && (spw_close (true) == 0)) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, spw_dbname ()); -@@ -657,7 +657,7 @@ static void check_pw_file (bool *errors, bool *changed) - } - #ifdef WITH_TCB - if (getdef_bool ("USE_TCB") && spw_locked) { -- if (spw_opened && (spw_close () == 0)) { -+ if (spw_opened && (spw_close (true) == 0)) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, spw_dbname ()); -diff --git a/src/pwconv.c b/src/pwconv.c -index da3a5820..296b527a 100644 ---- a/src/pwconv.c -+++ b/src/pwconv.c -@@ -274,7 +274,7 @@ int main (int argc, char **argv) - } - } - -- if (spw_close () == 0) { -+ if (spw_close (true) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, spw_dbname ()); -diff --git a/src/pwunconv.c b/src/pwunconv.c -index 8423cda4..e15c8c06 100644 ---- a/src/pwunconv.c -+++ b/src/pwunconv.c -@@ -205,7 +205,7 @@ int main (int argc, char **argv) - } - } - -- (void) spw_close (); /* was only open O_RDONLY */ -+ (void) spw_close (true); /* was only open O_RDONLY */ - - if (pw_close (true) == 0) { - fprintf (stderr, -diff --git a/src/useradd.c b/src/useradd.c -index 8c9e9003..8a7df6cf 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -1569,7 +1569,7 @@ static void close_files (void) - SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); - fail_exit (E_PW_UPDATE); - } -- if (is_shadow_pwd && (spw_close () == 0)) { -+ if (is_shadow_pwd && (spw_close (true) == 0)) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); -diff --git a/src/userdel.c b/src/userdel.c -index b5a02b3c..b87f2459 100644 ---- a/src/userdel.c -+++ b/src/userdel.c -@@ -403,7 +403,7 @@ static void close_files (void) - pw_locked = false; - - if (is_shadow_pwd) { -- if (spw_close () == 0) { -+ if (spw_close (true) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); -diff --git a/src/usermod.c b/src/usermod.c -index 180b7da0..d741508a 100644 ---- a/src/usermod.c -+++ b/src/usermod.c -@@ -1476,7 +1476,7 @@ static void close_files (void) - SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); - fail_exit (E_PW_UPDATE); - } -- if (is_shadow_pwd && (spw_close () == 0)) { -+ if (is_shadow_pwd && (spw_close (true) == 0)) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, spw_dbname ()); --- -2.50.0 - - -From 16bd1d985900fe83a1f7c9001fa3b9f18e0f06f0 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Fri, 25 Apr 2025 15:28:42 +0200 -Subject: [PATCH 04/15] lib/, src/: add SELinux control flag in gr_close() - -Expand gr_close() interface to add a control flag for SELinux file -context processing. - -Signed-off-by: Iker Pedrosa ---- - lib/groupio.c | 4 ++-- - lib/groupio.h | 3 ++- - src/chgpasswd.c | 2 +- - src/gpasswd.c | 4 ++-- - src/groupadd.c | 2 +- - src/groupdel.c | 2 +- - src/groupmems.c | 2 +- - src/groupmod.c | 2 +- - src/grpck.c | 2 +- - src/grpconv.c | 2 +- - src/grpunconv.c | 2 +- - src/newusers.c | 2 +- - src/useradd.c | 2 +- - src/userdel.c | 2 +- - src/usermod.c | 2 +- - 15 files changed, 18 insertions(+), 17 deletions(-) - -diff --git a/lib/groupio.c b/lib/groupio.c -index 5076fd3d..837e4c47 100644 ---- a/lib/groupio.c -+++ b/lib/groupio.c -@@ -184,9 +184,9 @@ int gr_rewind (void) - return commonio_next (&group_db); - } - --int gr_close (void) -+int gr_close (bool process_selinux) - { -- return commonio_close (&group_db, true); -+ return commonio_close (&group_db, process_selinux); - } - - int gr_unlock (void) -diff --git a/lib/groupio.h b/lib/groupio.h -index 2014de0c..ef9242d0 100644 ---- a/lib/groupio.h -+++ b/lib/groupio.h -@@ -14,8 +14,9 @@ - - #include - #include -+#include - --extern int gr_close (void); -+extern int gr_close (bool process_selinux); - extern /*@observer@*/ /*@null@*/const struct group *gr_locate (const char *name); - extern /*@observer@*/ /*@null@*/const struct group *gr_locate_gid (gid_t gid); - extern int gr_lock (void); -diff --git a/src/chgpasswd.c b/src/chgpasswd.c -index e7759657..9b686ef0 100644 ---- a/src/chgpasswd.c -+++ b/src/chgpasswd.c -@@ -397,7 +397,7 @@ static void close_files (void) - } - #endif - -- if (gr_close () == 0) { -+ if (gr_close (true) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, gr_dbname ()); -diff --git a/src/gpasswd.c b/src/gpasswd.c -index 460bd14c..1013f004 100644 ---- a/src/gpasswd.c -+++ b/src/gpasswd.c -@@ -593,7 +593,7 @@ static void log_gpasswd_success_group (MAYBE_UNUSED void *arg) - */ - static void close_files (void) - { -- if (gr_close () == 0) { -+ if (gr_close (true) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, gr_dbname ()); -@@ -724,7 +724,7 @@ static void get_group (struct group *gr) - gr->gr_passwd = xstrdup (tmpgr->gr_passwd); - gr->gr_mem = dup_list (tmpgr->gr_mem); - -- if (gr_close () == 0) { -+ if (gr_close (true) == 0) { - fprintf (stderr, - _("%s: failure while closing read-only %s\n"), - Prog, gr_dbname ()); -diff --git a/src/groupadd.c b/src/groupadd.c -index a0d5adeb..d9a9d36c 100644 ---- a/src/groupadd.c -+++ b/src/groupadd.c -@@ -274,7 +274,7 @@ check_new_name(void) - static void close_files (void) - { - /* First, write the changes in the regular group database */ -- if (gr_close () == 0) { -+ if (gr_close (true) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, gr_dbname ()); -diff --git a/src/groupdel.c b/src/groupdel.c -index 3d289fef..c52a2ae7 100644 ---- a/src/groupdel.c -+++ b/src/groupdel.c -@@ -149,7 +149,7 @@ static void grp_update (void) - static void close_files (void) - { - /* First, write the changes in the regular group database */ -- if (gr_close () == 0) { -+ if (gr_close (true) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, gr_dbname ()); -diff --git a/src/groupmems.c b/src/groupmems.c -index d37b237f..fff9ae10 100644 ---- a/src/groupmems.c -+++ b/src/groupmems.c -@@ -522,7 +522,7 @@ static void open_files (void) - - static void close_files (void) - { -- if ((gr_close () == 0) && !list) { -+ if ((gr_close (true) == 0) && !list) { - fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ())); - fail_exit (EXIT_GROUP_FILE); -diff --git a/src/groupmod.c b/src/groupmod.c -index 14b7e746..49b68c55 100644 ---- a/src/groupmod.c -+++ b/src/groupmod.c -@@ -481,7 +481,7 @@ static void process_flags (int argc, char **argv) - */ - static void close_files (void) - { -- if (gr_close () == 0) { -+ if (gr_close (true) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, gr_dbname ()); -diff --git a/src/grpck.c b/src/grpck.c -index 5fcf6fad..db8f1e68 100644 ---- a/src/grpck.c -+++ b/src/grpck.c -@@ -321,7 +321,7 @@ static void close_files (bool changed) - * changes to the files. - */ - if (changed) { -- if (gr_close () == 0) { -+ if (gr_close (true) == 0) { - fprintf (stderr, _("%s: failure while writing changes to %s\n"), - Prog, grp_file); - fail_exit (E_CANT_UPDATE); -diff --git a/src/grpconv.c b/src/grpconv.c -index 1b31cb85..e7928a4a 100644 ---- a/src/grpconv.c -+++ b/src/grpconv.c -@@ -241,7 +241,7 @@ int main (int argc, char **argv) - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ())); - fail_exit (3); - } -- if (gr_close () == 0) { -+ if (gr_close (true) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, gr_dbname ()); -diff --git a/src/grpunconv.c b/src/grpunconv.c -index ea65a329..63597da1 100644 ---- a/src/grpunconv.c -+++ b/src/grpunconv.c -@@ -193,7 +193,7 @@ int main (int argc, char **argv) - - (void) sgr_close (); /* was only open O_RDONLY */ - -- if (gr_close () == 0) { -+ if (gr_close (true) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, gr_dbname ()); -diff --git a/src/newusers.c b/src/newusers.c -index 43672dd2..29d3a536 100644 ---- a/src/newusers.c -+++ b/src/newusers.c -@@ -969,7 +969,7 @@ static void close_files (void) - spw_locked = false; - } - -- if (gr_close () == 0) { -+ if (gr_close (true) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, gr_dbname ()); -diff --git a/src/useradd.c b/src/useradd.c -index 8a7df6cf..f52e5483 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -1664,7 +1664,7 @@ static void close_group_files (void) - if (!do_grp_update) - return; - -- if (gr_close() == 0) { -+ if (gr_close(true) == 0) { - fprintf(stderr, - _("%s: failure while writing changes to %s\n"), - Prog, gr_dbname()); -diff --git a/src/userdel.c b/src/userdel.c -index b87f2459..b0e0d541 100644 ---- a/src/userdel.c -+++ b/src/userdel.c -@@ -417,7 +417,7 @@ static void close_files (void) - spw_locked = false; - } - -- if (gr_close () == 0) { -+ if (gr_close (true) == 0) { - fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ())); - fail_exit (E_GRP_UPDATE); -diff --git a/src/usermod.c b/src/usermod.c -index d741508a..d1d26eaa 100644 ---- a/src/usermod.c -+++ b/src/usermod.c -@@ -1487,7 +1487,7 @@ static void close_files (void) - } - - if (Gflg || lflg) { -- if (gr_close () == 0) { -+ if (gr_close (true) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, gr_dbname ()); --- -2.50.0 - - -From f4a67dd6281a513b56c15aa1a3f292ca05674f13 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Fri, 25 Apr 2025 15:32:05 +0200 -Subject: [PATCH 05/15] lib/, src/: add SELinux control flag in sgr_close() - -Expand sgr_close() interface to add a control flag for SELinux file -context processing. - -Signed-off-by: Iker Pedrosa ---- - lib/sgroupio.c | 4 ++-- - lib/sgroupio.h | 2 +- - src/chgpasswd.c | 2 +- - src/gpasswd.c | 4 ++-- - src/groupadd.c | 2 +- - src/groupdel.c | 2 +- - src/groupmems.c | 2 +- - src/groupmod.c | 2 +- - src/grpck.c | 2 +- - src/grpconv.c | 2 +- - src/grpunconv.c | 2 +- - src/newusers.c | 2 +- - src/useradd.c | 2 +- - src/userdel.c | 2 +- - src/usermod.c | 2 +- - 15 files changed, 17 insertions(+), 17 deletions(-) - -diff --git a/lib/sgroupio.c b/lib/sgroupio.c -index 659dcd06..025584ad 100644 ---- a/lib/sgroupio.c -+++ b/lib/sgroupio.c -@@ -276,9 +276,9 @@ int sgr_rewind (void) - return commonio_next (&gshadow_db); - } - --int sgr_close (void) -+int sgr_close (bool process_selinux) - { -- return commonio_close (&gshadow_db, true); -+ return commonio_close (&gshadow_db, process_selinux); - } - - int sgr_unlock (void) -diff --git a/lib/sgroupio.h b/lib/sgroupio.h -index 3474a985..0e25fc0b 100644 ---- a/lib/sgroupio.h -+++ b/lib/sgroupio.h -@@ -12,7 +12,7 @@ - #ifndef _SGROUPIO_H - #define _SGROUPIO_H - --extern int sgr_close (void); -+extern int sgr_close (bool process_selinux); - extern bool sgr_file_present (void); - extern /*@observer@*/ /*@null@*/const struct sgrp *sgr_locate (const char *name); - extern int sgr_lock (void); -diff --git a/src/chgpasswd.c b/src/chgpasswd.c -index 9b686ef0..47402ecc 100644 ---- a/src/chgpasswd.c -+++ b/src/chgpasswd.c -@@ -381,7 +381,7 @@ static void close_files (void) - { - #ifdef SHADOWGRP - if (is_shadow_grp) { -- if (sgr_close () == 0) { -+ if (sgr_close (true) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, sgr_dbname ()); -diff --git a/src/gpasswd.c b/src/gpasswd.c -index 1013f004..a49b9140 100644 ---- a/src/gpasswd.c -+++ b/src/gpasswd.c -@@ -607,7 +607,7 @@ static void close_files (void) - - #ifdef SHADOWGRP - if (is_shadowgrp) { -- if (sgr_close () == 0) { -+ if (sgr_close (true) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, sgr_dbname ()); -@@ -762,7 +762,7 @@ static void get_group (struct group *gr) - sg->sg_adm[0] = NULL; - - } -- if (sgr_close () == 0) { -+ if (sgr_close (true) == 0) { - fprintf (stderr, - _("%s: failure while closing read-only %s\n"), - Prog, sgr_dbname ()); -diff --git a/src/groupadd.c b/src/groupadd.c -index d9a9d36c..7cfb0eb5 100644 ---- a/src/groupadd.c -+++ b/src/groupadd.c -@@ -295,7 +295,7 @@ static void close_files (void) - /* Now, write the changes in the shadow database */ - #ifdef SHADOWGRP - if (is_shadow_grp) { -- if (sgr_close () == 0) { -+ if (sgr_close (true) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, sgr_dbname ()); -diff --git a/src/groupdel.c b/src/groupdel.c -index c52a2ae7..56123a7b 100644 ---- a/src/groupdel.c -+++ b/src/groupdel.c -@@ -173,7 +173,7 @@ static void close_files (void) - /* Then, write the changes in the shadow database */ - #ifdef SHADOWGRP - if (is_shadow_grp) { -- if (sgr_close () == 0) { -+ if (sgr_close (true) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, sgr_dbname ()); -diff --git a/src/groupmems.c b/src/groupmems.c -index fff9ae10..5976b074 100644 ---- a/src/groupmems.c -+++ b/src/groupmems.c -@@ -538,7 +538,7 @@ static void close_files (void) - - #ifdef SHADOWGRP - if (is_shadowgrp) { -- if ((sgr_close () == 0) && !list) { -+ if ((sgr_close (true) == 0) && !list) { - fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ())); - fail_exit (EXIT_GROUP_FILE); -diff --git a/src/groupmod.c b/src/groupmod.c -index 49b68c55..3c258feb 100644 ---- a/src/groupmod.c -+++ b/src/groupmod.c -@@ -504,7 +504,7 @@ static void close_files (void) - #ifdef SHADOWGRP - if ( is_shadow_grp - && (pflg || nflg || user_list)) { -- if (sgr_close () == 0) { -+ if (sgr_close (true) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, sgr_dbname ()); -diff --git a/src/grpck.c b/src/grpck.c -index db8f1e68..872f882f 100644 ---- a/src/grpck.c -+++ b/src/grpck.c -@@ -327,7 +327,7 @@ static void close_files (bool changed) - fail_exit (E_CANT_UPDATE); - } - #ifdef SHADOWGRP -- if (is_shadow && (sgr_close () == 0)) { -+ if (is_shadow && (sgr_close (true) == 0)) { - fprintf (stderr, _("%s: failure while writing changes to %s\n"), - Prog, sgr_file); - fail_exit (E_CANT_UPDATE); -diff --git a/src/grpconv.c b/src/grpconv.c -index e7928a4a..d9c59fc9 100644 ---- a/src/grpconv.c -+++ b/src/grpconv.c -@@ -234,7 +234,7 @@ int main (int argc, char **argv) - } - } - -- if (sgr_close () == 0) { -+ if (sgr_close (true) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, sgr_dbname ()); -diff --git a/src/grpunconv.c b/src/grpunconv.c -index 63597da1..03fc824e 100644 ---- a/src/grpunconv.c -+++ b/src/grpunconv.c -@@ -191,7 +191,7 @@ int main (int argc, char **argv) - } - } - -- (void) sgr_close (); /* was only open O_RDONLY */ -+ (void) sgr_close (true); /* was only open O_RDONLY */ - - if (gr_close (true) == 0) { - fprintf (stderr, -diff --git a/src/newusers.c b/src/newusers.c -index 29d3a536..19a32863 100644 ---- a/src/newusers.c -+++ b/src/newusers.c -@@ -1002,7 +1002,7 @@ static void close_files (void) - - #ifdef SHADOWGRP - if (is_shadow_grp) { -- if (sgr_close () == 0) { -+ if (sgr_close (true) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, sgr_dbname ()); -diff --git a/src/useradd.c b/src/useradd.c -index f52e5483..7f596673 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -1672,7 +1672,7 @@ static void close_group_files (void) - fail_exit(E_GRP_UPDATE); - } - #ifdef SHADOWGRP -- if (is_shadow_grp && sgr_close() == 0) { -+ if (is_shadow_grp && sgr_close(true) == 0) { - fprintf(stderr, - _("%s: failure while writing changes to %s\n"), - Prog, sgr_dbname()); -diff --git a/src/userdel.c b/src/userdel.c -index b0e0d541..1829ba4d 100644 ---- a/src/userdel.c -+++ b/src/userdel.c -@@ -431,7 +431,7 @@ static void close_files (void) - - #ifdef SHADOWGRP - if (is_shadow_grp) { -- if (sgr_close () == 0) { -+ if (sgr_close (true) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ())); -diff --git a/src/usermod.c b/src/usermod.c -index d1d26eaa..dbcb32b2 100644 ---- a/src/usermod.c -+++ b/src/usermod.c -@@ -1498,7 +1498,7 @@ static void close_files (void) - } - #ifdef SHADOWGRP - if (is_shadow_grp) { -- if (sgr_close () == 0) { -+ if (sgr_close (true) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, sgr_dbname ()); --- -2.50.0 - - -From f3dce7ede9c3f267e810fec3500498e76a305d8a Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Fri, 25 Apr 2025 15:35:48 +0200 -Subject: [PATCH 06/15] lib/, src/: add SELinux control flag in sub_uid_close() - -Expand sub_uid_close() interface to add a control flag for SELinux file -context processing. - -Signed-off-by: Iker Pedrosa ---- - lib/subordinateio.c | 14 +++++++------- - lib/subordinateio.h | 2 +- - lib/user_busy.c | 10 +++++----- - src/newuidmap.c | 2 +- - src/newusers.c | 2 +- - src/useradd.c | 2 +- - src/userdel.c | 2 +- - src/usermod.c | 2 +- - 8 files changed, 18 insertions(+), 18 deletions(-) - -diff --git a/lib/subordinateio.c b/lib/subordinateio.c -index 3638ec61..206a1348 100644 ---- a/lib/subordinateio.c -+++ b/lib/subordinateio.c -@@ -590,7 +590,7 @@ static bool have_range(struct commonio_db *db, - - if (doclose) { - if (db == &subordinate_uid_db) -- sub_uid_close(); -+ sub_uid_close(true); - else - sub_gid_close(); - } -@@ -668,9 +668,9 @@ int sub_uid_remove (const char *owner, uid_t start, unsigned long count) - return remove_range (&subordinate_uid_db, owner, start, count); - } - --int sub_uid_close (void) -+int sub_uid_close (bool process_selinux) - { -- return commonio_close (&subordinate_uid_db, true); -+ return commonio_close (&subordinate_uid_db, process_selinux); - } - - int sub_uid_unlock (void) -@@ -907,7 +907,7 @@ int list_owner_ranges(const char *owner, enum subid_type id_type, struct subid_r - - out: - if (id_type == ID_TYPE_UID) -- sub_uid_close(); -+ sub_uid_close(true); - else - sub_gid_close(); - -@@ -998,7 +998,7 @@ int find_subid_owners(unsigned long id, enum subid_type id_type, uid_t **uids) - } - - if (id_type == ID_TYPE_UID) -- sub_uid_close(); -+ sub_uid_close(true); - else - sub_gid_close(); - -@@ -1068,7 +1068,7 @@ bool new_subid_range(struct subordinate_range *range, enum subid_type id_type, b - - out: - if (id_type == ID_TYPE_UID) { -- sub_uid_close(); -+ sub_uid_close(true); - sub_uid_unlock(); - } else { - sub_gid_close(); -@@ -1118,7 +1118,7 @@ bool release_subid_range(struct subordinate_range *range, enum subid_type id_typ - ret = remove_range(db, range->owner, range->start, range->count) == 1; - - if (id_type == ID_TYPE_UID) { -- sub_uid_close(); -+ sub_uid_close(true); - sub_uid_unlock(); - } else { - sub_gid_close(); -diff --git a/lib/subordinateio.h b/lib/subordinateio.h -index 3d1a0547..d16c8b9e 100644 ---- a/lib/subordinateio.h -+++ b/lib/subordinateio.h -@@ -13,7 +13,7 @@ - - #include "../libsubid/subid.h" - --extern int sub_uid_close(void); -+extern int sub_uid_close(bool process_selinux); - extern bool have_sub_uids(const char *owner, uid_t start, unsigned long count); - extern bool sub_uid_file_present (void); - extern bool local_sub_uid_assigned(const char *owner); -diff --git a/lib/user_busy.c b/lib/user_busy.c -index d689d34d..ab1dd5a4 100644 ---- a/lib/user_busy.c -+++ b/lib/user_busy.c -@@ -180,7 +180,7 @@ static int user_busy_processes (const char *name, uid_t uid) - if (proc == NULL) { - perror ("opendir /proc"); - #ifdef ENABLE_SUBIDS -- sub_uid_close(); -+ sub_uid_close(true); - #endif - return 0; - } -@@ -188,7 +188,7 @@ static int user_busy_processes (const char *name, uid_t uid) - perror ("stat (\"/\")"); - (void) closedir (proc); - #ifdef ENABLE_SUBIDS -- sub_uid_close(); -+ sub_uid_close(true); - #endif - return 0; - } -@@ -225,7 +225,7 @@ static int user_busy_processes (const char *name, uid_t uid) - if (check_status (name, tmp_d_name, uid) != 0) { - (void) closedir (proc); - #ifdef ENABLE_SUBIDS -- sub_uid_close(); -+ sub_uid_close(true); - #endif - fprintf (log_get_logfd(), - _("%s: user %s is currently used by process %d\n"), -@@ -248,7 +248,7 @@ static int user_busy_processes (const char *name, uid_t uid) - (void) closedir (proc); - (void) closedir (task_dir); - #ifdef ENABLE_SUBIDS -- sub_uid_close(); -+ sub_uid_close(true); - #endif - fprintf (log_get_logfd(), - _("%s: user %s is currently used by process %d\n"), -@@ -264,7 +264,7 @@ static int user_busy_processes (const char *name, uid_t uid) - - (void) closedir (proc); - #ifdef ENABLE_SUBIDS -- sub_uid_close(); -+ sub_uid_close(true); - #endif /* ENABLE_SUBIDS */ - return 0; - } -diff --git a/src/newuidmap.c b/src/newuidmap.c -index 894c5ec8..90bd6de5 100644 ---- a/src/newuidmap.c -+++ b/src/newuidmap.c -@@ -158,7 +158,7 @@ int main(int argc, char **argv) - verify_ranges(pw, ranges, mappings); - - write_mapping(proc_dir_fd, ranges, mappings, "uid_map", pw->pw_uid); -- sub_uid_close(); -+ sub_uid_close(true); - - return EXIT_SUCCESS; - } -diff --git a/src/newusers.c b/src/newusers.c -index 19a32863..d71a792b 100644 ---- a/src/newusers.c -+++ b/src/newusers.c -@@ -977,7 +977,7 @@ static void close_files (void) - fail_exit (EXIT_FAILURE); - } - #ifdef ENABLE_SUBIDS -- if (is_sub_uid && (sub_uid_close () == 0)) { -+ if (is_sub_uid && (sub_uid_close (true) == 0)) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), Prog, sub_uid_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_uid_dbname ())); -diff --git a/src/useradd.c b/src/useradd.c -index 7f596673..971fec55 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -1579,7 +1579,7 @@ static void close_files (void) - close_group_files (); - - #ifdef ENABLE_SUBIDS -- if (is_sub_uid && (sub_uid_close () == 0)) { -+ if (is_sub_uid && (sub_uid_close (true) == 0)) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), Prog, sub_uid_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_uid_dbname ())); -diff --git a/src/userdel.c b/src/userdel.c -index 1829ba4d..8fe9f4e2 100644 ---- a/src/userdel.c -+++ b/src/userdel.c -@@ -449,7 +449,7 @@ static void close_files (void) - - #ifdef ENABLE_SUBIDS - if (is_sub_uid) { -- if (sub_uid_close () == 0) { -+ if (sub_uid_close (true) == 0) { - fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sub_uid_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_uid_dbname ())); - fail_exit (E_SUB_UID_UPDATE); -diff --git a/src/usermod.c b/src/usermod.c -index dbcb32b2..440c2406 100644 ---- a/src/usermod.c -+++ b/src/usermod.c -@@ -1561,7 +1561,7 @@ static void close_files (void) - - #ifdef ENABLE_SUBIDS - if (vflg || Vflg) { -- if (sub_uid_close () == 0) { -+ if (sub_uid_close (true) == 0) { - fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sub_uid_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_uid_dbname ())); - fail_exit (E_SUB_UID_UPDATE); --- -2.50.0 - - -From ab2a2656e442043d5b39e1320552ba9850aabd27 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Fri, 25 Apr 2025 15:38:18 +0200 -Subject: [PATCH 07/15] lib/, src/: add SELinux control flag in sub_gid_close() - -Expand sub_gid_close() interface to add a control flag for SELinux file -context processing. - -Signed-off-by: Iker Pedrosa ---- - lib/subordinateio.c | 14 +++++++------- - lib/subordinateio.h | 2 +- - src/newgidmap.c | 2 +- - src/newusers.c | 2 +- - src/useradd.c | 2 +- - src/userdel.c | 2 +- - src/usermod.c | 2 +- - 7 files changed, 13 insertions(+), 13 deletions(-) - -diff --git a/lib/subordinateio.c b/lib/subordinateio.c -index 206a1348..e2c2375a 100644 ---- a/lib/subordinateio.c -+++ b/lib/subordinateio.c -@@ -592,7 +592,7 @@ static bool have_range(struct commonio_db *db, - if (db == &subordinate_uid_db) - sub_uid_close(true); - else -- sub_gid_close(); -+ sub_gid_close(true); - } - - return ret; -@@ -775,9 +775,9 @@ int sub_gid_remove (const char *owner, gid_t start, unsigned long count) - return remove_range (&subordinate_gid_db, owner, start, count); - } - --int sub_gid_close (void) -+int sub_gid_close (bool process_selinux) - { -- return commonio_close (&subordinate_gid_db, true); -+ return commonio_close (&subordinate_gid_db, process_selinux); - } - - int sub_gid_unlock (void) -@@ -909,7 +909,7 @@ out: - if (id_type == ID_TYPE_UID) - sub_uid_close(true); - else -- sub_gid_close(); -+ sub_gid_close(true); - - *in_ranges = ranges; - return count; -@@ -1000,7 +1000,7 @@ int find_subid_owners(unsigned long id, enum subid_type id_type, uid_t **uids) - if (id_type == ID_TYPE_UID) - sub_uid_close(true); - else -- sub_gid_close(); -+ sub_gid_close(true); - - return n; - } -@@ -1071,7 +1071,7 @@ out: - sub_uid_close(true); - sub_uid_unlock(); - } else { -- sub_gid_close(); -+ sub_gid_close(true); - sub_gid_unlock(); - } - -@@ -1121,7 +1121,7 @@ bool release_subid_range(struct subordinate_range *range, enum subid_type id_typ - sub_uid_close(true); - sub_uid_unlock(); - } else { -- sub_gid_close(); -+ sub_gid_close(true); - sub_gid_unlock(); - } - -diff --git a/lib/subordinateio.h b/lib/subordinateio.h -index d16c8b9e..63f5b1fb 100644 ---- a/lib/subordinateio.h -+++ b/lib/subordinateio.h -@@ -31,7 +31,7 @@ extern bool release_subid_range(struct subordinate_range *range, enum subid_type - extern int find_subid_owners(unsigned long id, enum subid_type id_type, uid_t **uids); - extern void free_subordinate_ranges(struct subordinate_range **ranges, int count); - --extern int sub_gid_close(void); -+extern int sub_gid_close(bool process_selinux); - extern bool have_sub_gids(const char *owner, gid_t start, unsigned long count); - extern bool sub_gid_file_present (void); - extern bool local_sub_gid_assigned(const char *owner); -diff --git a/src/newgidmap.c b/src/newgidmap.c -index 3463e850..7ce22b5a 100644 ---- a/src/newgidmap.c -+++ b/src/newgidmap.c -@@ -230,7 +230,7 @@ int main(int argc, char **argv) - - write_setgroups(proc_dir_fd, allow_setgroups); - write_mapping(proc_dir_fd, ranges, mappings, "gid_map", pw->pw_uid); -- sub_gid_close(); -+ sub_gid_close(true); - - return EXIT_SUCCESS; - } -diff --git a/src/newusers.c b/src/newusers.c -index d71a792b..8cd11a71 100644 ---- a/src/newusers.c -+++ b/src/newusers.c -@@ -983,7 +983,7 @@ static void close_files (void) - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_uid_dbname ())); - fail_exit (EXIT_FAILURE); - } -- if (is_sub_gid && (sub_gid_close () == 0)) { -+ if (is_sub_gid && (sub_gid_close (true) == 0)) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), Prog, sub_gid_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_gid_dbname ())); -diff --git a/src/useradd.c b/src/useradd.c -index 971fec55..3d2fdb35 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -1585,7 +1585,7 @@ static void close_files (void) - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_uid_dbname ())); - fail_exit (E_SUB_UID_UPDATE); - } -- if (is_sub_gid && (sub_gid_close () == 0)) { -+ if (is_sub_gid && (sub_gid_close (true) == 0)) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), Prog, sub_gid_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_gid_dbname ())); -diff --git a/src/userdel.c b/src/userdel.c -index 8fe9f4e2..7dcbd923 100644 ---- a/src/userdel.c -+++ b/src/userdel.c -@@ -463,7 +463,7 @@ static void close_files (void) - } - - if (is_sub_gid) { -- if (sub_gid_close () == 0) { -+ if (sub_gid_close (true) == 0) { - fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sub_gid_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_gid_dbname ())); - fail_exit (E_SUB_GID_UPDATE); -diff --git a/src/usermod.c b/src/usermod.c -index 440c2406..534bdc74 100644 ---- a/src/usermod.c -+++ b/src/usermod.c -@@ -1574,7 +1574,7 @@ static void close_files (void) - sub_uid_locked = false; - } - if (wflg || Wflg) { -- if (sub_gid_close () == 0) { -+ if (sub_gid_close (true) == 0) { - fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sub_gid_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_gid_dbname ())); - fail_exit (E_SUB_GID_UPDATE); --- -2.50.0 - - -From 9161c63be728bfba7545bac1e4cbde8a069ad4e6 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Fri, 25 Apr 2025 15:44:06 +0200 -Subject: [PATCH 08/15] lib/: add SELinux control flag in commonio_unlock() - -Expand commonio_unlock() interface to add a control flag for SELinux -file context processing. - -Signed-off-by: Iker Pedrosa ---- - lib/commonio.c | 4 ++-- - lib/commonio.h | 2 +- - lib/groupio.c | 2 +- - lib/pwio.c | 2 +- - lib/sgroupio.c | 2 +- - lib/shadowio.c | 2 +- - lib/subordinateio.c | 4 ++-- - 7 files changed, 9 insertions(+), 9 deletions(-) - -diff --git a/lib/commonio.c b/lib/commonio.c -index 7ee6df4d..19653e7e 100644 ---- a/lib/commonio.c -+++ b/lib/commonio.c -@@ -467,13 +467,13 @@ static void dec_lock_count (void) - } - - --int commonio_unlock (struct commonio_db *db) -+int commonio_unlock (struct commonio_db *db, bool process_selinux) - { - char lock[1029]; - - if (db->isopen) { - db->readonly = true; -- if (commonio_close (db, true) == 0) { -+ if (commonio_close (db, process_selinux) == 0) { - if (db->locked) { - dec_lock_count (); - } -diff --git a/lib/commonio.h b/lib/commonio.h -index dadc0500..8b8f5cf4 100644 ---- a/lib/commonio.h -+++ b/lib/commonio.h -@@ -139,7 +139,7 @@ extern int commonio_remove (struct commonio_db *, const char *); - extern int commonio_rewind (struct commonio_db *); - extern /*@observer@*/ /*@null@*/const void *commonio_next (struct commonio_db *); - extern int commonio_close (struct commonio_db *, bool); --extern int commonio_unlock (struct commonio_db *); -+extern int commonio_unlock (struct commonio_db *, bool); - extern void commonio_del_entry (struct commonio_db *, - const struct commonio_entry *); - extern int commonio_sort_wrt (struct commonio_db *shadow, -diff --git a/lib/groupio.c b/lib/groupio.c -index 837e4c47..6ad4ae69 100644 ---- a/lib/groupio.c -+++ b/lib/groupio.c -@@ -191,7 +191,7 @@ int gr_close (bool process_selinux) - - int gr_unlock (void) - { -- return commonio_unlock (&group_db); -+ return commonio_unlock (&group_db, true); - } - - void __gr_set_changed (void) -diff --git a/lib/pwio.c b/lib/pwio.c -index c5c1cdb1..c5dcb904 100644 ---- a/lib/pwio.c -+++ b/lib/pwio.c -@@ -163,7 +163,7 @@ int pw_close (bool process_selinux) - - int pw_unlock (void) - { -- return commonio_unlock (&passwd_db); -+ return commonio_unlock (&passwd_db, true); - } - - /*@null@*/struct commonio_entry *__pw_get_head (void) -diff --git a/lib/sgroupio.c b/lib/sgroupio.c -index 025584ad..dbabcc36 100644 ---- a/lib/sgroupio.c -+++ b/lib/sgroupio.c -@@ -283,7 +283,7 @@ int sgr_close (bool process_selinux) - - int sgr_unlock (void) - { -- return commonio_unlock (&gshadow_db); -+ return commonio_unlock (&gshadow_db, true); - } - - void __sgr_set_changed (void) -diff --git a/lib/shadowio.c b/lib/shadowio.c -index a109576d..9866af6d 100644 ---- a/lib/shadowio.c -+++ b/lib/shadowio.c -@@ -211,7 +211,7 @@ int spw_unlock (void) - - if (!getdef_bool ("USE_TCB")) { - #endif /* WITH_TCB */ -- return commonio_unlock (&shadow_db); -+ return commonio_unlock (&shadow_db, true); - #ifdef WITH_TCB - } - if (shadowtcb_drop_priv () == SHADOWTCB_FAILURE) { -diff --git a/lib/subordinateio.c b/lib/subordinateio.c -index e2c2375a..9587e1a9 100644 ---- a/lib/subordinateio.c -+++ b/lib/subordinateio.c -@@ -675,7 +675,7 @@ int sub_uid_close (bool process_selinux) - - int sub_uid_unlock (void) - { -- return commonio_unlock (&subordinate_uid_db); -+ return commonio_unlock (&subordinate_uid_db, true); - } - - uid_t sub_uid_find_free_range(uid_t min, uid_t max, unsigned long count) -@@ -782,7 +782,7 @@ int sub_gid_close (bool process_selinux) - - int sub_gid_unlock (void) - { -- return commonio_unlock (&subordinate_gid_db); -+ return commonio_unlock (&subordinate_gid_db, true); - } - - gid_t sub_gid_find_free_range(gid_t min, gid_t max, unsigned long count) --- -2.50.0 - - -From 9609c3ba7d4097c2ff63ee6ccfa6b74c41fbde5e Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Fri, 25 Apr 2025 15:53:17 +0200 -Subject: [PATCH 09/15] lib/, src/: add SELinux control flag in pw_unlock() - -Expand pw_unlock() interface to add a control flag for SELinux file -context processing. - -Signed-off-by: Iker Pedrosa ---- - lib/cleanup_user.c | 2 +- - lib/lockpw.c | 4 ++-- - lib/pwio.c | 4 ++-- - lib/pwio.h | 2 +- - src/chage.c | 4 ++-- - src/chfn.c | 4 ++-- - src/chpasswd.c | 4 ++-- - src/chsh.c | 4 ++-- - src/newusers.c | 4 ++-- - src/passwd.c | 4 ++-- - src/pwck.c | 4 ++-- - src/pwconv.c | 4 ++-- - src/pwunconv.c | 4 ++-- - src/useradd.c | 4 ++-- - src/userdel.c | 4 ++-- - src/usermod.c | 4 ++-- - 16 files changed, 30 insertions(+), 30 deletions(-) - -diff --git a/lib/cleanup_user.c b/lib/cleanup_user.c -index 809caaf3..a661f5e9 100644 ---- a/lib/cleanup_user.c -+++ b/lib/cleanup_user.c -@@ -98,7 +98,7 @@ void cleanup_report_add_user_shadow (void *user_name) - */ - void cleanup_unlock_passwd (MAYBE_UNUSED void *arg) - { -- if (pw_unlock () == 0) { -+ if (pw_unlock (true) == 0) { - fprintf (log_get_logfd(), - _("%s: failed to unlock %s\n"), - log_get_progname(), pw_dbname ()); -diff --git a/lib/lockpw.c b/lib/lockpw.c -index 15e7c8f4..f73c434a 100644 ---- a/lib/lockpw.c -+++ b/lib/lockpw.c -@@ -56,7 +56,7 @@ int lckpwdf (void) - */ - - if (i == 15) { -- pw_unlock (); -+ pw_unlock (true); - return -1; - } - -@@ -78,7 +78,7 @@ int ulckpwdf (void) - * Unlock both files. - */ - -- return (pw_unlock () && spw_unlock ())? 0 : -1; -+ return (pw_unlock (true) && spw_unlock ())? 0 : -1; - } - #else - extern int ISO_C_forbids_an_empty_translation_unit; -diff --git a/lib/pwio.c b/lib/pwio.c -index c5dcb904..78146c37 100644 ---- a/lib/pwio.c -+++ b/lib/pwio.c -@@ -161,9 +161,9 @@ int pw_close (bool process_selinux) - return commonio_close (&passwd_db, process_selinux); - } - --int pw_unlock (void) -+int pw_unlock (bool process_selinux) - { -- return commonio_unlock (&passwd_db, true); -+ return commonio_unlock (&passwd_db, process_selinux); - } - - /*@null@*/struct commonio_entry *__pw_get_head (void) -diff --git a/lib/pwio.h b/lib/pwio.h -index b051a7e7..0903b8bd 100644 ---- a/lib/pwio.h -+++ b/lib/pwio.h -@@ -26,7 +26,7 @@ extern /*@observer@*/ /*@null@*/const struct passwd *pw_next (void); - extern int pw_open (int mode); - extern int pw_remove (const char *name); - extern int pw_rewind (void); --extern int pw_unlock (void); -+extern int pw_unlock (bool process_selinux); - extern int pw_update (const struct passwd *pw); - extern int pw_sort (void); - -diff --git a/src/chage.c b/src/chage.c -index a59428c5..d3a42ccf 100644 ---- a/src/chage.c -+++ b/src/chage.c -@@ -101,7 +101,7 @@ fail_exit (int code) - } - } - if (pw_locked) { -- if (pw_unlock () == 0) { -+ if (pw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -@@ -568,7 +568,7 @@ static void close_files (void) - /* continue */ - } - spw_locked = false; -- if (pw_unlock () == 0) { -+ if (pw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -diff --git a/src/chfn.c b/src/chfn.c -index abf88cc8..dca81486 100644 ---- a/src/chfn.c -+++ b/src/chfn.c -@@ -79,7 +79,7 @@ static void get_old_fields (const char *gecos); - static void fail_exit (int code) - { - if (pw_locked) { -- if (pw_unlock () == 0) { -+ if (pw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -@@ -498,7 +498,7 @@ static void update_gecos (const char *user, char *gecos) - SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); - fail_exit (E_NOPERM); - } -- if (pw_unlock () == 0) { -+ if (pw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -diff --git a/src/chpasswd.c b/src/chpasswd.c -index e3d8dcef..5323c520 100644 ---- a/src/chpasswd.c -+++ b/src/chpasswd.c -@@ -81,7 +81,7 @@ static void close_files (void); - static void fail_exit (int code) - { - if (pw_locked) { -- if (pw_unlock () == 0) { -+ if (pw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -@@ -400,7 +400,7 @@ static void close_files (void) - SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); - fail_exit (1); - } -- if (pw_unlock () == 0) { -+ if (pw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -diff --git a/src/chsh.c b/src/chsh.c -index b5ae28da..4403d412 100644 ---- a/src/chsh.c -+++ b/src/chsh.c -@@ -78,7 +78,7 @@ static void - fail_exit (int code) - { - if (pw_locked) { -- if (pw_unlock () == 0) { -+ if (pw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -@@ -433,7 +433,7 @@ static void update_shell (const char *user, char *newshell) - SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); - fail_exit (1); - } -- if (pw_unlock () == 0) { -+ if (pw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -diff --git a/src/newusers.c b/src/newusers.c -index 8cd11a71..669b6236 100644 ---- a/src/newusers.c -+++ b/src/newusers.c -@@ -172,7 +172,7 @@ static void fail_exit (int code) - } - } - if (pw_locked) { -- if (pw_unlock () == 0) { -+ if (pw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -@@ -944,7 +944,7 @@ static void close_files (void) - SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); - fail_exit (EXIT_FAILURE); - } -- if (pw_unlock () == 0) { -+ if (pw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -diff --git a/src/passwd.c b/src/passwd.c -index 01efb285..8a55d797 100644 ---- a/src/passwd.c -+++ b/src/passwd.c -@@ -483,7 +483,7 @@ static void - fail_exit (int status) - { - if (pw_locked) { -- if (pw_unlock () == 0) { -+ if (pw_unlock (true) == 0) { - (void) fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -@@ -593,7 +593,7 @@ static void update_noshadow (void) - SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); - fail_exit (E_FAILURE); - } -- if (pw_unlock () == 0) { -+ if (pw_unlock (true) == 0) { - (void) fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, pw_dbname ()); -diff --git a/src/pwck.c b/src/pwck.c -index 718b639f..f30c5289 100644 ---- a/src/pwck.c -+++ b/src/pwck.c -@@ -96,7 +96,7 @@ static void fail_exit (int code) - } - - if (pw_locked) { -- if (pw_unlock () == 0) { -+ if (pw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - if (use_system_pw_file) { - SYSLOG ((LOG_ERR, "failed to unlock %s", -@@ -351,7 +351,7 @@ static void close_files (bool changed) - } - spw_locked = false; - if (pw_locked) { -- if (pw_unlock () == 0) { -+ if (pw_unlock (true) == 0) { - fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, pw_dbname ()); -diff --git a/src/pwconv.c b/src/pwconv.c -index 296b527a..82181bb4 100644 ---- a/src/pwconv.c -+++ b/src/pwconv.c -@@ -83,7 +83,7 @@ static void process_flags (int argc, char **argv); - static void fail_exit (int status) - { - if (pw_locked) { -- if (pw_unlock () == 0) { -+ if (pw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -@@ -299,7 +299,7 @@ int main (int argc, char **argv) - /* continue */ - } - -- if (pw_unlock () == 0) { -+ if (pw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -diff --git a/src/pwunconv.c b/src/pwunconv.c -index e15c8c06..72944fe5 100644 ---- a/src/pwunconv.c -+++ b/src/pwunconv.c -@@ -54,7 +54,7 @@ static void fail_exit (int status) - } - } - if (pw_locked) { -- if (pw_unlock () == 0) { -+ if (pw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -@@ -227,7 +227,7 @@ int main (int argc, char **argv) - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - /* continue */ - } -- if (pw_unlock () == 0) { -+ if (pw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -diff --git a/src/useradd.c b/src/useradd.c -index 3d2fdb35..aa070f2d 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -270,7 +270,7 @@ static void fail_exit (int code) - SYSLOG((LOG_ERR, "failed to unlock %s", spw_dbname())); - /* continue */ - } -- if (pw_locked && pw_unlock() == 0) { -+ if (pw_locked && pw_unlock(true) == 0) { - fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname()); - SYSLOG((LOG_ERR, "failed to unlock %s", pw_dbname())); - /* continue */ -@@ -1606,7 +1606,7 @@ static void close_files (void) - } - spw_locked = false; - } -- if (pw_unlock () == 0) { -+ if (pw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - #ifdef WITH_AUDIT -diff --git a/src/userdel.c b/src/userdel.c -index 7dcbd923..b4e87820 100644 ---- a/src/userdel.c -+++ b/src/userdel.c -@@ -395,7 +395,7 @@ static void close_files (void) - SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); - fail_exit (E_PW_UPDATE); - } -- if (pw_unlock () == 0) { -+ if (pw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -@@ -484,7 +484,7 @@ static void close_files (void) - static void fail_exit (int code) - { - if (pw_locked) { -- if (pw_unlock () == 0) { -+ if (pw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -diff --git a/src/usermod.c b/src/usermod.c -index 534bdc74..6f761404 100644 ---- a/src/usermod.c -+++ b/src/usermod.c -@@ -655,7 +655,7 @@ fail_exit (int code) - } - } - if (pw_locked) { -- if (pw_unlock () == 0) { -+ if (pw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -@@ -1544,7 +1544,7 @@ static void close_files (void) - /* continue */ - } - } -- if (pw_unlock () == 0) { -+ if (pw_unlock (true) == 0) { - fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, pw_dbname ()); --- -2.50.0 - - -From bdce75b7b6f7ec69cda287b081de6ca83022ee79 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Fri, 25 Apr 2025 15:57:21 +0200 -Subject: [PATCH 10/15] lib/, src/: add SELinux control flag in spw_unlock() - -Expand spw_unlock() interface to add a control flag for SELinux file -context processing. - -Signed-off-by: Iker Pedrosa ---- - lib/cleanup_user.c | 2 +- - lib/lockpw.c | 2 +- - lib/shadowio.c | 4 ++-- - lib/shadowio.h | 2 +- - src/chage.c | 4 ++-- - src/chpasswd.c | 4 ++-- - src/newusers.c | 4 ++-- - src/passwd.c | 6 +++--- - src/pwck.c | 8 ++++---- - src/pwconv.c | 4 ++-- - src/pwunconv.c | 4 ++-- - src/useradd.c | 4 ++-- - src/userdel.c | 4 ++-- - src/usermod.c | 4 ++-- - 14 files changed, 28 insertions(+), 28 deletions(-) - -diff --git a/lib/cleanup_user.c b/lib/cleanup_user.c -index a661f5e9..b3a5a66e 100644 ---- a/lib/cleanup_user.c -+++ b/lib/cleanup_user.c -@@ -117,7 +117,7 @@ void cleanup_unlock_passwd (MAYBE_UNUSED void *arg) - */ - void cleanup_unlock_shadow (MAYBE_UNUSED void *arg) - { -- if (spw_unlock () == 0) { -+ if (spw_unlock (true) == 0) { - fprintf (log_get_logfd(), - _("%s: failed to unlock %s\n"), - log_get_progname(), spw_dbname ()); -diff --git a/lib/lockpw.c b/lib/lockpw.c -index f73c434a..7c99d56e 100644 ---- a/lib/lockpw.c -+++ b/lib/lockpw.c -@@ -78,7 +78,7 @@ int ulckpwdf (void) - * Unlock both files. - */ - -- return (pw_unlock (true) && spw_unlock ())? 0 : -1; -+ return (pw_unlock (true) && spw_unlock (true))? 0 : -1; - } - #else - extern int ISO_C_forbids_an_empty_translation_unit; -diff --git a/lib/shadowio.c b/lib/shadowio.c -index 9866af6d..71089eda 100644 ---- a/lib/shadowio.c -+++ b/lib/shadowio.c -@@ -204,14 +204,14 @@ int spw_close (bool process_selinux) - return retval; - } - --int spw_unlock (void) -+int spw_unlock (bool process_selinux) - { - #ifdef WITH_TCB - int retval = 0; - - if (!getdef_bool ("USE_TCB")) { - #endif /* WITH_TCB */ -- return commonio_unlock (&shadow_db, true); -+ return commonio_unlock (&shadow_db, process_selinux); - #ifdef WITH_TCB - } - if (shadowtcb_drop_priv () == SHADOWTCB_FAILURE) { -diff --git a/lib/shadowio.h b/lib/shadowio.h -index e64d8d60..be645d0e 100644 ---- a/lib/shadowio.h -+++ b/lib/shadowio.h -@@ -23,7 +23,7 @@ extern /*@observer@*/ /*@null@*/const struct spwd *spw_next (void); - extern int spw_open (int mode); - extern int spw_remove (const char *name); - extern int spw_rewind (void); --extern int spw_unlock (void); -+extern int spw_unlock (bool process_selinux); - extern int spw_update (const struct spwd *sp); - extern int spw_sort (void); - -diff --git a/src/chage.c b/src/chage.c -index d3a42ccf..e77a46de 100644 ---- a/src/chage.c -+++ b/src/chage.c -@@ -94,7 +94,7 @@ static void - fail_exit (int code) - { - if (spw_locked) { -- if (spw_unlock () == 0) { -+ if (spw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - /* continue */ -@@ -562,7 +562,7 @@ static void close_files (void) - SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); - fail_exit (E_NOPERM); - } -- if (spw_unlock () == 0) { -+ if (spw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - /* continue */ -diff --git a/src/chpasswd.c b/src/chpasswd.c -index 5323c520..2656b039 100644 ---- a/src/chpasswd.c -+++ b/src/chpasswd.c -@@ -89,7 +89,7 @@ static void fail_exit (int code) - } - - if (spw_locked) { -- if (spw_unlock () == 0) { -+ if (spw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - /* continue */ -@@ -385,7 +385,7 @@ static void close_files (void) - SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); - fail_exit (1); - } -- if (spw_unlock () == 0) { -+ if (spw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - /* continue */ -diff --git a/src/newusers.c b/src/newusers.c -index 669b6236..4cbb1639 100644 ---- a/src/newusers.c -+++ b/src/newusers.c -@@ -165,7 +165,7 @@ static void usage (int status) - static void fail_exit (int code) - { - if (spw_locked) { -- if (spw_unlock () == 0) { -+ if (spw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - /* continue */ -@@ -959,7 +959,7 @@ static void close_files (void) - SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); - fail_exit (EXIT_FAILURE); - } -- if (spw_unlock () == 0) { -+ if (spw_unlock (true) == 0) { - fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, spw_dbname ()); -diff --git a/src/passwd.c b/src/passwd.c -index 8a55d797..512dc572 100644 ---- a/src/passwd.c -+++ b/src/passwd.c -@@ -491,7 +491,7 @@ fail_exit (int status) - } - - if (spw_locked) { -- if (spw_unlock () == 0) { -+ if (spw_unlock (true) == 0) { - (void) fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - /* continue */ -@@ -627,7 +627,7 @@ static void update_shadow (void) - /* Try to update the password in /etc/passwd instead. */ - (void) spw_close (true); - update_noshadow (); -- if (spw_unlock () == 0) { -+ if (spw_unlock (true) == 0) { - (void) fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, spw_dbname ()); -@@ -688,7 +688,7 @@ static void update_shadow (void) - SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); - fail_exit (E_FAILURE); - } -- if (spw_unlock () == 0) { -+ if (spw_unlock (true) == 0) { - (void) fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, spw_dbname ()); -diff --git a/src/pwck.c b/src/pwck.c -index f30c5289..9c4cc29a 100644 ---- a/src/pwck.c -+++ b/src/pwck.c -@@ -85,7 +85,7 @@ extern int allow_bad_names; - static void fail_exit (int code) - { - if (spw_locked) { -- if (spw_unlock () == 0) { -+ if (spw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); - if (use_system_spw_file) { - SYSLOG ((LOG_ERR, "failed to unlock %s", -@@ -338,7 +338,7 @@ static void close_files (bool changed) - * Don't be anti-social - unlock the files when you're done. - */ - if (spw_locked) { -- if (spw_unlock () == 0) { -+ if (spw_unlock (true) == 0) { - fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, spw_dbname ()); -@@ -581,7 +581,7 @@ static void check_pw_file (bool *errors, bool *changed) - _("%s: cannot open %s\n"), - Prog, spw_dbname ()); - *errors = true; -- if (spw_unlock () == 0) { -+ if (spw_unlock (true) == 0) { - fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, spw_dbname ()); -@@ -669,7 +669,7 @@ static void check_pw_file (bool *errors, bool *changed) - } else { - spw_opened = false; - } -- if (spw_unlock () == 0) { -+ if (spw_unlock (true) == 0) { - fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, spw_dbname ()); -diff --git a/src/pwconv.c b/src/pwconv.c -index 82181bb4..b0d668b5 100644 ---- a/src/pwconv.c -+++ b/src/pwconv.c -@@ -91,7 +91,7 @@ static void fail_exit (int status) - } - - if (spw_locked) { -- if (spw_unlock () == 0) { -+ if (spw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - /* continue */ -@@ -305,7 +305,7 @@ int main (int argc, char **argv) - /* continue */ - } - -- if (spw_unlock () == 0) { -+ if (spw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - /* continue */ -diff --git a/src/pwunconv.c b/src/pwunconv.c -index 72944fe5..7a6d2be5 100644 ---- a/src/pwunconv.c -+++ b/src/pwunconv.c -@@ -47,7 +47,7 @@ static void process_flags (int argc, char **argv); - static void fail_exit (int status) - { - if (spw_locked) { -- if (spw_unlock () == 0) { -+ if (spw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - /* continue */ -@@ -222,7 +222,7 @@ int main (int argc, char **argv) - fail_exit (3); - } - -- if (spw_unlock () == 0) { -+ if (spw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - /* continue */ -diff --git a/src/useradd.c b/src/useradd.c -index aa070f2d..9c8b774f 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -265,7 +265,7 @@ static void fail_exit (int code) - SYSLOG((LOG_ERR, "failed to remove %s", prefix_user_home)); - } - -- if (spw_locked && spw_unlock() == 0) { -+ if (spw_locked && spw_unlock(true) == 0) { - fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname()); - SYSLOG((LOG_ERR, "failed to unlock %s", spw_dbname())); - /* continue */ -@@ -1593,7 +1593,7 @@ static void close_files (void) - } - #endif /* ENABLE_SUBIDS */ - if (is_shadow_pwd) { -- if (spw_unlock () == 0) { -+ if (spw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - #ifdef WITH_AUDIT -diff --git a/src/userdel.c b/src/userdel.c -index b4e87820..478c22d5 100644 ---- a/src/userdel.c -+++ b/src/userdel.c -@@ -409,7 +409,7 @@ static void close_files (void) - SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); - fail_exit (E_PW_UPDATE); - } -- if (spw_unlock () == 0) { -+ if (spw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - /* continue */ -@@ -498,7 +498,7 @@ static void fail_exit (int code) - } - } - if (spw_locked) { -- if (spw_unlock () == 0) { -+ if (spw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - /* continue */ -diff --git a/src/usermod.c b/src/usermod.c -index 6f761404..68373f35 100644 ---- a/src/usermod.c -+++ b/src/usermod.c -@@ -648,7 +648,7 @@ fail_exit (int code) - } - #endif - if (spw_locked) { -- if (spw_unlock () == 0) { -+ if (spw_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - /* continue */ -@@ -1534,7 +1534,7 @@ static void close_files (void) - } - - if (is_shadow_pwd) { -- if (spw_unlock () == 0) { -+ if (spw_unlock (true) == 0) { - fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, spw_dbname ()); --- -2.50.0 - - -From 68eb3395a4bcbbdb820b6c8c17cc64fb08749d11 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Fri, 25 Apr 2025 16:00:43 +0200 -Subject: [PATCH 11/15] lib/, src/: add SELinux control flag in gr_unlock() - -Expand gr_unlock() interface to add a control flag for SELinux file -context processing. - -Signed-off-by: Iker Pedrosa ---- - lib/cleanup_group.c | 2 +- - lib/groupio.c | 4 ++-- - lib/groupio.h | 2 +- - src/chgpasswd.c | 4 ++-- - src/groupmems.c | 4 ++-- - src/grpck.c | 4 ++-- - src/grpconv.c | 4 ++-- - src/grpunconv.c | 4 ++-- - src/newusers.c | 4 ++-- - src/useradd.c | 4 ++-- - src/userdel.c | 4 ++-- - src/usermod.c | 4 ++-- - 12 files changed, 22 insertions(+), 22 deletions(-) - -diff --git a/lib/cleanup_group.c b/lib/cleanup_group.c -index 54480092..a5846152 100644 ---- a/lib/cleanup_group.c -+++ b/lib/cleanup_group.c -@@ -181,7 +181,7 @@ void cleanup_report_del_group_gshadow (void *group_name) - */ - void cleanup_unlock_group (MAYBE_UNUSED void *arg) - { -- if (gr_unlock () == 0) { -+ if (gr_unlock (true) == 0) { - fprintf (log_get_logfd(), - _("%s: failed to unlock %s\n"), - log_get_progname(), gr_dbname ()); -diff --git a/lib/groupio.c b/lib/groupio.c -index 6ad4ae69..f21aa618 100644 ---- a/lib/groupio.c -+++ b/lib/groupio.c -@@ -189,9 +189,9 @@ int gr_close (bool process_selinux) - return commonio_close (&group_db, process_selinux); - } - --int gr_unlock (void) -+int gr_unlock (bool process_selinux) - { -- return commonio_unlock (&group_db, true); -+ return commonio_unlock (&group_db, process_selinux); - } - - void __gr_set_changed (void) -diff --git a/lib/groupio.h b/lib/groupio.h -index ef9242d0..eae13cd3 100644 ---- a/lib/groupio.h -+++ b/lib/groupio.h -@@ -26,7 +26,7 @@ extern /*@observer@*/ /*@null@*/const struct group *gr_next (void); - extern int gr_open (int mode); - extern int gr_remove (const char *name); - extern int gr_rewind (void); --extern int gr_unlock (void); -+extern int gr_unlock (bool process_selinux); - extern int gr_update (const struct group *gr); - extern int gr_sort (void); - -diff --git a/src/chgpasswd.c b/src/chgpasswd.c -index 47402ecc..84553d81 100644 ---- a/src/chgpasswd.c -+++ b/src/chgpasswd.c -@@ -82,7 +82,7 @@ static void close_files (void); - static void fail_exit (int code) - { - if (gr_locked) { -- if (gr_unlock () == 0) { -+ if (gr_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); - /* continue */ -@@ -404,7 +404,7 @@ static void close_files (void) - SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ())); - fail_exit (1); - } -- if (gr_unlock () == 0) { -+ if (gr_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); - /* continue */ -diff --git a/src/groupmems.c b/src/groupmems.c -index 5976b074..0c59474f 100644 ---- a/src/groupmems.c -+++ b/src/groupmems.c -@@ -457,7 +457,7 @@ static void check_perms (void) - static void fail_exit (int code) - { - if (gr_locked) { -- if (gr_unlock () == 0) { -+ if (gr_unlock (true) == 0) { - fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, gr_dbname ()); -@@ -528,7 +528,7 @@ static void close_files (void) - fail_exit (EXIT_GROUP_FILE); - } - if (gr_locked) { -- if (gr_unlock () == 0) { -+ if (gr_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); - /* continue */ -diff --git a/src/grpck.c b/src/grpck.c -index 872f882f..bd2014fc 100644 ---- a/src/grpck.c -+++ b/src/grpck.c -@@ -92,7 +92,7 @@ static void check_sgr_file (bool *errors, bool *changed); - static void fail_exit (int status) - { - if (gr_locked) { -- if (gr_unlock () == 0) { -+ if (gr_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); - /* continue */ -@@ -349,7 +349,7 @@ static void close_files (bool changed) - } - #endif - if (gr_locked) { -- if (gr_unlock () == 0) { -+ if (gr_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); - /* continue */ -diff --git a/src/grpconv.c b/src/grpconv.c -index d9c59fc9..3160b8b1 100644 ---- a/src/grpconv.c -+++ b/src/grpconv.c -@@ -56,7 +56,7 @@ static void process_flags (int argc, char **argv); - static void fail_exit (int status) - { - if (gr_locked) { -- if (gr_unlock () == 0) { -+ if (gr_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); - /* continue */ -@@ -253,7 +253,7 @@ int main (int argc, char **argv) - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - /* continue */ - } -- if (gr_unlock () == 0) { -+ if (gr_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); - /* continue */ -diff --git a/src/grpunconv.c b/src/grpunconv.c -index 03fc824e..085c48ac 100644 ---- a/src/grpunconv.c -+++ b/src/grpunconv.c -@@ -55,7 +55,7 @@ static void process_flags (int argc, char **argv); - static void fail_exit (int status) - { - if (gr_locked) { -- if (gr_unlock () == 0) { -+ if (gr_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); - /* continue */ -@@ -209,7 +209,7 @@ int main (int argc, char **argv) - fail_exit (3); - } - -- if (gr_unlock () == 0) { -+ if (gr_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); - /* continue */ -diff --git a/src/newusers.c b/src/newusers.c -index 4cbb1639..47f01661 100644 ---- a/src/newusers.c -+++ b/src/newusers.c -@@ -179,7 +179,7 @@ static void fail_exit (int code) - } - } - if (gr_locked) { -- if (gr_unlock () == 0) { -+ if (gr_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); - /* continue */ -@@ -991,7 +991,7 @@ static void close_files (void) - } - #endif /* ENABLE_SUBIDS */ - -- if (gr_unlock () == 0) { -+ if (gr_unlock (true) == 0) { - fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, gr_dbname ()); -diff --git a/src/useradd.c b/src/useradd.c -index 9c8b774f..75cfbde2 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -275,7 +275,7 @@ static void fail_exit (int code) - SYSLOG((LOG_ERR, "failed to unlock %s", pw_dbname())); - /* continue */ - } -- if (gr_locked && gr_unlock() == 0) { -+ if (gr_locked && gr_unlock(true) == 0) { - fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname()); - SYSLOG((LOG_ERR, "failed to unlock %s", gr_dbname())); - /* continue */ -@@ -1690,7 +1690,7 @@ static void close_group_files (void) - */ - static void unlock_group_files (void) - { -- if (gr_unlock () == 0) { -+ if (gr_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); - #ifdef WITH_AUDIT -diff --git a/src/userdel.c b/src/userdel.c -index 478c22d5..12696732 100644 ---- a/src/userdel.c -+++ b/src/userdel.c -@@ -422,7 +422,7 @@ static void close_files (void) - SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ())); - fail_exit (E_GRP_UPDATE); - } -- if (gr_unlock () == 0) { -+ if (gr_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); - /* continue */ -@@ -491,7 +491,7 @@ static void fail_exit (int code) - } - } - if (gr_locked) { -- if (gr_unlock () == 0) { -+ if (gr_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); - /* continue */ -diff --git a/src/usermod.c b/src/usermod.c -index 68373f35..2e21a70f 100644 ---- a/src/usermod.c -+++ b/src/usermod.c -@@ -632,7 +632,7 @@ static void - fail_exit (int code) - { - if (gr_locked) { -- if (gr_unlock () == 0) { -+ if (gr_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); - /* continue */ -@@ -1522,7 +1522,7 @@ static void close_files (void) - } - } - #endif -- if (gr_unlock () == 0) { -+ if (gr_unlock (true) == 0) { - fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, gr_dbname ()); --- -2.50.0 - - -From 37b636524cfb7c9b7dce8c56484fb60795ef2b91 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Fri, 25 Apr 2025 16:03:58 +0200 -Subject: [PATCH 12/15] lib/, src/: add SELinux control flag in sgr_unlock() - -Expand sgr_unlock() interface to add a control flag for SELinux file -context processing. - -Signed-off-by: Iker Pedrosa ---- - lib/cleanup_group.c | 2 +- - lib/sgroupio.c | 4 ++-- - lib/sgroupio.h | 2 +- - src/chgpasswd.c | 4 ++-- - src/groupmems.c | 4 ++-- - src/grpck.c | 4 ++-- - src/grpconv.c | 4 ++-- - src/grpunconv.c | 4 ++-- - src/newusers.c | 4 ++-- - src/useradd.c | 4 ++-- - src/userdel.c | 4 ++-- - src/usermod.c | 4 ++-- - 12 files changed, 22 insertions(+), 22 deletions(-) - -diff --git a/lib/cleanup_group.c b/lib/cleanup_group.c -index a5846152..dc9f1eb2 100644 ---- a/lib/cleanup_group.c -+++ b/lib/cleanup_group.c -@@ -201,7 +201,7 @@ void cleanup_unlock_group (MAYBE_UNUSED void *arg) - */ - void cleanup_unlock_gshadow (MAYBE_UNUSED void *arg) - { -- if (sgr_unlock () == 0) { -+ if (sgr_unlock (true) == 0) { - fprintf (log_get_logfd(), - _("%s: failed to unlock %s\n"), - log_get_progname(), sgr_dbname ()); -diff --git a/lib/sgroupio.c b/lib/sgroupio.c -index dbabcc36..4239e23d 100644 ---- a/lib/sgroupio.c -+++ b/lib/sgroupio.c -@@ -281,9 +281,9 @@ int sgr_close (bool process_selinux) - return commonio_close (&gshadow_db, process_selinux); - } - --int sgr_unlock (void) -+int sgr_unlock (bool process_selinux) - { -- return commonio_unlock (&gshadow_db, true); -+ return commonio_unlock (&gshadow_db, process_selinux); - } - - void __sgr_set_changed (void) -diff --git a/lib/sgroupio.h b/lib/sgroupio.h -index 0e25fc0b..256f6d54 100644 ---- a/lib/sgroupio.h -+++ b/lib/sgroupio.h -@@ -22,7 +22,7 @@ extern /*@null@*/const struct sgrp *sgr_next (void); - extern int sgr_open (int mode); - extern int sgr_remove (const char *name); - extern int sgr_rewind (void); --extern int sgr_unlock (void); -+extern int sgr_unlock (bool process_selinux); - extern int sgr_update (const struct sgrp *sg); - extern int sgr_sort (void); - -diff --git a/src/chgpasswd.c b/src/chgpasswd.c -index 84553d81..27094f50 100644 ---- a/src/chgpasswd.c -+++ b/src/chgpasswd.c -@@ -91,7 +91,7 @@ static void fail_exit (int code) - - #ifdef SHADOWGRP - if (sgr_locked) { -- if (sgr_unlock () == 0) { -+ if (sgr_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - /* continue */ -@@ -388,7 +388,7 @@ static void close_files (void) - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ())); - fail_exit (1); - } -- if (sgr_unlock () == 0) { -+ if (sgr_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - /* continue */ -diff --git a/src/groupmems.c b/src/groupmems.c -index 0c59474f..f39724c8 100644 ---- a/src/groupmems.c -+++ b/src/groupmems.c -@@ -468,7 +468,7 @@ static void fail_exit (int code) - - #ifdef SHADOWGRP - if (sgr_locked) { -- if (sgr_unlock () == 0) { -+ if (sgr_unlock (true) == 0) { - fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, sgr_dbname ()); -@@ -544,7 +544,7 @@ static void close_files (void) - fail_exit (EXIT_GROUP_FILE); - } - if (sgr_locked) { -- if (sgr_unlock () == 0) { -+ if (sgr_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - /* continue */ -diff --git a/src/grpck.c b/src/grpck.c -index bd2014fc..bc178d52 100644 ---- a/src/grpck.c -+++ b/src/grpck.c -@@ -101,7 +101,7 @@ static void fail_exit (int status) - - #ifdef SHADOWGRP - if (sgr_locked) { -- if (sgr_unlock () == 0) { -+ if (sgr_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - /* continue */ -@@ -340,7 +340,7 @@ static void close_files (bool changed) - */ - #ifdef SHADOWGRP - if (sgr_locked) { -- if (sgr_unlock () == 0) { -+ if (sgr_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - /* continue */ -diff --git a/src/grpconv.c b/src/grpconv.c -index 3160b8b1..5958d3f5 100644 ---- a/src/grpconv.c -+++ b/src/grpconv.c -@@ -64,7 +64,7 @@ static void fail_exit (int status) - } - - if (sgr_locked) { -- if (sgr_unlock () == 0) { -+ if (sgr_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - /* continue */ -@@ -248,7 +248,7 @@ int main (int argc, char **argv) - SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ())); - fail_exit (3); - } -- if (sgr_unlock () == 0) { -+ if (sgr_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - /* continue */ -diff --git a/src/grpunconv.c b/src/grpunconv.c -index 085c48ac..5256e0bc 100644 ---- a/src/grpunconv.c -+++ b/src/grpunconv.c -@@ -63,7 +63,7 @@ static void fail_exit (int status) - } - - if (sgr_locked) { -- if (sgr_unlock () == 0) { -+ if (sgr_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - /* continue */ -@@ -215,7 +215,7 @@ int main (int argc, char **argv) - /* continue */ - } - -- if (sgr_unlock () == 0) { -+ if (sgr_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - /* continue */ -diff --git a/src/newusers.c b/src/newusers.c -index 47f01661..261a5911 100644 ---- a/src/newusers.c -+++ b/src/newusers.c -@@ -187,7 +187,7 @@ static void fail_exit (int code) - } - #ifdef SHADOWGRP - if (sgr_locked) { -- if (sgr_unlock () == 0) { -+ if (sgr_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - /* continue */ -@@ -1009,7 +1009,7 @@ static void close_files (void) - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ())); - fail_exit (EXIT_FAILURE); - } -- if (sgr_unlock () == 0) { -+ if (sgr_unlock (true) == 0) { - fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, sgr_dbname ()); -diff --git a/src/useradd.c b/src/useradd.c -index 75cfbde2..cb7ac88e 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -281,7 +281,7 @@ static void fail_exit (int code) - /* continue */ - } - #ifdef SHADOWGRP -- if (sgr_locked && sgr_unlock() == 0) { -+ if (sgr_locked && sgr_unlock(true) == 0) { - fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname()); - SYSLOG((LOG_ERR, "failed to unlock %s", sgr_dbname())); - /* continue */ -@@ -1704,7 +1704,7 @@ static void unlock_group_files (void) - gr_locked = false; - #ifdef SHADOWGRP - if (is_shadow_grp) { -- if (sgr_unlock () == 0) { -+ if (sgr_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - #ifdef WITH_AUDIT -diff --git a/src/userdel.c b/src/userdel.c -index 12696732..80ed1a48 100644 ---- a/src/userdel.c -+++ b/src/userdel.c -@@ -438,7 +438,7 @@ static void close_files (void) - fail_exit (E_GRP_UPDATE); - } - -- if (sgr_unlock () == 0) { -+ if (sgr_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - /* continue */ -@@ -506,7 +506,7 @@ static void fail_exit (int code) - } - #ifdef SHADOWGRP - if (sgr_locked) { -- if (sgr_unlock () == 0) { -+ if (sgr_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - /* continue */ -diff --git a/src/usermod.c b/src/usermod.c -index 2e21a70f..69ea8e55 100644 ---- a/src/usermod.c -+++ b/src/usermod.c -@@ -640,7 +640,7 @@ fail_exit (int code) - } - #ifdef SHADOWGRP - if (sgr_locked) { -- if (sgr_unlock () == 0) { -+ if (sgr_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - /* continue */ -@@ -1511,7 +1511,7 @@ static void close_files (void) - #endif - #ifdef SHADOWGRP - if (is_shadow_grp) { -- if (sgr_unlock () == 0) { -+ if (sgr_unlock (true) == 0) { - fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, sgr_dbname ()); --- -2.50.0 - - -From dee1a5a5782b8aafcc32c7f93a53ce591355d1b3 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Fri, 25 Apr 2025 16:06:57 +0200 -Subject: [PATCH 13/15] src/vipw.c: add SELinux control flag in unlock - -All unlock functions require the SELinux control flag, thus add it as an -argument. - -Signed-off-by: Iker Pedrosa ---- - src/vipw.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/src/vipw.c b/src/vipw.c -index 3c840e9f..ba323e0e 100644 ---- a/src/vipw.c -+++ b/src/vipw.c -@@ -62,7 +62,7 @@ static const char *Prog; - static const char *filename, *fileeditname; - static bool filelocked = false; - static bool createedit = false; --static int (*unlock) (void); -+static int (*unlock) (bool); - static bool quiet = false; - #ifdef WITH_TCB - static const char *user = NULL; -@@ -74,7 +74,7 @@ static bool tcb_mode = false; - static void usage (int status); - static int create_backup_file (FILE *, const char *, struct stat *); - static void vipwexit (const char *msg, int syserr, int ret); --static void vipwedit (const char *, int (*)(void), int (*)(void)); -+static void vipwedit (const char *, int (*)(void), int (*)(bool)); - - /* - * usage - display usage message and exit -@@ -164,7 +164,7 @@ static void vipwexit (const char *msg, int syserr, int ret) - } - } - if (filelocked) { -- if ((*unlock) () == 0) { -+ if ((*unlock) (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, fileeditname); - SYSLOG ((LOG_ERR, "failed to unlock %s", fileeditname)); - /* continue */ -@@ -195,7 +195,7 @@ static void vipwexit (const char *msg, int syserr, int ret) - * - */ - static void --vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (void)) -+vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (bool)) - { - int status; - char *to_rename; -@@ -467,7 +467,7 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (void)) - } - #endif /* WITH_TCB */ - -- if ((*file_unlock) () == 0) { -+ if ((*file_unlock) (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, fileeditname); - SYSLOG ((LOG_ERR, "failed to unlock %s", fileeditname)); - /* continue */ --- -2.50.0 - - -From f297173f0247b9288c424e765e972eb13d4c9ded Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Fri, 25 Apr 2025 16:10:09 +0200 -Subject: [PATCH 14/15] lib/, src/: add SELinux control flag in - sub_uid_unlock() - -Expand sub_uid_unlock() interface to add a control flag for SELinux file -context processing. - -Signed-off-by: Iker Pedrosa ---- - lib/subordinateio.c | 12 ++++++------ - lib/subordinateio.h | 2 +- - src/newusers.c | 4 ++-- - src/useradd.c | 4 ++-- - src/userdel.c | 4 ++-- - src/usermod.c | 4 ++-- - 6 files changed, 15 insertions(+), 15 deletions(-) - -diff --git a/lib/subordinateio.c b/lib/subordinateio.c -index 9587e1a9..eaa2dc99 100644 ---- a/lib/subordinateio.c -+++ b/lib/subordinateio.c -@@ -673,9 +673,9 @@ int sub_uid_close (bool process_selinux) - return commonio_close (&subordinate_uid_db, process_selinux); - } - --int sub_uid_unlock (void) -+int sub_uid_unlock (bool process_selinux) - { -- return commonio_unlock (&subordinate_uid_db, true); -+ return commonio_unlock (&subordinate_uid_db, process_selinux); - } - - uid_t sub_uid_find_free_range(uid_t min, uid_t max, unsigned long count) -@@ -1022,7 +1022,7 @@ bool new_subid_range(struct subordinate_range *range, enum subid_type id_type, b - } - if (!sub_uid_open(O_CREAT | O_RDWR)) { - printf("Failed opening subuids (errno %d)\n", errno); -- sub_uid_unlock(); -+ sub_uid_unlock(true); - return false; - } - db = &subordinate_uid_db; -@@ -1069,7 +1069,7 @@ bool new_subid_range(struct subordinate_range *range, enum subid_type id_type, b - out: - if (id_type == ID_TYPE_UID) { - sub_uid_close(true); -- sub_uid_unlock(); -+ sub_uid_unlock(true); - } else { - sub_gid_close(true); - sub_gid_unlock(); -@@ -1094,7 +1094,7 @@ bool release_subid_range(struct subordinate_range *range, enum subid_type id_typ - } - if (!sub_uid_open(O_CREAT | O_RDWR)) { - printf("Failed opening subuids (errno %d)\n", errno); -- sub_uid_unlock(); -+ sub_uid_unlock(true); - return false; - } - db = &subordinate_uid_db; -@@ -1119,7 +1119,7 @@ bool release_subid_range(struct subordinate_range *range, enum subid_type id_typ - - if (id_type == ID_TYPE_UID) { - sub_uid_close(true); -- sub_uid_unlock(); -+ sub_uid_unlock(true); - } else { - sub_gid_close(true); - sub_gid_unlock(); -diff --git a/lib/subordinateio.h b/lib/subordinateio.h -index 63f5b1fb..7914613d 100644 ---- a/lib/subordinateio.h -+++ b/lib/subordinateio.h -@@ -21,7 +21,7 @@ extern int sub_uid_lock (void); - extern int sub_uid_setdbname (const char *filename); - extern /*@observer@*/const char *sub_uid_dbname (void); - extern int sub_uid_open (int mode); --extern int sub_uid_unlock (void); -+extern int sub_uid_unlock (bool process_selinux); - extern int sub_uid_add (const char *owner, uid_t start, unsigned long count); - extern int sub_uid_remove (const char *owner, uid_t start, unsigned long count); - extern uid_t sub_uid_find_free_range(uid_t min, uid_t max, unsigned long count); -diff --git a/src/newusers.c b/src/newusers.c -index 261a5911..65bedf9b 100644 ---- a/src/newusers.c -+++ b/src/newusers.c -@@ -196,7 +196,7 @@ static void fail_exit (int code) - #endif - #ifdef ENABLE_SUBIDS - if (sub_uid_locked) { -- if (sub_uid_unlock () == 0) { -+ if (sub_uid_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); - /* continue */ -@@ -1021,7 +1021,7 @@ static void close_files (void) - #endif - #ifdef ENABLE_SUBIDS - if (is_sub_uid) { -- if (sub_uid_unlock () == 0) { -+ if (sub_uid_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); - /* continue */ -diff --git a/src/useradd.c b/src/useradd.c -index cb7ac88e..f65d24d1 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -288,7 +288,7 @@ static void fail_exit (int code) - } - #endif - #ifdef ENABLE_SUBIDS -- if (sub_uid_locked && sub_uid_unlock() == 0) { -+ if (sub_uid_locked && sub_uid_unlock(true) == 0) { - fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname()); - SYSLOG((LOG_ERR, "failed to unlock %s", sub_uid_dbname())); - /* continue */ -@@ -1623,7 +1623,7 @@ static void close_files (void) - - #ifdef ENABLE_SUBIDS - if (is_sub_uid) { -- if (sub_uid_unlock () == 0) { -+ if (sub_uid_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); - #ifdef WITH_AUDIT -diff --git a/src/userdel.c b/src/userdel.c -index 80ed1a48..68e53b85 100644 ---- a/src/userdel.c -+++ b/src/userdel.c -@@ -454,7 +454,7 @@ static void close_files (void) - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_uid_dbname ())); - fail_exit (E_SUB_UID_UPDATE); - } -- if (sub_uid_unlock () == 0) { -+ if (sub_uid_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); - /* continue */ -@@ -515,7 +515,7 @@ static void fail_exit (int code) - #endif /* SHADOWGRP */ - #ifdef ENABLE_SUBIDS - if (sub_uid_locked) { -- if (sub_uid_unlock () == 0) { -+ if (sub_uid_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); - /* continue */ -diff --git a/src/usermod.c b/src/usermod.c -index 69ea8e55..fc6cc51c 100644 ---- a/src/usermod.c -+++ b/src/usermod.c -@@ -663,7 +663,7 @@ fail_exit (int code) - } - #ifdef ENABLE_SUBIDS - if (sub_uid_locked) { -- if (sub_uid_unlock () == 0) { -+ if (sub_uid_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); - /* continue */ -@@ -1566,7 +1566,7 @@ static void close_files (void) - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_uid_dbname ())); - fail_exit (E_SUB_UID_UPDATE); - } -- if (sub_uid_unlock () == 0) { -+ if (sub_uid_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); - /* continue */ --- -2.50.0 - - -From 7b2bbdd0347c34bc5e094caf26c55694fb5935e7 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Fri, 25 Apr 2025 16:12:40 +0200 -Subject: [PATCH 15/15] lib/, src/: add SELinux control flag in - sub_gid_unlock() - -Expand sub_gid_unlock() interface to add a control flag for SELinux file -context processing. - -Signed-off-by: Iker Pedrosa ---- - lib/subordinateio.c | 12 ++++++------ - lib/subordinateio.h | 2 +- - src/newusers.c | 4 ++-- - src/useradd.c | 4 ++-- - src/userdel.c | 4 ++-- - src/usermod.c | 4 ++-- - 6 files changed, 15 insertions(+), 15 deletions(-) - -diff --git a/lib/subordinateio.c b/lib/subordinateio.c -index eaa2dc99..d1ab03f3 100644 ---- a/lib/subordinateio.c -+++ b/lib/subordinateio.c -@@ -780,9 +780,9 @@ int sub_gid_close (bool process_selinux) - return commonio_close (&subordinate_gid_db, process_selinux); - } - --int sub_gid_unlock (void) -+int sub_gid_unlock (bool process_selinux) - { -- return commonio_unlock (&subordinate_gid_db, true); -+ return commonio_unlock (&subordinate_gid_db, process_selinux); - } - - gid_t sub_gid_find_free_range(gid_t min, gid_t max, unsigned long count) -@@ -1034,7 +1034,7 @@ bool new_subid_range(struct subordinate_range *range, enum subid_type id_type, b - } - if (!sub_gid_open(O_CREAT | O_RDWR)) { - printf("Failed opening subgids (errno %d)\n", errno); -- sub_gid_unlock(); -+ sub_gid_unlock(true); - return false; - } - db = &subordinate_gid_db; -@@ -1072,7 +1072,7 @@ out: - sub_uid_unlock(true); - } else { - sub_gid_close(true); -- sub_gid_unlock(); -+ sub_gid_unlock(true); - } - - return ret; -@@ -1106,7 +1106,7 @@ bool release_subid_range(struct subordinate_range *range, enum subid_type id_typ - } - if (!sub_gid_open(O_CREAT | O_RDWR)) { - printf("Failed opening subgids (errno %d)\n", errno); -- sub_gid_unlock(); -+ sub_gid_unlock(true); - return false; - } - db = &subordinate_gid_db; -@@ -1122,7 +1122,7 @@ bool release_subid_range(struct subordinate_range *range, enum subid_type id_typ - sub_uid_unlock(true); - } else { - sub_gid_close(true); -- sub_gid_unlock(); -+ sub_gid_unlock(true); - } - - return ret; -diff --git a/lib/subordinateio.h b/lib/subordinateio.h -index 7914613d..1ca4b66d 100644 ---- a/lib/subordinateio.h -+++ b/lib/subordinateio.h -@@ -39,7 +39,7 @@ extern int sub_gid_lock (void); - extern int sub_gid_setdbname (const char *filename); - extern /*@observer@*/const char *sub_gid_dbname (void); - extern int sub_gid_open (int mode); --extern int sub_gid_unlock (void); -+extern int sub_gid_unlock (bool process_selinux); - extern int sub_gid_add (const char *owner, gid_t start, unsigned long count); - extern int sub_gid_remove (const char *owner, gid_t start, unsigned long count); - extern uid_t sub_gid_find_free_range(gid_t min, gid_t max, unsigned long count); -diff --git a/src/newusers.c b/src/newusers.c -index 65bedf9b..4eb6065c 100644 ---- a/src/newusers.c -+++ b/src/newusers.c -@@ -203,7 +203,7 @@ static void fail_exit (int code) - } - } - if (sub_gid_locked) { -- if (sub_gid_unlock () == 0) { -+ if (sub_gid_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); - /* continue */ -@@ -1029,7 +1029,7 @@ static void close_files (void) - sub_uid_locked = false; - } - if (is_sub_gid) { -- if (sub_gid_unlock () == 0) { -+ if (sub_gid_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); - /* continue */ -diff --git a/src/useradd.c b/src/useradd.c -index f65d24d1..98c2d284 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -293,7 +293,7 @@ static void fail_exit (int code) - SYSLOG((LOG_ERR, "failed to unlock %s", sub_uid_dbname())); - /* continue */ - } -- if (sub_gid_locked && sub_gid_unlock() == 0) { -+ if (sub_gid_locked && sub_gid_unlock(true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname())); - /* continue */ -@@ -1637,7 +1637,7 @@ static void close_files (void) - sub_uid_locked = false; - } - if (is_sub_gid) { -- if (sub_gid_unlock () == 0) { -+ if (sub_gid_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); - #ifdef WITH_AUDIT -diff --git a/src/userdel.c b/src/userdel.c -index 68e53b85..524c96a6 100644 ---- a/src/userdel.c -+++ b/src/userdel.c -@@ -468,7 +468,7 @@ static void close_files (void) - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_gid_dbname ())); - fail_exit (E_SUB_GID_UPDATE); - } -- if (sub_gid_unlock () == 0) { -+ if (sub_gid_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); - /* continue */ -@@ -522,7 +522,7 @@ static void fail_exit (int code) - } - } - if (sub_gid_locked) { -- if (sub_gid_unlock () == 0) { -+ if (sub_gid_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); - /* continue */ -diff --git a/src/usermod.c b/src/usermod.c -index fc6cc51c..68000a0e 100644 ---- a/src/usermod.c -+++ b/src/usermod.c -@@ -670,7 +670,7 @@ fail_exit (int code) - } - } - if (sub_gid_locked) { -- if (sub_gid_unlock () == 0) { -+ if (sub_gid_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); - /* continue */ -@@ -1579,7 +1579,7 @@ static void close_files (void) - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_gid_dbname ())); - fail_exit (E_SUB_GID_UPDATE); - } -- if (sub_gid_unlock () == 0) { -+ if (sub_gid_unlock (true) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); - /* continue */ --- -2.50.0 - -diff -up shadow-4.18.0/src/newusers.c.test-chroot2 shadow-4.18.0/src/newusers.c ---- shadow-4.18.0/src/newusers.c.test-chroot2 2025-07-08 11:22:16.257291774 +0200 -+++ shadow-4.18.0/src/newusers.c 2025-07-08 11:23:28.210122190 +0200 -@@ -60,6 +60,10 @@ - #include "string/strtok/stpsep.h" - #include "string/strtok/strsep2arr.h" - -+struct option_flags { -+ bool chroot; -+}; -+ - - /* - * Global variables -@@ -103,7 +107,7 @@ static bool sub_gid_locked = false; - - /* local function prototypes */ - NORETURN static void usage (int status); --NORETURN static void fail_exit (int); -+NORETURN static void fail_exit (int, bool); - static int add_group (const char *, const char *, gid_t *, gid_t); - static int get_user_id (const char *, uid_t *); - static int add_user (const char *, uid_t, gid_t); -@@ -113,11 +117,11 @@ static int update_passwd (struct passwd - #endif /* !USE_PAM */ - #endif /* !ACCT_TOOLS_SETUID */ - static int add_passwd (struct passwd *, const char *); --static void process_flags (int argc, char **argv); -+static void process_flags (int argc, char **argv, struct option_flags *flags); - static void check_flags (void); - static void check_perms (void); --static void open_files (void); --static void close_files (void); -+static void open_files (bool process_selinux); -+static void close_files (struct option_flags *flags); - - extern int allow_bad_names; - -@@ -170,24 +174,24 @@ static void usage (int status) - /* - * fail_exit - undo as much as possible - */ --static void fail_exit (int code) -+static void fail_exit (int code, bool process_selinux) - { - if (spw_locked) { -- if (spw_unlock (true) == 0) { -+ if (spw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - /* continue */ - } - } - if (pw_locked) { -- if (pw_unlock (true) == 0) { -+ if (pw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ - } - } - if (gr_locked) { -- if (gr_unlock (true) == 0) { -+ if (gr_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); - /* continue */ -@@ -195,7 +199,7 @@ static void fail_exit (int code) - } - #ifdef SHADOWGRP - if (sgr_locked) { -- if (sgr_unlock (true) == 0) { -+ if (sgr_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - /* continue */ -@@ -204,14 +208,14 @@ static void fail_exit (int code) - #endif - #ifdef ENABLE_SUBIDS - if (sub_uid_locked) { -- if (sub_uid_unlock (true) == 0) { -+ if (sub_uid_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); - /* continue */ - } - } - if (sub_gid_locked) { -- if (sub_gid_unlock (true) == 0) { -+ if (sub_gid_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); - /* continue */ -@@ -637,7 +641,7 @@ static int add_passwd (struct passwd *pw - * - * It will not return if an error is encountered. - */ --static void process_flags (int argc, char **argv) -+static void process_flags (int argc, char **argv, struct option_flags *flags) - { - int c; - #ifndef ACCT_TOOLS_SETUID -@@ -696,6 +700,7 @@ static void process_flags (int argc, cha - rflg = true; - break; - case 'R': /* no-op, handled in process_root_flag () */ -+ flags->chroot = true; - break; - #ifndef ACCT_TOOLS_SETUID - #ifndef USE_PAM -@@ -755,7 +760,7 @@ static void process_flags (int argc, cha - - SNPRINTF(buf, "%s: %s", Prog, argv[1]); - perror (buf); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, !flags->chroot); - } - } - -@@ -859,7 +864,7 @@ static void check_perms (void) - /* - * open_files - lock and open the password, group and shadow databases - */ --static void open_files (void) -+static void open_files (bool process_selinux) - { - /* - * Lock the password files and open them for update. This will bring -@@ -871,7 +876,7 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, pw_dbname ()); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } - pw_locked = true; - if (is_shadow) { -@@ -879,7 +884,7 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, spw_dbname ()); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } - spw_locked = true; - } -@@ -887,7 +892,7 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, gr_dbname ()); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } - gr_locked = true; - #ifdef SHADOWGRP -@@ -896,7 +901,7 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, sgr_dbname ()); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } - sgr_locked = true; - } -@@ -907,7 +912,7 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, sub_uid_dbname ()); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } - sub_uid_locked = true; - } -@@ -916,7 +921,7 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, sub_gid_dbname ()); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } - sub_gid_locked = true; - } -@@ -924,20 +929,20 @@ static void open_files (void) - - if (pw_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, _("%s: cannot open %s\n"), Prog, pw_dbname ()); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } - if (is_shadow && (spw_open (O_CREAT | O_RDWR) == 0)) { - fprintf (stderr, _("%s: cannot open %s\n"), Prog, spw_dbname ()); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } - if (gr_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ()); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } - #ifdef SHADOWGRP - if (is_shadow_grp && (sgr_open (O_CREAT | O_RDWR) == 0)) { - fprintf (stderr, _("%s: cannot open %s\n"), Prog, sgr_dbname ()); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } - #endif - #ifdef ENABLE_SUBIDS -@@ -946,7 +951,7 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot open %s\n"), - Prog, sub_uid_dbname ()); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } - } - if (is_sub_gid) { -@@ -954,7 +959,7 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot open %s\n"), - Prog, sub_gid_dbname ()); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } - } - #endif /* ENABLE_SUBIDS */ -@@ -963,14 +968,18 @@ static void open_files (void) - /* - * close_files - close and unlock the password, group and shadow databases - */ --static void close_files (void) -+static void close_files (struct option_flags *flags) - { -- if (pw_close (true) == 0) { -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot; -+ -+ if (pw_close (process_selinux) == 0) { - fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } -- if (pw_unlock (true) == 0) { -+ if (pw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -@@ -978,14 +987,14 @@ static void close_files (void) - pw_locked = false; - - if (is_shadow) { -- if (spw_close (true) == 0) { -+ if (spw_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } -- if (spw_unlock (true) == 0) { -+ if (spw_unlock (process_selinux) == 0) { - fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, spw_dbname ()); -@@ -995,29 +1004,29 @@ static void close_files (void) - spw_locked = false; - } - -- if (gr_close (true) == 0) { -+ if (gr_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ())); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } - #ifdef ENABLE_SUBIDS -- if (is_sub_uid && (sub_uid_close (true) == 0)) { -+ if (is_sub_uid && (sub_uid_close (process_selinux) == 0)) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), Prog, sub_uid_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_uid_dbname ())); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } -- if (is_sub_gid && (sub_gid_close (true) == 0)) { -+ if (is_sub_gid && (sub_gid_close (process_selinux) == 0)) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), Prog, sub_gid_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_gid_dbname ())); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } - #endif /* ENABLE_SUBIDS */ - -- if (gr_unlock (true) == 0) { -+ if (gr_unlock (process_selinux) == 0) { - fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, gr_dbname ()); -@@ -1028,14 +1037,14 @@ static void close_files (void) - - #ifdef SHADOWGRP - if (is_shadow_grp) { -- if (sgr_close (true) == 0) { -+ if (sgr_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ())); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } -- if (sgr_unlock (true) == 0) { -+ if (sgr_unlock (process_selinux) == 0) { - fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, sgr_dbname ()); -@@ -1047,7 +1056,7 @@ static void close_files (void) - #endif - #ifdef ENABLE_SUBIDS - if (is_sub_uid) { -- if (sub_uid_unlock (true) == 0) { -+ if (sub_uid_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); - /* continue */ -@@ -1055,7 +1064,7 @@ static void close_files (void) - sub_uid_locked = false; - } - if (is_sub_gid) { -- if (sub_gid_unlock (true) == 0) { -+ if (sub_gid_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); - /* continue */ -@@ -1100,6 +1109,8 @@ int main (int argc, char **argv) - size_t nusers = 0; - #endif /* USE_PAM */ - #endif /* ACCT_TOOLS_SETUID */ -+ struct option_flags flags; -+ bool process_selinux; - - log_set_progname(Prog); - log_set_logfd(stderr); -@@ -1113,7 +1124,8 @@ int main (int argc, char **argv) - - OPENLOG ("newusers"); - -- process_flags (argc, argv); -+ process_flags (argc, argv, &flags); -+ process_selinux = !flags.chroot; - - check_perms (); - -@@ -1127,7 +1139,7 @@ int main (int argc, char **argv) - is_sub_gid = sub_gid_file_present () && !rflg; - #endif /* ENABLE_SUBIDS */ - -- open_files (); -+ open_files (process_selinux); - - /* - * Read each line. The line has the same format as a password file -@@ -1143,13 +1155,13 @@ int main (int argc, char **argv) - if (stpsep(buf, "\n") == NULL && feof(stdin) == 0) { - fprintf (stderr, _("%s: line %jd: line too long\n"), - Prog, line); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } - - if (STRSEP2ARR(buf, ":", fields) == -1) { - fprintf (stderr, _("%s: line %jd: invalid line\n"), - Prog, line); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } - - /* -@@ -1161,14 +1173,14 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: cannot update the entry of user %s (not in the passwd database)\n"), - Prog, fields[0]); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } - - if (NULL == pw && get_user_id(fields[2], &uid) != 0) { - fprintf (stderr, - _("%s: line %jd: can't create user\n"), - Prog, line); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } - - /* -@@ -1188,7 +1200,7 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: line %jd: can't create group\n"), - Prog, line); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } - - /* -@@ -1203,7 +1215,7 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: line %jd: can't create user\n"), - Prog, line); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } - - /* -@@ -1215,7 +1227,7 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: line %jd: user '%s' does not exist in %s\n"), - Prog, line, fields[0], pw_dbname ()); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } - newpw = *pw; - -@@ -1230,7 +1242,7 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: line %jd: %s\n"), - Prog, line, strerror(errno)); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } - lines[nusers-1] = line; - usernames[nusers-1] = xstrdup(fields[0]); -@@ -1241,7 +1253,7 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: line %jd: can't update password\n"), - Prog, line); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } - if (!streq(fields[4], "")) { - newpw.pw_gecos = fields[4]; -@@ -1264,7 +1276,7 @@ int main (int argc, char **argv) - fprintf(stderr, - _("%s: line %jd: homedir must be an absolute path\n"), - Prog, line); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } - if (mkdir (newpw.pw_dir, mode) != 0) { - fprintf (stderr, -@@ -1272,7 +1284,7 @@ int main (int argc, char **argv) - Prog, line, newpw.pw_dir, - strerror (errno)); - if (errno != EEXIST) { -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } - } - if (chown(newpw.pw_dir, newpw.pw_uid, newpw.pw_gid) != 0) -@@ -1281,7 +1293,7 @@ int main (int argc, char **argv) - _("%s: line %jd: chown %s failed: %s\n"), - Prog, line, newpw.pw_dir, - strerror (errno)); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } - } - -@@ -1292,7 +1304,7 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: line %jd: can't update entry\n"), - Prog, line); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } - - #ifdef ENABLE_SUBIDS -@@ -1307,14 +1319,14 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: can't find subordinate user range\n"), - Prog); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } - if (sub_uid_add(fields[0], sub_uid_start, sub_uid_count) == 0) - { - fprintf (stderr, - _("%s: failed to prepare new %s entry\n"), - Prog, sub_uid_dbname ()); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } - } - -@@ -1328,13 +1340,13 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: can't find subordinate group range\n"), - Prog); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } - if (sub_gid_add(fields[0], sub_gid_start, sub_gid_count) == 0) { - fprintf (stderr, - _("%s: failed to prepare new %s entry\n"), - Prog, sub_uid_dbname ()); -- fail_exit (EXIT_FAILURE); -+ fail_exit (EXIT_FAILURE, process_selinux); - } - } - #endif /* ENABLE_SUBIDS */ -@@ -1347,7 +1359,7 @@ int main (int argc, char **argv) - * changes to be written out all at once, and then unlocked - * afterwards. - */ -- close_files (); -+ close_files (&flags); - - nscd_flush_cache ("passwd"); - nscd_flush_cache ("group"); -diff -up shadow-4.18.0/src/useradd.c.test-chroot2 shadow-4.18.0/src/useradd.c ---- shadow-4.18.0/src/useradd.c.test-chroot2 2025-07-08 11:22:16.257383838 +0200 -+++ shadow-4.18.0/src/useradd.c 2025-07-08 11:22:16.261386737 +0200 -@@ -92,6 +92,15 @@ - #ifndef LASTLOG_FILE - #define LASTLOG_FILE "/var/log/lastlog" - #endif -+ -+/* -+ * Structures -+ */ -+struct option_flags { -+ bool chroot; -+ bool prefix; -+}; -+ - /* - * Global variables - */ -@@ -219,40 +228,41 @@ static bool home_added = false; - #define DLOG_INIT "LOG_INIT" - - /* local function prototypes */ --NORETURN static void fail_exit (int); --static void get_defaults (void); -+NORETURN static void fail_exit (int, bool); -+static void get_defaults (struct option_flags *); - static void show_defaults (void); - static int set_defaults (void); --static int get_groups (char *); --static struct group * get_local_group (char * grp_name); -+static int get_groups (char *, struct option_flags *); -+static struct group * get_local_group (char * grp_name, bool process_selinux); - NORETURN static void usage (int status); - static void new_pwent (struct passwd *); - - static void new_spent (struct spwd *); --static void grp_update (void); -+static void grp_update (bool); - --static void process_flags (int argc, char **argv); --static void close_files (void); --static void close_group_files (void); --static void unlock_group_files (void); --static void open_files (void); --static void open_group_files (void); --static void open_shadow (void); -+static void process_flags (int argc, char **argv, struct option_flags *flags); -+static void close_files (struct option_flags *flags); -+static void close_group_files (bool process_selinux); -+static void unlock_group_files (bool process_selinux); -+static void open_files (bool process_selinux); -+static void open_group_files (bool process_selinux); -+static void open_shadow (bool process_selinux); - static void faillog_reset (uid_t); - #ifdef ENABLE_LASTLOG - static void lastlog_reset (uid_t); - #endif /* ENABLE_LASTLOG */ - static void tallylog_reset (const char *); --static void usr_update (unsigned long subuid_count, unsigned long subgid_count); --static void create_home (void); --static void create_mail (void); -+static void usr_update (unsigned long subuid_count, unsigned long subgid_count, -+ struct option_flags *flags); -+static void create_home (struct option_flags *flags); -+static void create_mail (struct option_flags *flags); - static void check_uid_range(int rflg, uid_t user_id); - - - /* - * fail_exit - undo as much as possible - */ --static void fail_exit (int code) -+static void fail_exit (int code, bool process_selinux) - { - #ifdef WITH_AUDIT - int type; -@@ -265,35 +275,35 @@ static void fail_exit (int code) - SYSLOG((LOG_ERR, "failed to remove %s", prefix_user_home)); - } - -- if (spw_locked && spw_unlock(true) == 0) { -+ if (spw_locked && spw_unlock(process_selinux) == 0) { - fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname()); - SYSLOG((LOG_ERR, "failed to unlock %s", spw_dbname())); - /* continue */ - } -- if (pw_locked && pw_unlock(true) == 0) { -+ if (pw_locked && pw_unlock(process_selinux) == 0) { - fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname()); - SYSLOG((LOG_ERR, "failed to unlock %s", pw_dbname())); - /* continue */ - } -- if (gr_locked && gr_unlock(true) == 0) { -+ if (gr_locked && gr_unlock(process_selinux) == 0) { - fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname()); - SYSLOG((LOG_ERR, "failed to unlock %s", gr_dbname())); - /* continue */ - } - #ifdef SHADOWGRP -- if (sgr_locked && sgr_unlock(true) == 0) { -+ if (sgr_locked && sgr_unlock(process_selinux) == 0) { - fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname()); - SYSLOG((LOG_ERR, "failed to unlock %s", sgr_dbname())); - /* continue */ - } - #endif - #ifdef ENABLE_SUBIDS -- if (sub_uid_locked && sub_uid_unlock(true) == 0) { -+ if (sub_uid_locked && sub_uid_unlock(process_selinux) == 0) { - fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname()); - SYSLOG((LOG_ERR, "failed to unlock %s", sub_uid_dbname())); - /* continue */ - } -- if (sub_gid_locked && sub_gid_unlock(true) == 0) { -+ if (sub_gid_locked && sub_gid_unlock(process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname())); - /* continue */ -@@ -322,7 +332,7 @@ static void fail_exit (int code) - * file does not exist. - */ - static void --get_defaults(void) -+get_defaults(struct option_flags *flags) - { - FILE *fp; - char *default_file = USER_DEFAULTS_FILE; -@@ -377,7 +387,7 @@ get_defaults(void) - ccp = cp; - - if (streq(buf, DGROUPS)) { -- if (get_groups (cp) != 0) { -+ if (get_groups (cp, flags) != 0) { - fprintf (stderr, - _("%s: the '%s=' configuration in %s has an invalid group, ignoring the bad group\n"), - Prog, DGROUPS, default_file); -@@ -736,11 +746,14 @@ err_free_new: - * converts it to a NULL-terminated array. Any unknown group - * names are reported as errors. - */ --static int get_groups (char *list) -+static int get_groups (char *list, struct option_flags *flags) - { - struct group *grp; - bool errors = false; - int ngroups = 0; -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot && !flags->prefix; - - /* - * Free previous group list before creating a new one. -@@ -758,7 +771,7 @@ static int get_groups (char *list) - /* - * Open the group files - */ -- open_group_files (); -+ open_group_files (process_selinux); - - /* - * So long as there is some data to be converted, strip off -@@ -777,7 +790,7 @@ static int get_groups (char *list) - * Names starting with digits are treated as numerical - * GID values, otherwise the string is looked up as is. - */ -- grp = get_local_group(g); -+ grp = get_local_group(g, process_selinux); - - /* - * There must be a match, either by GID value or by -@@ -815,8 +828,8 @@ static int get_groups (char *list) - gr_free (grp); - } - -- close_group_files (); -- unlock_group_files (); -+ close_group_files (process_selinux); -+ unlock_group_files (process_selinux); - - user_groups[ngroups] = NULL; - -@@ -837,7 +850,7 @@ static int get_groups (char *list) - * If the name exists the group information is returned, otherwise NULL is - * returned. - */ --static struct group * get_local_group(char * grp_name) -+static struct group * get_local_group(char * grp_name, bool process_selinux) - { - gid_t gid; - struct group *result_grp = NULL; -@@ -854,7 +867,7 @@ static struct group * get_local_group(ch - fprintf (stderr, - _("%s: Out of memory. Cannot find group '%s'.\n"), - Prog, grp_name); -- fail_exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE, process_selinux); - } - } - -@@ -986,7 +999,7 @@ static void new_spent (struct spwd *spen - * close_files() should be called afterwards to commit the changes - * and unlocking the group files. - */ --static void grp_update (void) -+static void grp_update (bool process_selinux) - { - const struct group *grp; - struct group *ngrp; -@@ -1022,7 +1035,7 @@ static void grp_update (void) - _("%s: Out of memory. Cannot update %s.\n"), - Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", gr_dbname (), user_name)); -- fail_exit (E_GRP_UPDATE); /* XXX */ -+ fail_exit (E_GRP_UPDATE, process_selinux); /* XXX */ - } - - /* -@@ -1035,7 +1048,7 @@ static void grp_update (void) - _("%s: failed to prepare the new %s entry '%s'\n"), - Prog, gr_dbname (), ngrp->gr_name); - SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", gr_dbname (), user_name)); -- fail_exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE, process_selinux); - } - #ifdef WITH_AUDIT - audit_logger_with_group (AUDIT_USER_MGMT, -@@ -1085,7 +1098,7 @@ static void grp_update (void) - _("%s: Out of memory. Cannot update %s.\n"), - Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", sgr_dbname (), user_name)); -- fail_exit (E_GRP_UPDATE); /* XXX */ -+ fail_exit (E_GRP_UPDATE, process_selinux); /* XXX */ - } - - /* -@@ -1099,7 +1112,7 @@ static void grp_update (void) - Prog, sgr_dbname (), nsgrp->sg_namp); - SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", sgr_dbname (), user_name)); - -- fail_exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE, process_selinux); - } - #ifdef WITH_AUDIT - audit_logger_with_group (AUDIT_USER_MGMT, -@@ -1121,7 +1134,7 @@ static void grp_update (void) - * the values that the user will be created with accordingly. The - * values are checked for sanity. - */ --static void process_flags (int argc, char **argv) -+static void process_flags (int argc, char **argv, struct option_flags *flags) - { - const struct group *grp; - bool anyflag = false; -@@ -1296,7 +1309,7 @@ static void process_flags (int argc, cha - gflg = true; - break; - case 'G': -- if (get_groups (optarg) != 0) { -+ if (get_groups (optarg, flags) != 0) { - exit (E_NOTFOUND); - } - if (NULL != user_groups[0]) { -@@ -1356,8 +1369,10 @@ static void process_flags (int argc, cha - rflg = true; - break; - case 'R': /* no-op, handled in process_root_flag () */ -+ flags->chroot = true; - break; - case 'P': /* no-op, handled in process_prefix_flag () */ -+ flags->prefix = true; - break; - case 's': - if ( ( !VALID (optarg) ) -@@ -1562,38 +1577,42 @@ static void process_flags (int argc, cha - * close_files() closes all of the files that were opened for this - * new user. This causes any modified entries to be written out. - */ --static void close_files (void) -+static void close_files (struct option_flags *flags) - { -- if (pw_close (true) == 0) { -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot && !flags->prefix; -+ -+ if (pw_close (process_selinux) == 0) { - fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); -- fail_exit (E_PW_UPDATE); -+ fail_exit (E_PW_UPDATE, process_selinux); - } -- if (is_shadow_pwd && (spw_close (true) == 0)) { -+ if (is_shadow_pwd && (spw_close (process_selinux) == 0)) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); -- fail_exit (E_PW_UPDATE); -+ fail_exit (E_PW_UPDATE, process_selinux); - } - -- close_group_files (); -+ close_group_files (process_selinux); - - #ifdef ENABLE_SUBIDS -- if (is_sub_uid && (sub_uid_close (true) == 0)) { -+ if (is_sub_uid && (sub_uid_close (process_selinux) == 0)) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), Prog, sub_uid_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_uid_dbname ())); -- fail_exit (E_SUB_UID_UPDATE); -+ fail_exit (E_SUB_UID_UPDATE, process_selinux); - } -- if (is_sub_gid && (sub_gid_close (true) == 0)) { -+ if (is_sub_gid && (sub_gid_close (process_selinux) == 0)) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), Prog, sub_gid_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_gid_dbname ())); -- fail_exit (E_SUB_GID_UPDATE); -+ fail_exit (E_SUB_GID_UPDATE, process_selinux); - } - #endif /* ENABLE_SUBIDS */ - if (is_shadow_pwd) { -- if (spw_unlock (true) == 0) { -+ if (spw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - #ifdef WITH_AUDIT -@@ -1606,7 +1625,7 @@ static void close_files (void) - } - spw_locked = false; - } -- if (pw_unlock (true) == 0) { -+ if (pw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - #ifdef WITH_AUDIT -@@ -1619,11 +1638,11 @@ static void close_files (void) - } - pw_locked = false; - -- unlock_group_files (); -+ unlock_group_files (process_selinux); - - #ifdef ENABLE_SUBIDS - if (is_sub_uid) { -- if (sub_uid_unlock (true) == 0) { -+ if (sub_uid_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); - #ifdef WITH_AUDIT -@@ -1637,7 +1656,7 @@ static void close_files (void) - sub_uid_locked = false; - } - if (is_sub_gid) { -- if (sub_gid_unlock (true) == 0) { -+ if (sub_gid_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); - #ifdef WITH_AUDIT -@@ -1659,25 +1678,25 @@ static void close_files (void) - * close_group_files() closes all of the files that were opened related - * with groups. This causes any modified entries to be written out. - */ --static void close_group_files (void) -+static void close_group_files (bool process_selinux) - { - if (!do_grp_update) - return; - -- if (gr_close(true) == 0) { -+ if (gr_close(process_selinux) == 0) { - fprintf(stderr, - _("%s: failure while writing changes to %s\n"), - Prog, gr_dbname()); - SYSLOG((LOG_ERR, "failure while writing changes to %s", gr_dbname())); -- fail_exit(E_GRP_UPDATE); -+ fail_exit(E_GRP_UPDATE, process_selinux); - } - #ifdef SHADOWGRP -- if (is_shadow_grp && sgr_close(true) == 0) { -+ if (is_shadow_grp && sgr_close(process_selinux) == 0) { - fprintf(stderr, - _("%s: failure while writing changes to %s\n"), - Prog, sgr_dbname()); - SYSLOG((LOG_ERR, "failure while writing changes to %s", sgr_dbname())); -- fail_exit(E_GRP_UPDATE); -+ fail_exit(E_GRP_UPDATE, process_selinux); - } - #endif /* SHADOWGRP */ - } -@@ -1688,9 +1707,9 @@ static void close_group_files (void) - * unlock_group_files() unlocks all of the files that were locked related - * with groups. This causes any modified entries to be written out. - */ --static void unlock_group_files (void) -+static void unlock_group_files (bool process_selinux) - { -- if (gr_unlock (true) == 0) { -+ if (gr_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); - #ifdef WITH_AUDIT -@@ -1704,7 +1723,7 @@ static void unlock_group_files (void) - gr_locked = false; - #ifdef SHADOWGRP - if (is_shadow_grp) { -- if (sgr_unlock (true) == 0) { -+ if (sgr_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - #ifdef WITH_AUDIT -@@ -1725,7 +1744,7 @@ static void unlock_group_files (void) - * - * open_files() opens the two password files. - */ --static void open_files (void) -+static void open_files (bool process_selinux) - { - if (pw_lock () == 0) { - fprintf (stderr, -@@ -1736,12 +1755,12 @@ static void open_files (void) - pw_locked = true; - if (pw_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, _("%s: cannot open %s\n"), Prog, pw_dbname ()); -- fail_exit (E_PW_UPDATE); -+ fail_exit (E_PW_UPDATE, process_selinux); - } - - /* shadow file will be opened by open_shadow(); */ - -- open_group_files (); -+ open_group_files (process_selinux); - - #ifdef ENABLE_SUBIDS - if (is_sub_uid) { -@@ -1749,14 +1768,14 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, sub_uid_dbname ()); -- fail_exit (E_SUB_UID_UPDATE); -+ fail_exit (E_SUB_UID_UPDATE, process_selinux); - } - sub_uid_locked = true; - if (sub_uid_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, - _("%s: cannot open %s\n"), - Prog, sub_uid_dbname ()); -- fail_exit (E_SUB_UID_UPDATE); -+ fail_exit (E_SUB_UID_UPDATE, process_selinux); - } - } - if (is_sub_gid) { -@@ -1764,31 +1783,31 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, sub_gid_dbname ()); -- fail_exit (E_SUB_GID_UPDATE); -+ fail_exit (E_SUB_GID_UPDATE, process_selinux); - } - sub_gid_locked = true; - if (sub_gid_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, - _("%s: cannot open %s\n"), - Prog, sub_gid_dbname ()); -- fail_exit (E_SUB_GID_UPDATE); -+ fail_exit (E_SUB_GID_UPDATE, process_selinux); - } - } - #endif /* ENABLE_SUBIDS */ - } - --static void open_group_files (void) -+static void open_group_files (bool process_selinux) - { - if (gr_lock () == 0) { - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, gr_dbname ()); -- fail_exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE, process_selinux); - } - gr_locked = true; - if (gr_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ()); -- fail_exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE, process_selinux); - } - - #ifdef SHADOWGRP -@@ -1797,20 +1816,20 @@ static void open_group_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, sgr_dbname ()); -- fail_exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE, process_selinux); - } - sgr_locked = true; - if (sgr_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, - _("%s: cannot open %s\n"), - Prog, sgr_dbname ()); -- fail_exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE, process_selinux); - } - } - #endif /* SHADOWGRP */ - } - --static void open_shadow (void) -+static void open_shadow (bool process_selinux) - { - if (!is_shadow_pwd) { - return; -@@ -1819,14 +1838,14 @@ static void open_shadow (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, spw_dbname ()); -- fail_exit (E_PW_UPDATE); -+ fail_exit (E_PW_UPDATE, process_selinux); - } - spw_locked = true; - if (spw_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, - _("%s: cannot open %s\n"), - Prog, spw_dbname ()); -- fail_exit (E_PW_UPDATE); -+ fail_exit (E_PW_UPDATE, process_selinux); - } - } - -@@ -1880,7 +1899,7 @@ static void new_sgent (struct sgrp *sgen - * grp_add() writes the new records to the group files. - */ - --static void grp_add (void) -+static void grp_add (bool process_selinux) - { - struct group grp; - -@@ -1909,7 +1928,7 @@ static void grp_add (void) - grp.gr_name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); - #endif -- fail_exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE, process_selinux); - } - #ifdef SHADOWGRP - /* -@@ -1925,7 +1944,7 @@ static void grp_add (void) - grp.gr_name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); - #endif -- fail_exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE, process_selinux); - } - #endif /* SHADOWGRP */ - SYSLOG ((LOG_INFO, "new group: name=%s, GID=%u", user_name, user_gid)); -@@ -2074,11 +2093,16 @@ static void tallylog_reset (const char * - * usr_update() creates the password file entries for this user - * and will update the group entries if required. - */ --static void usr_update (unsigned long subuid_count, unsigned long subgid_count) -+static void -+usr_update (unsigned long subuid_count, unsigned long subgid_count, -+ struct option_flags *flags) - { - struct passwd pwent; - struct spwd spent; - char *tty; -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot && !flags->prefix; - - /* - * Fill in the password structure with any new fields, making -@@ -2119,7 +2143,7 @@ static void usr_update (unsigned long su - fprintf (stderr, - _("%s: failed to prepare the new %s entry '%s'\n"), - Prog, pw_dbname (), pwent.pw_name); -- fail_exit (E_PW_UPDATE); -+ fail_exit (E_PW_UPDATE, process_selinux); - } - - /* -@@ -2129,7 +2153,7 @@ static void usr_update (unsigned long su - fprintf (stderr, - _("%s: failed to prepare the new %s entry '%s'\n"), - Prog, spw_dbname (), spent.sp_namp); -- fail_exit (E_PW_UPDATE); -+ fail_exit (E_PW_UPDATE, process_selinux); - } - #ifdef ENABLE_SUBIDS - if (is_sub_uid && !local_sub_uid_assigned(user_name) && -@@ -2137,14 +2161,14 @@ static void usr_update (unsigned long su - fprintf (stderr, - _("%s: failed to prepare the new %s entry\n"), - Prog, sub_uid_dbname ()); -- fail_exit (E_SUB_UID_UPDATE); -+ fail_exit (E_SUB_UID_UPDATE, process_selinux); - } - if (is_sub_gid && !local_sub_gid_assigned(user_name) && - (sub_gid_add(user_name, sub_gid_start, subgid_count) == 0)) { - fprintf (stderr, - _("%s: failed to prepare the new %s entry\n"), - Prog, sub_uid_dbname ()); -- fail_exit (E_SUB_GID_UPDATE); -+ fail_exit (E_SUB_GID_UPDATE, process_selinux); - } - #endif /* ENABLE_SUBIDS */ - -@@ -2163,7 +2187,7 @@ static void usr_update (unsigned long su - * Do any group file updates for this user. - */ - if (do_grp_update) { -- grp_update (); -+ grp_update (process_selinux); - } - } - -@@ -2174,11 +2198,14 @@ static void usr_update (unsigned long su - * already exist. It will be created mode 755 owned by the user - * with the user's default group. - */ --static void create_home (void) -+static void create_home (struct option_flags *flags) - { - char path[strlen(prefix_user_home) + 2]; - char *bhome, *cp; - mode_t mode; -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot && !flags->prefix; - - if (access (prefix_user_home, F_OK) == 0) - return; -@@ -2189,15 +2216,17 @@ static void create_home (void) - fprintf(stderr, - _("%s: error while duplicating string %s\n"), - Prog, user_home); -- fail_exit(E_HOMEDIR); -+ fail_exit(E_HOMEDIR, process_selinux); - } - - #ifdef WITH_SELINUX -- if (set_selinux_file_context(prefix_user_home, S_IFDIR) != 0) { -- fprintf(stderr, -- _("%s: cannot set SELinux context for home directory %s\n"), -- Prog, user_home); -- fail_exit(E_HOMEDIR); -+ if (process_selinux) { -+ if (set_selinux_file_context(prefix_user_home, S_IFDIR) != 0) { -+ fprintf(stderr, -+ _("%s: cannot set SELinux context for home directory %s\n"), -+ Prog, user_home); -+ fail_exit(E_HOMEDIR, process_selinux); -+ } - } - #endif - -@@ -2227,14 +2256,14 @@ static void create_home (void) - fprintf(stderr, - _("%s: error while duplicating string in BTRFS check %s\n"), - Prog, path); -- fail_exit(E_HOMEDIR); -+ fail_exit(E_HOMEDIR, process_selinux); - } - stpcpy(&btrfs_check[strlen(path) - strlen(cp) - 1], ""); - if (is_btrfs(btrfs_check) <= 0) { - fprintf(stderr, - _("%s: home directory \"%s\" must be mounted on BTRFS\n"), - Prog, path); -- fail_exit(E_HOMEDIR); -+ fail_exit(E_HOMEDIR, process_selinux); - } - free(btrfs_check); - // make subvolume to mount for user instead of directory -@@ -2242,7 +2271,7 @@ static void create_home (void) - fprintf(stderr, - _("%s: failed to create BTRFS subvolume: %s\n"), - Prog, path); -- fail_exit(E_HOMEDIR); -+ fail_exit(E_HOMEDIR, process_selinux); - } - } - else -@@ -2250,7 +2279,7 @@ static void create_home (void) - if (mkdir(path, 0) != 0) { - fprintf(stderr, _("%s: cannot create directory %s\n"), - Prog, path); -- fail_exit(E_HOMEDIR); -+ fail_exit(E_HOMEDIR, process_selinux); - } - if (chown(path, 0, 0) < 0) { - fprintf(stderr, -@@ -2278,12 +2307,14 @@ static void create_home (void) - user_name, user_id, SHADOW_AUDIT_SUCCESS); - #endif - #ifdef WITH_SELINUX -- /* Reset SELinux to create files with default contexts */ -- if (reset_selinux_file_context() != 0) { -- fprintf(stderr, -- _("%s: cannot reset SELinux file creation context\n"), -- Prog); -- fail_exit(E_HOMEDIR); -+ if (process_selinux) { -+ /* Reset SELinux to create files with default contexts */ -+ if (reset_selinux_file_context() != 0) { -+ fprintf(stderr, -+ _("%s: cannot reset SELinux file creation context\n"), -+ Prog); -+ fail_exit(E_HOMEDIR, process_selinux); -+ } - } - #endif - } -@@ -2295,7 +2326,7 @@ static void create_home (void) - * exist. It will be created mode 660 owned by the user and group - * 'mail' - */ --static void create_mail (void) -+static void create_mail (struct option_flags *flags) - { - int fd; - char *file; -@@ -2303,6 +2334,9 @@ static void create_mail (void) - mode_t mode; - const char *spool; - struct group *gr; -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot && !flags->prefix; - - if (!strcaseeq(create_mail_spool, "yes")) - return; -@@ -2322,11 +2356,13 @@ static void create_mail (void) - file = xaprintf("%s/%s", spool, user_name); - - #ifdef WITH_SELINUX -- if (set_selinux_file_context(file, S_IFREG) != 0) { -- fprintf(stderr, -- _("%s: cannot set SELinux context for mailbox file %s\n"), -- Prog, file); -- fail_exit(E_MAILBOXFILE); -+ if (process_selinux) { -+ if (set_selinux_file_context(file, S_IFREG) != 0) { -+ fprintf(stderr, -+ _("%s: cannot set SELinux context for mailbox file %s\n"), -+ Prog, file); -+ fail_exit(E_MAILBOXFILE, process_selinux); -+ } - } - #endif - -@@ -2362,12 +2398,14 @@ static void create_mail (void) - perror (_("Closing mailbox file")); - } - #ifdef WITH_SELINUX -- /* Reset SELinux to create files with default contexts */ -- if (reset_selinux_file_context() != 0) { -- fprintf(stderr, -- _("%s: cannot reset SELinux file creation context\n"), -- Prog); -- fail_exit(E_MAILBOXFILE); -+ if (process_selinux) { -+ /* Reset SELinux to create files with default contexts */ -+ if (reset_selinux_file_context() != 0) { -+ fprintf(stderr, -+ _("%s: cannot reset SELinux file creation context\n"), -+ Prog); -+ fail_exit(E_MAILBOXFILE, process_selinux); -+ } - } - #endif - } -@@ -2409,6 +2447,8 @@ int main (int argc, char **argv) - #endif - unsigned long subuid_count = 0; - unsigned long subgid_count = 0; -+ struct option_flags flags; -+ bool process_selinux; - - log_set_progname(Prog); - log_set_logfd(stderr); -@@ -2439,9 +2479,10 @@ int main (int argc, char **argv) - is_shadow_grp = sgr_file_present (); - #endif - -- get_defaults (); -+ get_defaults (&flags); - -- process_flags (argc, argv); -+ process_flags (argc, argv, &flags); -+ process_selinux = !flags.chroot && !flags.prefix; - - #ifdef ENABLE_SUBIDS - uid_min = getdef_ulong ("UID_MIN", 1000UL); -@@ -2470,7 +2511,7 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: Cannot determine your user name.\n"), - Prog); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - - retval = pam_start (Prog, pampw?pampw->pw_name:"root", &conv, &pamh); -@@ -2491,7 +2532,7 @@ int main (int argc, char **argv) - if (NULL != pamh) { - (void) pam_end (pamh, retval); - } -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - (void) pam_end (pamh, retval); - #endif /* USE_PAM */ -@@ -2515,7 +2556,7 @@ int main (int argc, char **argv) - */ - if (prefix_getpwnam (user_name) != NULL) { /* local, no need for xgetpwnam */ - fprintf (stderr, _("%s: user '%s' already exists\n"), Prog, user_name); -- fail_exit (E_NAME_IN_USE); -+ fail_exit (E_NAME_IN_USE, process_selinux); - } - - /* -@@ -2530,7 +2571,7 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: group %s exists - if you want to add this user to that group, use -g.\n"), - Prog, user_name); -- fail_exit (E_NAME_IN_USE); -+ fail_exit (E_NAME_IN_USE, process_selinux); - } - } - -@@ -2543,7 +2584,7 @@ int main (int argc, char **argv) - * - flush nscd caches for passwd and group services, - * - then close and update the files. - */ -- open_files (); -+ open_files (process_selinux); - - if (!oflg) { - /* first, seek for a valid uid to use for this user. -@@ -2552,14 +2593,14 @@ int main (int argc, char **argv) - if (!uflg) { - if (find_new_uid (rflg, &user_id, NULL) < 0) { - fprintf (stderr, _("%s: can't create user\n"), Prog); -- fail_exit (E_UID_IN_USE); -+ fail_exit (E_UID_IN_USE, process_selinux); - } - } else { - if (prefix_getpwuid (user_id) != NULL) { - fprintf (stderr, - _("%s: UID %lu is not unique\n"), - Prog, (unsigned long) user_id); -- fail_exit (E_UID_IN_USE); -+ fail_exit (E_UID_IN_USE, process_selinux); - } - } - } -@@ -2572,11 +2613,11 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: Failed to create tcb directory for %s\n"), - Prog, user_name); -- fail_exit (E_UID_IN_USE); -+ fail_exit (E_UID_IN_USE, process_selinux); - } - } - #endif -- open_shadow (); -+ open_shadow (process_selinux); - - /* do we have to add a group for that user? This is why we need to - * open the group files in the open_files() function --gafton */ -@@ -2585,9 +2626,9 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: can't create group\n"), - Prog); -- fail_exit (4); -+ fail_exit (4, process_selinux); - } -- grp_add (); -+ grp_add (process_selinux); - } - - #ifdef ENABLE_SUBIDS -@@ -2596,7 +2637,7 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: can't create subordinate user IDs\n"), - Prog); -- fail_exit(E_SUB_UID_UPDATE); -+ fail_exit(E_SUB_UID_UPDATE, process_selinux); - } - } - if (is_sub_gid && subgid_count != 0) { -@@ -2604,14 +2645,14 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: can't create subordinate group IDs\n"), - Prog); -- fail_exit(E_SUB_GID_UPDATE); -+ fail_exit(E_SUB_GID_UPDATE, process_selinux); - } - } - #endif /* ENABLE_SUBIDS */ - -- usr_update (subuid_count, subgid_count); -+ usr_update (subuid_count, subgid_count, &flags); - -- close_files (); -+ close_files (&flags); - - nscd_flush_cache ("passwd"); - nscd_flush_cache ("group"); -@@ -2637,13 +2678,13 @@ int main (int argc, char **argv) - "add-selinux-user-mapping", - user_name, user_id, SHADOW_AUDIT_FAILURE); - #endif /* WITH_AUDIT */ -- fail_exit (E_SE_UPDATE); -+ fail_exit (E_SE_UPDATE, process_selinux); - } - } - #endif /* WITH_SELINUX */ - - if (mflg) { -- create_home (); -+ create_home (&flags); - if (home_added) { - copy_tree (def_template, prefix_user_home, false, true, - (uid_t)-1, user_id, (gid_t)-1, user_gid); -@@ -2660,7 +2701,7 @@ int main (int argc, char **argv) - - /* Do not create mail directory for system accounts */ - if (!rflg) { -- create_mail (); -+ create_mail (&flags); - } - - if (run_parts ("/etc/shadow-maint/useradd-post.d", user_name, -diff -up shadow-4.18.0/src/userdel.c.test-chroot2 shadow-4.18.0/src/userdel.c ---- shadow-4.18.0/src/userdel.c.test-chroot2 2025-07-08 11:22:16.257469516 +0200 -+++ shadow-4.18.0/src/userdel.c 2025-07-08 11:22:16.263226317 +0200 -@@ -73,6 +73,14 @@ - #endif /* ENABLE_SUBIDS */ - - /* -+ * Structures -+ */ -+struct option_flags { -+ bool chroot; -+ bool prefix; -+}; -+ -+/* - * Global variables - */ - static const char Prog[] = "userdel"; -@@ -87,7 +95,6 @@ static bool rflg = false; - #ifdef WITH_SELINUX - static bool Zflg = false; - #endif --static bool Rflg = false; - - static bool is_shadow_pwd; - -@@ -109,12 +116,12 @@ static const char* prefix = ""; - - /* local function prototypes */ - static void usage (int status); --static void update_groups (void); --static void remove_usergroup (void); --static void close_files (void); --static void fail_exit (int); --static void open_files (void); --static void update_user (void); -+static void update_groups (bool process_selinux); -+static void remove_usergroup (bool process_selinux); -+static void close_files (struct option_flags *flags); -+static void fail_exit (int, bool); -+static void open_files (bool process_selinux); -+static void update_user (bool process_selinux); - static void user_cancel (const char *); - - #ifdef EXTRA_CHECK_HOME_DIR -@@ -162,7 +169,7 @@ static void usage (int status) - * name is their user name) and delete them too (only if USERGROUPS_ENAB - * is enabled). - */ --static void update_groups (void) -+static void update_groups (bool process_selinux) - { - const struct group *grp; - struct group *ngrp; -@@ -219,7 +226,7 @@ static void update_groups (void) - } - - if (getdef_bool ("USERGROUPS_ENAB")) { -- remove_usergroup (); -+ remove_usergroup (process_selinux); - } - - #ifdef SHADOWGRP -@@ -291,7 +298,7 @@ static void update_groups (void) - * + it has no other members - * + it is not the primary group of any other user - */ --static void remove_usergroup (void) -+static void remove_usergroup (bool process_selinux) - { - const struct group *grp; - const struct passwd *pwd = NULL; -@@ -346,7 +353,7 @@ static void remove_usergroup (void) - fprintf (stderr, - _("%s: cannot remove entry '%s' from %s\n"), - Prog, user_name, gr_dbname ()); -- fail_exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE, process_selinux); - } - - #ifdef WITH_AUDIT -@@ -365,7 +372,7 @@ static void remove_usergroup (void) - fprintf (stderr, - _("%s: cannot remove entry '%s' from %s\n"), - Prog, user_name, sgr_dbname ()); -- fail_exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE, process_selinux); - } - #ifdef WITH_AUDIT - audit_logger_with_group (AUDIT_GRP_MGMT, -@@ -388,14 +395,18 @@ static void remove_usergroup (void) - * close_files() closes all of the files that were opened for this - * new user. This causes any modified entries to be written out. - */ --static void close_files (void) -+static void close_files (struct option_flags *flags) - { -- if (pw_close (true) == 0) { -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot && !flags->prefix; -+ -+ if (pw_close (process_selinux) == 0) { - fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); -- fail_exit (E_PW_UPDATE); -+ fail_exit (E_PW_UPDATE, process_selinux); - } -- if (pw_unlock (true) == 0) { -+ if (pw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -@@ -403,13 +414,13 @@ static void close_files (void) - pw_locked = false; - - if (is_shadow_pwd) { -- if (spw_close (true) == 0) { -+ if (spw_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); -- fail_exit (E_PW_UPDATE); -+ fail_exit (E_PW_UPDATE, process_selinux); - } -- if (spw_unlock (true) == 0) { -+ if (spw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - /* continue */ -@@ -417,12 +428,12 @@ static void close_files (void) - spw_locked = false; - } - -- if (gr_close (true) == 0) { -+ if (gr_close (process_selinux) == 0) { - fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ())); -- fail_exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE, process_selinux); - } -- if (gr_unlock (true) == 0) { -+ if (gr_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); - /* continue */ -@@ -431,14 +442,14 @@ static void close_files (void) - - #ifdef SHADOWGRP - if (is_shadow_grp) { -- if (sgr_close (true) == 0) { -+ if (sgr_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ())); -- fail_exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE, process_selinux); - } - -- if (sgr_unlock (true) == 0) { -+ if (sgr_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - /* continue */ -@@ -449,12 +460,12 @@ static void close_files (void) - - #ifdef ENABLE_SUBIDS - if (is_sub_uid) { -- if (sub_uid_close (true) == 0) { -+ if (sub_uid_close (process_selinux) == 0) { - fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sub_uid_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_uid_dbname ())); -- fail_exit (E_SUB_UID_UPDATE); -+ fail_exit (E_SUB_UID_UPDATE, process_selinux); - } -- if (sub_uid_unlock (true) == 0) { -+ if (sub_uid_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); - /* continue */ -@@ -463,12 +474,12 @@ static void close_files (void) - } - - if (is_sub_gid) { -- if (sub_gid_close (true) == 0) { -+ if (sub_gid_close (process_selinux) == 0) { - fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sub_gid_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_gid_dbname ())); -- fail_exit (E_SUB_GID_UPDATE); -+ fail_exit (E_SUB_GID_UPDATE, process_selinux); - } -- if (sub_gid_unlock (true) == 0) { -+ if (sub_gid_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); - /* continue */ -@@ -481,24 +492,24 @@ static void close_files (void) - /* - * fail_exit - exit with a failure code after unlocking the files - */ --static void fail_exit (int code) -+static void fail_exit (int code, bool process_selinux) - { - if (pw_locked) { -- if (pw_unlock (true) == 0) { -+ if (pw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ - } - } - if (gr_locked) { -- if (gr_unlock (true) == 0) { -+ if (gr_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); - /* continue */ - } - } - if (spw_locked) { -- if (spw_unlock (true) == 0) { -+ if (spw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - /* continue */ -@@ -506,7 +517,7 @@ static void fail_exit (int code) - } - #ifdef SHADOWGRP - if (sgr_locked) { -- if (sgr_unlock (true) == 0) { -+ if (sgr_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - /* continue */ -@@ -515,14 +526,14 @@ static void fail_exit (int code) - #endif /* SHADOWGRP */ - #ifdef ENABLE_SUBIDS - if (sub_uid_locked) { -- if (sub_uid_unlock (true) == 0) { -+ if (sub_uid_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); - /* continue */ - } - } - if (sub_gid_locked) { -- if (sub_gid_unlock (true) == 0) { -+ if (sub_gid_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); - /* continue */ -@@ -545,45 +556,45 @@ static void fail_exit (int code) - * open_files() opens the two password files. - */ - --static void open_files (void) -+static void open_files (bool process_selinux) - { - if (pw_lock () == 0) { - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, pw_dbname ()); -- fail_exit (E_PW_UPDATE); -+ fail_exit (E_PW_UPDATE, process_selinux); - } - pw_locked = true; - if (pw_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, - _("%s: cannot open %s\n"), Prog, pw_dbname ()); -- fail_exit (E_PW_UPDATE); -+ fail_exit (E_PW_UPDATE, process_selinux); - } - if (is_shadow_pwd) { - if (spw_lock () == 0) { - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, spw_dbname ()); -- fail_exit (E_PW_UPDATE); -+ fail_exit (E_PW_UPDATE, process_selinux); - } - spw_locked = true; - if (spw_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, - _("%s: cannot open %s\n"), - Prog, spw_dbname ()); -- fail_exit (E_PW_UPDATE); -+ fail_exit (E_PW_UPDATE, process_selinux); - } - } - if (gr_lock () == 0) { - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, gr_dbname ()); -- fail_exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE, process_selinux); - } - gr_locked = true; - if (gr_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ()); -- fail_exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE, process_selinux); - } - #ifdef SHADOWGRP - if (is_shadow_grp) { -@@ -591,13 +602,13 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, sgr_dbname ()); -- fail_exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE, process_selinux); - } - sgr_locked= true; - if (sgr_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, _("%s: cannot open %s\n"), - Prog, sgr_dbname ()); -- fail_exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE, process_selinux); - } - } - #endif /* SHADOWGRP */ -@@ -607,13 +618,13 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, sub_uid_dbname ()); -- fail_exit (E_SUB_UID_UPDATE); -+ fail_exit (E_SUB_UID_UPDATE, process_selinux); - } - sub_uid_locked = true; - if (sub_uid_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, - _("%s: cannot open %s\n"), Prog, sub_uid_dbname ()); -- fail_exit (E_SUB_UID_UPDATE); -+ fail_exit (E_SUB_UID_UPDATE, process_selinux); - } - } - if (is_sub_gid) { -@@ -621,13 +632,13 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, sub_gid_dbname ()); -- fail_exit (E_SUB_GID_UPDATE); -+ fail_exit (E_SUB_GID_UPDATE, process_selinux); - } - sub_gid_locked = true; - if (sub_gid_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, - _("%s: cannot open %s\n"), Prog, sub_gid_dbname ()); -- fail_exit (E_SUB_GID_UPDATE); -+ fail_exit (E_SUB_GID_UPDATE, process_selinux); - } - } - #endif /* ENABLE_SUBIDS */ -@@ -639,13 +650,13 @@ static void open_files (void) - * update_user() deletes the password file entries for this user - * and will update the group entries as required. - */ --static void update_user (void) -+static void update_user (bool process_selinux) - { - if (pw_remove (user_name) == 0) { - fprintf (stderr, - _("%s: cannot remove entry '%s' from %s\n"), - Prog, user_name, pw_dbname ()); -- fail_exit (E_PW_UPDATE); -+ fail_exit (E_PW_UPDATE, process_selinux); - } - if ( is_shadow_pwd - && (spw_locate (user_name) != NULL) -@@ -653,20 +664,20 @@ static void update_user (void) - fprintf (stderr, - _("%s: cannot remove entry '%s' from %s\n"), - Prog, user_name, spw_dbname ()); -- fail_exit (E_PW_UPDATE); -+ fail_exit (E_PW_UPDATE, process_selinux); - } - #ifdef ENABLE_SUBIDS - if (is_sub_uid && sub_uid_remove(user_name, 0, ULONG_MAX) == 0) { - fprintf (stderr, - _("%s: cannot remove entry %lu from %s\n"), - Prog, (unsigned long)user_id, sub_uid_dbname ()); -- fail_exit (E_SUB_UID_UPDATE); -+ fail_exit (E_SUB_UID_UPDATE, process_selinux); - } - if (is_sub_gid && sub_gid_remove(user_name, 0, ULONG_MAX) == 0) { - fprintf (stderr, - _("%s: cannot remove entry %lu from %s\n"), - Prog, (unsigned long)user_id, sub_gid_dbname ()); -- fail_exit (E_SUB_GID_UPDATE); -+ fail_exit (E_SUB_GID_UPDATE, process_selinux); - } - #endif /* ENABLE_SUBIDS */ - #ifdef WITH_AUDIT -@@ -905,6 +916,8 @@ int main (int argc, char **argv) - int retval; - #endif /* USE_PAM */ - #endif /* ACCT_TOOLS_SETUID */ -+ struct option_flags flags; -+ bool process_selinux; - - log_set_progname(Prog); - log_set_logfd(stderr); -@@ -954,9 +967,10 @@ int main (int argc, char **argv) - rflg = true; - break; - case 'R': /* no-op, handled in process_root_flag () */ -- Rflg = true; -+ flags.chroot = true; - break; - case 'P': /* no-op, handled in process_prefix_flag () */ -+ flags.prefix = true; - break; - #ifdef WITH_SELINUX - case 'Z': -@@ -982,6 +996,7 @@ int main (int argc, char **argv) - } - } - } -+ process_selinux = !flags.chroot && !flags.prefix; - - if ((optind + 1) != argc) { - usage (E_USAGE); -@@ -1046,7 +1061,7 @@ int main (int argc, char **argv) - pw_open(O_RDONLY); - pwd = pw_locate (user_name); /* we care only about local users */ - if (NULL == pwd) { -- pw_close(true); -+ pw_close(process_selinux); - fprintf (stderr, _("%s: user '%s' does not exist\n"), - Prog, user_name); - #ifdef WITH_AUDIT -@@ -1065,7 +1080,7 @@ int main (int argc, char **argv) - } else { - user_home = xstrdup(pwd->pw_dir); - } -- pw_close(true); -+ pw_close(process_selinux); - } - #ifdef WITH_TCB - if (shadowtcb_set_user (user_name) == SHADOWTCB_FAILURE) { -@@ -1077,7 +1092,7 @@ int main (int argc, char **argv) - * Note: This is a best effort basis. The user may log in between, - * a cron job may be started on her behalf, etc. - */ -- if (streq(prefix, "") && !Rflg && user_busy(user_name, user_id) != 0) { -+ if (streq(prefix, "") && !flags.chroot && user_busy(user_name, user_id) != 0) { - if (!fflg) { - #ifdef WITH_AUDIT - audit_logger (AUDIT_DEL_USER, Prog, -@@ -1093,9 +1108,9 @@ int main (int argc, char **argv) - * Do the hard stuff - open the files, create the user entries, - * create the home directory, then close and update the files. - */ -- open_files (); -- update_user (); -- update_groups (); -+ open_files (process_selinux); -+ update_user (process_selinux); -+ update_groups (process_selinux); - - if (rflg) { - if (remove_mailbox ()) { -@@ -1203,7 +1218,7 @@ int main (int argc, char **argv) - "delete-selinux-user-mapping", - user_name, user_id, SHADOW_AUDIT_FAILURE); - #endif /* WITH_AUDIT */ -- fail_exit (E_SE_UPDATE); -+ fail_exit (E_SE_UPDATE, process_selinux); - } - } - #endif /* WITH_SELINUX */ -@@ -1214,7 +1229,7 @@ int main (int argc, char **argv) - */ - if (streq(prefix, "")) - user_cancel (user_name); -- close_files (); -+ close_files (&flags); - - if (run_parts ("/etc/shadow-maint/userdel-post.d", user_name, "userdel")) { - exit(1); -diff -up shadow-4.18.0/src/usermod.c.test-chroot2 shadow-4.18.0/src/usermod.c ---- shadow-4.18.0/src/usermod.c.test-chroot2 2025-07-08 11:22:16.257549046 +0200 -+++ shadow-4.18.0/src/usermod.c 2025-07-08 11:22:16.262408337 +0200 -@@ -97,6 +97,14 @@ - #define VALID(s) (!strpbrk(s, ":\n")) - - /* -+ * Structures -+ */ -+struct option_flags { -+ bool chroot; -+ bool prefix; -+}; -+ -+/* - * Global variables - */ - static const char Prog[] = "usermod"; -@@ -182,23 +190,23 @@ static bool sub_gid_locked = false; - /* local function prototypes */ - static int get_groups (char *); - NORETURN static void usage (int status); --static void new_pwent (struct passwd *); --static void new_spent (struct spwd *); --NORETURN static void fail_exit (int); --static void update_group_file(void); --static void update_group(const struct group *grp); -+static void new_pwent (struct passwd *, bool); -+static void new_spent (struct spwd *, bool); -+NORETURN static void fail_exit (int, bool); -+static void update_group_file(bool); -+static void update_group(const struct group *grp, bool process_selinux); - - #ifdef SHADOWGRP --static void update_gshadow_file(void); --static void update_gshadow(const struct sgrp *sgrp); -+static void update_gshadow_file(bool process_selinux); -+static void update_gshadow(const struct sgrp *sgrp, bool process_selinux); - #endif --static void grp_update (void); -+static void grp_update (bool process_selinux); - --static void process_flags (int, char **); --static void close_files (void); --static void open_files (void); --static void usr_update (void); --static void move_home (void); -+static void process_flags (int, char **, struct option_flags *); -+static void close_files (struct option_flags *); -+static void open_files (bool process_selinux); -+static void usr_update (struct option_flags *flags); -+static void move_home (bool process_selinux); - #ifdef ENABLE_LASTLOG - static void update_lastlog (void); - #endif /* ENABLE_LASTLOG */ -@@ -466,7 +474,7 @@ static char *new_pw_passwd (char *pw_pas - * new_pwent() takes all of the values that have been entered and fills - * in a (struct passwd) with them. - */ --static void new_pwent (struct passwd *pwent) -+static void new_pwent (struct passwd *pwent, bool process_selinux) - { - if (lflg) { - if (pw_locate (user_newname) != NULL) { -@@ -477,7 +485,7 @@ static void new_pwent (struct passwd *pw - fprintf (stderr, - _("%s: user '%s' already exists in %s\n"), - Prog, user_newname, pw_dbname ()); -- fail_exit (E_NAME_IN_USE); -+ fail_exit (E_NAME_IN_USE, process_selinux); - } - #ifdef WITH_AUDIT - audit_logger (AUDIT_USER_MGMT, Prog, -@@ -563,14 +571,14 @@ static void new_pwent (struct passwd *pw - * new_spent() takes all of the values that have been entered and fills - * in a (struct spwd) with them. - */ --static void new_spent (struct spwd *spent) -+static void new_spent (struct spwd *spent, bool process_selinux) - { - if (lflg) { - if (spw_locate (user_newname) != NULL) { - fprintf (stderr, - _("%s: user '%s' already exists in %s\n"), - Prog, user_newname, spw_dbname ()); -- fail_exit (E_NAME_IN_USE); -+ fail_exit (E_NAME_IN_USE, process_selinux); - } - spent->sp_namp = xstrdup (user_newname); - } -@@ -629,10 +637,10 @@ static void new_spent (struct spwd *spen - */ - NORETURN - static void --fail_exit (int code) -+fail_exit (int code, bool process_selinux) - { - if (gr_locked) { -- if (gr_unlock (true) == 0) { -+ if (gr_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); - /* continue */ -@@ -640,7 +648,7 @@ fail_exit (int code) - } - #ifdef SHADOWGRP - if (sgr_locked) { -- if (sgr_unlock (true) == 0) { -+ if (sgr_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - /* continue */ -@@ -648,14 +656,14 @@ fail_exit (int code) - } - #endif - if (spw_locked) { -- if (spw_unlock (true) == 0) { -+ if (spw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - /* continue */ - } - } - if (pw_locked) { -- if (pw_unlock (true) == 0) { -+ if (pw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -@@ -663,14 +671,14 @@ fail_exit (int code) - } - #ifdef ENABLE_SUBIDS - if (sub_uid_locked) { -- if (sub_uid_unlock (true) == 0) { -+ if (sub_uid_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); - /* continue */ - } - } - if (sub_gid_locked) { -- if (sub_gid_unlock (true) == 0) { -+ if (sub_gid_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); - /* continue */ -@@ -688,7 +696,7 @@ fail_exit (int code) - - - static void --update_group_file(void) -+update_group_file(bool process_selinux) - { - const struct group *grp; - -@@ -697,12 +705,12 @@ update_group_file(void) - * the user is a member of. - */ - while ((grp = gr_next()) != NULL) -- update_group(grp); -+ update_group(grp, process_selinux); - } - - - static void --update_group(const struct group *grp) -+update_group(const struct group *grp, bool process_selinux) - { - bool changed; - bool is_member; -@@ -735,7 +743,7 @@ update_group(const struct group *grp) - fprintf (stderr, - _("%s: Out of memory. Cannot update %s.\n"), - Prog, gr_dbname ()); -- fail_exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE, process_selinux); - } - - if (was_member) { -@@ -804,7 +812,7 @@ update_group(const struct group *grp) - _("%s: failed to prepare the new %s entry '%s'\n"), - Prog, gr_dbname (), ngrp->gr_name); - SYSLOG ((LOG_WARN, "failed to prepare the new %s entry '%s'", gr_dbname (), ngrp->gr_name)); -- fail_exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE, process_selinux); - } - - free_ngrp: -@@ -814,7 +822,7 @@ free_ngrp: - - #ifdef SHADOWGRP - static void --update_gshadow_file(void) -+update_gshadow_file(bool process_selinux) - { - const struct sgrp *sgrp; - -@@ -823,14 +831,14 @@ update_gshadow_file(void) - * that the user is a member of. - */ - while ((sgrp = sgr_next()) != NULL) -- update_gshadow(sgrp); -+ update_gshadow(sgrp, process_selinux); - } - #endif /* SHADOWGRP */ - - - #ifdef SHADOWGRP - static void --update_gshadow(const struct sgrp *sgrp) -+update_gshadow(const struct sgrp *sgrp, bool process_selinux) - { - bool changed; - bool is_member; -@@ -873,7 +881,7 @@ update_gshadow(const struct sgrp *sgrp) - fprintf (stderr, - _("%s: Out of memory. Cannot update %s.\n"), - Prog, sgr_dbname ()); -- fail_exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE, process_selinux); - } - - if (was_admin && lflg) { -@@ -960,7 +968,7 @@ update_gshadow(const struct sgrp *sgrp) - Prog, sgr_dbname (), nsgrp->sg_namp); - SYSLOG ((LOG_WARN, "failed to prepare the new %s entry '%s'", - sgr_dbname (), nsgrp->sg_namp)); -- fail_exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE, process_selinux); - } - - free_nsgrp: -@@ -975,12 +983,12 @@ free_nsgrp: - * grp_update() takes the secondary group set given in user_groups and - * adds the user to each group given by that set. - */ --static void grp_update (void) -+static void grp_update (bool process_selinux) - { -- update_group_file(); -+ update_group_file(process_selinux); - #ifdef SHADOWGRP - if (is_shadow_grp) { -- update_gshadow_file(); -+ update_gshadow_file(process_selinux); - } - #endif - } -@@ -993,7 +1001,7 @@ static void grp_update (void) - * are checked for sanity. - */ - static void --process_flags(int argc, char **argv) -+process_flags(int argc, char **argv, struct option_flags *flags) - { - struct stat st; - bool anyflag = false; -@@ -1158,8 +1166,10 @@ process_flags(int argc, char **argv) - rflg = true; - break; - case 'R': /* no-op, handled in process_root_flag () */ -+ flags->chroot = true; - break; - case 'P': /* no-op, handled in process_prefix_flag () */ -+ flags->prefix = true; - break; - case 's': - if ( ( !VALID (optarg) ) -@@ -1467,51 +1477,55 @@ process_flags(int argc, char **argv) - * close_files() closes all of the files that were opened for this new - * user. This causes any modified entries to be written out. - */ --static void close_files (void) -+static void close_files (struct option_flags *flags) - { -- if (pw_close (true) == 0) { -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot && !flags->prefix; -+ -+ if (pw_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); -- fail_exit (E_PW_UPDATE); -+ fail_exit (E_PW_UPDATE, process_selinux); - } -- if (is_shadow_pwd && (spw_close (true) == 0)) { -+ if (is_shadow_pwd && (spw_close (process_selinux) == 0)) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, - "failure while writing changes to %s", - spw_dbname ())); -- fail_exit (E_PW_UPDATE); -+ fail_exit (E_PW_UPDATE, process_selinux); - } - - if (Gflg || lflg) { -- if (gr_close (true) == 0) { -+ if (gr_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, - "failure while writing changes to %s", - gr_dbname ())); -- fail_exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE, process_selinux); - } - #ifdef SHADOWGRP - if (is_shadow_grp) { -- if (sgr_close (true) == 0) { -+ if (sgr_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, - "failure while writing changes to %s", - sgr_dbname ())); -- fail_exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE, process_selinux); - } - } - #endif - #ifdef SHADOWGRP - if (is_shadow_grp) { -- if (sgr_unlock (true) == 0) { -+ if (sgr_unlock (process_selinux) == 0) { - fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, sgr_dbname ()); -@@ -1522,7 +1536,7 @@ static void close_files (void) - } - } - #endif -- if (gr_unlock (true) == 0) { -+ if (gr_unlock (process_selinux) == 0) { - fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, gr_dbname ()); -@@ -1534,7 +1548,7 @@ static void close_files (void) - } - - if (is_shadow_pwd) { -- if (spw_unlock (true) == 0) { -+ if (spw_unlock (process_selinux) == 0) { - fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, spw_dbname ()); -@@ -1544,7 +1558,7 @@ static void close_files (void) - /* continue */ - } - } -- if (pw_unlock (true) == 0) { -+ if (pw_unlock (process_selinux) == 0) { - fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, pw_dbname ()); -@@ -1561,12 +1575,12 @@ static void close_files (void) - - #ifdef ENABLE_SUBIDS - if (vflg || Vflg) { -- if (sub_uid_close (true) == 0) { -+ if (sub_uid_close (process_selinux) == 0) { - fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sub_uid_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_uid_dbname ())); -- fail_exit (E_SUB_UID_UPDATE); -+ fail_exit (E_SUB_UID_UPDATE, process_selinux); - } -- if (sub_uid_unlock (true) == 0) { -+ if (sub_uid_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); - /* continue */ -@@ -1574,12 +1588,12 @@ static void close_files (void) - sub_uid_locked = false; - } - if (wflg || Wflg) { -- if (sub_gid_close (true) == 0) { -+ if (sub_gid_close (process_selinux) == 0) { - fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sub_gid_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_gid_dbname ())); -- fail_exit (E_SUB_GID_UPDATE); -+ fail_exit (E_SUB_GID_UPDATE, process_selinux); - } -- if (sub_gid_unlock (true) == 0) { -+ if (sub_gid_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); - /* continue */ -@@ -1604,33 +1618,33 @@ static void close_files (void) - * - * open_files() opens the two password files. - */ --static void open_files (void) -+static void open_files (bool process_selinux) - { - if (pw_lock () == 0) { - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, pw_dbname ()); -- fail_exit (E_PW_UPDATE); -+ fail_exit (E_PW_UPDATE, process_selinux); - } - pw_locked = true; - if (pw_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, - _("%s: cannot open %s\n"), - Prog, pw_dbname ()); -- fail_exit (E_PW_UPDATE); -+ fail_exit (E_PW_UPDATE, process_selinux); - } - if (is_shadow_pwd && (spw_lock () == 0)) { - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, spw_dbname ()); -- fail_exit (E_PW_UPDATE); -+ fail_exit (E_PW_UPDATE, process_selinux); - } - spw_locked = true; - if (is_shadow_pwd && (spw_open (O_CREAT | O_RDWR) == 0)) { - fprintf (stderr, - _("%s: cannot open %s\n"), - Prog, spw_dbname ()); -- fail_exit (E_PW_UPDATE); -+ fail_exit (E_PW_UPDATE, process_selinux); - } - - if (Gflg || lflg) { -@@ -1642,28 +1656,28 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, gr_dbname ()); -- fail_exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE, process_selinux); - } - gr_locked = true; - if (gr_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, - _("%s: cannot open %s\n"), - Prog, gr_dbname ()); -- fail_exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE, process_selinux); - } - #ifdef SHADOWGRP - if (is_shadow_grp && (sgr_lock () == 0)) { - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, sgr_dbname ()); -- fail_exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE, process_selinux); - } - sgr_locked = true; - if (is_shadow_grp && (sgr_open (O_CREAT | O_RDWR) == 0)) { - fprintf (stderr, - _("%s: cannot open %s\n"), - Prog, sgr_dbname ()); -- fail_exit (E_GRP_UPDATE); -+ fail_exit (E_GRP_UPDATE, process_selinux); - } - #endif - } -@@ -1673,14 +1687,14 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, sub_uid_dbname ()); -- fail_exit (E_SUB_UID_UPDATE); -+ fail_exit (E_SUB_UID_UPDATE, process_selinux); - } - sub_uid_locked = true; - if (sub_uid_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, - _("%s: cannot open %s\n"), - Prog, sub_uid_dbname ()); -- fail_exit (E_SUB_UID_UPDATE); -+ fail_exit (E_SUB_UID_UPDATE, process_selinux); - } - } - if (wflg || Wflg) { -@@ -1688,14 +1702,14 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, sub_gid_dbname ()); -- fail_exit (E_SUB_GID_UPDATE); -+ fail_exit (E_SUB_GID_UPDATE, process_selinux); - } - sub_gid_locked = true; - if (sub_gid_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, - _("%s: cannot open %s\n"), - Prog, sub_gid_dbname ()); -- fail_exit (E_SUB_GID_UPDATE); -+ fail_exit (E_SUB_GID_UPDATE, process_selinux); - } - } - #endif /* ENABLE_SUBIDS */ -@@ -1707,13 +1721,15 @@ static void open_files (void) - * usr_update() creates the password file entries for this user and - * will update the group entries if required. - */ --static void usr_update (void) -+static void usr_update (struct option_flags *flags) - { - struct passwd pwent; - const struct passwd *pwd; -- - struct spwd spent; - const struct spwd *spwd = NULL; -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot && !flags->prefix; - - /* - * Locate the entry in /etc/passwd, which MUST exist. -@@ -1723,10 +1739,10 @@ static void usr_update (void) - fprintf (stderr, - _("%s: user '%s' does not exist in %s\n"), - Prog, user_name, pw_dbname ()); -- fail_exit (E_NOTFOUND); -+ fail_exit (E_NOTFOUND, process_selinux); - } - pwent = *pwd; -- new_pwent (&pwent); -+ new_pwent (&pwent, process_selinux); - - - /* If the shadow file does not exist, it won't be created */ -@@ -1735,7 +1751,7 @@ static void usr_update (void) - if (NULL != spwd) { - /* Update the shadow entry if it exists */ - spent = *spwd; -- new_spent (&spent); -+ new_spent (&spent, process_selinux); - } else if ( ( pflg - && streq(pwent.pw_passwd, SHADOW_PASSWD_STRING)) - || eflg || fflg) { -@@ -1766,7 +1782,7 @@ static void usr_update (void) - spent.sp_inact = -1; - spent.sp_expire = -1; - spent.sp_flag = SHADOW_SP_FLAG_UNSET; -- new_spent (&spent); -+ new_spent (&spent, process_selinux); - spwd = &spent; /* entry needs to be committed */ - } - } -@@ -1777,13 +1793,13 @@ static void usr_update (void) - fprintf (stderr, - _("%s: failed to prepare the new %s entry '%s'\n"), - Prog, pw_dbname (), pwent.pw_name); -- fail_exit (E_PW_UPDATE); -+ fail_exit (E_PW_UPDATE, process_selinux); - } - if (lflg && (pw_remove (user_name) == 0)) { - fprintf (stderr, - _("%s: cannot remove entry '%s' from %s\n"), - Prog, user_name, pw_dbname ()); -- fail_exit (E_PW_UPDATE); -+ fail_exit (E_PW_UPDATE, process_selinux); - } - } - if ((NULL != spwd) && (lflg || eflg || fflg || pflg || Lflg || Uflg)) { -@@ -1791,13 +1807,13 @@ static void usr_update (void) - fprintf (stderr, - _("%s: failed to prepare the new %s entry '%s'\n"), - Prog, spw_dbname (), spent.sp_namp); -- fail_exit (E_PW_UPDATE); -+ fail_exit (E_PW_UPDATE, process_selinux); - } - if (lflg && (spw_remove (user_name) == 0)) { - fprintf (stderr, - _("%s: cannot remove entry '%s' from %s\n"), - Prog, user_name, spw_dbname ()); -- fail_exit (E_PW_UPDATE); -+ fail_exit (E_PW_UPDATE, process_selinux); - } - } - } -@@ -1808,7 +1824,7 @@ static void usr_update (void) - * move_home() moves the user's home directory to a new location. The - * files will be copied if the directory cannot simply be renamed. - */ --static void move_home (void) -+static void move_home (bool process_selinux) - { - struct stat sb; - -@@ -1820,7 +1836,7 @@ static void move_home (void) - fprintf (stderr, - _("%s: directory %s exists\n"), - Prog, user_newhome); -- fail_exit (E_HOMEDIR); -+ fail_exit (E_HOMEDIR, process_selinux); - } - - if (stat (prefix_user_home, &sb) == 0) { -@@ -1834,7 +1850,7 @@ static void move_home (void) - "not a directory. It is not removed and no " - "home directories are created.\n"), - Prog, user_home); -- fail_exit (E_HOMEDIR); -+ fail_exit (E_HOMEDIR, process_selinux); - } - - #ifdef WITH_AUDIT -@@ -1855,7 +1871,7 @@ static void move_home (void) - fprintf (stderr, - _("%s: Failed to change ownership of the home directory"), - Prog); -- fail_exit (E_HOMEDIR); -+ fail_exit (E_HOMEDIR, process_selinux); - } - #ifdef WITH_AUDIT - audit_logger (AUDIT_USER_MGMT, Prog, -@@ -1870,7 +1886,7 @@ static void move_home (void) - fprintf (stderr, - _("%s: error: cannot move subvolume from %s to %s - different device\n"), - Prog, prefix_user_home, prefix_user_newhome); -- fail_exit (E_HOMEDIR); -+ fail_exit (E_HOMEDIR, process_selinux); - } - #endif - -@@ -1901,7 +1917,7 @@ static void move_home (void) - fprintf (stderr, - _("%s: cannot rename directory %s to %s\n"), - Prog, prefix_user_home, prefix_user_newhome); -- fail_exit (E_HOMEDIR); -+ fail_exit (E_HOMEDIR, process_selinux); - } - } else { - fprintf (stderr, -@@ -2160,6 +2176,8 @@ int main (int argc, char **argv) - int retval; - #endif /* USE_PAM */ - #endif /* ACCT_TOOLS_SETUID */ -+ struct option_flags flags; -+ bool process_selinux; - - log_set_progname(Prog); - log_set_logfd(stderr); -@@ -2189,7 +2207,8 @@ int main (int argc, char **argv) - is_sub_gid = sub_gid_file_present (); - #endif /* ENABLE_SUBIDS */ - -- process_flags (argc, argv); -+ process_flags (argc, argv, &flags); -+ process_selinux = !flags.chroot && !flags.prefix; - - /* - * The home directory, the username and the user's UID should not -@@ -2251,13 +2270,13 @@ int main (int argc, char **argv) - * Do the hard stuff - open the files, change the user entries, - * change the home directory, then close and update the files. - */ -- open_files (); -+ open_files (process_selinux); - if ( cflg || dflg || eflg || fflg || gflg || Lflg || lflg || pflg - || sflg || uflg || Uflg) { -- usr_update (); -+ usr_update (&flags); - } - if (Gflg || lflg) { -- grp_update (); -+ grp_update (process_selinux); - } - #ifdef ENABLE_SUBIDS - if (Vflg) { -@@ -2273,7 +2292,7 @@ int main (int argc, char **argv) - (uintmax_t) ptr->range.first, - (uintmax_t) ptr->range.last, - sub_uid_dbname()); -- fail_exit (E_SUB_UID_UPDATE); -+ fail_exit (E_SUB_UID_UPDATE, process_selinux); - } - } - } -@@ -2290,7 +2309,7 @@ int main (int argc, char **argv) - (uintmax_t) ptr->range.first, - (uintmax_t) ptr->range.last, - sub_uid_dbname()); -- fail_exit (E_SUB_UID_UPDATE); -+ fail_exit (E_SUB_UID_UPDATE, process_selinux); - } - } - } -@@ -2307,7 +2326,7 @@ int main (int argc, char **argv) - (uintmax_t) ptr->range.first, - (uintmax_t) ptr->range.last, - sub_gid_dbname()); -- fail_exit (E_SUB_GID_UPDATE); -+ fail_exit (E_SUB_GID_UPDATE, process_selinux); - } - } - } -@@ -2324,12 +2343,12 @@ int main (int argc, char **argv) - (uintmax_t) ptr->range.first, - (uintmax_t) ptr->range.last, - sub_gid_dbname()); -- fail_exit (E_SUB_GID_UPDATE); -+ fail_exit (E_SUB_GID_UPDATE, process_selinux); - } - } - } - #endif /* ENABLE_SUBIDS */ -- close_files (); -+ close_files (&flags); - - #ifdef WITH_TCB - if ( (lflg || uflg) -@@ -2355,7 +2374,7 @@ int main (int argc, char **argv) - user_name, user_id, - SHADOW_AUDIT_FAILURE); - #endif /* WITH_AUDIT */ -- fail_exit (E_SE_UPDATE); -+ fail_exit (E_SE_UPDATE, process_selinux); - } - } else { - if (del_seuser (user_name) != 0) { -@@ -2368,14 +2387,14 @@ int main (int argc, char **argv) - user_name, user_id, - SHADOW_AUDIT_FAILURE); - #endif /* WITH_AUDIT */ -- fail_exit (E_SE_UPDATE); -+ fail_exit (E_SE_UPDATE, process_selinux); - } - } - } - #endif /* WITH_SELINUX */ - - if (mflg) { -- move_home (); -+ move_home (process_selinux); - } - - #ifndef NO_MOVE_MAILBOX -@@ -2420,7 +2439,7 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: Failed to change ownership of the home directory"), - Prog); -- fail_exit (E_HOMEDIR); -+ fail_exit (E_HOMEDIR, process_selinux); - } - } - } - -diff -up shadow-4.18.0/lib/cleanup_group.c.test-chroot3 shadow-4.18.0/lib/cleanup_group.c ---- shadow-4.18.0/lib/cleanup_group.c.test-chroot3 2025-07-04 11:15:02.302179208 +0200 -+++ shadow-4.18.0/lib/cleanup_group.c 2025-07-04 11:15:02.311510389 +0200 -@@ -179,9 +179,11 @@ void cleanup_report_del_group_gshadow (v - * - * It should be registered after the group file is successfully locked. - */ --void cleanup_unlock_group (MAYBE_UNUSED void *arg) -+void cleanup_unlock_group (void *process_selinux) - { -- if (gr_unlock (true) == 0) { -+ bool process = *((bool *) process_selinux); -+ -+ if (gr_unlock (process) == 0) { - fprintf (log_get_logfd(), - _("%s: failed to unlock %s\n"), - log_get_progname(), gr_dbname ()); -@@ -199,9 +201,11 @@ void cleanup_unlock_group (MAYBE_UNUSED - * - * It should be registered after the gshadow file is successfully locked. - */ --void cleanup_unlock_gshadow (MAYBE_UNUSED void *arg) -+void cleanup_unlock_gshadow (void *process_selinux) - { -- if (sgr_unlock (true) == 0) { -+ bool process = *((bool *) process_selinux); -+ -+ if (sgr_unlock (process) == 0) { - fprintf (log_get_logfd(), - _("%s: failed to unlock %s\n"), - log_get_progname(), sgr_dbname ()); -diff -up shadow-4.18.0/lib/cleanup_user.c.test-chroot3 shadow-4.18.0/lib/cleanup_user.c ---- shadow-4.18.0/lib/cleanup_user.c.test-chroot3 2025-07-04 11:15:02.297132547 +0200 -+++ shadow-4.18.0/lib/cleanup_user.c 2025-07-04 11:15:02.311622726 +0200 -@@ -96,9 +96,11 @@ void cleanup_report_add_user_shadow (voi - * - * It should be registered after the passwd database is successfully locked. - */ --void cleanup_unlock_passwd (MAYBE_UNUSED void *arg) -+void cleanup_unlock_passwd (void *process_selinux) - { -- if (pw_unlock (true) == 0) { -+ bool process = *((bool *) process_selinux); -+ -+ if (pw_unlock (process) == 0) { - fprintf (log_get_logfd(), - _("%s: failed to unlock %s\n"), - log_get_progname(), pw_dbname ()); -@@ -115,9 +117,11 @@ void cleanup_unlock_passwd (MAYBE_UNUSED - * - * It should be registered after the shadow database is successfully locked. - */ --void cleanup_unlock_shadow (MAYBE_UNUSED void *arg) -+void cleanup_unlock_shadow (void *process_selinux) - { -- if (spw_unlock (true) == 0) { -+ bool process = *((bool *) process_selinux); -+ -+ if (spw_unlock (process) == 0) { - fprintf (log_get_logfd(), - _("%s: failed to unlock %s\n"), - log_get_progname(), spw_dbname ()); -diff -up shadow-4.18.0/lib/prototypes.h.test-chroot3 shadow-4.18.0/lib/prototypes.h ---- shadow-4.18.0/lib/prototypes.h.test-chroot3 2025-06-24 22:28:01.058453223 +0200 -+++ shadow-4.18.0/lib/prototypes.h 2025-07-04 11:15:02.311703893 +0200 -@@ -92,11 +92,11 @@ void cleanup_report_del_group_gshadow (v - void cleanup_report_mod_passwd (void *cleanup_info); - void cleanup_report_mod_group (void *cleanup_info); - void cleanup_report_mod_gshadow (void *cleanup_info); --void cleanup_unlock_group (/*@null@*/void *MAYBE_UNUSED); -+void cleanup_unlock_group (void *process_selinux); - #ifdef SHADOWGRP --void cleanup_unlock_gshadow (/*@null@*/void *MAYBE_UNUSED); -+void cleanup_unlock_gshadow (void *process_selinux); - #endif --void cleanup_unlock_passwd (/*@null@*/void *MAYBE_UNUSED); -+void cleanup_unlock_passwd (void *process_selinux); - - /* console.c */ - extern bool console (const char *); -diff -up shadow-4.18.0/src/chgpasswd.c.test-chroot3 shadow-4.18.0/src/chgpasswd.c ---- shadow-4.18.0/src/chgpasswd.c.test-chroot3 2025-07-04 11:15:02.302260729 +0200 -+++ shadow-4.18.0/src/chgpasswd.c 2025-07-04 11:15:02.312527205 +0200 -@@ -38,6 +38,12 @@ - #include "string/strcmp/streq.h" - #include "string/strtok/stpsep.h" - -+/* -+ * Structures -+ */ -+struct option_flags { -+ bool chroot; -+}; - - /* - * Global variables -@@ -68,21 +74,21 @@ static bool sgr_locked = false; - static bool gr_locked = false; - - /* local function prototypes */ --NORETURN static void fail_exit (int code); -+NORETURN static void fail_exit (int code, bool process_selinux); - NORETURN static void usage (int status); --static void process_flags (int argc, char **argv); -+static void process_flags (int argc, char **argv, struct option_flags *flags); - static void check_flags (void); - static void check_perms (void); --static void open_files (void); --static void close_files (void); -+static void open_files (bool process_selinux); -+static void close_files (struct option_flags *flags); - - /* - * fail_exit - exit with a failure code after unlocking the files - */ --static void fail_exit (int code) -+static void fail_exit (int code, bool process_selinux) - { - if (gr_locked) { -- if (gr_unlock (true) == 0) { -+ if (gr_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); - /* continue */ -@@ -91,7 +97,7 @@ static void fail_exit (int code) - - #ifdef SHADOWGRP - if (sgr_locked) { -- if (sgr_unlock (true) == 0) { -+ if (sgr_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - /* continue */ -@@ -149,7 +155,7 @@ usage (int status) - * - * It will not return if an error is encountered. - */ --static void process_flags (int argc, char **argv) -+static void process_flags (int argc, char **argv, struct option_flags *flags) - { - int c; - #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) -@@ -187,6 +193,7 @@ static void process_flags (int argc, cha - md5flg = true; - break; - case 'R': /* no-op, handled in process_root_flag () */ -+ flags->chroot = true; - break; - #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) - case 's': -@@ -336,7 +343,7 @@ static void check_perms (void) - /* - * open_files - lock and open the group databases - */ --static void open_files (void) -+static void open_files (bool process_selinux) - { - /* - * Lock the group file and open it for reading and writing. This will -@@ -346,13 +353,13 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, gr_dbname ()); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - gr_locked = true; - if (gr_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, - _("%s: cannot open %s\n"), Prog, gr_dbname ()); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - - #ifdef SHADOWGRP -@@ -362,13 +369,13 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, sgr_dbname ()); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - sgr_locked = true; - if (sgr_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, _("%s: cannot open %s\n"), - Prog, sgr_dbname ()); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - } - #endif -@@ -377,18 +384,21 @@ static void open_files (void) - /* - * close_files - close and unlock the group databases - */ --static void close_files (void) -+static void close_files (struct option_flags *flags) - { -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot; - #ifdef SHADOWGRP - if (is_shadow_grp) { -- if (sgr_close (true) == 0) { -+ if (sgr_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ())); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } -- if (sgr_unlock (true) == 0) { -+ if (sgr_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - /* continue */ -@@ -397,14 +407,14 @@ static void close_files (void) - } - #endif - -- if (gr_close (true) == 0) { -+ if (gr_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ())); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } -- if (gr_unlock (true) == 0) { -+ if (gr_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); - /* continue */ -@@ -428,6 +438,8 @@ int main (int argc, char **argv) - struct group newgr; - bool errors = false; - intmax_t line = 0; -+ struct option_flags flags; -+ bool process_selinux; - - log_set_progname(Prog); - log_set_logfd(stderr); -@@ -444,7 +456,8 @@ int main (int argc, char **argv) - - process_root_flag ("-R", argc, argv); - -- process_flags (argc, argv); -+ process_flags (argc, argv, &flags); -+ process_selinux = !flags.chroot; - - OPENLOG (Prog); - -@@ -454,7 +467,7 @@ int main (int argc, char **argv) - is_shadow_grp = sgr_file_present (); - #endif - -- open_files (); -+ open_files (process_selinux); - - /* - * Read each line, separating the group name from the password. The -@@ -523,7 +536,7 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: failed to crypt password with salt '%s': %s\n"), - Prog, salt, strerror (errno)); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - } - -@@ -624,10 +637,10 @@ int main (int argc, char **argv) - if (errors) { - fprintf (stderr, - _("%s: error detected, changes ignored\n"), Prog); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - -- close_files (); -+ close_files (&flags); - - nscd_flush_cache ("group"); - sssd_flush_cache (SSSD_DB_GROUP); -diff -up shadow-4.18.0/src/groupadd.c.test-chroot3 shadow-4.18.0/src/groupadd.c ---- shadow-4.18.0/src/groupadd.c.test-chroot3 2025-07-04 11:15:02.284218582 +0200 -+++ shadow-4.18.0/src/groupadd.c 2025-07-04 11:15:02.311806157 +0200 -@@ -54,6 +54,14 @@ - #define E_GRP_UPDATE 10 /* can't update group file */ - - /* -+ * Structures -+ */ -+struct option_flags { -+ bool chroot; -+ bool prefix; -+}; -+ -+/* - * Global variables - */ - static const char Prog[] = "groupadd"; -@@ -85,9 +93,9 @@ static void new_sgent (struct sgrp *sgen - #endif - static void grp_update (void); - static void check_new_name (void); --static void close_files (void); --static void open_files (void); --static void process_flags (int argc, char **argv); -+static void close_files (struct option_flags *flags); -+static void open_files (struct option_flags *flags); -+static void process_flags (int argc, char **argv, struct option_flags *flags); - static void check_flags (void); - static void check_perms (void); - -@@ -271,10 +279,14 @@ check_new_name(void) - * close_files() closes all of the files that were opened for this new - * group. This causes any modified entries to be written out. - */ --static void close_files (void) -+static void close_files (struct option_flags *flags) - { -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot && !flags->prefix; -+ - /* First, write the changes in the regular group database */ -- if (gr_close (true) == 0) { -+ if (gr_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, gr_dbname ()); -@@ -289,13 +301,13 @@ static void close_files (void) - gr_dbname (), group_name, (unsigned int) group_id)); - del_cleanup (cleanup_report_add_group_group); - -- cleanup_unlock_group (NULL); -+ cleanup_unlock_group (&process_selinux); - del_cleanup (cleanup_unlock_group); - - /* Now, write the changes in the shadow database */ - #ifdef SHADOWGRP - if (is_shadow_grp) { -- if (sgr_close (true) == 0) { -+ if (sgr_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, sgr_dbname ()); -@@ -310,7 +322,7 @@ static void close_files (void) - sgr_dbname (), group_name)); - del_cleanup (cleanup_report_add_group_gshadow); - -- cleanup_unlock_gshadow (NULL); -+ cleanup_unlock_gshadow (&process_selinux); - del_cleanup (cleanup_unlock_gshadow); - } - #endif /* SHADOWGRP */ -@@ -326,8 +338,12 @@ static void close_files (void) - * - * open_files() opens the two group files. - */ --static void open_files (void) -+static void open_files (struct option_flags *flags) - { -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot && !flags->prefix; -+ - /* First, lock the databases */ - if (gr_lock () == 0) { - fprintf (stderr, -@@ -335,7 +351,7 @@ static void open_files (void) - Prog, gr_dbname ()); - fail_exit (E_GRP_UPDATE); - } -- add_cleanup (cleanup_unlock_group, NULL); -+ add_cleanup (cleanup_unlock_group, &process_selinux); - - #ifdef SHADOWGRP - if (is_shadow_grp) { -@@ -345,7 +361,7 @@ static void open_files (void) - Prog, sgr_dbname ()); - fail_exit (E_GRP_UPDATE); - } -- add_cleanup (cleanup_unlock_gshadow, NULL); -+ add_cleanup (cleanup_unlock_gshadow, &process_selinux); - } - #endif /* SHADOWGRP */ - -@@ -380,7 +396,7 @@ static void open_files (void) - * - * It will not return if an error is encountered. - */ --static void process_flags (int argc, char **argv) -+static void process_flags (int argc, char **argv, struct option_flags *flags) - { - /* - * Parse the command line options. -@@ -455,8 +471,10 @@ static void process_flags (int argc, cha - rflg = true; - break; - case 'R': /* no-op, handled in process_root_flag () */ -+ flags->chroot = true; - break; - case 'P': /* no-op, handled in process_prefix_flag () */ -+ flags->prefix = true; - break; - case 'U': - user_list = optarg; -@@ -583,6 +601,8 @@ static void check_perms (void) - */ - int main (int argc, char **argv) - { -+ struct option_flags flags; -+ - log_set_progname(Prog); - log_set_logfd(stderr); - -@@ -608,7 +628,7 @@ int main (int argc, char **argv) - /* - * Parse the command line options. - */ -- process_flags (argc, argv); -+ process_flags (argc, argv, &flags); - - check_perms (); - -@@ -625,7 +645,7 @@ int main (int argc, char **argv) - * Do the hard stuff - open the files, create the group entries, - * then close and update the files. - */ -- open_files (); -+ open_files (&flags); - - if (!gflg) { - if (find_new_gid (rflg, &group_id, NULL) < 0) { -@@ -634,7 +654,7 @@ int main (int argc, char **argv) - } - - grp_update (); -- close_files (); -+ close_files (&flags); - if (run_parts ("/etc/shadow-maint/groupadd-post.d", group_name, - Prog)) { - exit(1); -diff -up shadow-4.18.0/src/groupdel.c.test-chroot3 shadow-4.18.0/src/groupdel.c ---- shadow-4.18.0/src/groupdel.c.test-chroot3 2025-07-04 11:15:02.284261326 +0200 -+++ shadow-4.18.0/src/groupdel.c 2025-07-04 11:15:02.312079796 +0200 -@@ -33,6 +33,12 @@ - #endif - #include "shadowlog.h" - #include "run_part.h" -+ -+struct option_flags { -+ bool chroot; -+ bool prefix; -+}; -+ - /* - * Global variables - */ -@@ -61,10 +67,10 @@ static bool is_shadow_grp; - /* local function prototypes */ - NORETURN static void usage (int status); - static void grp_update (void); --static void close_files (void); --static void open_files (void); -+static void close_files (struct option_flags *flags); -+static void open_files (struct option_flags *flags); - static void group_busy (gid_t gid); --static void process_flags (int argc, char **argv); -+static void process_flags (int argc, char **argv, struct option_flags *flags); - - /* - * usage - display usage message and exit -@@ -146,10 +152,14 @@ static void grp_update (void) - * close_files() closes all of the files that were opened for this - * new group. This causes any modified entries to be written out. - */ --static void close_files (void) -+static void close_files (struct option_flags *flags) - { -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot && !flags->prefix; -+ - /* First, write the changes in the regular group database */ -- if (gr_close (true) == 0) { -+ if (gr_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, gr_dbname ()); -@@ -166,14 +176,14 @@ static void close_files (void) - group_name, gr_dbname ())); - del_cleanup (cleanup_report_del_group_group); - -- cleanup_unlock_group (NULL); -+ cleanup_unlock_group (&process_selinux); - del_cleanup (cleanup_unlock_group); - - - /* Then, write the changes in the shadow database */ - #ifdef SHADOWGRP - if (is_shadow_grp) { -- if (sgr_close (true) == 0) { -+ if (sgr_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, sgr_dbname ()); -@@ -190,7 +200,7 @@ static void close_files (void) - group_name, sgr_dbname ())); - del_cleanup (cleanup_report_del_group_gshadow); - -- cleanup_unlock_gshadow (NULL); -+ cleanup_unlock_gshadow (&process_selinux); - del_cleanup (cleanup_unlock_gshadow); - } - #endif /* SHADOWGRP */ -@@ -204,8 +214,12 @@ static void close_files (void) - * - * open_files() opens the two group files. - */ --static void open_files (void) -+static void open_files (struct option_flags *flags) - { -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot && !flags->prefix; -+ - /* First, lock the databases */ - if (gr_lock () == 0) { - fprintf (stderr, -@@ -213,7 +227,7 @@ static void open_files (void) - Prog, gr_dbname ()); - fail_exit (E_GRP_UPDATE); - } -- add_cleanup (cleanup_unlock_group, NULL); -+ add_cleanup (cleanup_unlock_group, &process_selinux); - #ifdef SHADOWGRP - if (is_shadow_grp) { - if (sgr_lock () == 0) { -@@ -222,7 +236,7 @@ static void open_files (void) - Prog, sgr_dbname ()); - fail_exit (E_GRP_UPDATE); - } -- add_cleanup (cleanup_unlock_gshadow, NULL); -+ add_cleanup (cleanup_unlock_gshadow, &process_selinux); - } - #endif - -@@ -296,7 +310,7 @@ static void group_busy (gid_t gid) - * - * It will not return if an error is encountered. - */ --static void process_flags (int argc, char **argv) -+static void process_flags (int argc, char **argv, struct option_flags *flags) - { - /* - * Parse the command line options. -@@ -317,8 +331,10 @@ static void process_flags (int argc, cha - usage (E_SUCCESS); - /*@notreached@*/break; - case 'R': /* no-op, handled in process_root_flag () */ -+ flags->chroot = true; - break; - case 'P': /* no-op, handled in process_prefix_flag () */ -+ flags->prefix = true; - break; - case 'f': - check_group_busy = false; -@@ -352,6 +368,7 @@ int main (int argc, char **argv) - int retval; - #endif /* USE_PAM */ - #endif /* ACCT_TOOLS_SETUID */ -+ struct option_flags flags; - - log_set_progname(Prog); - log_set_logfd(stderr); -@@ -375,7 +392,7 @@ int main (int argc, char **argv) - fail_exit (1); - } - -- process_flags (argc, argv); -+ process_flags (argc, argv, &flags); - - #ifdef ACCT_TOOLS_SETUID - #ifdef USE_PAM -@@ -449,11 +466,11 @@ int main (int argc, char **argv) - * Do the hard stuff - open the files, delete the group entries, - * then close and update the files. - */ -- open_files (); -+ open_files (&flags); - - grp_update (); - -- close_files (); -+ close_files (&flags); - - if (run_parts ("/etc/shadow-maint/groupdel-post.d", group_name, - Prog)) { -diff -up shadow-4.18.0/src/groupmems.c.test-chroot3 shadow-4.18.0/src/groupmems.c ---- shadow-4.18.0/src/groupmems.c.test-chroot3 2025-07-04 11:15:02.302301588 +0200 -+++ shadow-4.18.0/src/groupmems.c 2025-07-04 11:15:57.404278255 +0200 -@@ -47,6 +47,13 @@ - #define EXIT_INVALID_GROUP 9 /* specified group does not exist */ - - /* -+ * Structures -+ */ -+struct option_flags { -+ bool chroot; -+}; -+ -+/* - * Global variables - */ - static const char Prog[] = "groupmems"; -@@ -68,15 +75,17 @@ static bool sgr_locked = false; - /* local function prototypes */ - static char *whoami (void); - static void add_user (const char *user, -- const struct group *grp); -+ const struct group *grp, -+ bool process_selinux); - static void remove_user (const char *user, -- const struct group *grp); --static void purge_members (const struct group *grp); -+ const struct group *grp, -+ bool process_selinux); -+static void purge_members (const struct group *grp, bool process_selinux); - static void display_members (const char *const *members); - NORETURN static void usage (int status); --static void process_flags (int argc, char **argv); --static void check_perms (void); --NORETURN static void fail_exit (int code); -+static void process_flags (int argc, char **argv, struct option_flags *flags); -+static void check_perms (bool process_selinux); -+NORETURN static void fail_exit (int code, bool process_selinux); - #define isroot() (getuid () == 0) - - static char *whoami (void) -@@ -99,7 +108,8 @@ static char *whoami (void) - * add_user - Add a user to the specified group - */ - static void add_user (const char *user, -- const struct group *grp) -+ const struct group *grp, -+ bool process_selinux) - { - struct group *newgrp; - -@@ -108,7 +118,7 @@ static void add_user (const char *user, - fprintf (stderr, - _("%s: user '%s' is already a member of '%s'\n"), - Prog, user, grp->gr_name); -- fail_exit (EXIT_MEMBER_EXISTS); -+ fail_exit (EXIT_MEMBER_EXISTS, process_selinux); - } - - newgrp = __gr_dup(grp); -@@ -116,7 +126,7 @@ static void add_user (const char *user, - fprintf (stderr, - _("%s: Out of memory. Cannot update %s.\n"), - Prog, gr_dbname ()); -- fail_exit (13); -+ fail_exit (13, process_selinux); - } - - /* Add the user to the /etc/group group */ -@@ -146,7 +156,7 @@ static void add_user (const char *user, - fprintf (stderr, - _("%s: Out of memory. Cannot update %s.\n"), - Prog, sgr_dbname ()); -- fail_exit (13); -+ fail_exit (13, process_selinux); - } - /* Add the user to the members */ - newsg->sg_mem = add_list (newsg->sg_mem, user); -@@ -157,7 +167,7 @@ static void add_user (const char *user, - fprintf (stderr, - _("%s: failed to prepare the new %s entry '%s'\n"), - Prog, sgr_dbname (), newsg->sg_namp); -- fail_exit (13); -+ fail_exit (13, process_selinux); - } - } - #endif -@@ -166,7 +176,7 @@ static void add_user (const char *user, - fprintf (stderr, - _("%s: failed to prepare the new %s entry '%s'\n"), - Prog, gr_dbname (), newgrp->gr_name); -- fail_exit (13); -+ fail_exit (13, process_selinux); - } - } - -@@ -174,7 +184,8 @@ static void add_user (const char *user, - * remove_user - Remove a user from a given group - */ - static void remove_user (const char *user, -- const struct group *grp) -+ const struct group *grp, -+ bool process_selinux) - { - struct group *newgrp; - -@@ -183,7 +194,7 @@ static void remove_user (const char *use - fprintf (stderr, - _("%s: user '%s' is not a member of '%s'\n"), - Prog, user, grp->gr_name); -- fail_exit (EXIT_NOT_MEMBER); -+ fail_exit (EXIT_NOT_MEMBER, process_selinux); - } - - newgrp = __gr_dup (grp); -@@ -191,7 +202,7 @@ static void remove_user (const char *use - fprintf (stderr, - _("%s: Out of memory. Cannot update %s.\n"), - Prog, gr_dbname ()); -- fail_exit (13); -+ fail_exit (13, process_selinux); - } - - /* Remove the user from the /etc/group group */ -@@ -221,7 +232,7 @@ static void remove_user (const char *use - fprintf (stderr, - _("%s: Out of memory. Cannot update %s.\n"), - Prog, sgr_dbname ()); -- fail_exit (13); -+ fail_exit (13, process_selinux); - } - /* Remove the user from the members */ - newsg->sg_mem = del_list (newsg->sg_mem, user); -@@ -233,7 +244,7 @@ static void remove_user (const char *use - fprintf (stderr, - _("%s: failed to prepare the new %s entry '%s'\n"), - Prog, sgr_dbname (), newsg->sg_namp); -- fail_exit (13); -+ fail_exit (13, process_selinux); - } - } - #endif -@@ -242,14 +253,14 @@ static void remove_user (const char *use - fprintf (stderr, - _("%s: failed to prepare the new %s entry '%s'\n"), - Prog, gr_dbname (), newgrp->gr_name); -- fail_exit (13); -+ fail_exit (13, process_selinux); - } - } - - /* - * purge_members - Remove every members of the specified group - */ --static void purge_members (const struct group *grp) -+static void purge_members (const struct group *grp, bool process_selinux) - { - struct group *newgrp = __gr_dup (grp); - -@@ -257,7 +268,7 @@ static void purge_members (const struct - fprintf (stderr, - _("%s: Out of memory. Cannot update %s.\n"), - Prog, gr_dbname ()); -- fail_exit (13); -+ fail_exit (13, process_selinux); - } - - /* Remove all the members of the /etc/group group */ -@@ -288,7 +299,7 @@ static void purge_members (const struct - fprintf (stderr, - _("%s: Out of memory. Cannot update %s.\n"), - Prog, sgr_dbname ()); -- fail_exit (13); -+ fail_exit (13, process_selinux); - } - /* Remove all the members of the /etc/gshadow - * group */ -@@ -302,7 +313,7 @@ static void purge_members (const struct - fprintf (stderr, - _("%s: failed to prepare the new %s entry '%s'\n"), - Prog, sgr_dbname (), newsg->sg_namp); -- fail_exit (13); -+ fail_exit (13, process_selinux); - } - } - #endif -@@ -311,7 +322,7 @@ static void purge_members (const struct - fprintf (stderr, - _("%s: failed to prepare the new %s entry '%s'\n"), - Prog, gr_dbname (), newgrp->gr_name); -- fail_exit (13); -+ fail_exit (13, process_selinux); - } - } - -@@ -356,7 +367,7 @@ usage (int status) - /* - * process_flags - perform command line argument setting - */ --static void process_flags (int argc, char **argv) -+static void process_flags (int argc, char **argv, struct option_flags *flags) - { - int c; - static struct option long_options[] = { -@@ -396,6 +407,7 @@ static void process_flags (int argc, cha - ++exclusive; - break; - case 'R': /* no-op, handled in process_root_flag () */ -+ flags->chroot = true; - break; - default: - usage (EXIT_USAGE); -@@ -411,12 +423,12 @@ static void process_flags (int argc, cha - && (getpwnam (adduser) == NULL)) { - fprintf (stderr, _("%s: user '%s' does not exist\n"), - Prog, adduser); -- fail_exit (EXIT_INVALID_USER); -+ fail_exit (EXIT_INVALID_USER, !flags->chroot); - } - - } - --static void check_perms (void) -+static void check_perms (bool process_selinux) - { - if (!list) { - #ifdef ACCT_TOOLS_SETUID -@@ -430,7 +442,7 @@ static void check_perms (void) - fprintf (stderr, - _("%s: Cannot determine your user name.\n"), - Prog); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - - retval = pam_start (Prog, pampw->pw_name, &conv, &pamh); -@@ -450,7 +462,7 @@ static void check_perms (void) - if (NULL != pamh) { - (void) pam_end (pamh, retval); - } -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - (void) pam_end (pamh, retval); - #endif /* USE_PAM */ -@@ -458,10 +470,10 @@ static void check_perms (void) - } - } - --static void fail_exit (int code) -+static void fail_exit (int code, bool process_selinux) - { - if (gr_locked) { -- if (gr_unlock (true) == 0) { -+ if (gr_unlock (process_selinux) == 0) { - fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, gr_dbname ()); -@@ -472,7 +484,7 @@ static void fail_exit (int code) - - #ifdef SHADOWGRP - if (sgr_locked) { -- if (sgr_unlock (true) == 0) { -+ if (sgr_unlock (process_selinux) == 0) { - fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, sgr_dbname ()); -@@ -485,14 +497,14 @@ static void fail_exit (int code) - exit (code); - } - --static void open_files (void) -+static void open_files (bool process_selinux) - { - if (!list) { - if (gr_lock () == 0) { - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, gr_dbname ()); -- fail_exit (EXIT_GROUP_FILE); -+ fail_exit (EXIT_GROUP_FILE, process_selinux); - } - gr_locked = true; - -@@ -502,7 +514,7 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, sgr_dbname ()); -- fail_exit (EXIT_GROUP_FILE); -+ fail_exit (EXIT_GROUP_FILE, process_selinux); - } - sgr_locked = true; - } -@@ -511,28 +523,32 @@ static void open_files (void) - - if (gr_open (list ? O_RDONLY : O_CREAT | O_RDWR) == 0) { - fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ()); -- fail_exit (EXIT_GROUP_FILE); -+ fail_exit (EXIT_GROUP_FILE, process_selinux); - } - - #ifdef SHADOWGRP - if (is_shadowgrp) { - if (sgr_open (list ? O_RDONLY : O_CREAT | O_RDWR) == 0) { - fprintf (stderr, _("%s: cannot open %s\n"), Prog, sgr_dbname ()); -- fail_exit (EXIT_GROUP_FILE); -+ fail_exit (EXIT_GROUP_FILE, process_selinux); - } - } - #endif - } - --static void close_files (void) -+static void close_files (struct option_flags *flags) - { -- if ((gr_close (true) == 0) && !list) { -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot; -+ -+ if ((gr_close (process_selinux) == 0) && !list) { - fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ())); -- fail_exit (EXIT_GROUP_FILE); -+ fail_exit (EXIT_GROUP_FILE, process_selinux); - } - if (gr_locked) { -- if (gr_unlock (true) == 0) { -+ if (gr_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); - /* continue */ -@@ -542,13 +558,13 @@ static void close_files (void) - - #ifdef SHADOWGRP - if (is_shadowgrp) { -- if ((sgr_close (true) == 0) && !list) { -+ if ((sgr_close (process_selinux) == 0) && !list) { - fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ())); -- fail_exit (EXIT_GROUP_FILE); -+ fail_exit (EXIT_GROUP_FILE, process_selinux); - } - if (sgr_locked) { -- if (sgr_unlock (true) == 0) { -+ if (sgr_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - /* continue */ -@@ -563,6 +579,8 @@ int main (int argc, char **argv) - { - char *name; - const struct group *grp; -+ struct option_flags flags; -+ bool process_selinux; - - log_set_progname(Prog); - log_set_logfd(stderr); -@@ -579,44 +597,45 @@ int main (int argc, char **argv) - is_shadowgrp = sgr_file_present (); - #endif - -- process_flags (argc, argv); -+ process_flags (argc, argv, &flags); -+ process_selinux = !flags.chroot; - - if (NULL == thisgroup) { - name = whoami (); - if (!list && (NULL == name)) { - fprintf (stderr, _("%s: your groupname does not match your username\n"), Prog); -- fail_exit (EXIT_NOT_PRIMARY); -+ fail_exit (EXIT_NOT_PRIMARY, process_selinux); - } - } else { - name = thisgroup; - if (!list && !isroot ()) { - fprintf (stderr, _("%s: only root can use the -g/--group option\n"), Prog); -- fail_exit (EXIT_NOT_ROOT); -+ fail_exit (EXIT_NOT_ROOT, process_selinux); - } - } - -- check_perms (); -+ check_perms (process_selinux); - -- open_files (); -+ open_files (process_selinux); - - grp = gr_locate (name); - if (NULL == grp) { - fprintf (stderr, _("%s: group '%s' does not exist in %s\n"), - Prog, name, gr_dbname ()); -- fail_exit (EXIT_INVALID_GROUP); -+ fail_exit (EXIT_INVALID_GROUP, process_selinux); - } - - if (list) { - display_members ((const char *const *)grp->gr_mem); - } else if (NULL != adduser) { -- add_user (adduser, grp); -+ add_user (adduser, grp, process_selinux); - } else if (NULL != deluser) { -- remove_user (deluser, grp); -+ remove_user (deluser, grp, process_selinux); - } else if (purge) { -- purge_members (grp); -+ purge_members (grp, process_selinux); - } - -- close_files (); -+ close_files (&flags); - - exit (EXIT_SUCCESS); - } -diff -up shadow-4.18.0/src/groupmod.c.test-chroot3 shadow-4.18.0/src/groupmod.c ---- shadow-4.18.0/src/groupmod.c.test-chroot3 2025-07-04 11:15:02.284354823 +0200 -+++ shadow-4.18.0/src/groupmod.c 2025-07-04 11:15:02.311945828 +0200 -@@ -61,6 +61,10 @@ - #define E_PAM_USERNAME 12 /* can't determine your username for use with pam */ - #define E_PAM_ERROR 13 /* pam returned an error, see Syslog facility id groupmod */ - -+struct option_flags { -+ bool chroot; -+ bool prefix; -+}; - - /* - * Global variables -@@ -102,11 +106,11 @@ static void new_sgent (struct sgrp *); - static void grp_update (void); - static void check_new_gid (void); - static void check_new_name (void); --static void process_flags (int, char **); --static void lock_files (void); -+static void process_flags (int, char **, struct option_flags *); -+static void lock_files (struct option_flags *flags); - static void prepare_failure_reports (void); - static void open_files (void); --static void close_files (void); -+static void close_files (struct option_flags *flags); - static void update_primary_groups (gid_t ogid, gid_t ngid); - - -@@ -405,7 +409,7 @@ check_new_name(void) - * values that the user will be created with accordingly. The values - * are checked for sanity. - */ --static void process_flags (int argc, char **argv) -+static void process_flags (int argc, char **argv, struct option_flags *flags) - { - int c; - static struct option long_options[] = { -@@ -451,8 +455,10 @@ static void process_flags (int argc, cha - pflg = true; - break; - case 'R': /* no-op, handled in process_root_flag () */ -+ flags->chroot = true; - break; - case 'P': /* no-op, handled in process_prefix_flag () */ -+ flags->prefix = true; - break; - case 'U': - user_list = optarg; -@@ -479,9 +485,13 @@ static void process_flags (int argc, cha - * close_files() closes all of the files that were opened for this new - * group. This causes any modified entries to be written out. - */ --static void close_files (void) -+static void close_files (struct option_flags *flags) - { -- if (gr_close (true) == 0) { -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot && !flags->prefix; -+ -+ if (gr_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, gr_dbname ()); -@@ -498,13 +508,13 @@ static void close_files (void) - gr_dbname (), info_group.action)); - del_cleanup (cleanup_report_mod_group); - -- cleanup_unlock_group (NULL); -+ cleanup_unlock_group (&process_selinux); - del_cleanup (cleanup_unlock_group); - - #ifdef SHADOWGRP - if ( is_shadow_grp - && (pflg || nflg || user_list)) { -- if (sgr_close (true) == 0) { -+ if (sgr_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, sgr_dbname ()); -@@ -528,13 +538,13 @@ static void close_files (void) - sgr_dbname (), info_gshadow.action)); - del_cleanup (cleanup_report_mod_gshadow); - -- cleanup_unlock_gshadow (NULL); -+ cleanup_unlock_gshadow (&process_selinux); - del_cleanup (cleanup_unlock_gshadow); - } - #endif /* SHADOWGRP */ - - if (gflg) { -- if (pw_close (true) == 0) { -+ if (pw_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, pw_dbname ()); -@@ -551,7 +561,7 @@ static void close_files (void) - pw_dbname (), info_passwd.action)); - del_cleanup (cleanup_report_mod_passwd); - -- cleanup_unlock_passwd (NULL); -+ cleanup_unlock_passwd (&process_selinux); - del_cleanup (cleanup_unlock_passwd); - } - -@@ -657,15 +667,19 @@ static void prepare_failure_reports (voi - * - * lock_files() locks the group, gshadow, and passwd databases. - */ --static void lock_files (void) -+static void lock_files (struct option_flags *flags) - { -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot && !flags->prefix; -+ - if (gr_lock () == 0) { - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, gr_dbname ()); - exit (E_GRP_UPDATE); - } -- add_cleanup (cleanup_unlock_group, NULL); -+ add_cleanup (cleanup_unlock_group, &process_selinux); - - #ifdef SHADOWGRP - if ( is_shadow_grp -@@ -676,7 +690,7 @@ static void lock_files (void) - Prog, sgr_dbname ()); - exit (E_GRP_UPDATE); - } -- add_cleanup (cleanup_unlock_gshadow, NULL); -+ add_cleanup (cleanup_unlock_gshadow, &process_selinux); - } - #endif - -@@ -687,7 +701,7 @@ static void lock_files (void) - Prog, pw_dbname ()); - exit (E_GRP_UPDATE); - } -- add_cleanup (cleanup_unlock_passwd, NULL); -+ add_cleanup (cleanup_unlock_passwd, &process_selinux); - } - } - -@@ -771,6 +785,7 @@ int main (int argc, char **argv) - int retval; - #endif /* USE_PAM */ - #endif /* ACCT_TOOLS_SETUID */ -+ struct option_flags flags; - - log_set_progname(Prog); - log_set_logfd(stderr); -@@ -794,7 +809,7 @@ int main (int argc, char **argv) - exit (E_CLEANUP_SERVICE); - } - -- process_flags (argc, argv); -+ process_flags (argc, argv, &flags); - - #ifdef ACCT_TOOLS_SETUID - #ifdef USE_PAM -@@ -859,7 +874,7 @@ int main (int argc, char **argv) - check_new_name (); - } - -- lock_files (); -+ lock_files (&flags); - - /* - * Now if the group is not changed, it's our fault. -@@ -875,7 +890,7 @@ int main (int argc, char **argv) - - grp_update (); - -- close_files (); -+ close_files (&flags); - - nscd_flush_cache ("group"); - sssd_flush_cache (SSSD_DB_GROUP); -diff -up shadow-4.18.0/src/grpck.c.test-chroot3 shadow-4.18.0/src/grpck.c ---- shadow-4.18.0/src/grpck.c.test-chroot3 2025-07-04 11:15:02.302354224 +0200 -+++ shadow-4.18.0/src/grpck.c 2025-07-04 11:15:02.313643179 +0200 -@@ -44,6 +44,13 @@ - #define E_CANT_UPDATE 5 - - /* -+ * Structures -+ */ -+struct option_flags { -+ bool chroot; -+}; -+ -+/* - * Global variables - */ - static const char Prog[] = "grpck"; -@@ -64,19 +71,20 @@ static bool sort_mode = false; - static bool silence_warnings = false; - - /* local function prototypes */ --static void fail_exit (int status); -+static void fail_exit (int status, bool process_selinux); - NORETURN static void usage (int status); - static void delete_member (char **, const char *); --static void process_flags (int argc, char **argv); --static void open_files (void); --static void close_files (bool changed); -+static void process_flags (int argc, char **argv, struct option_flags *flags); -+static void open_files (bool process_selinux); -+static void close_files (bool changed, struct option_flags *flags); - static int check_members (const char *groupname, - char **members, - const char *fmt_info, - const char *fmt_prompt, - const char *fmt_syslog, - bool *errors); --static void check_grp_file (bool *errors, bool *changed); -+static void check_grp_file (bool *errors, bool *changed, -+ struct option_flags *flags); - #ifdef SHADOWGRP - static void compare_members_lists (const char *groupname, - char **members, -@@ -89,10 +97,10 @@ static void check_sgr_file (bool *errors - /* - * fail_exit - exit with an error code after unlocking files - */ --static void fail_exit (int status) -+static void fail_exit (int status, bool process_selinux) - { - if (gr_locked) { -- if (gr_unlock (true) == 0) { -+ if (gr_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); - /* continue */ -@@ -101,7 +109,7 @@ static void fail_exit (int status) - - #ifdef SHADOWGRP - if (sgr_locked) { -- if (sgr_unlock (true) == 0) { -+ if (sgr_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - /* continue */ -@@ -172,7 +180,7 @@ static void delete_member (char **list, - * - * It will not return if an error is encountered. - */ --static void process_flags (int argc, char **argv) -+static void process_flags (int argc, char **argv, struct option_flags *flags) - { - int c; - static struct option long_options[] = { -@@ -201,6 +209,7 @@ static void process_flags (int argc, cha - read_only = true; - break; - case 'R': /* no-op, handled in process_root_flag () */ -+ flags->chroot = true; - break; - case 's': - sort_mode = true; -@@ -257,7 +266,7 @@ static void process_flags (int argc, cha - * In read-only mode, the databases are not locked and are opened - * only for reading. - */ --static void open_files (void) -+static void open_files (bool process_selinux) - { - /* - * Lock the files if we aren't in "read-only" mode -@@ -267,7 +276,7 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, grp_file); -- fail_exit (E_CANT_LOCK); -+ fail_exit (E_CANT_LOCK, process_selinux); - } - gr_locked = true; - #ifdef SHADOWGRP -@@ -276,7 +285,7 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, sgr_file); -- fail_exit (E_CANT_LOCK); -+ fail_exit (E_CANT_LOCK, process_selinux); - } - sgr_locked = true; - } -@@ -293,7 +302,7 @@ static void open_files (void) - if (use_system_grp_file) { - SYSLOG ((LOG_WARN, "cannot open %s", grp_file)); - } -- fail_exit (E_CANT_OPEN); -+ fail_exit (E_CANT_OPEN, process_selinux); - } - #ifdef SHADOWGRP - if (is_shadow && (sgr_open (read_only ? O_RDONLY : O_CREAT | O_RDWR) == 0)) { -@@ -302,7 +311,7 @@ static void open_files (void) - if (use_system_sgr_file) { - SYSLOG ((LOG_WARN, "cannot open %s", sgr_file)); - } -- fail_exit (E_CANT_OPEN); -+ fail_exit (E_CANT_OPEN, process_selinux); - } - #endif - } -@@ -314,23 +323,27 @@ static void open_files (void) - * changes are committed in the databases. The databases are - * unlocked anyway. - */ --static void close_files (bool changed) -+static void close_files (bool changed, struct option_flags *flags) - { -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot; -+ - /* - * All done. If there were no change we can just abandon any - * changes to the files. - */ - if (changed) { -- if (gr_close (true) == 0) { -+ if (gr_close (process_selinux) == 0) { - fprintf (stderr, _("%s: failure while writing changes to %s\n"), - Prog, grp_file); -- fail_exit (E_CANT_UPDATE); -+ fail_exit (E_CANT_UPDATE, process_selinux); - } - #ifdef SHADOWGRP -- if (is_shadow && (sgr_close (true) == 0)) { -+ if (is_shadow && (sgr_close (process_selinux) == 0)) { - fprintf (stderr, _("%s: failure while writing changes to %s\n"), - Prog, sgr_file); -- fail_exit (E_CANT_UPDATE); -+ fail_exit (E_CANT_UPDATE, process_selinux); - } - #endif - } -@@ -340,7 +353,7 @@ static void close_files (bool changed) - */ - #ifdef SHADOWGRP - if (sgr_locked) { -- if (sgr_unlock (true) == 0) { -+ if (sgr_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - /* continue */ -@@ -349,7 +362,7 @@ static void close_files (bool changed) - } - #endif - if (gr_locked) { -- if (gr_unlock (true) == 0) { -+ if (gr_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); - /* continue */ -@@ -455,13 +468,16 @@ static void compare_members_lists (const - /* - * check_grp_file - check the content of the group file - */ --static void check_grp_file (bool *errors, bool *changed) -+static void check_grp_file (bool *errors, bool *changed, struct option_flags *flags) - { - struct commonio_entry *gre, *tgre; - struct group *grp; - #ifdef SHADOWGRP - const struct sgrp *sgr; - #endif -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot; - - /* - * Loop through the entire group file. -@@ -627,7 +643,7 @@ static void check_grp_file (bool *errors - fprintf (stderr, - _("%s: failed to prepare the new %s entry '%s'\n"), - Prog, sgr_dbname (), sg.sg_namp); -- fail_exit (E_CANT_UPDATE); -+ fail_exit (E_CANT_UPDATE, process_selinux); - } - /* remove password from /etc/group */ - gr = *grp; -@@ -636,7 +652,7 @@ static void check_grp_file (bool *errors - fprintf (stderr, - _("%s: failed to prepare the new %s entry '%s'\n"), - Prog, gr_dbname (), gr.gr_name); -- fail_exit (E_CANT_UPDATE); -+ fail_exit (E_CANT_UPDATE, process_selinux); - } - } - } else { -@@ -819,6 +835,8 @@ int main (int argc, char **argv) - { - bool errors = false; - bool changed = false; -+ struct option_flags flags; -+ bool process_selinux; - - log_set_progname(Prog); - log_set_logfd(stderr); -@@ -832,9 +850,10 @@ int main (int argc, char **argv) - OPENLOG (Prog); - - /* Parse the command line arguments */ -- process_flags (argc, argv); -+ process_flags (argc, argv, &flags); -+ process_selinux = !flags.chroot; - -- open_files (); -+ open_files (process_selinux); - - if (sort_mode) { - gr_sort (); -@@ -845,7 +864,7 @@ int main (int argc, char **argv) - changed = true; - #endif - } else { -- check_grp_file (&errors, &changed); -+ check_grp_file (&errors, &changed, &flags); - #ifdef SHADOWGRP - if (is_shadow) { - check_sgr_file (&errors, &changed); -@@ -854,7 +873,7 @@ int main (int argc, char **argv) - } - - /* Commit the change in the database if needed */ -- close_files (changed); -+ close_files (changed, &flags); - - if (!read_only) { - nscd_flush_cache ("group"); - -diff -up shadow-4.18.0/src/chage.c.test-chroot4 shadow-4.18.0/src/chage.c ---- shadow-4.18.0/src/chage.c.test-chroot4 2025-07-04 11:17:37.593707379 +0200 -+++ shadow-4.18.0/src/chage.c 2025-07-04 11:17:37.613081862 +0200 -@@ -42,6 +42,10 @@ - #include "tcbfuncs.h" - #endif - -+struct option_flags { -+ bool chroot; -+ bool prefix; -+}; - - /* - * Global variables -@@ -79,29 +83,29 @@ NORETURN static void usage (int status); - static int new_fields (void); - static void print_day_as_date (long day); - static void list_fields (void); --static void process_flags (int argc, char **argv); -+static void process_flags (int argc, char **argv, struct option_flags *flags); - static void check_flags (int argc, int opt_index); --static void check_perms (void); --static void open_files (bool readonly); --static void close_files (void); --NORETURN static void fail_exit (int code); -+static void check_perms (struct option_flags *flags); -+static void open_files (bool readonly, struct option_flags *flags); -+static void close_files (struct option_flags *flags); -+NORETURN static void fail_exit (int code, bool process_selinux); - - /* - * fail_exit - do some cleanup and exit with the given error code - */ - NORETURN - static void --fail_exit (int code) -+fail_exit (int code, bool process_selinux) - { - if (spw_locked) { -- if (spw_unlock (true) == 0) { -+ if (spw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - /* continue */ - } - } - if (pw_locked) { -- if (pw_unlock (true) == 0) { -+ if (pw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -@@ -338,7 +342,7 @@ static void list_fields (void) - * - * It will not return if an error is encountered. - */ --static void process_flags (int argc, char **argv) -+static void process_flags (int argc, char **argv, struct option_flags *flags) - { - /* - * Parse the command line options. -@@ -419,8 +423,10 @@ static void process_flags (int argc, cha - } - break; - case 'R': /* no-op, handled in process_root_flag () */ -+ flags->chroot = true; - break; - case 'P': /* no-op, handled in process_prefix_flag () */ -+ flags->prefix = true; - break; - case 'W': - Wflg = true; -@@ -472,8 +478,12 @@ static void check_flags (int argc, int o - * - * It will not return if the user is not allowed. - */ --static void check_perms (void) -+static void check_perms (struct option_flags *flags) - { -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot && !flags->prefix; -+ - /* - * An unprivileged user can ask for their own aging information, but - * only root can change it, or list another user's aging -@@ -482,7 +492,7 @@ static void check_perms (void) - - if (!amroot && !lflg) { - fprintf (stderr, _("%s: Permission denied.\n"), Prog); -- fail_exit (E_NOPERM); -+ fail_exit (E_NOPERM, process_selinux); - } - } - -@@ -492,8 +502,12 @@ static void check_perms (void) - * In read-only mode, the databases are not locked and are opened - * only for reading. - */ --static void open_files (bool readonly) -+static void open_files (bool readonly, struct option_flags *flags) - { -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot && !flags->prefix; -+ - /* - * Lock and open the password file. This loads all of the password - * file entries into memory. Then we get a pointer to the password -@@ -504,14 +518,14 @@ static void open_files (bool readonly) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, pw_dbname ()); -- fail_exit (E_NOPERM); -+ fail_exit (E_NOPERM, process_selinux); - } - pw_locked = true; - } - if (pw_open (readonly ? O_RDONLY: O_CREAT | O_RDWR) == 0) { - fprintf (stderr, _("%s: cannot open %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_WARN, "cannot open %s", pw_dbname ())); -- fail_exit (E_NOPERM); -+ fail_exit (E_NOPERM, process_selinux); - } - - /* -@@ -525,7 +539,7 @@ static void open_files (bool readonly) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, spw_dbname ()); -- fail_exit (E_NOPERM); -+ fail_exit (E_NOPERM, process_selinux); - } - spw_locked = true; - } -@@ -533,42 +547,46 @@ static void open_files (bool readonly) - fprintf (stderr, - _("%s: cannot open %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_WARN, "cannot open %s", spw_dbname ())); -- fail_exit (E_NOPERM); -+ fail_exit (E_NOPERM, process_selinux); - } - } - - /* - * close_files - close and unlock the password/shadow databases - */ --static void close_files (void) -+static void close_files (struct option_flags *flags) - { -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot && !flags->prefix; -+ - /* - * Now close the shadow password file, which will cause all of the - * entries to be re-written. - */ -- if (spw_close (true) == 0) { -+ if (spw_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); -- fail_exit (E_NOPERM); -+ fail_exit (E_NOPERM, process_selinux); - } - - /* - * Close the password file. If any entries were modified, the file - * will be re-written. - */ -- if (pw_close (true) == 0) { -+ if (pw_close (process_selinux) == 0) { - fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); -- fail_exit (E_NOPERM); -+ fail_exit (E_NOPERM, process_selinux); - } -- if (spw_unlock (true) == 0) { -+ if (spw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - /* continue */ - } - spw_locked = false; -- if (pw_unlock (true) == 0) { -+ if (pw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -@@ -582,7 +600,8 @@ static void close_files (void) - * It will not return in case of error - */ - static void update_age (/*@null@*/const struct spwd *sp, -- /*@notnull@*/const struct passwd *pw) -+ /*@notnull@*/const struct passwd *pw, -+ bool process_selinux) - { - struct spwd spwent; - -@@ -603,7 +622,7 @@ static void update_age (/*@null@*/const - if (pw_update (&pwent) == 0) { - fprintf (stderr, - _("%s: failed to prepare the new %s entry '%s'\n"), Prog, pw_dbname (), pwent.pw_name); -- fail_exit (E_NOPERM); -+ fail_exit (E_NOPERM, process_selinux); - } - } else { - spwent.sp_namp = xstrdup (sp->sp_namp); -@@ -626,7 +645,7 @@ static void update_age (/*@null@*/const - if (spw_update (&spwent) == 0) { - fprintf (stderr, - _("%s: failed to prepare the new %s entry '%s'\n"), Prog, spw_dbname (), spwent.sp_namp); -- fail_exit (E_NOPERM); -+ fail_exit (E_NOPERM, process_selinux); - } - - } -@@ -712,6 +731,8 @@ int main (int argc, char **argv) - uid_t ruid; - gid_t rgid; - const struct passwd *pw; -+ struct option_flags flags; -+ bool process_selinux; - - sanitize_env (); - check_fds (); -@@ -740,9 +761,10 @@ int main (int argc, char **argv) - } - #endif - -- process_flags (argc, argv); -+ process_flags (argc, argv, &flags); -+ process_selinux = !flags.chroot && !flags.prefix; - -- check_perms (); -+ check_perms (&flags); - - if (!spw_file_present ()) { - fprintf (stderr, -@@ -753,13 +775,13 @@ int main (int argc, char **argv) - exit (E_SHADOW_NOTFOUND); - } - -- open_files (lflg); -+ open_files (lflg, &flags); - /* Drop privileges */ - if (lflg && ( (setregid (rgid, rgid) != 0) - || (setreuid (ruid, ruid) != 0))) { - fprintf (stderr, _("%s: failed to drop privileges (%s)\n"), - Prog, strerror (errno)); -- fail_exit (E_NOPERM); -+ fail_exit (E_NOPERM, process_selinux); - } - - pw = pw_locate (argv[optind]); -@@ -767,13 +789,13 @@ int main (int argc, char **argv) - fprintf (stderr, _("%s: user '%s' does not exist in %s\n"), - Prog, argv[optind], pw_dbname ()); - closelog (); -- fail_exit (E_NOPERM); -+ fail_exit (E_NOPERM, process_selinux); - } - - STRTCPY(user_name, pw->pw_name); - #ifdef WITH_TCB - if (shadowtcb_set_user (pw->pw_name) == SHADOWTCB_FAILURE) { -- fail_exit (E_NOPERM); -+ fail_exit (E_NOPERM, process_selinux); - } - #endif - user_uid = pw->pw_uid; -@@ -788,11 +810,11 @@ int main (int argc, char **argv) - if (lflg) { - if (!amroot && (ruid != user_uid)) { - fprintf (stderr, _("%s: Permission denied.\n"), Prog); -- fail_exit (E_NOPERM); -+ fail_exit (E_NOPERM, process_selinux); - } - /* Displaying fields is not of interest to audit */ - list_fields (); -- fail_exit (E_SUCCESS); -+ fail_exit (E_SUCCESS, process_selinux); - } - - /* -@@ -805,7 +827,7 @@ int main (int argc, char **argv) - if (new_fields () == 0) { - fprintf (stderr, _("%s: error changing fields\n"), - Prog); -- fail_exit (E_NOPERM); -+ fail_exit (E_NOPERM, process_selinux); - } - #ifdef WITH_AUDIT - else { -@@ -847,9 +869,9 @@ int main (int argc, char **argv) - #endif - } - -- update_age (sp, pw); -+ update_age (sp, pw, process_selinux); - -- close_files (); -+ close_files (&flags); - - SYSLOG ((LOG_INFO, "changed password expiry for %s", user_name)); - -diff -up shadow-4.18.0/src/chfn.c.test-chroot4 shadow-4.18.0/src/chfn.c ---- shadow-4.18.0/src/chfn.c.test-chroot4 2025-07-04 11:17:37.590501245 +0200 -+++ shadow-4.18.0/src/chfn.c 2025-07-04 11:17:37.613576062 +0200 -@@ -39,6 +39,9 @@ - #include "string/strdup/xstrdup.h" - #include "string/strtok/stpsep.h" - -+struct option_flags { -+ bool chroot; -+}; - - /* - * Global variables. -@@ -63,23 +66,23 @@ static bool pw_locked = false; - */ - - /* local function prototypes */ --NORETURN static void fail_exit (int code); -+NORETURN static void fail_exit (int code, bool process_selinux); - NORETURN static void usage (int status); - static bool may_change_field (int); - static void new_fields (void); - static char *copy_field (char *, char *, char *); --static void process_flags (int argc, char **argv); -+static void process_flags (int argc, char **argv, struct option_flags *flags); - static void check_perms (const struct passwd *pw); --static void update_gecos (const char *user, char *gecos); -+static void update_gecos (const char *user, char *gecos, struct option_flags *flags); - static void get_old_fields (const char *gecos); - - /* - * fail_exit - exit with an error and do some cleanup - */ --static void fail_exit (int code) -+static void fail_exit (int code, bool process_selinux) - { - if (pw_locked) { -- if (pw_unlock (true) == 0) { -+ if (pw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -@@ -250,7 +253,7 @@ static char *copy_field (char *in, char - * - * It will not return if an error is encountered. - */ --static void process_flags (int argc, char **argv) -+static void process_flags (int argc, char **argv, struct option_flags *flags) - { - int c; /* flag currently being processed */ - static struct option long_options[] = { -@@ -316,6 +319,7 @@ static void process_flags (int argc, cha - STRTCPY(roomno, optarg); - break; - case 'R': /* no-op, handled in process_root_flag () */ -+ flags->chroot = true; - break; - case 'u': - usage (E_SUCCESS); -@@ -423,10 +427,13 @@ static void check_perms (const struct pa - * - * Commit the user's entry after changing her gecos field. - */ --static void update_gecos (const char *user, char *gecos) -+static void update_gecos (const char *user, char *gecos, struct option_flags *flags) - { - const struct passwd *pw; /* The user's password file entry */ - struct passwd pwent; /* modified password file entry */ -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot; - - /* - * Before going any further, raise the ulimit to prevent colliding -@@ -437,7 +444,7 @@ static void update_gecos (const char *us - if (setuid (0) != 0) { - fputs (_("Cannot change ID to root.\n"), stderr); - SYSLOG ((LOG_ERR, "can't setuid(0)")); -- fail_exit (E_NOPERM); -+ fail_exit (E_NOPERM, process_selinux); - } - pwd_init (); - -@@ -449,13 +456,13 @@ static void update_gecos (const char *us - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, pw_dbname ()); -- fail_exit (E_NOPERM); -+ fail_exit (E_NOPERM, process_selinux); - } - pw_locked = true; - if (pw_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, - _("%s: cannot open %s\n"), Prog, pw_dbname ()); -- fail_exit (E_NOPERM); -+ fail_exit (E_NOPERM, process_selinux); - } - - /* -@@ -469,7 +476,7 @@ static void update_gecos (const char *us - fprintf (stderr, - _("%s: user '%s' does not exist in %s\n"), - Prog, user, pw_dbname ()); -- fail_exit (E_NOPERM); -+ fail_exit (E_NOPERM, process_selinux); - } - - /* -@@ -487,18 +494,18 @@ static void update_gecos (const char *us - fprintf (stderr, - _("%s: failed to prepare the new %s entry '%s'\n"), - Prog, pw_dbname (), pwent.pw_name); -- fail_exit (E_NOPERM); -+ fail_exit (E_NOPERM, process_selinux); - } - - /* - * Changes have all been made, so commit them and unlock the file. - */ -- if (pw_close (true) == 0) { -+ if (pw_close (process_selinux) == 0) { - fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); -- fail_exit (E_NOPERM); -+ fail_exit (E_NOPERM, process_selinux); - } -- if (pw_unlock (true) == 0) { -+ if (pw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -@@ -562,7 +569,7 @@ static void get_old_fields (const char * - * - * It will not return if a field is not valid. - */ --static void check_fields (void) -+static void check_fields (bool process_selinux) - { - int err; - err = valid_field (fullnm, ":,=\n"); -@@ -570,7 +577,7 @@ static void check_fields (void) - fprintf (stderr, _("%s: name with non-ASCII characters: '%s'\n"), Prog, fullnm); - } else if (err < 0) { - fprintf (stderr, _("%s: invalid name: '%s'\n"), Prog, fullnm); -- fail_exit (E_NOPERM); -+ fail_exit (E_NOPERM, process_selinux); - } - err = valid_field (roomno, ":,=\n"); - if (err > 0) { -@@ -578,17 +585,17 @@ static void check_fields (void) - } else if (err < 0) { - fprintf (stderr, _("%s: invalid room number: '%s'\n"), - Prog, roomno); -- fail_exit (E_NOPERM); -+ fail_exit (E_NOPERM, process_selinux); - } - if (valid_field (workph, ":,=\n") != 0) { - fprintf (stderr, _("%s: invalid work phone: '%s'\n"), - Prog, workph); -- fail_exit (E_NOPERM); -+ fail_exit (E_NOPERM, process_selinux); - } - if (valid_field (homeph, ":,=\n") != 0) { - fprintf (stderr, _("%s: invalid home phone: '%s'\n"), - Prog, homeph); -- fail_exit (E_NOPERM); -+ fail_exit (E_NOPERM, process_selinux); - } - err = valid_field (slop, ":\n"); - if (err > 0) { -@@ -597,7 +604,7 @@ static void check_fields (void) - fprintf (stderr, - _("%s: '%s' contains illegal characters\n"), - Prog, slop); -- fail_exit (E_NOPERM); -+ fail_exit (E_NOPERM, process_selinux); - } - } - -@@ -622,6 +629,8 @@ int main (int argc, char **argv) - char new_gecos[BUFSIZ]; - char *user; - const struct passwd *pw; -+ struct option_flags flags; -+ bool process_selinux; - - sanitize_env (); - check_fds (); -@@ -644,7 +653,7 @@ int main (int argc, char **argv) - OPENLOG (Prog); - - /* parse the command line options */ -- process_flags (argc, argv); -+ process_flags (argc, argv, &flags); - - /* - * Get the name of the user to check. It is either the command line -@@ -653,14 +662,14 @@ int main (int argc, char **argv) - if (optind < argc) { - if (!is_valid_user_name (argv[optind])) { - fprintf (stderr, _("%s: Provided user name is not a valid name\n"), Prog); -- fail_exit (E_NOPERM); -+ fail_exit (E_NOPERM, process_selinux); - } - user = argv[optind]; - pw = xgetpwnam (user); - if (NULL == pw) { - fprintf (stderr, _("%s: user '%s' does not exist\n"), Prog, - user); -- fail_exit (E_NOPERM); -+ fail_exit (E_NOPERM, process_selinux); - } - } else { - pw = get_my_pwent (); -@@ -670,7 +679,7 @@ int main (int argc, char **argv) - Prog); - SYSLOG ((LOG_WARN, "Cannot determine the user name of the caller (UID %lu)", - (unsigned long) getuid ())); -- fail_exit (E_NOPERM); -+ fail_exit (E_NOPERM, process_selinux); - } - user = xstrdup (pw->pw_name); - } -@@ -695,7 +704,7 @@ int main (int argc, char **argv) - /* - * Check all of the fields for valid information - */ -- check_fields (); -+ check_fields (process_selinux); - - /* - * Build the new GECOS field by plastering all the pieces together, -@@ -704,14 +713,14 @@ int main (int argc, char **argv) - if ((strlen (fullnm) + strlen (roomno) + strlen (workph) + - strlen (homeph) + strlen (slop)) > (unsigned int) 80) { - fprintf (stderr, _("%s: fields too long\n"), Prog); -- fail_exit (E_NOPERM); -+ fail_exit (E_NOPERM, process_selinux); - } - SNPRINTF(new_gecos, "%s,%s,%s,%s%s%s", - fullnm, roomno, workph, homeph, - (!streq(slop, "")) ? "," : "", slop); - - /* Rewrite the user's gecos in the passwd file */ -- update_gecos (user, new_gecos); -+ update_gecos (user, new_gecos, &flags); - - SYSLOG ((LOG_INFO, "changed user '%s' information", user)); - -diff -up shadow-4.18.0/src/chpasswd.c.test-chroot4 shadow-4.18.0/src/chpasswd.c ---- shadow-4.18.0/src/chpasswd.c.test-chroot4 2025-07-04 11:17:37.593768325 +0200 -+++ shadow-4.18.0/src/chpasswd.c 2025-07-04 11:18:06.785652711 +0200 -@@ -38,6 +38,11 @@ - - #define IS_CRYPT_METHOD(str) ((crypt_method != NULL && streq(crypt_method, str)) ? true : false) - -+struct option_flags { -+ bool chroot; -+ bool prefix; -+}; -+ - /* - * Global variables - */ -@@ -67,21 +72,21 @@ static bool pw_locked = false; - static bool spw_locked = false; - - /* local function prototypes */ --NORETURN static void fail_exit (int code); -+NORETURN static void fail_exit (int code, bool process_selinux); - NORETURN static void usage (int status); --static void process_flags (int argc, char **argv); -+static void process_flags (int argc, char **argv, struct option_flags *flags); - static void check_flags (void); - static void check_perms (void); --static void open_files (void); --static void close_files (void); -+static void open_files (struct option_flags *flags); -+static void close_files (struct option_flags *flags); - - /* - * fail_exit - exit with a failure code after unlocking the files - */ --static void fail_exit (int code) -+static void fail_exit (int code, bool process_selinux) - { - if (pw_locked) { -- if (pw_unlock (true) == 0) { -+ if (pw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -@@ -89,7 +94,7 @@ static void fail_exit (int code) - } - - if (spw_locked) { -- if (spw_unlock (true) == 0) { -+ if (spw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - /* continue */ -@@ -147,7 +152,7 @@ usage (int status) - * - * It will not return if an error is encountered. - */ --static void process_flags (int argc, char **argv) -+static void process_flags (int argc, char **argv, struct option_flags *flags) - { - int c; - #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) -@@ -187,8 +192,10 @@ static void process_flags (int argc, cha - md5flg = true; - break; - case 'R': /* no-op, handled in process_root_flag () */ -+ flags->chroot = true; - break; - case 'P': /* no-op, handled in process_prefix_flag () */ -+ flags->prefix = true; - break; - #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) - case 's': -@@ -335,8 +342,12 @@ static void check_perms (void) - /* - * open_files - lock and open the password databases - */ --static void open_files (void) -+static void open_files (struct option_flags *flags) - { -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot && !flags->prefix; -+ - /* - * Lock the password file and open it for reading and writing. This - * will bring all of the entries into memory where they may be updated. -@@ -345,13 +356,13 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, pw_dbname ()); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - pw_locked = true; - if (pw_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, - _("%s: cannot open %s\n"), Prog, pw_dbname ()); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - - /* Do the same for the shadowed database, if it exist */ -@@ -360,14 +371,14 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, spw_dbname ()); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - spw_locked = true; - if (spw_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, - _("%s: cannot open %s\n"), - Prog, spw_dbname ()); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - } - } -@@ -375,17 +386,21 @@ static void open_files (void) - /* - * close_files - close and unlock the password databases - */ --static void close_files (void) -+static void close_files (struct option_flags *flags) - { -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot && !flags->prefix; -+ - if (is_shadow_pwd) { -- if (spw_close (true) == 0) { -+ if (spw_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } -- if (spw_unlock (true) == 0) { -+ if (spw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - /* continue */ -@@ -393,14 +408,14 @@ static void close_files (void) - spw_locked = false; - } - -- if (pw_close (true) == 0) { -+ if (pw_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } -- if (pw_unlock (true) == 0) { -+ if (pw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -@@ -456,6 +471,8 @@ int main (int argc, char **argv) - - bool errors = false; - intmax_t line = 0; -+ struct option_flags flags; -+ bool process_selinux; - - log_set_progname(Prog); - log_set_logfd(stderr); -@@ -470,7 +487,8 @@ int main (int argc, char **argv) - } - #endif /* WITH_SELINUX */ - -- process_flags (argc, argv); -+ process_flags (argc, argv, &flags); -+ process_selinux = !flags.chroot && !flags.prefix; - - salt = get_salt(); - process_root_flag ("-R", argc, argv); -@@ -496,7 +514,7 @@ int main (int argc, char **argv) - { - is_shadow_pwd = spw_file_present (); - -- open_files (); -+ open_files (&flags); - } - - /* -@@ -573,7 +591,7 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: failed to crypt password with salt '%s': %s\n"), - Prog, salt, strerror (errno)); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - } - -@@ -690,7 +708,7 @@ int main (int argc, char **argv) - _("%s: error detected, changes ignored\n"), - Prog); - } -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - - #ifdef ACCT_TOOLS_SETUID -@@ -700,7 +718,7 @@ int main (int argc, char **argv) - #endif /* ACCT_TOOLS_SETUID */ - { - /* Save the changes */ -- close_files (); -+ close_files (&flags); - } - - nscd_flush_cache ("passwd"); -diff -up shadow-4.18.0/src/grpconv.c.test-chroot4 shadow-4.18.0/src/grpconv.c ---- shadow-4.18.0/src/grpconv.c.test-chroot4 2025-07-04 11:17:37.598073521 +0200 -+++ shadow-4.18.0/src/grpconv.c 2025-07-04 11:17:37.612354766 +0200 -@@ -39,6 +39,12 @@ - #include "shadowlog.h" - #include "sssd.h" - -+/* -+ * Structures -+ */ -+struct option_flags { -+ bool chroot; -+}; - - /* - * Global variables -@@ -49,14 +55,14 @@ static bool gr_locked = false; - static bool sgr_locked = false; - - /* local function prototypes */ --static void fail_exit (int status); -+static void fail_exit (int status, bool process_selinux); - static void usage (int status); --static void process_flags (int argc, char **argv); -+static void process_flags (int argc, char **argv, struct option_flags *flags); - --static void fail_exit (int status) -+static void fail_exit (int status, bool process_selinux) - { - if (gr_locked) { -- if (gr_unlock (true) == 0) { -+ if (gr_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); - /* continue */ -@@ -64,7 +70,7 @@ static void fail_exit (int status) - } - - if (sgr_locked) { -- if (sgr_unlock (true) == 0) { -+ if (sgr_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - /* continue */ -@@ -93,7 +99,7 @@ static void usage (int status) - * - * It will not return if an error is encountered. - */ --static void process_flags (int argc, char **argv) -+static void process_flags (int argc, char **argv, struct option_flags *flags) - { - /* - * Parse the command line options. -@@ -112,6 +118,7 @@ static void process_flags (int argc, cha - usage (E_SUCCESS); - /*@notreached@*/break; - case 'R': /* no-op, handled in process_root_flag () */ -+ flags->chroot = true; - break; - default: - usage (E_USAGE); -@@ -129,6 +136,8 @@ int main (int argc, char **argv) - struct group grent; - const struct sgrp *sg; - struct sgrp sgent; -+ struct option_flags flags; -+ bool process_selinux; - - log_set_progname(Prog); - log_set_logfd(stderr); -@@ -141,30 +150,31 @@ int main (int argc, char **argv) - - OPENLOG (Prog); - -- process_flags (argc, argv); -+ process_flags (argc, argv, &flags); -+ process_selinux = !flags.chroot; - - if (gr_lock () == 0) { - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, gr_dbname ()); -- fail_exit (5); -+ fail_exit (5, process_selinux); - } - gr_locked = true; - if (gr_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ()); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - - if (sgr_lock () == 0) { - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, sgr_dbname ()); -- fail_exit (5); -+ fail_exit (5, process_selinux); - } - sgr_locked = true; - if (sgr_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, _("%s: cannot open %s\n"), Prog, sgr_dbname ()); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - - /* -@@ -183,7 +193,7 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: cannot remove entry '%s' from %s\n"), - Prog, sg->sg_namp, sgr_dbname ()); -- fail_exit (3); -+ fail_exit (3, process_selinux); - } - (void) sgr_rewind (); - } -@@ -221,7 +231,7 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: failed to prepare the new %s entry '%s'\n"), - Prog, sgr_dbname (), sgent.sg_namp); -- fail_exit (3); -+ fail_exit (3, process_selinux); - } - /* remove password from /etc/group */ - grent = *gr; -@@ -230,30 +240,30 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: failed to prepare the new %s entry '%s'\n"), - Prog, gr_dbname (), grent.gr_name); -- fail_exit (3); -+ fail_exit (3, process_selinux); - } - } - -- if (sgr_close (true) == 0) { -+ if (sgr_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ())); -- fail_exit (3); -+ fail_exit (3, process_selinux); - } -- if (gr_close (true) == 0) { -+ if (gr_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ())); -- fail_exit (3); -+ fail_exit (3, process_selinux); - } -- if (sgr_unlock (true) == 0) { -+ if (sgr_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - /* continue */ - } -- if (gr_unlock (true) == 0) { -+ if (gr_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); - /* continue */ -diff -up shadow-4.18.0/src/grpunconv.c.test-chroot4 shadow-4.18.0/src/grpunconv.c ---- shadow-4.18.0/src/grpunconv.c.test-chroot4 2025-07-04 11:17:37.598110132 +0200 -+++ shadow-4.18.0/src/grpunconv.c 2025-07-04 11:17:37.612706894 +0200 -@@ -38,6 +38,12 @@ - #include "sgroupio.h" - #include "shadowlog.h" - -+/* -+ * Structures -+ */ -+struct option_flags { -+ bool chroot; -+}; - - /* - * Global variables -@@ -48,14 +54,14 @@ static bool gr_locked = false; - static bool sgr_locked = false; - - /* local function prototypes */ --static void fail_exit (int status); -+static void fail_exit (int status, bool process_selinux); - static void usage (int status); --static void process_flags (int argc, char **argv); -+static void process_flags (int argc, char **argv, struct option_flags *flags); - --static void fail_exit (int status) -+static void fail_exit (int status, bool process_selinux) - { - if (gr_locked) { -- if (gr_unlock (true) == 0) { -+ if (gr_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); - /* continue */ -@@ -63,7 +69,7 @@ static void fail_exit (int status) - } - - if (sgr_locked) { -- if (sgr_unlock (true) == 0) { -+ if (sgr_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - /* continue */ -@@ -92,7 +98,7 @@ static void usage (int status) - * - * It will not return if an error is encountered. - */ --static void process_flags (int argc, char **argv) -+static void process_flags (int argc, char **argv, struct option_flags *flags) - { - /* - * Parse the command line options. -@@ -111,6 +117,7 @@ static void process_flags (int argc, cha - usage (E_SUCCESS); - /*@notreached@*/break; - case 'R': /* no-op, handled in process_root_flag () */ -+ flags->chroot = true; - break; - default: - usage (E_USAGE); -@@ -127,6 +134,8 @@ int main (int argc, char **argv) - const struct group *gr; - struct group grent; - const struct sgrp *sg; -+ struct option_flags flags; -+ bool process_selinux; - - log_set_progname(Prog); - log_set_logfd(stderr); -@@ -139,7 +148,8 @@ int main (int argc, char **argv) - - OPENLOG (Prog); - -- process_flags (argc, argv); -+ process_flags (argc, argv, &flags); -+ process_selinux = !flags.chroot; - - if (sgr_file_present () == 0) { - exit (0); /* no /etc/gshadow, nothing to do */ -@@ -149,26 +159,26 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, gr_dbname ()); -- fail_exit (5); -+ fail_exit (5, process_selinux); - } - gr_locked = true; - if (gr_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, - _("%s: cannot open %s\n"), Prog, gr_dbname ()); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - - if (sgr_lock () == 0) { - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, sgr_dbname ()); -- fail_exit (5); -+ fail_exit (5, process_selinux); - } - sgr_locked = true; - if (sgr_open (O_RDONLY) == 0) { - fprintf (stderr, - _("%s: cannot open %s\n"), Prog, sgr_dbname ()); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - - /* -@@ -186,19 +196,19 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: failed to prepare the new %s entry '%s'\n"), - Prog, gr_dbname (), grent.gr_name); -- fail_exit (3); -+ fail_exit (3, process_selinux); - } - } - } - -- (void) sgr_close (true); /* was only open O_RDONLY */ -+ (void) sgr_close (process_selinux); /* was only open O_RDONLY */ - -- if (gr_close (true) == 0) { -+ if (gr_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ())); -- fail_exit (3); -+ fail_exit (3, process_selinux); - } - - if (unlink (SGROUP_FILE) != 0) { -@@ -206,16 +216,16 @@ int main (int argc, char **argv) - _("%s: cannot delete %s\n"), - Prog, SGROUP_FILE); - SYSLOG ((LOG_ERR, "cannot delete %s", SGROUP_FILE)); -- fail_exit (3); -+ fail_exit (3, process_selinux); - } - -- if (gr_unlock (true) == 0) { -+ if (gr_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); - /* continue */ - } - -- if (sgr_unlock (true) == 0) { -+ if (sgr_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); - /* continue */ - -From e7634eac3da8b6a2a046b7e8ab6148d07618c7f5 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Thu, 3 Jul 2025 11:59:32 +0200 -Subject: [PATCH 01/12] src/chsh.c: chroot or prefix SELinux file context - -Do not process SELinux file context during file closure when chroot or -prefix options are selected. - -Signed-off-by: Iker Pedrosa ---- - src/chsh.c | 25 +++++++++++++++++-------- - 1 file changed, 17 insertions(+), 8 deletions(-) - -diff --git a/src/chsh.c b/src/chsh.c -index 4403d412..f460e329 100644 ---- a/src/chsh.c -+++ b/src/chsh.c -@@ -47,6 +47,9 @@ - #define ETCDIR "/etc" - #endif - -+struct option_flags { -+ bool chroot; -+}; - - /* - * Global variables -@@ -66,9 +69,10 @@ NORETURN static void usage (int status); - static void new_fields (void); - static bool shell_is_listed (const char *); - static bool is_restricted_shell (const char *); --static void process_flags (int argc, char **argv); -+static void process_flags (int argc, char **argv, struct option_flags *flags); - static void check_perms (const struct passwd *pw); --static void update_shell (const char *user, char *loginsh); -+static void update_shell (const char *user, char *loginsh, -+ struct option_flags *flags); - - /* - * fail_exit - do some cleanup and exit with the given error code -@@ -217,7 +221,7 @@ static bool shell_is_listed (const char *sh) - * - * It will not return if an error is encountered. - */ --static void process_flags (int argc, char **argv) -+static void process_flags (int argc, char **argv, struct option_flags *flags) - { - int c; - static struct option long_options[] = { -@@ -234,6 +238,7 @@ static void process_flags (int argc, char **argv) - usage (E_SUCCESS); - /*@notreached@*/break; - case 'R': /* no-op, handled in process_root_flag () */ -+ flags->chroot = true; - break; - case 's': - sflg = true; -@@ -359,10 +364,13 @@ static void check_perms (const struct passwd *pw) - * - * It will not return in case of error. - */ --static void update_shell (const char *user, char *newshell) -+static void update_shell (const char *user, char *newshell, struct option_flags *flags) - { - const struct passwd *pw; /* Password entry from /etc/passwd */ - struct passwd pwent; /* New password entry */ -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot; - - /* - * Before going any further, raise the ulimit to prevent -@@ -428,12 +436,12 @@ static void update_shell (const char *user, char *newshell) - /* - * Changes have all been made, so commit them and unlock the file. - */ -- if (pw_close (true) == 0) { -+ if (pw_close (process_selinux) == 0) { - fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); - fail_exit (1); - } -- if (pw_unlock (true) == 0) { -+ if (pw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -@@ -451,6 +459,7 @@ int main (int argc, char **argv) - { - char *user; /* User name */ - const struct passwd *pw; /* Password entry from /etc/passwd */ -+ struct option_flags flags; - - sanitize_env (); - check_fds (); -@@ -472,7 +481,7 @@ int main (int argc, char **argv) - OPENLOG (Prog); - - /* parse the command line options */ -- process_flags (argc, argv); -+ process_flags (argc, argv, &flags); - - /* - * Get the name of the user to check. It is either the command line -@@ -555,7 +564,7 @@ int main (int argc, char **argv) - } - } - -- update_shell (user, loginsh); -+ update_shell (user, loginsh, &flags); - - SYSLOG ((LOG_INFO, "changed user '%s' shell to '%s'", user, loginsh)); - --- -2.50.0 - - -From cbcf54b3e5c77a4992bca0ae4f32f0060d120884 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Thu, 3 Jul 2025 12:03:30 +0200 -Subject: [PATCH 02/12] src/chsh.c: SELinux file context for fail_exit() - -Do not process SELinux file context when running fail_exit() when chroot -or prefix options are selected. - -Signed-off-by: Iker Pedrosa ---- - src/chsh.c | 45 +++++++++++++++++++++++++-------------------- - 1 file changed, 25 insertions(+), 20 deletions(-) - -diff --git a/src/chsh.c b/src/chsh.c -index f460e329..77cd30e5 100644 ---- a/src/chsh.c -+++ b/src/chsh.c -@@ -64,13 +64,13 @@ static bool pw_locked = false; - /* external identifiers */ - - /* local function prototypes */ --NORETURN static void fail_exit (int code); -+NORETURN static void fail_exit (int code, bool process_selinux); - NORETURN static void usage (int status); - static void new_fields (void); - static bool shell_is_listed (const char *); - static bool is_restricted_shell (const char *); - static void process_flags (int argc, char **argv, struct option_flags *flags); --static void check_perms (const struct passwd *pw); -+static void check_perms (const struct passwd *pw, struct option_flags *flags); - static void update_shell (const char *user, char *loginsh, - struct option_flags *flags); - -@@ -79,10 +79,10 @@ static void update_shell (const char *user, char *loginsh, - */ - NORETURN - static void --fail_exit (int code) -+fail_exit (int code, bool process_selinux) - { - if (pw_locked) { -- if (pw_unlock (true) == 0) { -+ if (pw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -@@ -268,13 +268,16 @@ static void process_flags (int argc, char **argv, struct option_flags *flags) - * - * It will not return if the user is not allowed. - */ --static void check_perms (const struct passwd *pw) -+static void check_perms (const struct passwd *pw, struct option_flags *flags) - { - #ifdef USE_PAM - pam_handle_t *pamh = NULL; - int retval; - struct passwd *pampw; - #endif -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot; - - /* - * Non-privileged users are only allowed to change the shell if the -@@ -285,7 +288,7 @@ static void check_perms (const struct passwd *pw) - fprintf (stderr, - _("You may not change the shell for '%s'.\n"), - pw->pw_name); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - - /* -@@ -297,7 +300,7 @@ static void check_perms (const struct passwd *pw) - fprintf (stderr, - _("You may not change the shell for '%s'.\n"), - pw->pw_name); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - #ifdef WITH_SELINUX - /* -@@ -310,7 +313,7 @@ static void check_perms (const struct passwd *pw) - fprintf (stderr, - _("You may not change the shell for '%s'.\n"), - pw->pw_name); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - #endif - -@@ -381,7 +384,7 @@ static void update_shell (const char *user, char *newshell, struct option_flags - if (setuid (0) != 0) { - SYSLOG ((LOG_ERR, "can't setuid(0)")); - fputs (_("Cannot change ID to root.\n"), stderr); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - pwd_init (); - -@@ -392,13 +395,13 @@ static void update_shell (const char *user, char *newshell, struct option_flags - if (pw_lock () == 0) { - fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), - Prog, pw_dbname ()); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - pw_locked = true; - if (pw_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, _("%s: cannot open %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_WARN, "cannot open %s", pw_dbname ())); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - - /* -@@ -412,7 +415,7 @@ static void update_shell (const char *user, char *newshell, struct option_flags - fprintf (stderr, - _("%s: user '%s' does not exist in %s\n"), - Prog, user, pw_dbname ()); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - - /* -@@ -430,7 +433,7 @@ static void update_shell (const char *user, char *newshell, struct option_flags - fprintf (stderr, - _("%s: failed to prepare the new %s entry '%s'\n"), - Prog, pw_dbname (), pwent.pw_name); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - - /* -@@ -439,7 +442,7 @@ static void update_shell (const char *user, char *newshell, struct option_flags - if (pw_close (process_selinux) == 0) { - fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - if (pw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); -@@ -460,6 +463,7 @@ int main (int argc, char **argv) - char *user; /* User name */ - const struct passwd *pw; /* Password entry from /etc/passwd */ - struct option_flags flags; -+ bool process_selinux; - - sanitize_env (); - check_fds (); -@@ -482,6 +486,7 @@ int main (int argc, char **argv) - - /* parse the command line options */ - process_flags (argc, argv, &flags); -+ process_selinux = !flags.chroot; - - /* - * Get the name of the user to check. It is either the command line -@@ -490,14 +495,14 @@ int main (int argc, char **argv) - if (optind < argc) { - if (!is_valid_user_name (argv[optind])) { - fprintf (stderr, _("%s: Provided user name is not a valid name\n"), Prog); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - user = argv[optind]; - pw = xgetpwnam (user); - if (NULL == pw) { - fprintf (stderr, - _("%s: user '%s' does not exist\n"), Prog, user); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - } else { - pw = get_my_pwent (); -@@ -507,12 +512,12 @@ int main (int argc, char **argv) - Prog); - SYSLOG ((LOG_WARN, "Cannot determine the user name of the caller (UID %lu)", - (unsigned long) getuid ())); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - user = xstrdup (pw->pw_name); - } - -- check_perms (pw); -+ check_perms (pw, &flags); - - /* - * Now get the login shell. Either get it from the password -@@ -539,7 +544,7 @@ int main (int argc, char **argv) - */ - if (valid_field (loginsh, ":,=\n") != 0) { - fprintf (stderr, _("%s: Invalid entry: %s\n"), Prog, loginsh); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - if (!streq(loginsh, "") - && (loginsh[0] != '/' -@@ -550,7 +555,7 @@ int main (int argc, char **argv) - fprintf (stderr, _("%s: Warning: %s is an invalid shell\n"), Prog, loginsh); - } else { - fprintf (stderr, _("%s: %s is an invalid shell\n"), Prog, loginsh); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - } - --- -2.50.0 - - -From 58600326353a2198df7f8753e2ad8ffa216b68cc Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Thu, 3 Jul 2025 12:35:44 +0200 -Subject: [PATCH 03/12] src/passwd.c: chroot or prefix SELinux file context - -Do not process SELinux file context during file closure when chroot or -prefix options are selected. - -Signed-off-by: Iker Pedrosa ---- - src/passwd.c | 41 ++++++++++++++++++++++++++++------------- - 1 file changed, 28 insertions(+), 13 deletions(-) - -diff --git a/src/passwd.c b/src/passwd.c -index 512dc572..6d6f319e 100644 ---- a/src/passwd.c -+++ b/src/passwd.c -@@ -53,6 +53,12 @@ - #define E_PWDBUSY 5 /* passwd file busy, try again later */ - #define E_BAD_ARG 6 /* invalid argument to option */ - #define E_PAM_ERR 10 /* PAM returned an error */ -+ -+struct option_flags { -+ bool chroot; -+ bool prefix; -+}; -+ - /* - * Global variables - */ -@@ -131,9 +137,9 @@ static void print_status (const struct passwd *); - NORETURN static void fail_exit (int); - NORETURN static void oom (void); - static char *update_crypt_pw (char *); --static void update_noshadow (void); -+static void update_noshadow (struct option_flags *flags); - --static void update_shadow (void); -+static void update_shadow (struct option_flags *flags); - - /* - * usage - print command usage and exit -@@ -549,10 +555,13 @@ static char *update_crypt_pw (char *cp) - } - - --static void update_noshadow (void) -+static void update_noshadow (struct option_flags *flags) - { - const struct passwd *pw; - struct passwd *npw; -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot && !flags->prefix; - - if (pw_lock () == 0) { - (void) fprintf (stderr, -@@ -586,14 +595,14 @@ static void update_noshadow (void) - Prog, pw_dbname (), npw->pw_name); - fail_exit (E_FAILURE); - } -- if (pw_close (true) == 0) { -+ if (pw_close (process_selinux) == 0) { - (void) fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); - fail_exit (E_FAILURE); - } -- if (pw_unlock (true) == 0) { -+ if (pw_unlock (process_selinux) == 0) { - (void) fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, pw_dbname ()); -@@ -603,10 +612,13 @@ static void update_noshadow (void) - pw_locked = false; - } - --static void update_shadow (void) -+static void update_shadow (struct option_flags *flags) - { - const struct spwd *sp; - struct spwd *nsp; -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot && !flags->prefix; - - if (spw_lock () == 0) { - (void) fprintf (stderr, -@@ -625,9 +637,9 @@ static void update_shadow (void) - sp = spw_locate (name); - if (NULL == sp) { - /* Try to update the password in /etc/passwd instead. */ -- (void) spw_close (true); -- update_noshadow (); -- if (spw_unlock (true) == 0) { -+ (void) spw_close (process_selinux); -+ update_noshadow (flags); -+ if (spw_unlock (process_selinux) == 0) { - (void) fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, spw_dbname ()); -@@ -681,14 +693,14 @@ static void update_shadow (void) - Prog, spw_dbname (), nsp->sp_namp); - fail_exit (E_FAILURE); - } -- if (spw_close (true) == 0) { -+ if (spw_close (process_selinux) == 0) { - (void) fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); - fail_exit (E_FAILURE); - } -- if (spw_unlock (true) == 0) { -+ if (spw_unlock (process_selinux) == 0) { - (void) fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, spw_dbname ()); -@@ -733,6 +745,7 @@ main(int argc, char **argv) - char *cp; /* Miscellaneous character pointing */ - - const struct spwd *sp; /* Shadow file entry for user */ -+ struct option_flags flags; - - sanitize_env (); - check_fds (); -@@ -849,8 +862,10 @@ main(int argc, char **argv) - } - break; - case 'R': /* no-op, handled in process_root_flag () */ -+ flags.chroot = true; - break; - case 'P': /* no-op, handled in process_prefix_flag () */ -+ flags.prefix = true; - break; - case 'S': - Sflg = true; /* ok for users */ -@@ -1107,9 +1122,9 @@ main(int argc, char **argv) - exit (E_NOPERM); - } - if (spw_file_present ()) { -- update_shadow (); -+ update_shadow (&flags); - } else { -- update_noshadow (); -+ update_noshadow (&flags); - } - - nscd_flush_cache ("passwd"); --- -2.50.0 - - -From d5a9144c809e808600c7dc730970efc04bc032fd Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Thu, 3 Jul 2025 12:48:18 +0200 -Subject: [PATCH 04/12] src/passwd.c: SELinux file context for fail_exit() - -Do not process SELinux file context when running fail_exit() when chroot -or prefix options are selected. - -Signed-off-by: Iker Pedrosa ---- - src/passwd.c | 46 ++++++++++++++++++++++++---------------------- - 1 file changed, 24 insertions(+), 22 deletions(-) - -diff --git a/src/passwd.c b/src/passwd.c -index 6d6f319e..78859c96 100644 ---- a/src/passwd.c -+++ b/src/passwd.c -@@ -134,9 +134,9 @@ static int new_password (const struct passwd *); - static void check_password (const struct passwd *, const struct spwd *); - static /*@observer@*/const char *pw_status (const char *); - static void print_status (const struct passwd *); --NORETURN static void fail_exit (int); --NORETURN static void oom (void); --static char *update_crypt_pw (char *); -+NORETURN static void fail_exit (int, bool); -+NORETURN static void oom (bool process_selinux); -+static char *update_crypt_pw (char *, bool); - static void update_noshadow (struct option_flags *flags); - - static void update_shadow (struct option_flags *flags); -@@ -486,10 +486,10 @@ static void print_status (const struct passwd *pw) - - NORETURN - static void --fail_exit (int status) -+fail_exit (int status, bool process_selinux) - { - if (pw_locked) { -- if (pw_unlock (true) == 0) { -+ if (pw_unlock (process_selinux) == 0) { - (void) fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -@@ -497,7 +497,7 @@ fail_exit (int status) - } - - if (spw_locked) { -- if (spw_unlock (true) == 0) { -+ if (spw_unlock (process_selinux) == 0) { - (void) fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - /* continue */ -@@ -509,13 +509,13 @@ fail_exit (int status) - - NORETURN - static void --oom (void) -+oom (bool process_selinux) - { - (void) fprintf (stderr, _("%s: out of memory\n"), Prog); -- fail_exit (E_FAILURE); -+ fail_exit (E_FAILURE, process_selinux); - } - --static char *update_crypt_pw (char *cp) -+static char *update_crypt_pw (char *cp, bool process_selinux) - { - if (!use_pam) - { -@@ -533,7 +533,7 @@ static char *update_crypt_pw (char *cp) - _("%s: unlocking the password would result in a passwordless account.\n" - "You should set a password with usermod -p to unlock the password of this account.\n"), - Prog); -- fail_exit (E_FAILURE); -+ fail_exit (E_FAILURE, process_selinux); - } else { - cp++; - } -@@ -575,32 +575,32 @@ static void update_noshadow (struct option_flags *flags) - _("%s: cannot open %s\n"), - Prog, pw_dbname ()); - SYSLOG ((LOG_WARN, "cannot open %s", pw_dbname ())); -- fail_exit (E_MISSING); -+ fail_exit (E_MISSING, process_selinux); - } - pw = pw_locate (name); - if (NULL == pw) { - (void) fprintf (stderr, - _("%s: user '%s' does not exist in %s\n"), - Prog, name, pw_dbname ()); -- fail_exit (E_NOPERM); -+ fail_exit (E_NOPERM, process_selinux); - } - npw = __pw_dup (pw); - if (NULL == npw) { -- oom (); -+ oom (process_selinux); - } -- npw->pw_passwd = update_crypt_pw (npw->pw_passwd); -+ npw->pw_passwd = update_crypt_pw (npw->pw_passwd, process_selinux); - if (pw_update (npw) == 0) { - (void) fprintf (stderr, - _("%s: failed to prepare the new %s entry '%s'\n"), - Prog, pw_dbname (), npw->pw_name); -- fail_exit (E_FAILURE); -+ fail_exit (E_FAILURE, process_selinux); - } - if (pw_close (process_selinux) == 0) { - (void) fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); -- fail_exit (E_FAILURE); -+ fail_exit (E_FAILURE, process_selinux); - } - if (pw_unlock (process_selinux) == 0) { - (void) fprintf (stderr, -@@ -632,7 +632,7 @@ static void update_shadow (struct option_flags *flags) - _("%s: cannot open %s\n"), - Prog, spw_dbname ()); - SYSLOG ((LOG_WARN, "cannot open %s", spw_dbname ())); -- fail_exit (E_FAILURE); -+ fail_exit (E_FAILURE, process_selinux); - } - sp = spw_locate (name); - if (NULL == sp) { -@@ -651,9 +651,9 @@ static void update_shadow (struct option_flags *flags) - } - nsp = __spw_dup (sp); - if (NULL == nsp) { -- oom (); -+ oom (process_selinux); - } -- nsp->sp_pwdp = update_crypt_pw (nsp->sp_pwdp); -+ nsp->sp_pwdp = update_crypt_pw (nsp->sp_pwdp, process_selinux); - if (xflg) { - nsp->sp_max = age_max; - } -@@ -691,14 +691,14 @@ static void update_shadow (struct option_flags *flags) - (void) fprintf (stderr, - _("%s: failed to prepare the new %s entry '%s'\n"), - Prog, spw_dbname (), nsp->sp_namp); -- fail_exit (E_FAILURE); -+ fail_exit (E_FAILURE, process_selinux); - } - if (spw_close (process_selinux) == 0) { - (void) fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); -- fail_exit (E_FAILURE); -+ fail_exit (E_FAILURE, process_selinux); - } - if (spw_unlock (process_selinux) == 0) { - (void) fprintf (stderr, -@@ -746,6 +746,7 @@ main(int argc, char **argv) - - const struct spwd *sp; /* Shadow file entry for user */ - struct option_flags flags; -+ bool process_selinux; - - sanitize_env (); - check_fds (); -@@ -912,6 +913,7 @@ main(int argc, char **argv) - } - } - } -+ process_selinux = !flags.chroot && !flags.prefix; - - /* - * Now I have to get the user name. The name will be gotten from the -@@ -931,7 +933,7 @@ main(int argc, char **argv) - if (optind < argc) { - if (!is_valid_user_name (argv[optind])) { - fprintf (stderr, _("%s: Provided user name is not a valid name\n"), Prog); -- fail_exit (E_NOPERM); -+ fail_exit (E_NOPERM, process_selinux); - } - name = argv[optind]; - } else { --- -2.50.0 - - -From a736c2af5702e98081bace5fde10a264f443d318 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Thu, 3 Jul 2025 12:55:35 +0200 -Subject: [PATCH 05/12] src/pwck.c: chroot or prefix SELinux file context - -Do not process SELinux file context during file closure when chroot or -prefix options are selected. - -Signed-off-by: Iker Pedrosa ---- - src/pwck.c | 46 ++++++++++++++++++++++++++++++---------------- - 1 file changed, 30 insertions(+), 16 deletions(-) - -diff --git a/src/pwck.c b/src/pwck.c -index 9c4cc29a..d0f2f1c9 100644 ---- a/src/pwck.c -+++ b/src/pwck.c -@@ -48,6 +48,10 @@ - #define E_CANTUPDATE 5 - #define E_CANTSORT 6 - -+struct option_flags { -+ bool chroot; -+}; -+ - /* - * Global variables - */ -@@ -71,10 +75,11 @@ static bool quiet = false; /* don't report warnings, only errors */ - /* local function prototypes */ - static void fail_exit (int code); - NORETURN static void usage (int status); --static void process_flags (int argc, char **argv); -+static void process_flags (int argc, char **argv, struct option_flags *flags); - static void open_files (void); --static void close_files (bool changed); --static void check_pw_file (bool *errors, bool *changed); -+static void close_files (bool changed, struct option_flags *flags); -+static void check_pw_file (bool *errors, bool *changed, -+ struct option_flags *flags); - static void check_spw_file (bool *errors, bool *changed); - - extern int allow_bad_names; -@@ -155,7 +160,7 @@ usage (int status) - * - * It will not return if an error is encountered. - */ --static void process_flags (int argc, char **argv) -+static void process_flags (int argc, char **argv, struct option_flags *flags) - { - int c; - static struct option long_options[] = { -@@ -188,6 +193,7 @@ static void process_flags (int argc, char **argv) - read_only = true; - break; - case 'R': /* no-op, handled in process_root_flag () */ -+ flags->chroot = true; - break; - case 's': - sort_mode = true; -@@ -302,14 +308,18 @@ static void open_files (void) - * changes are committed in the databases. The databases are - * unlocked anyway. - */ --static void close_files (bool changed) -+static void close_files (bool changed, struct option_flags *flags) - { -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot; -+ - /* - * All done. If there were no change we can just abandon any - * changes to the files. - */ - if (changed) { -- if (pw_close (true) == 0) { -+ if (pw_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, pw_dbname ()); -@@ -320,7 +330,7 @@ static void close_files (bool changed) - } - fail_exit (E_CANTUPDATE); - } -- if (spw_opened && (spw_close (true) == 0)) { -+ if (spw_opened && (spw_close (process_selinux) == 0)) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, spw_dbname ()); -@@ -338,7 +348,7 @@ static void close_files (bool changed) - * Don't be anti-social - unlock the files when you're done. - */ - if (spw_locked) { -- if (spw_unlock (true) == 0) { -+ if (spw_unlock (process_selinux) == 0) { - fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, spw_dbname ()); -@@ -351,7 +361,7 @@ static void close_files (bool changed) - } - spw_locked = false; - if (pw_locked) { -- if (pw_unlock (true) == 0) { -+ if (pw_unlock (process_selinux) == 0) { - fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, pw_dbname ()); -@@ -368,13 +378,16 @@ static void close_files (bool changed) - /* - * check_pw_file - check the content of the passwd file - */ --static void check_pw_file (bool *errors, bool *changed) -+static void check_pw_file (bool *errors, bool *changed, struct option_flags *flags) - { - struct commonio_entry *pfe, *tpfe; - struct passwd *pwd; - const struct spwd *spw; - uid_t min_sys_id = getdef_ulong ("SYS_UID_MIN", 101UL); - uid_t max_sys_id = getdef_ulong ("SYS_UID_MAX", 999UL); -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot; - - /* - * Loop through the entire password file. -@@ -581,7 +594,7 @@ static void check_pw_file (bool *errors, bool *changed) - _("%s: cannot open %s\n"), - Prog, spw_dbname ()); - *errors = true; -- if (spw_unlock (true) == 0) { -+ if (spw_unlock (process_selinux) == 0) { - fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, spw_dbname ()); -@@ -657,7 +670,7 @@ static void check_pw_file (bool *errors, bool *changed) - } - #ifdef WITH_TCB - if (getdef_bool ("USE_TCB") && spw_locked) { -- if (spw_opened && (spw_close (true) == 0)) { -+ if (spw_opened && (spw_close (process_selinux) == 0)) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, spw_dbname ()); -@@ -669,7 +682,7 @@ static void check_pw_file (bool *errors, bool *changed) - } else { - spw_opened = false; - } -- if (spw_unlock (true) == 0) { -+ if (spw_unlock (process_selinux) == 0) { - fprintf (stderr, - _("%s: failed to unlock %s\n"), - Prog, spw_dbname ()); -@@ -840,6 +853,7 @@ int main (int argc, char **argv) - { - bool errors = false; - bool changed = false; -+ struct option_flags flags; - - log_set_progname(Prog); - log_set_logfd(stderr); -@@ -853,7 +867,7 @@ int main (int argc, char **argv) - OPENLOG (Prog); - - /* Parse the command line arguments */ -- process_flags (argc, argv); -+ process_flags (argc, argv, &flags); - - open_files (); - -@@ -874,14 +888,14 @@ int main (int argc, char **argv) - } - changed = true; - } else { -- check_pw_file (&errors, &changed); -+ check_pw_file (&errors, &changed, &flags); - - if (is_shadow) { - check_spw_file (&errors, &changed); - } - } - -- close_files (changed); -+ close_files (changed, &flags); - - if (!read_only) { - nscd_flush_cache ("passwd"); --- -2.50.0 - - -From 09957a9748ae6cd28e0826d4cacd939ac288ca1b Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Thu, 3 Jul 2025 12:58:58 +0200 -Subject: [PATCH 06/12] src/pwck.c: SELinux file context for fail_exit() - -Do not process SELinux file context when running fail_exit() when chroot -or prefix options are selected. - -Signed-off-by: Iker Pedrosa ---- - src/pwck.c | 39 ++++++++++++++++++++++----------------- - 1 file changed, 22 insertions(+), 17 deletions(-) - -diff --git a/src/pwck.c b/src/pwck.c -index d0f2f1c9..f1e9c085 100644 ---- a/src/pwck.c -+++ b/src/pwck.c -@@ -73,10 +73,10 @@ static bool sort_mode = false; - static bool quiet = false; /* don't report warnings, only errors */ - - /* local function prototypes */ --static void fail_exit (int code); -+static void fail_exit (int code, bool process_selinux); - NORETURN static void usage (int status); - static void process_flags (int argc, char **argv, struct option_flags *flags); --static void open_files (void); -+static void open_files (struct option_flags *flags); - static void close_files (bool changed, struct option_flags *flags); - static void check_pw_file (bool *errors, bool *changed, - struct option_flags *flags); -@@ -87,10 +87,10 @@ extern int allow_bad_names; - /* - * fail_exit - do some cleanup and exit with the given error code - */ --static void fail_exit (int code) -+static void fail_exit (int code, bool process_selinux) - { - if (spw_locked) { -- if (spw_unlock (true) == 0) { -+ if (spw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); - if (use_system_spw_file) { - SYSLOG ((LOG_ERR, "failed to unlock %s", -@@ -101,7 +101,7 @@ static void fail_exit (int code) - } - - if (pw_locked) { -- if (pw_unlock (true) == 0) { -+ if (pw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - if (use_system_pw_file) { - SYSLOG ((LOG_ERR, "failed to unlock %s", -@@ -246,12 +246,15 @@ static void process_flags (int argc, char **argv, struct option_flags *flags) - * In read-only mode, the databases are not locked and are opened - * only for reading. - */ --static void open_files (void) -+static void open_files (struct option_flags *flags) - { - bool use_tcb = false; - #ifdef WITH_TCB - use_tcb = getdef_bool ("USE_TCB"); - #endif /* WITH_TCB */ -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot; - - /* - * Lock the files if we aren't in "read-only" mode -@@ -261,7 +264,7 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, pw_dbname ()); -- fail_exit (E_CANTLOCK); -+ fail_exit (E_CANTLOCK, process_selinux); - } - pw_locked = true; - if (is_shadow && !use_tcb) { -@@ -269,7 +272,7 @@ static void open_files (void) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, spw_dbname ()); -- fail_exit (E_CANTLOCK); -+ fail_exit (E_CANTLOCK, process_selinux); - } - spw_locked = true; - } -@@ -285,7 +288,7 @@ static void open_files (void) - if (use_system_pw_file) { - SYSLOG ((LOG_WARN, "cannot open %s", pw_dbname ())); - } -- fail_exit (E_CANTOPEN); -+ fail_exit (E_CANTOPEN, process_selinux); - } - if (is_shadow && !use_tcb) { - if (spw_open (read_only ? O_RDONLY : O_RDWR) == 0) { -@@ -295,7 +298,7 @@ static void open_files (void) - SYSLOG ((LOG_WARN, "cannot open %s", - spw_dbname ())); - } -- fail_exit (E_CANTOPEN); -+ fail_exit (E_CANTOPEN, process_selinux); - } - spw_opened = true; - } -@@ -328,7 +331,7 @@ static void close_files (bool changed, struct option_flags *flags) - "failure while writing changes to %s", - pw_dbname ())); - } -- fail_exit (E_CANTUPDATE); -+ fail_exit (E_CANTUPDATE, process_selinux); - } - if (spw_opened && (spw_close (process_selinux) == 0)) { - fprintf (stderr, -@@ -339,7 +342,7 @@ static void close_files (bool changed, struct option_flags *flags) - "failure while writing changes to %s", - spw_dbname ())); - } -- fail_exit (E_CANTUPDATE); -+ fail_exit (E_CANTUPDATE, process_selinux); - } - spw_opened = false; - } -@@ -644,7 +647,7 @@ static void check_pw_file (bool *errors, bool *changed, struct option_flags *fla - fprintf (stderr, - _("%s: failed to prepare the new %s entry '%s'\n"), - Prog, spw_dbname (), sp.sp_namp); -- fail_exit (E_CANTUPDATE); -+ fail_exit (E_CANTUPDATE, process_selinux); - } - /* remove password from /etc/passwd */ - pw = *pwd; -@@ -653,7 +656,7 @@ static void check_pw_file (bool *errors, bool *changed, struct option_flags *fla - fprintf (stderr, - _("%s: failed to prepare the new %s entry '%s'\n"), - Prog, pw_dbname (), pw.pw_name); -- fail_exit (E_CANTUPDATE); -+ fail_exit (E_CANTUPDATE, process_selinux); - } - } - } else { -@@ -854,6 +857,7 @@ int main (int argc, char **argv) - bool errors = false; - bool changed = false; - struct option_flags flags; -+ bool process_selinux; - - log_set_progname(Prog); - log_set_logfd(stderr); -@@ -868,22 +872,23 @@ int main (int argc, char **argv) - - /* Parse the command line arguments */ - process_flags (argc, argv, &flags); -+ process_selinux = !flags.chroot; - -- open_files (); -+ open_files (&flags); - - if (sort_mode) { - if (pw_sort () != 0) { - fprintf (stderr, - _("%s: cannot sort entries in %s\n"), - Prog, pw_dbname ()); -- fail_exit (E_CANTSORT); -+ fail_exit (E_CANTSORT, process_selinux); - } - if (is_shadow) { - if (spw_sort () != 0) { - fprintf (stderr, - _("%s: cannot sort entries in %s\n"), - Prog, spw_dbname ()); -- fail_exit (E_CANTSORT); -+ fail_exit (E_CANTSORT, process_selinux); - } - } - changed = true; --- -2.50.0 - - -From 0c39283e9298fc130c55516fd0a4a0c6b6003bc9 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Thu, 3 Jul 2025 13:04:26 +0200 -Subject: [PATCH 07/12] src/pwconv.c: chroot or prefix SELinux file context - -Do not process SELinux file context during file closure when chroot or -prefix options are selected. - -Signed-off-by: Iker Pedrosa ---- - src/pwconv.c | 23 ++++++++++++++++------- - 1 file changed, 16 insertions(+), 7 deletions(-) - -diff --git a/src/pwconv.c b/src/pwconv.c -index b0d668b5..6c81cc6e 100644 ---- a/src/pwconv.c -+++ b/src/pwconv.c -@@ -67,6 +67,11 @@ - #define E_MISSING 4 /* unexpected failure, passwd file missing */ - #define E_PWDBUSY 5 /* passwd file(s) busy */ - #define E_BADENTRY 6 /* bad shadow entry */ -+ -+struct option_flags { -+ bool chroot; -+}; -+ - /* - * Global variables - */ -@@ -78,7 +83,7 @@ static bool pw_locked = false; - /* local function prototypes */ - static void fail_exit (int status); - static void usage (int status); --static void process_flags (int argc, char **argv); -+static void process_flags (int argc, char **argv, struct option_flags *flags); - - static void fail_exit (int status) - { -@@ -120,7 +125,7 @@ static void usage (int status) - * - * It will not return if an error is encountered. - */ --static void process_flags (int argc, char **argv) -+static void process_flags (int argc, char **argv, struct option_flags *flags) - { - /* - * Parse the command line options. -@@ -139,6 +144,7 @@ static void process_flags (int argc, char **argv) - usage (E_SUCCESS); - /*@notreached@*/break; - case 'R': /* no-op, handled in process_root_flag () */ -+ flags->chroot = true; - break; - default: - usage (E_USAGE); -@@ -156,6 +162,8 @@ int main (int argc, char **argv) - struct passwd pwent; - const struct spwd *sp; - struct spwd spent; -+ struct option_flags flags; -+ bool process_selinux; - - log_set_progname(Prog); - log_set_logfd(stderr); -@@ -168,7 +176,8 @@ int main (int argc, char **argv) - - OPENLOG (Prog); - -- process_flags (argc, argv); -+ process_flags (argc, argv, &flags); -+ process_selinux = !flags.chroot; - - #ifdef WITH_TCB - if (getdef_bool("USE_TCB")) { -@@ -274,14 +283,14 @@ int main (int argc, char **argv) - } - } - -- if (spw_close (true) == 0) { -+ if (spw_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); - fail_exit (E_FAILURE); - } -- if (pw_close (true) == 0) { -+ if (pw_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, pw_dbname ()); -@@ -299,13 +308,13 @@ int main (int argc, char **argv) - /* continue */ - } - -- if (pw_unlock (true) == 0) { -+ if (pw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ - } - -- if (spw_unlock (true) == 0) { -+ if (spw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - /* continue */ --- -2.50.0 - - -From 997a523d41bb513f37ca88cab35cba9281f036b6 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Thu, 3 Jul 2025 13:05:52 +0200 -Subject: [PATCH 08/12] src/pwconv.c: SELinux file context for fail_exit() - -Do not process SELinux file context when running fail_exit() when chroot -or prefix options are selected. - -Signed-off-by: Iker Pedrosa ---- - src/pwconv.c | 26 +++++++++++++------------- - 1 file changed, 13 insertions(+), 13 deletions(-) - -diff --git a/src/pwconv.c b/src/pwconv.c -index 6c81cc6e..1dc1fd86 100644 ---- a/src/pwconv.c -+++ b/src/pwconv.c -@@ -81,14 +81,14 @@ static bool spw_locked = false; - static bool pw_locked = false; - - /* local function prototypes */ --static void fail_exit (int status); -+static void fail_exit (int status, bool process_selinux); - static void usage (int status); - static void process_flags (int argc, char **argv, struct option_flags *flags); - --static void fail_exit (int status) -+static void fail_exit (int status, bool process_selinux) - { - if (pw_locked) { -- if (pw_unlock (true) == 0) { -+ if (pw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -@@ -96,7 +96,7 @@ static void fail_exit (int status) - } - - if (spw_locked) { -- if (spw_unlock (true) == 0) { -+ if (spw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - /* continue */ -@@ -190,26 +190,26 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, pw_dbname ()); -- fail_exit (E_PWDBUSY); -+ fail_exit (E_PWDBUSY, process_selinux); - } - pw_locked = true; - if (pw_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, - _("%s: cannot open %s\n"), Prog, pw_dbname ()); -- fail_exit (E_MISSING); -+ fail_exit (E_MISSING, process_selinux); - } - - if (spw_lock () == 0) { - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, spw_dbname ()); -- fail_exit (E_PWDBUSY); -+ fail_exit (E_PWDBUSY, process_selinux); - } - spw_locked = true; - if (spw_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, - _("%s: cannot open %s\n"), Prog, spw_dbname ()); -- fail_exit (E_FAILURE); -+ fail_exit (E_FAILURE, process_selinux); - } - - /* -@@ -228,7 +228,7 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: cannot remove entry '%s' from %s\n"), - Prog, sp->sp_namp, spw_dbname ()); -- fail_exit (E_FAILURE); -+ fail_exit (E_FAILURE, process_selinux); - } - (void) spw_rewind(); - } -@@ -269,7 +269,7 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: failed to prepare the new %s entry '%s'\n"), - Prog, spw_dbname (), spent.sp_namp); -- fail_exit (E_FAILURE); -+ fail_exit (E_FAILURE, process_selinux); - } - - /* remove password from /etc/passwd */ -@@ -279,7 +279,7 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: failed to prepare the new %s entry '%s'\n"), - Prog, pw_dbname (), pwent.pw_name); -- fail_exit (E_FAILURE); -+ fail_exit (E_FAILURE, process_selinux); - } - } - -@@ -288,14 +288,14 @@ int main (int argc, char **argv) - _("%s: failure while writing changes to %s\n"), - Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); -- fail_exit (E_FAILURE); -+ fail_exit (E_FAILURE, process_selinux); - } - if (pw_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); -- fail_exit (E_FAILURE); -+ fail_exit (E_FAILURE, process_selinux); - } - - /* /etc/passwd- (backup file) */ --- -2.50.0 - - -From 13e902a1b368049cb4c6853a7470f66efbac6e72 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Thu, 3 Jul 2025 13:08:10 +0200 -Subject: [PATCH 09/12] src/pwunconv.c: chroot or prefix SELinux file context - -Do not process SELinux file context during file closure when chroot or -prefix options are selected. - -Signed-off-by: Iker Pedrosa ---- - src/pwunconv.c | 21 ++++++++++++++------- - 1 file changed, 14 insertions(+), 7 deletions(-) - -diff --git a/src/pwunconv.c b/src/pwunconv.c -index 7a6d2be5..d46bde6d 100644 ---- a/src/pwunconv.c -+++ b/src/pwunconv.c -@@ -30,6 +30,9 @@ - #include "sssd.h" - #include "string/strcmp/streq.h" - -+struct option_flags { -+ bool chroot; -+}; - - /* - * Global variables -@@ -42,7 +45,7 @@ static bool pw_locked = false; - /* local function prototypes */ - static void fail_exit (int status); - static void usage (int status); --static void process_flags (int argc, char **argv); -+static void process_flags (int argc, char **argv, struct option_flags *flags); - - static void fail_exit (int status) - { -@@ -82,7 +85,7 @@ static void usage (int status) - * - * It will not return if an error is encountered. - */ --static void process_flags (int argc, char **argv) -+static void process_flags (int argc, char **argv, struct option_flags *flags) - { - /* - * Parse the command line options. -@@ -101,6 +104,7 @@ static void process_flags (int argc, char **argv) - usage (E_SUCCESS); - /*@notreached@*/break; - case 'R': /* no-op, handled in process_root_flag () */ -+ flags->chroot = true; - break; - default: - usage (E_USAGE); -@@ -117,6 +121,8 @@ int main (int argc, char **argv) - const struct passwd *pw; - struct passwd pwent; - const struct spwd *spwd; -+ struct option_flags flags; -+ bool process_selinux; - - log_set_progname(Prog); - log_set_logfd(stderr); -@@ -129,7 +135,8 @@ int main (int argc, char **argv) - - OPENLOG (Prog); - -- process_flags (argc, argv); -+ process_flags (argc, argv, &flags); -+ process_selinux = !flags.chroot; - - #ifdef WITH_TCB - if (getdef_bool("USE_TCB")) { -@@ -205,9 +212,9 @@ int main (int argc, char **argv) - } - } - -- (void) spw_close (true); /* was only open O_RDONLY */ -+ (void) spw_close (process_selinux); /* was only open O_RDONLY */ - -- if (pw_close (true) == 0) { -+ if (pw_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, pw_dbname ()); -@@ -222,12 +229,12 @@ int main (int argc, char **argv) - fail_exit (3); - } - -- if (spw_unlock (true) == 0) { -+ if (spw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - /* continue */ - } -- if (pw_unlock (true) == 0) { -+ if (pw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ --- -2.50.0 - - -From 849e748fe08129684da13acba13a247f0aa98eff Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Thu, 3 Jul 2025 13:09:12 +0200 -Subject: [PATCH 10/12] src/pwunconv.c: SELinux file context for fail_exit() - -Do not process SELinux file context when running fail_exit() when chroot -or prefix options are selected. - -Signed-off-by: Iker Pedrosa ---- - src/pwunconv.c | 22 +++++++++++----------- - 1 file changed, 11 insertions(+), 11 deletions(-) - -diff --git a/src/pwunconv.c b/src/pwunconv.c -index d46bde6d..d3e10f68 100644 ---- a/src/pwunconv.c -+++ b/src/pwunconv.c -@@ -43,21 +43,21 @@ static bool spw_locked = false; - static bool pw_locked = false; - - /* local function prototypes */ --static void fail_exit (int status); -+static void fail_exit (int status, bool process_selinux); - static void usage (int status); - static void process_flags (int argc, char **argv, struct option_flags *flags); - --static void fail_exit (int status) -+static void fail_exit (int status, bool process_selinux) - { - if (spw_locked) { -- if (spw_unlock (true) == 0) { -+ if (spw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); - /* continue */ - } - } - if (pw_locked) { -- if (pw_unlock (true) == 0) { -+ if (pw_unlock (process_selinux) == 0) { - fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); - /* continue */ -@@ -154,28 +154,28 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, pw_dbname ()); -- fail_exit (5); -+ fail_exit (5, process_selinux); - } - pw_locked = true; - if (pw_open (O_CREAT | O_RDWR) == 0) { - fprintf (stderr, - _("%s: cannot open %s\n"), - Prog, pw_dbname ()); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - - if (spw_lock () == 0) { - fprintf (stderr, - _("%s: cannot lock %s; try again later.\n"), - Prog, spw_dbname ()); -- fail_exit (5); -+ fail_exit (5, process_selinux); - } - spw_locked = true; - if (spw_open (O_RDONLY) == 0) { - fprintf (stderr, - _("%s: cannot open %s\n"), - Prog, spw_dbname ()); -- fail_exit (1); -+ fail_exit (1, process_selinux); - } - - (void) pw_rewind (); -@@ -208,7 +208,7 @@ int main (int argc, char **argv) - fprintf (stderr, - _("%s: failed to prepare the new %s entry '%s'\n"), - Prog, pw_dbname (), pwent.pw_name); -- fail_exit (3); -+ fail_exit (3, process_selinux); - } - } - -@@ -219,14 +219,14 @@ int main (int argc, char **argv) - _("%s: failure while writing changes to %s\n"), - Prog, pw_dbname ()); - SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); -- fail_exit (3); -+ fail_exit (3, process_selinux); - } - - if (unlink (SHADOW) != 0) { - fprintf (stderr, - _("%s: cannot delete %s\n"), Prog, SHADOW); - SYSLOG ((LOG_ERR, "cannot delete %s", SHADOW)); -- fail_exit (3); -+ fail_exit (3, process_selinux); - } - - if (spw_unlock (process_selinux) == 0) { --- -2.50.0 - - -From b1bcf1cf8245b195cff7586770ad861f89cb7c92 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Thu, 3 Jul 2025 14:29:55 +0200 -Subject: [PATCH 11/12] src/gpasswd.c: chroot or prefix SELinux file context - -Do not process SELinux file context during file closure when chroot or -prefix options are selected. - -Signed-off-by: Iker Pedrosa ---- - src/gpasswd.c | 44 ++++++++++++++++++++++++++++---------------- - 1 file changed, 28 insertions(+), 16 deletions(-) - -diff --git a/src/gpasswd.c b/src/gpasswd.c -index a49b9140..94b2bb32 100644 ---- a/src/gpasswd.c -+++ b/src/gpasswd.c -@@ -40,6 +40,9 @@ - #include "string/strcpy/strtcpy.h" - #include "string/strdup/xstrdup.h" - -+struct option_flags { -+ bool chroot; -+}; - - /* - * Global variables -@@ -87,17 +90,17 @@ NORETURN static void failure(void); - static void usage (int status); - static void catch_signals (int killed); - static bool is_valid_user_list (const char *users); --static void process_flags (int argc, char **argv); -+static void process_flags (int argc, char **argv, struct option_flags *flags); - static void check_flags (int argc, int opt_index); - static void open_files (void); --static void close_files (void); -+static void close_files (struct option_flags *flags); - #ifdef SHADOWGRP --static void get_group (struct group *gr, struct sgrp *sg); -+static void get_group (struct group *gr, struct sgrp *sg, struct option_flags *flags); - static void check_perms (const struct group *gr, const struct sgrp *sg); - static void update_group (struct group *gr, struct sgrp *sg); - static void change_passwd (struct group *gr, struct sgrp *sg); - #else --static void get_group (struct group *gr); -+static void get_group (struct group *gr, struct option_flags *flags); - static void check_perms (const struct group *gr); - static void update_group (struct group *gr); - static void change_passwd (struct group *gr); -@@ -211,7 +214,7 @@ static void failure(void) - /* - * process_flags - process the command line options and arguments - */ --static void process_flags (int argc, char **argv) -+static void process_flags (int argc, char **argv, struct option_flags *flags) - { - int c; - static struct option long_options[] = { -@@ -272,6 +275,7 @@ static void process_flags (int argc, char **argv) - Mflg = true; - break; - case 'Q': /* no-op, handled in process_root_flag () */ -+ flags->chroot = true; - break; - case 'r': /* remove group password */ - rflg = true; -@@ -591,9 +595,13 @@ static void log_gpasswd_success_group (MAYBE_UNUSED void *arg) - * - * It will call exit in case of error. - */ --static void close_files (void) -+static void close_files (struct option_flags *flags) - { -- if (gr_close (true) == 0) { -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot; -+ -+ if (gr_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, gr_dbname ()); -@@ -607,7 +615,7 @@ static void close_files (void) - - #ifdef SHADOWGRP - if (is_shadowgrp) { -- if (sgr_close (true) == 0) { -+ if (sgr_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while writing changes to %s\n"), - Prog, sgr_dbname ()); -@@ -695,15 +703,18 @@ static void update_group (struct group *gr) - * Note: If !is_shadowgrp, *sg will not be initialized. - */ - #ifdef SHADOWGRP --static void get_group (struct group *gr, struct sgrp *sg) -+static void get_group (struct group *gr, struct sgrp *sg, struct option_flags *flags) - #else --static void get_group (struct group *gr) -+static void get_group (struct group *gr, struct option_flags *flags) - #endif - { - struct group const*tmpgr = NULL; - #ifdef SHADOWGRP - struct sgrp const*tmpsg = NULL; - #endif -+ bool process_selinux; -+ -+ process_selinux = !flags->chroot; - - if (gr_open (O_RDONLY) == 0) { - fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ()); -@@ -724,7 +735,7 @@ static void get_group (struct group *gr) - gr->gr_passwd = xstrdup (tmpgr->gr_passwd); - gr->gr_mem = dup_list (tmpgr->gr_mem); - -- if (gr_close (true) == 0) { -+ if (gr_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while closing read-only %s\n"), - Prog, gr_dbname ()); -@@ -762,7 +773,7 @@ static void get_group (struct group *gr) - sg->sg_adm[0] = NULL; - - } -- if (sgr_close (true) == 0) { -+ if (sgr_close (process_selinux) == 0) { - fprintf (stderr, - _("%s: failure while closing read-only %s\n"), - Prog, sgr_dbname ()); -@@ -864,6 +875,7 @@ int main (int argc, char **argv) - struct sgrp sgent; - #endif - struct passwd *pw = NULL; -+ struct option_flags flags; - - #ifdef WITH_AUDIT - audit_help_open (); -@@ -924,15 +936,15 @@ int main (int argc, char **argv) - } - - /* Parse the options */ -- process_flags (argc, argv); -+ process_flags (argc, argv, &flags); - - /* - * Replicate the group so it can be modified later on. - */ - #ifdef SHADOWGRP -- get_group (&grent, &sgent); -+ get_group (&grent, &sgent, &flags); - #else -- get_group (&grent); -+ get_group (&grent, &flags); - #endif - - /* -@@ -1095,7 +1107,7 @@ int main (int argc, char **argv) - update_group (&grent); - #endif - -- close_files (); -+ close_files (&flags); - - nscd_flush_cache ("group"); - sssd_flush_cache (SSSD_DB_GROUP); --- -2.50.0 - - -From 2c250fae8866a682bac686dcaa198b325d198cf9 Mon Sep 17 00:00:00 2001 -From: Iker Pedrosa -Date: Fri, 4 Jul 2025 10:03:42 +0200 -Subject: [PATCH 12/12] man/: update `--root` flag with no SELinux support - -Signed-off-by: Iker Pedrosa ---- - man/chage.1.xml | 1 + - man/chfn.1.xml | 1 + - man/chgpasswd.8.xml | 1 + - man/chpasswd.8.xml | 1 + - man/chsh.1.xml | 1 + - man/faillog.8.xml | 1 + - man/gpasswd.1.xml | 1 + - man/groupadd.8.xml | 1 + - man/groupdel.8.xml | 1 + - man/groupmems.8.xml | 1 + - man/groupmod.8.xml | 1 + - man/grpck.8.xml | 1 + - man/lastlog.8.xml | 1 + - man/newusers.8.xml | 1 + - man/passwd.1.xml | 1 + - man/pwck.8.xml | 1 + - man/pwconv.8.xml | 1 + - man/useradd.8.xml | 1 + - man/userdel.8.xml | 1 + - man/usermod.8.xml | 1 + - man/vipw.8.xml | 1 + - 21 files changed, 21 insertions(+) - -diff --git a/man/chage.1.xml b/man/chage.1.xml -index 4ccdf483..a3fff291 100644 ---- a/man/chage.1.xml -+++ b/man/chage.1.xml -@@ -205,6 +205,7 @@ - directory and use the configuration files from the - CHROOT_DIR directory. - Only absolute paths are supported. -+ No SELINUX support. - - - -diff --git a/man/chfn.1.xml b/man/chfn.1.xml -index 2fa49feb..d199ef03 100644 ---- a/man/chfn.1.xml -+++ b/man/chfn.1.xml -@@ -138,6 +138,7 @@ - Apply changes in the CHROOT_DIR - directory and use the configuration files from the - CHROOT_DIR directory. -+ No SELINUX support. - - - -diff --git a/man/chgpasswd.8.xml b/man/chgpasswd.8.xml -index f4a83c24..184c1696 100644 ---- a/man/chgpasswd.8.xml -+++ b/man/chgpasswd.8.xml -@@ -134,6 +134,7 @@ - directory and use the configuration files from the - CHROOT_DIR directory. - Only absolute paths are supported. -+ No SELINUX support. - - - -diff --git a/man/chpasswd.8.xml b/man/chpasswd.8.xml -index cffd9df1..440c8342 100644 ---- a/man/chpasswd.8.xml -+++ b/man/chpasswd.8.xml -@@ -176,6 +176,7 @@ - directory and use the configuration files from the - CHROOT_DIR directory. - Only absolute paths are supported. -+ No SELINUX support. - - - -diff --git a/man/chsh.1.xml b/man/chsh.1.xml -index db2d0ceb..8f253731 100644 ---- a/man/chsh.1.xml -+++ b/man/chsh.1.xml -@@ -89,6 +89,7 @@ - directory and use the configuration files from the - CHROOT_DIR directory. - Only absolute paths are supported. -+ No SELINUX support. - - - -diff --git a/man/faillog.8.xml b/man/faillog.8.xml -index effe43a9..7d453fd2 100644 ---- a/man/faillog.8.xml -+++ b/man/faillog.8.xml -@@ -162,6 +162,7 @@ - directory and use the configuration files from the - CHROOT_DIR directory. - Only absolute paths are supported. -+ No SELINUX support. - - - -diff --git a/man/gpasswd.1.xml b/man/gpasswd.1.xml -index 9b89d915..f918442f 100644 ---- a/man/gpasswd.1.xml -+++ b/man/gpasswd.1.xml -@@ -165,6 +165,7 @@ - directory and use the configuration files from the - CHROOT_DIR directory. - Only absolute paths are supported. -+ No SELINUX support. - - - -diff --git a/man/groupadd.8.xml b/man/groupadd.8.xml -index 9abf159a..2dea7ae5 100644 ---- a/man/groupadd.8.xml -+++ b/man/groupadd.8.xml -@@ -206,6 +206,7 @@ - directory and use the configuration files from the - CHROOT_DIR directory. - Only absolute paths are supported. -+ No SELINUX support. - - - -diff --git a/man/groupdel.8.xml b/man/groupdel.8.xml -index 8d41b883..31f29994 100644 ---- a/man/groupdel.8.xml -+++ b/man/groupdel.8.xml -@@ -94,6 +94,7 @@ - directory and use the configuration files from the - CHROOT_DIR directory. - Only absolute paths are supported. -+ No SELINUX support. - - - -diff --git a/man/groupmems.8.xml b/man/groupmems.8.xml -index cbc84622..0def6c99 100644 ---- a/man/groupmems.8.xml -+++ b/man/groupmems.8.xml -@@ -147,6 +147,7 @@ - directory and use the configuration files from the - CHROOT_DIR directory. - Only absolute paths are supported. -+ No SELINUX support. - - - -diff --git a/man/groupmod.8.xml b/man/groupmod.8.xml -index 2d51f271..ca287441 100644 ---- a/man/groupmod.8.xml -+++ b/man/groupmod.8.xml -@@ -169,6 +169,7 @@ - directory and use the configuration files from the - CHROOT_DIR directory. - Only absolute paths are supported. -+ No SELINUX support. - - - -diff --git a/man/grpck.8.xml b/man/grpck.8.xml -index 31aa6ca3..9feb190e 100644 ---- a/man/grpck.8.xml -+++ b/man/grpck.8.xml -@@ -154,6 +154,7 @@ - directory and use the configuration files from the - CHROOT_DIR directory. - Only absolute paths are supported. -+ No SELINUX support. - - - -diff --git a/man/lastlog.8.xml b/man/lastlog.8.xml -index cefe5ac2..b0589203 100644 ---- a/man/lastlog.8.xml -+++ b/man/lastlog.8.xml -@@ -109,6 +109,7 @@ - directory and use the configuration files from the - CHROOT_DIR directory. - Only absolute paths are supported. -+ No SELINUX support. - - - -diff --git a/man/newusers.8.xml b/man/newusers.8.xml -index 6812c750..e0380608 100644 ---- a/man/newusers.8.xml -+++ b/man/newusers.8.xml -@@ -313,6 +313,7 @@ - directory and use the configuration files from the - CHROOT_DIR directory. - Only absolute paths are supported. -+ No SELINUX support. - - - -diff --git a/man/passwd.1.xml b/man/passwd.1.xml -index 65dca040..def35609 100644 ---- a/man/passwd.1.xml -+++ b/man/passwd.1.xml -@@ -279,6 +279,7 @@ - directory and use the configuration files from the - CHROOT_DIR directory. - Only absolute paths are supported. -+ No SELINUX support. - - - -diff --git a/man/pwck.8.xml b/man/pwck.8.xml -index 4eb820d6..998bb44a 100644 ---- a/man/pwck.8.xml -+++ b/man/pwck.8.xml -@@ -202,6 +202,7 @@ - directory and use the configuration files from the - CHROOT_DIR directory. - Only absolute paths are supported. -+ No SELINUX support. - - - -diff --git a/man/pwconv.8.xml b/man/pwconv.8.xml -index c4aedef6..9be3f7c5 100644 ---- a/man/pwconv.8.xml -+++ b/man/pwconv.8.xml -@@ -183,6 +183,7 @@ - directory and use the configuration files from the - CHROOT_DIR directory. - Only absolute paths are supported. -+ No SELINUX support. - - - -diff --git a/man/useradd.8.xml b/man/useradd.8.xml -index fd9ff697..e6db7f6d 100644 ---- a/man/useradd.8.xml -+++ b/man/useradd.8.xml -@@ -515,6 +515,7 @@ - directory and use the configuration files from the - CHROOT_DIR directory. - Only absolute paths are supported. -+ No SELINUX support. - - - -diff --git a/man/userdel.8.xml b/man/userdel.8.xml -index 32851f11..de8eff24 100644 ---- a/man/userdel.8.xml -+++ b/man/userdel.8.xml -@@ -120,6 +120,7 @@ - directory and use the configuration files from the - CHROOT_DIR directory. - Only absolute paths are supported. -+ No SELINUX support. - - - -diff --git a/man/usermod.8.xml b/man/usermod.8.xml -index 61b5e3a9..2c704ab5 100644 ---- a/man/usermod.8.xml -+++ b/man/usermod.8.xml -@@ -337,6 +337,7 @@ - directory and use the configuration files from the - CHROOT_DIR directory. - Only absolute paths are supported. -+ No SELINUX support. - - - -diff --git a/man/vipw.8.xml b/man/vipw.8.xml -index fb80582b..975fba37 100644 ---- a/man/vipw.8.xml -+++ b/man/vipw.8.xml -@@ -120,6 +120,7 @@ - directory and use the configuration files from the - CHROOT_DIR directory. - Only absolute paths are supported. -+ No SELINUX support. - - - --- -2.50.0 - diff --git a/shadow-utils.spec b/shadow-utils.spec index 483eb21..c6773d9 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -24,8 +24,6 @@ Source7: passwd.pamd Patch0: shadow-4.15.0-manfix.patch # Probably non-upstreamable Patch1: shadow-4.18.0-account-tools-setuid.patch -# https://github.com/shadow-maint/shadow/commit/db0e0b9112332a45131912021317ab5ab4fd6e40 -Patch2: shadow-4.18.0-selinux-chroot-prefix.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -271,6 +269,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Tue Nov 25 2025 Adam Williamson - 2:4.18.0-7 +- Also revert changes from -4 (last known good was -3) + * Tue Nov 25 2025 Adam Williamson - 2:4.18.0-6 - Revert changes from -5 (they were only meant for testing) From d39147a22233042f440eae625add65ddefeaa4bc Mon Sep 17 00:00:00 2001 From: Adam Williamson Date: Tue, 25 Nov 2025 13:25:22 -0800 Subject: [PATCH 118/134] Really bump release, d'oh --- shadow-utils.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index c6773d9..1769e3c 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.18.0 -Release: 6%{?dist} +Release: 7%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow From 43599b7b5e1d8f42c88fd974404fbb9bbb69a21c Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Fri, 9 Jan 2026 14:55:44 +0100 Subject: [PATCH 119/134] Rebase to version 4.19.0 Resolves: #2426288 and #2249524 Signed-off-by: Iker Pedrosa --- .gitignore | 2 + ...> shadow-4.19.0-account-tools-setuid.patch | 113 +++++++++--------- shadow-utils.spec | 16 ++- sources | 4 +- 4 files changed, 69 insertions(+), 66 deletions(-) rename shadow-4.18.0-account-tools-setuid.patch => shadow-4.19.0-account-tools-setuid.patch (73%) diff --git a/.gitignore b/.gitignore index f4e82f2..0ceb6c8 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,5 @@ shadow-4.1.4.2.tar.bz2 /shadow-4.17.4.tar.xz.asc /shadow-4.18.0.tar.xz /shadow-4.18.0.tar.xz.asc +/shadow-4.19.0.tar.xz +/shadow-4.19.0.tar.xz.asc diff --git a/shadow-4.18.0-account-tools-setuid.patch b/shadow-4.19.0-account-tools-setuid.patch similarity index 73% rename from shadow-4.18.0-account-tools-setuid.patch rename to shadow-4.19.0-account-tools-setuid.patch index 9c018f7..9452582 100644 --- a/shadow-4.18.0-account-tools-setuid.patch +++ b/shadow-4.19.0-account-tools-setuid.patch @@ -1,7 +1,7 @@ -diff -up shadow-4.18.0-rc1/src/chpasswd.c.account-tools-setuid shadow-4.18.0-rc1/src/chpasswd.c ---- shadow-4.18.0-rc1/src/chpasswd.c.account-tools-setuid 2025-06-08 15:58:36.650175673 +0200 -+++ shadow-4.18.0-rc1/src/chpasswd.c 2025-06-09 10:09:17.902939220 +0200 -@@ -448,9 +448,11 @@ int main (int argc, char **argv) +diff -up shadow-4.19.0-rc1/src/chpasswd.c.account-tools-setuid shadow-4.19.0-rc1/src/chpasswd.c +--- shadow-4.19.0-rc1/src/chpasswd.c.account-tools-setuid 2025-12-07 16:56:38.563285789 +0100 ++++ shadow-4.19.0-rc1/src/chpasswd.c 2025-12-09 14:54:29.232282499 +0100 +@@ -466,9 +466,11 @@ int main (int argc, char **argv) char *newpwd; const char *salt; @@ -13,7 +13,7 @@ diff -up shadow-4.18.0-rc1/src/chpasswd.c.account-tools-setuid shadow-4.18.0-rc1 bool errors = false; intmax_t line = 0; -@@ -474,19 +476,23 @@ int main (int argc, char **argv) +@@ -495,19 +497,23 @@ int main (int argc, char **argv) process_root_flag ("-R", argc, argv); prefix = process_prefix_flag ("-P", argc, argv); @@ -37,7 +37,7 @@ diff -up shadow-4.18.0-rc1/src/chpasswd.c.account-tools-setuid shadow-4.18.0-rc1 { is_shadow_pwd = spw_file_present (); -@@ -543,6 +549,7 @@ int main (int argc, char **argv) +@@ -562,6 +568,7 @@ int main (int argc, char **argv) } newpwd = cp; @@ -45,15 +45,15 @@ diff -up shadow-4.18.0-rc1/src/chpasswd.c.account-tools-setuid shadow-4.18.0-rc1 #ifdef USE_PAM if (use_pam) { if (do_pam_passwd_non_interactive (Prog, name, newpwd) != 0) { -@@ -553,6 +560,7 @@ int main (int argc, char **argv) +@@ -572,6 +579,7 @@ int main (int argc, char **argv) } } else #endif /* USE_PAM */ +#endif /* ACCT_TOOLS_SETUID */ { - const struct spwd *sp; - struct spwd newsp; -@@ -672,9 +680,11 @@ int main (int argc, char **argv) + + /* +@@ -706,9 +714,11 @@ int main (int argc, char **argv) * password database. */ if (errors) { @@ -65,8 +65,8 @@ diff -up shadow-4.18.0-rc1/src/chpasswd.c.account-tools-setuid shadow-4.18.0-rc1 { fprintf (stderr, _("%s: error detected, changes ignored\n"), -@@ -683,9 +693,11 @@ int main (int argc, char **argv) - fail_exit (1); +@@ -717,9 +727,11 @@ int main (int argc, char **argv) + fail_exit (1, process_selinux); } +#ifdef ACCT_TOOLS_SETUID @@ -76,10 +76,10 @@ diff -up shadow-4.18.0-rc1/src/chpasswd.c.account-tools-setuid shadow-4.18.0-rc1 +#endif /* ACCT_TOOLS_SETUID */ { /* Save the changes */ - close_files (); -diff -up shadow-4.18.0-rc1/src/groupmems.c.account-tools-setuid shadow-4.18.0-rc1/src/groupmems.c ---- shadow-4.18.0-rc1/src/groupmems.c.account-tools-setuid 2025-06-08 15:58:36.651250652 +0200 -+++ shadow-4.18.0-rc1/src/groupmems.c 2025-06-09 10:08:59.836763261 +0200 + close_files (&flags); +diff -up shadow-4.19.0-rc1/src/groupmems.c.account-tools-setuid shadow-4.19.0-rc1/src/groupmems.c +--- shadow-4.19.0-rc1/src/groupmems.c.account-tools-setuid 2025-12-07 16:56:38.564285805 +0100 ++++ shadow-4.19.0-rc1/src/groupmems.c 2025-12-09 14:57:23.767054141 +0100 @@ -14,9 +14,11 @@ #include #include @@ -91,17 +91,17 @@ diff -up shadow-4.18.0-rc1/src/groupmems.c.account-tools-setuid shadow-4.18.0-rc +#endif /* ACCT_TOOLS_SETUID */ #include - #include "alloc/x/xmalloc.h" -@@ -417,6 +419,7 @@ static void process_flags (int argc, cha - static void check_perms (void) + #include "alloc/malloc.h" +@@ -432,6 +434,7 @@ static void + check_perms(MAYBE_UNUSED bool process_selinux) { if (!list) { +#ifdef ACCT_TOOLS_SETUID #ifdef USE_PAM pam_handle_t *pamh = NULL; int retval; -@@ -450,7 +453,8 @@ static void check_perms (void) - fail_exit (1); +@@ -465,7 +468,8 @@ check_perms(MAYBE_UNUSED bool process_se + fail_exit (1, process_selinux); } (void) pam_end (pamh, retval); -#endif @@ -110,10 +110,10 @@ diff -up shadow-4.18.0-rc1/src/groupmems.c.account-tools-setuid shadow-4.18.0-rc } } -diff -up shadow-4.18.0-rc1/src/newusers.c.account-tools-setuid shadow-4.18.0-rc1/src/newusers.c ---- shadow-4.18.0-rc1/src/newusers.c.account-tools-setuid 2025-06-08 15:58:36.652250643 +0200 -+++ shadow-4.18.0-rc1/src/newusers.c 2025-06-09 10:08:59.836928828 +0200 -@@ -67,6 +67,7 @@ +diff -up shadow-4.19.0-rc1/src/newusers.c.account-tools-setuid shadow-4.19.0-rc1/src/newusers.c +--- shadow-4.19.0-rc1/src/newusers.c.account-tools-setuid 2025-12-07 16:56:38.565285821 +0100 ++++ shadow-4.19.0-rc1/src/newusers.c 2025-12-09 15:07:40.115500988 +0100 +@@ -74,6 +74,7 @@ struct option_flags { static const char Prog[] = "newusers"; static bool rflg = false; /* create a system account */ @@ -121,7 +121,7 @@ diff -up shadow-4.18.0-rc1/src/newusers.c.account-tools-setuid shadow-4.18.0-rc1 #ifndef USE_PAM static /*@null@*//*@observer@*/char *crypt_method = NULL; #define cflg (NULL != crypt_method) -@@ -83,6 +84,7 @@ static long bcrypt_rounds = 13; +@@ -90,6 +91,7 @@ static long bcrypt_rounds = 13; static long yescrypt_cost = 5; #endif /* USE_YESCRYPT */ #endif /* !USE_PAM */ @@ -129,7 +129,7 @@ diff -up shadow-4.18.0-rc1/src/newusers.c.account-tools-setuid shadow-4.18.0-rc1 static bool is_shadow; #ifdef SHADOWGRP -@@ -105,9 +107,11 @@ NORETURN static void fail_exit (int); +@@ -112,9 +114,11 @@ NORETURN static void fail_exit (int, boo static int add_group (const char *, const char *, gid_t *, gid_t); static int get_user_id (const char *, uid_t *); static int add_user (const char *, uid_t, gid_t); @@ -139,9 +139,9 @@ diff -up shadow-4.18.0-rc1/src/newusers.c.account-tools-setuid shadow-4.18.0-rc1 #endif /* !USE_PAM */ +#endif /* !ACCT_TOOLS_SETUID */ static int add_passwd (struct passwd *, const char *); - static void process_flags (int argc, char **argv); + static void process_flags (int argc, char **argv, struct option_flags *flags); static void check_flags (void); -@@ -129,6 +133,7 @@ static void usage (int status) +@@ -136,6 +140,7 @@ static void usage (int status) "Options:\n"), Prog); (void) fputs (_(" -b, --badname allow bad names\n"), usageout); @@ -149,7 +149,7 @@ diff -up shadow-4.18.0-rc1/src/newusers.c.account-tools-setuid shadow-4.18.0-rc1 #ifndef USE_PAM (void) fprintf (usageout, _(" -c, --crypt-method METHOD the crypt method (one of %s)\n"), -@@ -144,9 +149,11 @@ static void usage (int status) +@@ -151,9 +156,11 @@ static void usage (int status) #endif ); #endif /* !USE_PAM */ @@ -161,7 +161,7 @@ diff -up shadow-4.18.0-rc1/src/newusers.c.account-tools-setuid shadow-4.18.0-rc1 #ifndef USE_PAM #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT\n" -@@ -154,6 +161,7 @@ static void usage (int status) +@@ -161,6 +168,7 @@ static void usage (int status) usageout); #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ #endif /* !USE_PAM */ @@ -169,7 +169,7 @@ diff -up shadow-4.18.0-rc1/src/newusers.c.account-tools-setuid shadow-4.18.0-rc1 (void) fputs ("\n", usageout); exit (status); -@@ -419,6 +427,7 @@ static int add_user (const char *name, u +@@ -426,6 +434,7 @@ static int add_user (const char *name, u return (pw_update (&pwent) == 0) ? -1 : 0; } @@ -177,7 +177,7 @@ diff -up shadow-4.18.0-rc1/src/newusers.c.account-tools-setuid shadow-4.18.0-rc1 #ifndef USE_PAM /* * update_passwd - update the password in the passwd entry -@@ -471,6 +480,7 @@ static int update_passwd (struct passwd +@@ -478,6 +487,7 @@ static int update_passwd (struct passwd return 0; } #endif /* !USE_PAM */ @@ -185,7 +185,7 @@ diff -up shadow-4.18.0-rc1/src/newusers.c.account-tools-setuid shadow-4.18.0-rc1 /* * add_passwd - add or update the encrypted password -@@ -479,10 +489,13 @@ static int add_passwd (struct passwd *pw +@@ -487,10 +497,13 @@ add_passwd(struct passwd *pwd, MAYBE_UNU { const struct spwd *sp; struct spwd spent; @@ -199,7 +199,7 @@ diff -up shadow-4.18.0-rc1/src/newusers.c.account-tools-setuid shadow-4.18.0-rc1 #ifndef USE_PAM void *crypt_arg = NULL; if (NULL != crypt_method) { -@@ -520,13 +533,14 @@ static int add_passwd (struct passwd *pw +@@ -528,13 +541,14 @@ add_passwd(struct passwd *pwd, MAYBE_UNU return update_passwd (pwd, password); } #endif /* USE_PAM */ @@ -215,7 +215,7 @@ diff -up shadow-4.18.0-rc1/src/newusers.c.account-tools-setuid shadow-4.18.0-rc1 if (NULL != sp) { spent = *sp; if ( (NULL != crypt_method) -@@ -563,7 +577,7 @@ static int add_passwd (struct passwd *pw +@@ -571,7 +585,7 @@ add_passwd(struct passwd *pwd, MAYBE_UNU if (!streq(pwd->pw_passwd, "x")) { return update_passwd (pwd, password); } @@ -224,7 +224,7 @@ diff -up shadow-4.18.0-rc1/src/newusers.c.account-tools-setuid shadow-4.18.0-rc1 /* * If there is already a shadow entry, do not touch it. * If there is already a passwd entry with a password, do not -@@ -574,14 +588,14 @@ static int add_passwd (struct passwd *pw +@@ -582,14 +596,14 @@ add_passwd(struct passwd *pwd, MAYBE_UNU || !streq(pwd->pw_passwd, "x")) { return 0; } @@ -241,14 +241,14 @@ diff -up shadow-4.18.0-rc1/src/newusers.c.account-tools-setuid shadow-4.18.0-rc1 if ((crypt_method != NULL) && streq(crypt_method, "NONE")) { spent.sp_pwdp = (char *)password; } else { -@@ -626,35 +640,41 @@ static int add_passwd (struct passwd *pw - static void process_flags (int argc, char **argv) +@@ -647,32 +647,38 @@ add_passwd(struct passwd *pwd, MAYBE_UNU + static void process_flags (int argc, char **argv, struct option_flags *flags) { int c; +#ifndef ACCT_TOOLS_SETUID #ifndef USE_PAM #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) - int bad_s; + int bad_s; #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ #endif /* !USE_PAM */ +#endif /* !ACCT_TOOLS_SETUID */ @@ -277,15 +277,12 @@ diff -up shadow-4.18.0-rc1/src/newusers.c.account-tools-setuid shadow-4.18.0-rc1 +#if !defined(ACCT_TOOLS_SETUID) && !defined(USE_PAM) #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) "c:bhrs:", - #else /* !USE_SHA_CRYPT && !USE_BCRYPT && !USE_YESCRYPT */ +-#else /* !USE_SHA_CRYPT && !USE_BCRYPT && !USE_YESCRYPT */ ++#else /* !ACCT_TOOLS_SETUID && !USE_PAM */ "c:bhr", #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ --#else /* USE_PAM */ -+#else /* !ACCT_TOOLS_SETUID && !USE_PAM */ - "bhr", - #endif - long_options, NULL)) != -1) { -@@ -662,11 +682,13 @@ static void process_flags (int argc, cha + #else /* USE_PAM */ +@@ -670,11 +690,13 @@ static void process_flags (int argc, cha case 'b': allow_bad_names = true; break; @@ -299,15 +296,15 @@ diff -up shadow-4.18.0-rc1/src/newusers.c.account-tools-setuid shadow-4.18.0-rc1 case 'h': usage (EXIT_SUCCESS); break; -@@ -675,6 +697,7 @@ static void process_flags (int argc, cha - break; +@@ -684,6 +706,7 @@ static void process_flags (int argc, cha case 'R': /* no-op, handled in process_root_flag () */ + flags->chroot = true; break; +#ifndef ACCT_TOOLS_SETUID #ifndef USE_PAM #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) case 's': -@@ -714,6 +737,7 @@ static void process_flags (int argc, cha +@@ -723,6 +746,7 @@ static void process_flags (int argc, cha break; #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ #endif /* !USE_PAM */ @@ -315,7 +312,7 @@ diff -up shadow-4.18.0-rc1/src/newusers.c.account-tools-setuid shadow-4.18.0-rc1 default: usage (EXIT_FAILURE); break; -@@ -746,6 +770,7 @@ static void process_flags (int argc, cha +@@ -755,6 +779,7 @@ static void process_flags (int argc, cha */ static void check_flags (void) { @@ -323,7 +320,7 @@ diff -up shadow-4.18.0-rc1/src/newusers.c.account-tools-setuid shadow-4.18.0-rc1 #ifndef USE_PAM #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) if (sflg && !cflg) { -@@ -778,6 +803,7 @@ static void check_flags (void) +@@ -787,6 +812,7 @@ static void check_flags (void) } } #endif /* !USE_PAM */ @@ -331,7 +328,7 @@ diff -up shadow-4.18.0-rc1/src/newusers.c.account-tools-setuid shadow-4.18.0-rc1 } /* -@@ -1066,12 +1092,14 @@ int main (int argc, char **argv) +@@ -1065,12 +1091,14 @@ int main (int argc, char **argv) intmax_t line = 0; uid_t uid; gid_t gid; @@ -343,10 +340,10 @@ diff -up shadow-4.18.0-rc1/src/newusers.c.account-tools-setuid shadow-4.18.0-rc1 size_t nusers = 0; #endif /* USE_PAM */ +#endif /* ACCT_TOOLS_SETUID */ + struct option_flags flags = {.chroot = false}; + bool process_selinux; - log_set_progname(Prog); - log_set_logfd(stderr); -@@ -1191,6 +1219,7 @@ int main (int argc, char **argv) +@@ -1193,6 +1221,7 @@ int main (int argc, char **argv) } newpw = *pw; @@ -359,10 +356,10 @@ diff -up shadow-4.18.0-rc1/src/newusers.c.account-tools-setuid shadow-4.18.0-rc1 passwords[nusers-1] = xstrdup(fields[1]); #endif /* USE_PAM */ +#endif /* ACCT_TOOLS_SETUID */ - if (add_passwd (&newpw, fields[1]) != 0) { + if (!streq(fields[1], "") && add_passwd(&newpw, fields[1]) != 0) { fprintf (stderr, _("%s: line %jd: can't update password\n"), -@@ -1323,6 +1353,7 @@ int main (int argc, char **argv) +@@ -1321,6 +1351,7 @@ int main (int argc, char **argv) nscd_flush_cache ("group"); sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP); diff --git a/shadow-utils.spec b/shadow-utils.spec index 1769e3c..9aff11f 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,12 +1,12 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils -Version: 4.18.0 -Release: 7%{?dist} +Version: 4.19.0 +Release: 1%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow -Source0: https://github.com/shadow-maint/shadow/releases/download/4.18.0/shadow-4.18.0.tar.xz -Source1: https://github.com/shadow-maint/shadow/releases/download/4.18.0/shadow-4.18.0.tar.xz.asc +Source0: https://github.com/shadow-maint/shadow/releases/download/4.19.0/shadow-4.19.0.tar.xz +Source1: https://github.com/shadow-maint/shadow/releases/download/4.19.0/shadow-4.19.0.tar.xz.asc Source2: shadow-utils.useradd Source3: shadow-utils.login.defs Source4: shadow-bsd.txt @@ -23,7 +23,7 @@ Source7: passwd.pamd # Misc manual page changes - non-upstreamable Patch0: shadow-4.15.0-manfix.patch # Probably non-upstreamable -Patch1: shadow-4.18.0-account-tools-setuid.patch +Patch1: shadow-4.19.0-account-tools-setuid.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -101,7 +101,7 @@ Requires: shadow-utils-subid = %{epoch}:%{version}-%{release} Development files for shadow-utils-subid. %prep -%autosetup -p 1 -S git -n shadow-4.18.0 +%autosetup -p 1 -S git -n shadow-4.19.0 iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -269,6 +269,10 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Fri Jan 9 2026 Iker Pedrosa - 2:4.19.0-1 +- Rebase to version 4.19.0 + Resolves: #2426288 and #2249524 + * Tue Nov 25 2025 Adam Williamson - 2:4.18.0-7 - Also revert changes from -4 (last known good was -3) diff --git a/sources b/sources index 8e3da98..22ae907 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (shadow-4.18.0.tar.xz) = e724670362949ccb570bb300322eb280c28ad609d631072b8db15a5e6eeba9fb9ac5d3df1df270f8b894235e4995b56c0e8f9aadb34d66bb5cea9b7a4f55e6ce -SHA512 (shadow-4.18.0.tar.xz.asc) = bb82b3d54eec0f11ace57609281974b315bba1240eafdae3b6513c7d7dfbcf10c3ae855c74c9eae33539709072046787e4b3e86dfb8bbfbf4bf23446daeb3422 +SHA512 (shadow-4.19.0.tar.xz) = 0846c34f426101213ab6277bbcdc58c28b3a54df2f68d1c1addcc8c5aa79ce3e15d5d8dfcb9cc6dbd1b758e0cd8676c68ca65268f5a037d4c24aa7d358c9a390 +SHA512 (shadow-4.19.0.tar.xz.asc) = 34c1a764d06a5d24533cbb57310de7462eb632c1de904901699d48f44401b1b1f4751db35f2b0e2b9a057cf1a777ccddbae4bc6b19a6db865ebc3e30fde0d060 From 19e27b9aa53dde8f63e79bde6d7a7cdb2725a875 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Fri, 9 Jan 2026 15:01:29 +0100 Subject: [PATCH 120/134] Enable unit-tests Signed-off-by: Iker Pedrosa --- shadow-utils.spec | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index 9aff11f..78bf8a9 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.19.0 -Release: 1%{?dist} +Release: 2%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -45,6 +45,7 @@ BuildRequires: git BuildRequires: itstool BuildRequires: libacl-devel BuildRequires: libattr-devel +BuildRequires: libcmocka-devel BuildRequires: libeconf-devel BuildRequires: libselinux-devel >= 1.25.2-1 BuildRequires: libsemanage-devel @@ -130,6 +131,9 @@ autoreconf --without-sssd %make_build +%check +make check + %install %make_install gnulocaledir=$RPM_BUILD_ROOT%{_datadir}/locale MKINSTALLDIRS=`pwd`/mkinstalldirs install -d -m 755 $RPM_BUILD_ROOT%{_sysconfdir}/default @@ -269,6 +273,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Fri Jan 9 2026 Iker Pedrosa - 2:4.19.0-2 +- Enable unit-tests + * Fri Jan 9 2026 Iker Pedrosa - 2:4.19.0-1 - Rebase to version 4.19.0 Resolves: #2426288 and #2249524 From f47e36e72a473fbb90a92bc73f63042fea7e87df Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Mon, 12 Jan 2026 11:42:00 +0100 Subject: [PATCH 121/134] useradd: Support config for creating home dirs as Btrfs subvolumes Signed-off-by: Iker Pedrosa --- shadow-4-19-useradd-support-btrfs.patch | 149 ++++++++++++++++++++++++ shadow-utils.spec | 7 +- 2 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 shadow-4-19-useradd-support-btrfs.patch diff --git a/shadow-4-19-useradd-support-btrfs.patch b/shadow-4-19-useradd-support-btrfs.patch new file mode 100644 index 0000000..b801289 --- /dev/null +++ b/shadow-4-19-useradd-support-btrfs.patch @@ -0,0 +1,149 @@ +From 3e8c105f0703264e947d8c034b90419794955d49 Mon Sep 17 00:00:00 2001 +From: Hadi Chokr +Date: Fri, 12 Dec 2025 11:18:06 +0100 +Subject: [PATCH] src/useradd: Support config for creating home dirs as Btrfs + subvolumes + +Closes: #1162 + +Co-authored-by: Neal Gompa +Signed-off-by: Hadi Chokr +Signed-off-by: Neal Gompa +Reviewed-by: Alejandro Colomar +--- + man/useradd.8.xml | 27 +++++++++++++++++++++++++++ + src/useradd.c | 24 ++++++++++++++++++++++++ + 2 files changed, 51 insertions(+) + +diff --git a/man/useradd.8.xml b/man/useradd.8.xml +index e6db7f6d..c745a620 100644 +--- a/man/useradd.8.xml ++++ b/man/useradd.8.xml +@@ -134,6 +134,33 @@ + + + ++ ++ ++ ++ ++ ++ ++ Create the user's home directory as a Btrfs subvolume. ++ ++ ++ If this option is not specified, ++ useradd will follow the default behavior ++ defined by the variable ++ in /etc/default/useradd. ++ If this variable is not set, the default value is no. ++ ++ ++ When the command-line option ++ is specified, ++ a Btrfs subvolume is created ++ regardless of any configuration file settings. ++ ++ ++ Note: this feature works only if the underlying filesystem supports ++ Btrfs subvolumes. ++ ++ ++ + + + ,  COMMENT +diff --git a/src/useradd.c b/src/useradd.c +index 899efe3c..8433ed8a 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -114,6 +114,7 @@ static const char *def_shell = "/bin/bash"; + static const char *def_template = SKEL_DIR; + static const char *def_usrtemplate = USRSKELDIR; + static const char *def_create_mail_spool = "yes"; ++static const char *def_btrfs_subvolume_home = "no"; + static const char *def_log_init = "yes"; + + static long def_inactive = -1; +@@ -222,6 +223,7 @@ static bool home_added = false; + #define DSKEL "SKEL" + #define DUSRSKEL "USRSKEL" + #define DCREATE_MAIL_SPOOL "CREATE_MAIL_SPOOL" ++#define DBTRFS_SUBVOLUME_HOME "BTRFS_SUBVOLUME_HOME" + #define DLOG_INIT "LOG_INIT" + + /* local function prototypes */ +@@ -456,6 +458,7 @@ get_defaults(const struct option_flags *flags) + def_usrtemplate = xstrdup(ccp); + } + } ++ + /* + * Create by default user mail spool or not ? + */ +@@ -466,6 +469,15 @@ get_defaults(const struct option_flags *flags) + def_create_mail_spool = xstrdup(ccp); + } + ++ /* ++ * Create home directories as Btrfs subvolumes by default? ++ */ ++ else if (streq(buf, DBTRFS_SUBVOLUME_HOME)) { ++ if (streq(ccp, "")) ++ ccp = "no"; ++ def_btrfs_subvolume_home = xstrdup(ccp); ++ } ++ + /* + * By default do we add the user to the lastlog and faillog databases ? + */ +@@ -500,6 +512,7 @@ static void show_defaults (void) + printf ("SKEL=%s\n", def_template); + printf ("USRSKEL=%s\n", def_usrtemplate); + printf ("CREATE_MAIL_SPOOL=%s\n", def_create_mail_spool); ++ printf ("BTRFS_SUBVOLUME_HOME=%s\n", def_btrfs_subvolume_home); + printf ("LOG_INIT=%s\n", def_log_init); + } + +@@ -523,6 +536,7 @@ set_defaults(void) + bool out_skel = false; + bool out_usrskel = false; + bool out_create_mail_spool = false; ++ bool out_btrfs_subvolume_home = false; + bool out_log_init = false; + char buf[1024]; + char *new_file = NULL; +@@ -639,6 +653,11 @@ set_defaults(void) + DCREATE_MAIL_SPOOL "=%s\n", + def_create_mail_spool); + out_create_mail_spool = true; ++ } else if (!out_btrfs_subvolume_home && streq(buf, DBTRFS_SUBVOLUME_HOME)) { ++ fprintf(ofp, ++ DBTRFS_SUBVOLUME_HOME "=%s\n", ++ def_btrfs_subvolume_home); ++ out_btrfs_subvolume_home = true; + } else if (!out_log_init && streq(buf, DLOG_INIT)) { + fprintf(ofp, DLOG_INIT "=%s\n", def_log_init); + out_log_init = true; +@@ -673,6 +692,8 @@ set_defaults(void) + + if (!out_create_mail_spool) + fprintf (ofp, DCREATE_MAIL_SPOOL "=%s\n", def_create_mail_spool); ++ if (!out_btrfs_subvolume_home) ++ fprintf (ofp, DBTRFS_SUBVOLUME_HOME "=%s\n", def_btrfs_subvolume_home); + if (!out_log_init) + fprintf (ofp, DLOG_INIT "=%s\n", def_log_init); + /* +@@ -1431,6 +1452,9 @@ static void process_flags (int argc, char **argv, struct option_flags *flags) + } + } + ++ if (!subvolflg && strcaseeq(def_btrfs_subvolume_home, "yes")) ++ subvolflg = true; ++ + if (!gflg && !Nflg && !Uflg) { + /* Get the settings from login.defs */ + Uflg = getdef_bool ("USERGROUPS_ENAB"); +-- +2.52.0 + diff --git a/shadow-utils.spec b/shadow-utils.spec index 78bf8a9..f625b8e 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.19.0 -Release: 2%{?dist} +Release: 3%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -24,6 +24,8 @@ Source7: passwd.pamd Patch0: shadow-4.15.0-manfix.patch # Probably non-upstreamable Patch1: shadow-4.19.0-account-tools-setuid.patch +# https://github.com/shadow-maint/shadow/commit/3e8c105f0703264e947d8c034b90419794955d49 +Patch2: shadow-4-19-useradd-support-btrfs.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -273,6 +275,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Mon Jan 12 2026 Iker Pedrosa - 2:4.19.0-3 +- useradd: Support config for creating home dirs as Btrfs subvolumes + * Fri Jan 9 2026 Iker Pedrosa - 2:4.19.0-2 - Enable unit-tests From c78272db1abeab24ef3676dc669f5752bd571108 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Sat, 17 Jan 2026 17:57:49 +0000 Subject: [PATCH 122/134] Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild --- shadow-utils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index f625b8e..f58ceee 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.19.0 -Release: 3%{?dist} +Release: 4%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -275,6 +275,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Sat Jan 17 2026 Fedora Release Engineering - 2:4.19.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild + * Mon Jan 12 2026 Iker Pedrosa - 2:4.19.0-3 - useradd: Support config for creating home dirs as Btrfs subvolumes From be2ac1934789e9a3a5ac74f6803ac101ccb16791 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Mon, 26 Jan 2026 10:03:00 +0100 Subject: [PATCH 123/134] - chkhash.c: fix support for ! and * in hashes - usermod.c: add back optimizations Signed-off-by: Iker Pedrosa --- shadow-4.19.0-chkhash1.patch | 88 +++++++++++ shadow-4.19.0-chkhash2.patch | 137 ++++++++++++++++++ shadow-4.19.0-usermod-add-optimizations.patch | 75 ++++++++++ shadow-utils.spec | 12 +- 4 files changed, 311 insertions(+), 1 deletion(-) create mode 100644 shadow-4.19.0-chkhash1.patch create mode 100644 shadow-4.19.0-chkhash2.patch create mode 100644 shadow-4.19.0-usermod-add-optimizations.patch diff --git a/shadow-4.19.0-chkhash1.patch b/shadow-4.19.0-chkhash1.patch new file mode 100644 index 0000000..986f10b --- /dev/null +++ b/shadow-4.19.0-chkhash1.patch @@ -0,0 +1,88 @@ +From 87ec7a52ab25dd6e91253c274fd651f16844cf2a Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Wed, 7 Jan 2026 23:39:53 +0100 +Subject: [PATCH 1/2] lib/chkhash.c: is_valid_hash(): Accept a leading '!' + +A leading '!' means that the account is locked. + +Fixes: c44f1e096a19 (2025-07-20; "chpasswd: Check hash before write when using -e") +Link: +Link: +Reported-by: Chris Hofstaedtler +Reviewed-by: Chris Hofstaedtler +Cc: vinz +Signed-off-by: Alejandro Colomar +--- + lib/chkhash.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/lib/chkhash.c b/lib/chkhash.c +index 66870500..cb45f3aa 100644 +--- a/lib/chkhash.c ++++ b/lib/chkhash.c +@@ -7,6 +7,8 @@ + #include + #include + ++#include "string/strcmp/strprefix.h" ++ + + /* + * match_regex - return true if match, false if not +@@ -37,6 +39,8 @@ match_regex(const char *pattern, const char *string) + bool + is_valid_hash(const char *hash) + { ++ hash = strprefix(hash, "!") ?: hash; ++ + // Minimum hash length + if (strlen(hash) < 13) + return false; +-- +2.52.0 + + +From ddc2549f87e3001f663d5179e9b6d7fe2e1f3b3f Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Wed, 7 Jan 2026 23:44:26 +0100 +Subject: [PATCH 2/2] lib/chkhash.c: is_valid_hash(): Accept '*' as the hash + +This is widely accepted as an invalid hash, to remove password access +for an account (that is, no passwords will match the "hash"). + +Fixes: c44f1e096a19 (2025-07-20; "chpasswd: Check hash before write when using -e") +Closes: +Closes: +Reported-by: Chris Hofstaedtler +Reviewed-by: Chris Hofstaedtler +Cc: vinz +Signed-off-by: Alejandro Colomar +--- + lib/chkhash.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/lib/chkhash.c b/lib/chkhash.c +index cb45f3aa..71e0fb4e 100644 +--- a/lib/chkhash.c ++++ b/lib/chkhash.c +@@ -7,6 +7,7 @@ + #include + #include + ++#include "string/strcmp/streq.h" + #include "string/strcmp/strprefix.h" + + +@@ -41,6 +42,9 @@ is_valid_hash(const char *hash) + { + hash = strprefix(hash, "!") ?: hash; + ++ if (streq(hash, "*")) ++ return true; ++ + // Minimum hash length + if (strlen(hash) < 13) + return false; +-- +2.52.0 + diff --git a/shadow-4.19.0-chkhash2.patch b/shadow-4.19.0-chkhash2.patch new file mode 100644 index 0000000..1742544 --- /dev/null +++ b/shadow-4.19.0-chkhash2.patch @@ -0,0 +1,137 @@ +From 9b67543987e3d140c86f1b8e2b5db5c10d8bc3c5 Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Thu, 15 Jan 2026 01:11:52 +0100 +Subject: [PATCH 1/4] lib/chkhash.c: is_valid_hash(): Accept an empty hash + +It represents a passwordless account. +That is discouraged, but accepted. + +Fixes: c44f1e096a19 (2025-07-20; "chpasswd: Check hash before write when using -e") +Link: +Reported-by: Marc 'Zugschlus' Haber +Reported-by: "Serge E. Hallyn" +Reported-by: Adam Williamson +Co-authored-by: "Serge E. Hallyn" +Signed-off-by: Alejandro Colomar +--- + lib/chkhash.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/lib/chkhash.c b/lib/chkhash.c +index 71e0fb4e..d0a8dc01 100644 +--- a/lib/chkhash.c ++++ b/lib/chkhash.c +@@ -42,6 +42,10 @@ is_valid_hash(const char *hash) + { + hash = strprefix(hash, "!") ?: hash; + ++ // Passwordless account; discouraged ++ if (streq(hash, "")) ++ return true; ++ + if (streq(hash, "*")) + return true; + +-- +2.52.0 + + +From bce404a7a831de911cf20fc8d4c548957f70bc72 Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Thu, 15 Jan 2026 01:14:46 +0100 +Subject: [PATCH 2/4] lib/chkhash.c: is_valid_hash(): Update comment + +This checks the entire shadow(5) 2nd field, which is more than just +a hash. + +Reported-by: Tobias Stoeckmann +Signed-off-by: Alejandro Colomar +--- + lib/chkhash.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/lib/chkhash.c b/lib/chkhash.c +index d0a8dc01..1723f862 100644 +--- a/lib/chkhash.c ++++ b/lib/chkhash.c +@@ -31,9 +31,7 @@ match_regex(const char *pattern, const char *string) + + + /* +- * is_valid_hash - check if the given string is a valid password hash +- * +- * Returns true if the string appears to be a valid hash, false otherwise. ++ * is_valid_hash - check if the string is a valid shadow(5) 2nd field. + * + * regex from: https://man.archlinux.org/man/crypt.5.en + */ +-- +2.52.0 + + +From 9a86c515a1e7caeeb9e60fa63871170a2dfd98f0 Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Thu, 15 Jan 2026 01:24:10 +0100 +Subject: [PATCH 3/4] lib/chkhash.c: is_valid_hash(): Comment meaning of !hash + and * + +Signed-off-by: Alejandro Colomar +--- + lib/chkhash.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/lib/chkhash.c b/lib/chkhash.c +index 1723f862..101f2004 100644 +--- a/lib/chkhash.c ++++ b/lib/chkhash.c +@@ -38,12 +38,14 @@ match_regex(const char *pattern, const char *string) + bool + is_valid_hash(const char *hash) + { ++ // Password temporarily locked + hash = strprefix(hash, "!") ?: hash; + + // Passwordless account; discouraged + if (streq(hash, "")) + return true; + ++ // Password permanently locked (and forgotten) + if (streq(hash, "*")) + return true; + +-- +2.52.0 + + +From 6be13b2f84a2c1a0d0f4129b5258b4b443e7f86c Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Fri, 16 Jan 2026 01:52:32 +0100 +Subject: [PATCH 4/4] man/shadow.5.xml: Document "*" + +Signed-off-by: Alejandro Colomar +--- + man/shadow.5.xml | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/man/shadow.5.xml b/man/shadow.5.xml +index dc7fdfde..d3cc0398 100644 +--- a/man/shadow.5.xml ++++ b/man/shadow.5.xml +@@ -82,8 +82,12 @@ + If the password field begins with an exclamation mark !, + the password is locked. + The remaining characters on the +- line represent the password field before the password was +- locked. ++ line represent the password hash. ++ ++ ++ If the password hash consists of a star *, ++ password access is effectively disallowed; ++ this is because no password can produce a hash like this. + + + Refer to crypt +-- +2.52.0 + diff --git a/shadow-4.19.0-usermod-add-optimizations.patch b/shadow-4.19.0-usermod-add-optimizations.patch new file mode 100644 index 0000000..4a883e6 --- /dev/null +++ b/shadow-4.19.0-usermod-add-optimizations.patch @@ -0,0 +1,75 @@ +From 958b4859991e700b61af2f9e07e3aa87ad1d9218 Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Sat, 17 Jan 2026 00:56:21 +0100 +Subject: [PATCH] Revert "src/usermod.c: Remove optimizations" + +This wasn't only an optimization; it also skipped some checks that were +now spuriously triggering errors. We may be able to get rid of the +optimizations, but that will need more analysis. For now, let's revert +to a known-good state. + +Fixes: 6a8a25dc7de6 (2025-10-15; "src/usermod.c: Remove optimizations") +Reverts: 6a8a25dc7de6 (2025-10-15; "src/usermod.c: Remove optimizations") +Closes: +Reported-by: Adam Williamson +Signed-off-by: Alejandro Colomar +--- + src/usermod.c | 42 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 42 insertions(+) + +diff --git a/src/usermod.c b/src/usermod.c +index 7400bf84..7cd7a859 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -1391,6 +1391,48 @@ process_flags(int argc, char **argv, struct option_flags *flags) + } + #endif /* WITH_SELINUX */ + ++ if (user_newid == user_id) { ++ uflg = false; ++ oflg = false; ++ } ++ if (user_newgid == user_gid) { ++ gflg = false; ++ } ++ if ( (NULL != user_newshell) ++ && streq(user_newshell, user_shell)) { ++ sflg = false; ++ } ++ if (streq(user_newname, user_name)) { ++ lflg = false; ++ } ++ if (user_newinactive == user_inactive) { ++ fflg = false; ++ } ++ if (user_newexpire == user_expire) { ++ eflg = false; ++ } ++ if ( (NULL != user_newhome) ++ && streq(user_newhome, user_home)) { ++ dflg = false; ++ mflg = false; ++ } ++ if ( (NULL != user_newcomment) ++ && streq(user_newcomment, user_comment)) { ++ cflg = false; ++ } ++ ++ if (!(Uflg || uflg || sflg || pflg || mflg || Lflg || ++ lflg || Gflg || gflg || fflg || eflg || dflg || cflg ++#ifdef ENABLE_SUBIDS ++ || vflg || Vflg || wflg || Wflg ++#endif /* ENABLE_SUBIDS */ ++#ifdef WITH_SELINUX ++ || Zflg ++#endif /* WITH_SELINUX */ ++ )) { ++ exit (E_SUCCESS); ++ } ++ + if (!is_shadow_pwd && (eflg || fflg)) { + fprintf (stderr, + _("%s: shadow passwords required for -e and -f\n"), +-- +2.52.0 + diff --git a/shadow-utils.spec b/shadow-utils.spec index f58ceee..82ea3c4 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.19.0 -Release: 4%{?dist} +Release: 5%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -26,6 +26,12 @@ Patch0: shadow-4.15.0-manfix.patch Patch1: shadow-4.19.0-account-tools-setuid.patch # https://github.com/shadow-maint/shadow/commit/3e8c105f0703264e947d8c034b90419794955d49 Patch2: shadow-4-19-useradd-support-btrfs.patch +# https://github.com/shadow-maint/shadow/commit/3e8c105f0703264e947d8c034b90419794955d49 +Patch3: shadow-4.19.0-chkhash1.patch +# https://github.com/shadow-maint/shadow/commit/9b67543987e3d140c86f1b8e2b5db5c10d8bc3c5 +Patch4: shadow-4.19.0-chkhash2.patch +# https://github.com/shadow-maint/shadow/commit/958b4859991e700b61af2f9e07e3aa87ad1d9218 +Patch5: shadow-4.19.0-usermod-add-optimizations.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -275,6 +281,10 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Mon Jan 26 2026 Iker Pedrosa - 2:4.19.0-5 +- chkhash.c: fix support for ! and * in hashes +- usermod.c: add back optimizations + * Sat Jan 17 2026 Fedora Release Engineering - 2:4.19.0-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild From dac50e34f899a79c7dc94ef1a0f76a5af6ffcc8d Mon Sep 17 00:00:00 2001 From: Adam Williamson Date: Wed, 28 Jan 2026 11:21:11 -0800 Subject: [PATCH 124/134] chkhash.c: fix escaping in SHA-256 / SHA-512 / MD5 regexes Signed-off-by: Adam Williamson --- 1520.patch | 40 ++++++++++++++++++++++++++++++++++++++++ shadow-utils.spec | 10 +++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 1520.patch diff --git a/1520.patch b/1520.patch new file mode 100644 index 0000000..069eebb --- /dev/null +++ b/1520.patch @@ -0,0 +1,40 @@ +From b721cdd03daa3416127289da02fe781efb2562df Mon Sep 17 00:00:00 2001 +From: Adam Williamson +Date: Tue, 27 Jan 2026 15:11:07 -0800 +Subject: [PATCH] lib/chkhash.c: fix escaping in SHA-256 / SHA-512 / MD5 + regexes + +`\\n` inside square brackets doesn't include or exclude the +newline character. It includes or excludes a literal slash and +the literal character 'n'. + +Fixes: c44f1e096a19 (2025-07-20; "chpasswd: Check hash before write when using -e") +Closes: +Signed-off-by: Adam Williamson +--- + lib/chkhash.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/lib/chkhash.c b/lib/chkhash.c +index 101f2004e8..9123038ade 100644 +--- a/lib/chkhash.c ++++ b/lib/chkhash.c +@@ -62,15 +62,15 @@ is_valid_hash(const char *hash) + return true; + + // SHA-512: $6$ + salt + $ + 86-char hash +- if (match_regex("^\\$6\\$(rounds=[1-9][0-9]{3,8}\\$)?[^$:\\n]{1,16}\\$[./A-Za-z0-9]{86}$", hash)) ++ if (match_regex("^\\$6\\$(rounds=[1-9][0-9]{3,8}\\$)?[^$:\n]{1,16}\\$[./A-Za-z0-9]{86}$", hash)) + return true; + + // SHA-256: $5$ + salt + $ + 43-char hash +- if (match_regex("^\\$5\\$(rounds=[1-9][0-9]{3,8}\\$)?[^$:\\n]{1,16}\\$[./A-Za-z0-9]{43}$", hash)) ++ if (match_regex("^\\$5\\$(rounds=[1-9][0-9]{3,8}\\$)?[^$:\n]{1,16}\\$[./A-Za-z0-9]{43}$", hash)) + return true; + + // MD5: $1$ + salt + $ + 22-char hash +- if (match_regex("^\\$1\\$[^$:\\n]{1,8}\\$[./A-Za-z0-9]{22}$", hash)) ++ if (match_regex("^\\$1\\$[^$:\n]{1,8}\\$[./A-Za-z0-9]{22}$", hash)) + return true; + + // DES: exactly 13 characters from [A-Za-z0-9./] diff --git a/shadow-utils.spec b/shadow-utils.spec index 82ea3c4..de8a156 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.19.0 -Release: 5%{?dist} +Release: 6%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -32,6 +32,11 @@ Patch3: shadow-4.19.0-chkhash1.patch Patch4: shadow-4.19.0-chkhash2.patch # https://github.com/shadow-maint/shadow/commit/958b4859991e700b61af2f9e07e3aa87ad1d9218 Patch5: shadow-4.19.0-usermod-add-optimizations.patch +# https://github.com/shadow-maint/shadow/pull/1520 +# Approved by upstream for 4.19.3 this weekend: +# https://github.com/shadow-maint/shadow/issues/1521 +# Fixes the hash check to accept hashes with \ or n in the salt +Patch6: 1520.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -281,6 +286,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Tue Jan 27 2026 Adam Williamson - 2:4.19.0-6 +- chkhash.c: fix escaping in SHA-256 / SHA-512 / MD5 regexes + * Mon Jan 26 2026 Iker Pedrosa - 2:4.19.0-5 - chkhash.c: fix support for ! and * in hashes - usermod.c: add back optimizations From cf630b1c3cb7762caef5ffa0ce75446e7a5afb75 Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Mon, 19 Jan 2026 14:26:44 +0100 Subject: [PATCH 125/134] Remove unused patches There's no need to do a build just for this. Fallout from 799aaaa5088cde64c65f2897d9c335c52e4de0bc https://src.fedoraproject.org/rpms/shadow-utils/pull-request/25 --- ...3-newidmap-support-passing-pid-as-fd.patch | 441 ------------------ shadow-utils-configure-gshadow.patch | 20 - 2 files changed, 461 deletions(-) delete mode 100644 shadow-4.13-newidmap-support-passing-pid-as-fd.patch delete mode 100644 shadow-utils-configure-gshadow.patch diff --git a/shadow-4.13-newidmap-support-passing-pid-as-fd.patch b/shadow-4.13-newidmap-support-passing-pid-as-fd.patch deleted file mode 100644 index 37e0d41..0000000 --- a/shadow-4.13-newidmap-support-passing-pid-as-fd.patch +++ /dev/null @@ -1,441 +0,0 @@ -From 6974df39a708abf8bafbdfa2b7827e0f70f874cb Mon Sep 17 00:00:00 2001 -From: Serge Hallyn -Date: Mon, 6 Feb 2023 22:49:42 -0600 -Subject: [PATCH] newuidmap and newgidmap: support passing pid as fd - -Closes #635 - -newuidmap and newgidmap currently take an integner pid as -the first argument, determining the process id on which to -act. Accept also "fd:N", where N must be an open file -descriptor to the /proc/pid directory for the process to -act upon. This way, if you - -exec 10 ---- - lib/get_pid.c | 51 +++++++++++++++++++++++++++++++++++++++++++++ - lib/prototypes.h | 2 ++ - man/newgidmap.1.xml | 11 ++++++++++ - man/newuidmap.1.xml | 11 ++++++++++ - src/newgidmap.c | 41 ++++++++++++++---------------------- - src/newuidmap.c | 40 +++++++++++++---------------------- - 6 files changed, 106 insertions(+), 50 deletions(-) - -diff --git a/lib/get_pid.c b/lib/get_pid.c -index 10184bf0..ab91d158 100644 ---- a/lib/get_pid.c -+++ b/lib/get_pid.c -@@ -10,6 +10,9 @@ - - #include "prototypes.h" - #include "defines.h" -+#include -+#include -+#include - - int get_pid (const char *pidstr, pid_t *pid) - { -@@ -29,3 +32,51 @@ int get_pid (const char *pidstr, pid_t *pid) - return 1; - } - -+/* -+ * If use passed in fd:4 as an argument, then return the -+ * value '4', the fd to use. -+ */ -+int get_pidfd_from_fd(const char *pidfdstr) -+{ -+ long long int val; -+ char *endptr; -+ -+ errno = 0; -+ val = strtoll (pidfdstr, &endptr, 10); -+ if ( ('\0' == *pidfdstr) -+ || ('\0' != *endptr) -+ || (ERANGE == errno) -+ || (/*@+longintegral@*/val != (pid_t)val)/*@=longintegral@*/) { -+ return 0; -+ } -+ -+ return (int)val; -+} -+ -+int open_pidfd(const char *pidstr) -+{ -+ int proc_dir_fd; -+ int written; -+ char proc_dir_name[32]; -+ pid_t target; -+ -+ if (get_pid(pidstr, &target) == 0) -+ return -ENOENT; -+ -+ /* max string length is 6 + 10 + 1 + 1 = 18, allocate 32 bytes */ -+ written = snprintf(proc_dir_name, sizeof(proc_dir_name), "/proc/%u/", -+ target); -+ if ((written <= 0) || ((size_t)written >= sizeof(proc_dir_name))) { -+ fprintf(stderr, "snprintf of proc path failed for %u: %s\n", -+ target, strerror(errno)); -+ return -EINVAL; -+ } -+ -+ proc_dir_fd = open(proc_dir_name, O_DIRECTORY); -+ if (proc_dir_fd < 0) { -+ fprintf(stderr, _("Could not open proc directory for target %u: %s\n"), -+ target, strerror(errno)); -+ return -EINVAL; -+ } -+ return proc_dir_fd; -+} -diff --git a/lib/prototypes.h b/lib/prototypes.h -index 400d5b97..21df6f61 100644 ---- a/lib/prototypes.h -+++ b/lib/prototypes.h -@@ -160,6 +160,8 @@ extern int getlong (const char *numstr, /*@out@*/long int *result); - - /* get_pid.c */ - extern int get_pid (const char *pidstr, pid_t *pid); -+extern int get_pidfd_from_fd(const char *pidfdstr); -+extern int open_pidfd(const char *pidstr); - - /* getrange */ - extern int getrange (const char *range, -diff --git a/man/newgidmap.1.xml b/man/newgidmap.1.xml -index e4ebc69e..9b7683eb 100644 ---- a/man/newgidmap.1.xml -+++ b/man/newgidmap.1.xml -@@ -116,6 +116,17 @@ - - Note that newgidmap may be used only once for a given process. - -+ -+ Instead of an integer process id, the first argument may be -+ specified as fd:N, where the integer N -+ is the file descriptor number for the calling process's opened -+ file for /proc/[pid[. In this case, -+ newgidmap will use -+ openat2 -+ to open the gid_map file under that -+ directory, avoiding a TOCTTOU in case the process exits and -+ the pid is immediately reused. -+ - - - -diff --git a/man/newuidmap.1.xml b/man/newuidmap.1.xml -index f5cb5b48..ca917a77 100644 ---- a/man/newuidmap.1.xml -+++ b/man/newuidmap.1.xml -@@ -116,6 +116,17 @@ - - Note that newuidmap may be used only once for a given process. - -+ -+ Instead of an integer process id, the first argument may be -+ specified as fd:N, where the integer N -+ is the file descriptor number for the calling process's opened -+ file for /proc/[pid[. In this case, -+ newuidmap will use -+ openat2 -+ to open the uid_map file under that -+ directory, avoiding a TOCTTOU in case the process exits and -+ the pid is immediately reused. -+ - - - -diff --git a/src/newgidmap.c b/src/newgidmap.c -index 01d0fe90..d6d29725 100644 ---- a/src/newgidmap.c -+++ b/src/newgidmap.c -@@ -69,7 +69,7 @@ static void verify_ranges(struct passwd *pw, int ranges, - - static void usage(void) - { -- fprintf(stderr, _("usage: %s [ ] ... \n"), Prog); -+ fprintf(stderr, _("usage: %s [] [ ] ... \n"), Prog); - exit(EXIT_FAILURE); - } - -@@ -143,15 +143,12 @@ out: - */ - int main(int argc, char **argv) - { -- char proc_dir_name[32]; - char *target_str; -- pid_t target; - int proc_dir_fd; - int ranges; - struct map_range *mappings; - struct stat st; - struct passwd *pw; -- int written; - bool allow_setgroups = false; - - Prog = Basename (argv[0]); -@@ -168,25 +165,19 @@ int main(int argc, char **argv) - /* Find the process that needs its user namespace - * gid mapping set. - */ -- target_str = argv[1]; -- if (!get_pid(target_str, &target)) -- usage(); - -- /* max string length is 6 + 10 + 1 + 1 = 18, allocate 32 bytes */ -- written = snprintf(proc_dir_name, sizeof(proc_dir_name), "/proc/%u/", -- target); -- if ((written <= 0) || (written >= sizeof(proc_dir_name))) { -- fprintf(stderr, "%s: snprintf of proc path failed: %s\n", -- Prog, strerror(errno)); -- } -- -- proc_dir_fd = open(proc_dir_name, O_DIRECTORY); -- if (proc_dir_fd < 0) { -- fprintf(stderr, _("%s: Could not open proc directory for target %u\n"), -- Prog, target); -- return EXIT_FAILURE; -+ target_str = argv[1]; -+ if (strlen(target_str) > 3 && strncmp(target_str, "fd:", 3) == 0) { -+ /* the user passed in a /proc/pid fd for the process */ -+ target_str = &target_str[3]; -+ proc_dir_fd = get_pidfd_from_fd(target_str); -+ if (proc_dir_fd < 0) -+ usage(); -+ } else { -+ proc_dir_fd = open_pidfd(target_str); -+ if (proc_dir_fd < 0) -+ usage(); - } -- - /* Who am i? */ - pw = get_my_pwent (); - if (NULL == pw) { -@@ -200,8 +191,8 @@ int main(int argc, char **argv) - - /* Get the effective uid and effective gid of the target process */ - if (fstat(proc_dir_fd, &st) < 0) { -- fprintf(stderr, _("%s: Could not stat directory for target %u\n"), -- Prog, target); -+ fprintf(stderr, _("%s: Could not stat directory for process\n"), -+ Prog); - return EXIT_FAILURE; - } - -@@ -213,8 +204,8 @@ int main(int argc, char **argv) - (!getdef_bool("GRANT_AUX_GROUP_SUBIDS") && (getgid() != pw->pw_gid)) || - (pw->pw_uid != st.st_uid) || - (getgid() != st.st_gid)) { -- fprintf(stderr, _( "%s: Target %u is owned by a different user: uid:%lu pw_uid:%lu st_uid:%lu, gid:%lu pw_gid:%lu st_gid:%lu\n" ), -- Prog, target, -+ fprintf(stderr, _( "%s: Target process is owned by a different user: uid:%lu pw_uid:%lu st_uid:%lu, gid:%lu pw_gid:%lu st_gid:%lu\n" ), -+ Prog, - (unsigned long int)getuid(), (unsigned long int)pw->pw_uid, (unsigned long int)st.st_uid, - (unsigned long int)getgid(), (unsigned long int)pw->pw_gid, (unsigned long int)st.st_gid); - return EXIT_FAILURE; -diff --git a/src/newuidmap.c b/src/newuidmap.c -index e8798409..e99655c9 100644 ---- a/src/newuidmap.c -+++ b/src/newuidmap.c -@@ -64,7 +64,7 @@ static void verify_ranges(struct passwd *pw, int ranges, - - static void usage(void) - { -- fprintf(stderr, _("usage: %s [ ] ... \n"), Prog); -+ fprintf(stderr, _("usage: %s [|fd:] [ ] ... \n"), Prog); - exit(EXIT_FAILURE); - } - -@@ -73,15 +73,12 @@ static void usage(void) - */ - int main(int argc, char **argv) - { -- char proc_dir_name[32]; - char *target_str; -- pid_t target; - int proc_dir_fd; - int ranges; - struct map_range *mappings; - struct stat st; - struct passwd *pw; -- int written; - - Prog = Basename (argv[0]); - log_set_progname(Prog); -@@ -94,26 +91,20 @@ int main(int argc, char **argv) - if (argc < 2) - usage(); - -+ target_str = argv[1]; - /* Find the process that needs its user namespace - * uid mapping set. - */ -- target_str = argv[1]; -- if (!get_pid(target_str, &target)) -- usage(); -- -- /* max string length is 6 + 10 + 1 + 1 = 18, allocate 32 bytes */ -- written = snprintf(proc_dir_name, sizeof(proc_dir_name), "/proc/%u/", -- target); -- if ((written <= 0) || (written >= sizeof(proc_dir_name))) { -- fprintf(stderr, "%s: snprintf of proc path failed: %s\n", -- Prog, strerror(errno)); -- } -- -- proc_dir_fd = open(proc_dir_name, O_DIRECTORY); -- if (proc_dir_fd < 0) { -- fprintf(stderr, _("%s: Could not open proc directory for target %u\n"), -- Prog, target); -- return EXIT_FAILURE; -+ if (strlen(target_str) > 3 && strncmp(target_str, "fd:", 3) == 0) { -+ /* the user passed in a /proc/pid fd for the process */ -+ target_str = &target_str[3]; -+ proc_dir_fd = get_pidfd_from_fd(target_str); -+ if (proc_dir_fd < 0) -+ usage(); -+ } else { -+ proc_dir_fd = open_pidfd(target_str); -+ if (proc_dir_fd < 0) -+ usage(); - } - - /* Who am i? */ -@@ -129,8 +120,7 @@ int main(int argc, char **argv) - - /* Get the effective uid and effective gid of the target process */ - if (fstat(proc_dir_fd, &st) < 0) { -- fprintf(stderr, _("%s: Could not stat directory for target %u\n"), -- Prog, target); -+ fprintf(stderr, _("%s: Could not stat directory for target process\n"), Prog); - return EXIT_FAILURE; - } - -@@ -142,8 +132,8 @@ int main(int argc, char **argv) - (!getdef_bool("GRANT_AUX_GROUP_SUBIDS") && (getgid() != pw->pw_gid)) || - (pw->pw_uid != st.st_uid) || - (getgid() != st.st_gid)) { -- fprintf(stderr, _( "%s: Target process %u is owned by a different user: uid:%lu pw_uid:%lu st_uid:%lu, gid:%lu pw_gid:%lu st_gid:%lu\n" ), -- Prog, target, -+ fprintf(stderr, _( "%s: Target process is owned by a different user: uid:%lu pw_uid:%lu st_uid:%lu, gid:%lu pw_gid:%lu st_gid:%lu\n" ), -+ Prog, - (unsigned long int)getuid(), (unsigned long int)pw->pw_uid, (unsigned long int)st.st_uid, - (unsigned long int)getgid(), (unsigned long int)pw->pw_gid, (unsigned long int)st.st_gid); - return EXIT_FAILURE; --- -2.39.2 - -From 7ff33fae6f9cd79c0e012671c37a172e9a681d0b Mon Sep 17 00:00:00 2001 -From: Serge Hallyn -Date: Fri, 24 Feb 2023 13:52:32 -0600 -Subject: [PATCH] get_pidfd_from_fd: return -1 on error, not 0 - -Fixes: 6974df39a: newuidmap and newgidmap: support passing pid as fd -Signed-off-by: Serge Hallyn ---- - lib/get_pid.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/lib/get_pid.c b/lib/get_pid.c -index ab91d158..5b6d9da4 100644 ---- a/lib/get_pid.c -+++ b/lib/get_pid.c -@@ -35,6 +35,7 @@ int get_pid (const char *pidstr, pid_t *pid) - /* - * If use passed in fd:4 as an argument, then return the - * value '4', the fd to use. -+ * On error, return -1. - */ - int get_pidfd_from_fd(const char *pidfdstr) - { -@@ -47,7 +48,7 @@ int get_pidfd_from_fd(const char *pidfdstr) - || ('\0' != *endptr) - || (ERANGE == errno) - || (/*@+longintegral@*/val != (pid_t)val)/*@=longintegral@*/) { -- return 0; -+ return -1; - } - - return (int)val; --- -2.39.2 - -From 05e2adf509ba0e3779dae66a276b86927a8e1e0e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Vin=C3=ADcius=20dos=20Santos=20Oliveira?= - -Date: Fri, 24 Feb 2023 18:06:02 -0300 -Subject: [PATCH] Validate fds created by the user - -write_mapping() will do the following: - -openat(proc_dir_fd, map_file, O_WRONLY); - -An attacker could create a directory containing a symlink named -"uid_map" pointing to any file owned by root, and thus allow him to -overwrite any root-owned file. ---- - lib/get_pid.c | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - -diff --git a/lib/get_pid.c b/lib/get_pid.c -index 5b6d9da4..8e5e6014 100644 ---- a/lib/get_pid.c -+++ b/lib/get_pid.c -@@ -41,6 +41,8 @@ int get_pidfd_from_fd(const char *pidfdstr) - { - long long int val; - char *endptr; -+ struct stat st; -+ dev_t proc_st_dev, proc_st_rdev; - - errno = 0; - val = strtoll (pidfdstr, &endptr, 10); -@@ -51,6 +53,21 @@ int get_pidfd_from_fd(const char *pidfdstr) - return -1; - } - -+ if (stat("/proc/self/uid_map", &st) < 0) { -+ return -1; -+ } -+ -+ proc_st_dev = st.st_dev; -+ proc_st_rdev = st.st_rdev; -+ -+ if (fstat(val, &st) < 0) { -+ return -1; -+ } -+ -+ if (st.st_dev != proc_st_dev || st.st_rdev != proc_st_rdev) { -+ return -1; -+ } -+ - return (int)val; - } - --- -2.39.2 - diff --git a/shadow-utils-configure-gshadow.patch b/shadow-utils-configure-gshadow.patch deleted file mode 100644 index a983ce0..0000000 --- a/shadow-utils-configure-gshadow.patch +++ /dev/null @@ -1,20 +0,0 @@ -The missing #include causes the configure check to fail -spuriously, resulting in HAVE_SHADOWGRP not being defined. - -Submitted upstream: - -diff --git a/configure.ac b/configure.ac -index 924254a0c8171802..6c7d9839979e037d 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -116,6 +116,10 @@ if test "$ac_cv_header_shadow_h" = "yes"; then - ac_cv_libc_shadowgrp, - AC_RUN_IFELSE([AC_LANG_SOURCE([ - #include -+ #ifdef HAVE_GSHADOW_H -+ #include -+ #endif -+ int - main() - { - struct sgrp *sg = sgetsgent("test:x::"); From a85675911953dc0d1a9ecd8c606ea06e73903c22 Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Thu, 22 Jan 2026 15:25:57 +0100 Subject: [PATCH 126/134] Silence mixed-use-of-spaces-and-tabs There's no need to do a build just for this. Fallout from 4642a65eb4963253b1abd952aa727fcbb238df53 and fe4f9dc5c0ad3270c280392bb574748f7c49bf81 https://src.fedoraproject.org/rpms/shadow-utils/pull-request/25 --- shadow-utils.spec | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index de8a156..ec8df78 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -126,9 +126,9 @@ cp -a %{SOURCE6} man/login.defs.d/HOME_MODE.xml %build autoreconf %configure \ - --disable-account-tools-setuid \ - --enable-logind=no \ - --enable-man \ + --disable-account-tools-setuid \ + --enable-logind=no \ + --enable-man \ --enable-shadowgrp \ --enable-shared \ --with-audit \ @@ -140,7 +140,7 @@ autoreconf --with-yescrypt \ --without-libbsd \ --without-libcrack \ - --without-nscd \ + --without-nscd \ --without-sssd %make_build From 77fbaa4e9a6b97735947d575ade3f167fad09b59 Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Thu, 22 Jan 2026 15:21:36 +0100 Subject: [PATCH 127/134] Rebase to version 4.19.3 Resolves: #2426288 https://src.fedoraproject.org/rpms/shadow-utils/pull-request/27 --- .gitignore | 4 + 1520.patch | 40 --------- shadow-4.19.0-chkhash1.patch | 88 ------------------- shadow-4.19.0-usermod-add-optimizations.patch | 75 ---------------- ...hash2.patch => shadow-4.19.3-chkhash.patch | 65 ++++---------- shadow-utils.spec | 27 +++--- sources | 4 +- 7 files changed, 32 insertions(+), 271 deletions(-) delete mode 100644 1520.patch delete mode 100644 shadow-4.19.0-chkhash1.patch delete mode 100644 shadow-4.19.0-usermod-add-optimizations.patch rename shadow-4.19.0-chkhash2.patch => shadow-4.19.3-chkhash.patch (59%) diff --git a/.gitignore b/.gitignore index 0ceb6c8..7db552e 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,7 @@ shadow-4.1.4.2.tar.bz2 /shadow-4.18.0.tar.xz.asc /shadow-4.19.0.tar.xz /shadow-4.19.0.tar.xz.asc +/shadow-4.19.2.tar.xz +/shadow-4.19.2.tar.xz.asc +/shadow-4.19.3.tar.xz +/shadow-4.19.3.tar.xz.asc diff --git a/1520.patch b/1520.patch deleted file mode 100644 index 069eebb..0000000 --- a/1520.patch +++ /dev/null @@ -1,40 +0,0 @@ -From b721cdd03daa3416127289da02fe781efb2562df Mon Sep 17 00:00:00 2001 -From: Adam Williamson -Date: Tue, 27 Jan 2026 15:11:07 -0800 -Subject: [PATCH] lib/chkhash.c: fix escaping in SHA-256 / SHA-512 / MD5 - regexes - -`\\n` inside square brackets doesn't include or exclude the -newline character. It includes or excludes a literal slash and -the literal character 'n'. - -Fixes: c44f1e096a19 (2025-07-20; "chpasswd: Check hash before write when using -e") -Closes: -Signed-off-by: Adam Williamson ---- - lib/chkhash.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/lib/chkhash.c b/lib/chkhash.c -index 101f2004e8..9123038ade 100644 ---- a/lib/chkhash.c -+++ b/lib/chkhash.c -@@ -62,15 +62,15 @@ is_valid_hash(const char *hash) - return true; - - // SHA-512: $6$ + salt + $ + 86-char hash -- if (match_regex("^\\$6\\$(rounds=[1-9][0-9]{3,8}\\$)?[^$:\\n]{1,16}\\$[./A-Za-z0-9]{86}$", hash)) -+ if (match_regex("^\\$6\\$(rounds=[1-9][0-9]{3,8}\\$)?[^$:\n]{1,16}\\$[./A-Za-z0-9]{86}$", hash)) - return true; - - // SHA-256: $5$ + salt + $ + 43-char hash -- if (match_regex("^\\$5\\$(rounds=[1-9][0-9]{3,8}\\$)?[^$:\\n]{1,16}\\$[./A-Za-z0-9]{43}$", hash)) -+ if (match_regex("^\\$5\\$(rounds=[1-9][0-9]{3,8}\\$)?[^$:\n]{1,16}\\$[./A-Za-z0-9]{43}$", hash)) - return true; - - // MD5: $1$ + salt + $ + 22-char hash -- if (match_regex("^\\$1\\$[^$:\\n]{1,8}\\$[./A-Za-z0-9]{22}$", hash)) -+ if (match_regex("^\\$1\\$[^$:\n]{1,8}\\$[./A-Za-z0-9]{22}$", hash)) - return true; - - // DES: exactly 13 characters from [A-Za-z0-9./] diff --git a/shadow-4.19.0-chkhash1.patch b/shadow-4.19.0-chkhash1.patch deleted file mode 100644 index 986f10b..0000000 --- a/shadow-4.19.0-chkhash1.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 87ec7a52ab25dd6e91253c274fd651f16844cf2a Mon Sep 17 00:00:00 2001 -From: Alejandro Colomar -Date: Wed, 7 Jan 2026 23:39:53 +0100 -Subject: [PATCH 1/2] lib/chkhash.c: is_valid_hash(): Accept a leading '!' - -A leading '!' means that the account is locked. - -Fixes: c44f1e096a19 (2025-07-20; "chpasswd: Check hash before write when using -e") -Link: -Link: -Reported-by: Chris Hofstaedtler -Reviewed-by: Chris Hofstaedtler -Cc: vinz -Signed-off-by: Alejandro Colomar ---- - lib/chkhash.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/lib/chkhash.c b/lib/chkhash.c -index 66870500..cb45f3aa 100644 ---- a/lib/chkhash.c -+++ b/lib/chkhash.c -@@ -7,6 +7,8 @@ - #include - #include - -+#include "string/strcmp/strprefix.h" -+ - - /* - * match_regex - return true if match, false if not -@@ -37,6 +39,8 @@ match_regex(const char *pattern, const char *string) - bool - is_valid_hash(const char *hash) - { -+ hash = strprefix(hash, "!") ?: hash; -+ - // Minimum hash length - if (strlen(hash) < 13) - return false; --- -2.52.0 - - -From ddc2549f87e3001f663d5179e9b6d7fe2e1f3b3f Mon Sep 17 00:00:00 2001 -From: Alejandro Colomar -Date: Wed, 7 Jan 2026 23:44:26 +0100 -Subject: [PATCH 2/2] lib/chkhash.c: is_valid_hash(): Accept '*' as the hash - -This is widely accepted as an invalid hash, to remove password access -for an account (that is, no passwords will match the "hash"). - -Fixes: c44f1e096a19 (2025-07-20; "chpasswd: Check hash before write when using -e") -Closes: -Closes: -Reported-by: Chris Hofstaedtler -Reviewed-by: Chris Hofstaedtler -Cc: vinz -Signed-off-by: Alejandro Colomar ---- - lib/chkhash.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/lib/chkhash.c b/lib/chkhash.c -index cb45f3aa..71e0fb4e 100644 ---- a/lib/chkhash.c -+++ b/lib/chkhash.c -@@ -7,6 +7,7 @@ - #include - #include - -+#include "string/strcmp/streq.h" - #include "string/strcmp/strprefix.h" - - -@@ -41,6 +42,9 @@ is_valid_hash(const char *hash) - { - hash = strprefix(hash, "!") ?: hash; - -+ if (streq(hash, "*")) -+ return true; -+ - // Minimum hash length - if (strlen(hash) < 13) - return false; --- -2.52.0 - diff --git a/shadow-4.19.0-usermod-add-optimizations.patch b/shadow-4.19.0-usermod-add-optimizations.patch deleted file mode 100644 index 4a883e6..0000000 --- a/shadow-4.19.0-usermod-add-optimizations.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 958b4859991e700b61af2f9e07e3aa87ad1d9218 Mon Sep 17 00:00:00 2001 -From: Alejandro Colomar -Date: Sat, 17 Jan 2026 00:56:21 +0100 -Subject: [PATCH] Revert "src/usermod.c: Remove optimizations" - -This wasn't only an optimization; it also skipped some checks that were -now spuriously triggering errors. We may be able to get rid of the -optimizations, but that will need more analysis. For now, let's revert -to a known-good state. - -Fixes: 6a8a25dc7de6 (2025-10-15; "src/usermod.c: Remove optimizations") -Reverts: 6a8a25dc7de6 (2025-10-15; "src/usermod.c: Remove optimizations") -Closes: -Reported-by: Adam Williamson -Signed-off-by: Alejandro Colomar ---- - src/usermod.c | 42 ++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 42 insertions(+) - -diff --git a/src/usermod.c b/src/usermod.c -index 7400bf84..7cd7a859 100644 ---- a/src/usermod.c -+++ b/src/usermod.c -@@ -1391,6 +1391,48 @@ process_flags(int argc, char **argv, struct option_flags *flags) - } - #endif /* WITH_SELINUX */ - -+ if (user_newid == user_id) { -+ uflg = false; -+ oflg = false; -+ } -+ if (user_newgid == user_gid) { -+ gflg = false; -+ } -+ if ( (NULL != user_newshell) -+ && streq(user_newshell, user_shell)) { -+ sflg = false; -+ } -+ if (streq(user_newname, user_name)) { -+ lflg = false; -+ } -+ if (user_newinactive == user_inactive) { -+ fflg = false; -+ } -+ if (user_newexpire == user_expire) { -+ eflg = false; -+ } -+ if ( (NULL != user_newhome) -+ && streq(user_newhome, user_home)) { -+ dflg = false; -+ mflg = false; -+ } -+ if ( (NULL != user_newcomment) -+ && streq(user_newcomment, user_comment)) { -+ cflg = false; -+ } -+ -+ if (!(Uflg || uflg || sflg || pflg || mflg || Lflg || -+ lflg || Gflg || gflg || fflg || eflg || dflg || cflg -+#ifdef ENABLE_SUBIDS -+ || vflg || Vflg || wflg || Wflg -+#endif /* ENABLE_SUBIDS */ -+#ifdef WITH_SELINUX -+ || Zflg -+#endif /* WITH_SELINUX */ -+ )) { -+ exit (E_SUCCESS); -+ } -+ - if (!is_shadow_pwd && (eflg || fflg)) { - fprintf (stderr, - _("%s: shadow passwords required for -e and -f\n"), --- -2.52.0 - diff --git a/shadow-4.19.0-chkhash2.patch b/shadow-4.19.3-chkhash.patch similarity index 59% rename from shadow-4.19.0-chkhash2.patch rename to shadow-4.19.3-chkhash.patch index 1742544..6dfc159 100644 --- a/shadow-4.19.0-chkhash2.patch +++ b/shadow-4.19.3-chkhash.patch @@ -1,57 +1,20 @@ -From 9b67543987e3d140c86f1b8e2b5db5c10d8bc3c5 Mon Sep 17 00:00:00 2001 -From: Alejandro Colomar -Date: Thu, 15 Jan 2026 01:11:52 +0100 -Subject: [PATCH 1/4] lib/chkhash.c: is_valid_hash(): Accept an empty hash - -It represents a passwordless account. -That is discouraged, but accepted. - -Fixes: c44f1e096a19 (2025-07-20; "chpasswd: Check hash before write when using -e") -Link: -Reported-by: Marc 'Zugschlus' Haber -Reported-by: "Serge E. Hallyn" -Reported-by: Adam Williamson -Co-authored-by: "Serge E. Hallyn" -Signed-off-by: Alejandro Colomar ---- - lib/chkhash.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/lib/chkhash.c b/lib/chkhash.c -index 71e0fb4e..d0a8dc01 100644 ---- a/lib/chkhash.c -+++ b/lib/chkhash.c -@@ -42,6 +42,10 @@ is_valid_hash(const char *hash) - { - hash = strprefix(hash, "!") ?: hash; - -+ // Passwordless account; discouraged -+ if (streq(hash, "")) -+ return true; -+ - if (streq(hash, "*")) - return true; - --- -2.52.0 - - -From bce404a7a831de911cf20fc8d4c548957f70bc72 Mon Sep 17 00:00:00 2001 +From 4b2e669441438a6ae91c82a24c796894aa6a53b2 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Thu, 15 Jan 2026 01:14:46 +0100 -Subject: [PATCH 2/4] lib/chkhash.c: is_valid_hash(): Update comment +Subject: [PATCH 1/3] lib/chkhash.c: is_valid_hash(): Update comment This checks the entire shadow(5) 2nd field, which is more than just a hash. Reported-by: Tobias Stoeckmann Signed-off-by: Alejandro Colomar +(cherry picked from commit bce404a7a831de911cf20fc8d4c548957f70bc72) --- lib/chkhash.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/chkhash.c b/lib/chkhash.c -index d0a8dc01..1723f862 100644 +index 348dfe7478f8..48aaa417e9a9 100644 --- a/lib/chkhash.c +++ b/lib/chkhash.c @@ -31,9 +31,7 @@ match_regex(const char *pattern, const char *string) @@ -66,22 +29,23 @@ index d0a8dc01..1723f862 100644 * regex from: https://man.archlinux.org/man/crypt.5.en */ -- -2.52.0 +2.53.0 -From 9a86c515a1e7caeeb9e60fa63871170a2dfd98f0 Mon Sep 17 00:00:00 2001 +From b72386978e0c994c5efc91d548da68a8d97088ab Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Thu, 15 Jan 2026 01:24:10 +0100 -Subject: [PATCH 3/4] lib/chkhash.c: is_valid_hash(): Comment meaning of !hash +Subject: [PATCH 2/3] lib/chkhash.c: is_valid_hash(): Comment meaning of !hash and * Signed-off-by: Alejandro Colomar +(cherry picked from commit 9a86c515a1e7caeeb9e60fa63871170a2dfd98f0) --- lib/chkhash.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/chkhash.c b/lib/chkhash.c -index 1723f862..101f2004 100644 +index 48aaa417e9a9..9123038adef0 100644 --- a/lib/chkhash.c +++ b/lib/chkhash.c @@ -38,12 +38,14 @@ match_regex(const char *pattern, const char *string) @@ -100,21 +64,22 @@ index 1723f862..101f2004 100644 return true; -- -2.52.0 +2.53.0 -From 6be13b2f84a2c1a0d0f4129b5258b4b443e7f86c Mon Sep 17 00:00:00 2001 +From 4486e3e0f8b74e6af27b5dcb4114fd776afdd605 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Fri, 16 Jan 2026 01:52:32 +0100 -Subject: [PATCH 4/4] man/shadow.5.xml: Document "*" +Subject: [PATCH 3/3] man/shadow.5.xml: Document "*" Signed-off-by: Alejandro Colomar +(cherry picked from commit 6be13b2f84a2c1a0d0f4129b5258b4b443e7f86c) --- man/shadow.5.xml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/man/shadow.5.xml b/man/shadow.5.xml -index dc7fdfde..d3cc0398 100644 +index dc7fdfde542f..d3cc03982c47 100644 --- a/man/shadow.5.xml +++ b/man/shadow.5.xml @@ -82,8 +82,12 @@ @@ -133,5 +98,5 @@ index dc7fdfde..d3cc0398 100644 Refer to crypt -- -2.52.0 +2.53.0 diff --git a/shadow-utils.spec b/shadow-utils.spec index ec8df78..426f19b 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,12 +1,12 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils -Version: 4.19.0 -Release: 6%{?dist} +Version: 4.19.3 +Release: 1%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow -Source0: https://github.com/shadow-maint/shadow/releases/download/4.19.0/shadow-4.19.0.tar.xz -Source1: https://github.com/shadow-maint/shadow/releases/download/4.19.0/shadow-4.19.0.tar.xz.asc +Source0: https://github.com/shadow-maint/shadow/releases/download/4.19.3/shadow-4.19.3.tar.xz +Source1: https://github.com/shadow-maint/shadow/releases/download/4.19.3/shadow-4.19.3.tar.xz.asc Source2: shadow-utils.useradd Source3: shadow-utils.login.defs Source4: shadow-bsd.txt @@ -26,17 +26,8 @@ Patch0: shadow-4.15.0-manfix.patch Patch1: shadow-4.19.0-account-tools-setuid.patch # https://github.com/shadow-maint/shadow/commit/3e8c105f0703264e947d8c034b90419794955d49 Patch2: shadow-4-19-useradd-support-btrfs.patch -# https://github.com/shadow-maint/shadow/commit/3e8c105f0703264e947d8c034b90419794955d49 -Patch3: shadow-4.19.0-chkhash1.patch -# https://github.com/shadow-maint/shadow/commit/9b67543987e3d140c86f1b8e2b5db5c10d8bc3c5 -Patch4: shadow-4.19.0-chkhash2.patch -# https://github.com/shadow-maint/shadow/commit/958b4859991e700b61af2f9e07e3aa87ad1d9218 -Patch5: shadow-4.19.0-usermod-add-optimizations.patch -# https://github.com/shadow-maint/shadow/pull/1520 -# Approved by upstream for 4.19.3 this weekend: -# https://github.com/shadow-maint/shadow/issues/1521 -# Fixes the hash check to accept hashes with \ or n in the salt -Patch6: 1520.patch +# https://github.com/shadow-maint/shadow/commit/6be13b2f84a2c1a0d0f4129b5258b4b443e7f86c +Patch3: shadow-4.19.3-chkhash.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -115,7 +106,7 @@ Requires: shadow-utils-subid = %{epoch}:%{version}-%{release} Development files for shadow-utils-subid. %prep -%autosetup -p 1 -S git -n shadow-4.19.0 +%autosetup -p 1 -S git -n shadow-4.19.3 iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -286,6 +277,10 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Wed Feb 11 2026 Debarshi Ray - 2:4.19.3-1 +- Rebase to version 4.19.3 + Resolves: #2426288 + * Tue Jan 27 2026 Adam Williamson - 2:4.19.0-6 - chkhash.c: fix escaping in SHA-256 / SHA-512 / MD5 regexes diff --git a/sources b/sources index 22ae907..d12859f 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (shadow-4.19.0.tar.xz) = 0846c34f426101213ab6277bbcdc58c28b3a54df2f68d1c1addcc8c5aa79ce3e15d5d8dfcb9cc6dbd1b758e0cd8676c68ca65268f5a037d4c24aa7d358c9a390 -SHA512 (shadow-4.19.0.tar.xz.asc) = 34c1a764d06a5d24533cbb57310de7462eb632c1de904901699d48f44401b1b1f4751db35f2b0e2b9a057cf1a777ccddbae4bc6b19a6db865ebc3e30fde0d060 +SHA512 (shadow-4.19.3.tar.xz) = f2b41f8186681eb98dae0da87ed1a1f03327c5005c9d4bf9500801352e318de6f5954dc5b8f30ab9aece728b1efb74b4ff8fb2720acc4c2aaef701331a4a5a05 +SHA512 (shadow-4.19.3.tar.xz.asc) = 295a6bffefd333a9ea84fa59b368f5c48d0ac5224199624b768087098110b0f0c19bef37f5c474c45277980758dcb6728e8bb17eb7ab1a57603cad41f1dd00ab From 0fba1e26ce07e5cb003b594266f8b34fdb3477f6 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Thu, 23 Apr 2026 15:20:03 +0200 Subject: [PATCH 128/134] btrfs: simplify checks improve useradd behavior for non-btrfs Signed-off-by: Iker Pedrosa --- shadow-4.19.3-useradd-fix-btrfs.patch | 492 ++++++++++++++++++++++++++ shadow-utils.spec | 7 +- 2 files changed, 498 insertions(+), 1 deletion(-) create mode 100644 shadow-4.19.3-useradd-fix-btrfs.patch diff --git a/shadow-4.19.3-useradd-fix-btrfs.patch b/shadow-4.19.3-useradd-fix-btrfs.patch new file mode 100644 index 0000000..47671d9 --- /dev/null +++ b/shadow-4.19.3-useradd-fix-btrfs.patch @@ -0,0 +1,492 @@ +From 4079070c4b8ced8df9d86366ad113fc3c2e4e49c Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Wed, 22 Apr 2026 11:02:36 +0200 +Subject: [PATCH 1/5] lib/btrfs.c: btrfs_is_subvolume(): Simplify error check + +Signed-off-by: Alejandro Colomar +--- + lib/btrfs.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/lib/btrfs.c b/lib/btrfs.c +index 85ec7dbc..fe20cf30 100644 +--- a/lib/btrfs.c ++++ b/lib/btrfs.c +@@ -67,8 +67,7 @@ int btrfs_is_subvolume(const char *path) + if (ret <= 0) + return ret; + +- ret = stat(path, &st); +- if (ret == -1) ++ if (stat(path, &st) == -1) + return -1; + + if (st.st_ino != BTRFS_FIRST_FREE_OBJECTID || !S_ISDIR(st.st_mode)) { +-- +2.53.0 + + +From 7a4faaaf46314547cc5e6c8264c3a11753ef9352 Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Wed, 22 Apr 2026 11:14:20 +0200 +Subject: [PATCH 2/5] lib/, src/: Move statfs(2) call out of is_btrfs() + +This simplifies the return value of is_btrfs() into a boolean. + +Signed-off-by: Alejandro Colomar +--- + lib/btrfs.c | 25 +++++++++---------------- + lib/prototypes.h | 3 ++- + src/useradd.c | 11 +++++++++-- + 3 files changed, 20 insertions(+), 19 deletions(-) + +diff --git a/lib/btrfs.c b/lib/btrfs.c +index fe20cf30..065c7938 100644 +--- a/lib/btrfs.c ++++ b/lib/btrfs.c +@@ -60,12 +60,13 @@ int btrfs_remove_subvolume(const char *path) + */ + int btrfs_is_subvolume(const char *path) + { +- struct stat st; +- int ret; ++ struct stat st; ++ struct statfs sfs; + +- ret = is_btrfs(path); +- if (ret <= 0) +- return ret; ++ if (statfs(path, &sfs) == -1) ++ return -1; ++ if (!is_btrfs(&sfs)) ++ return 0; + + if (stat(path, &st) == -1) + return -1; +@@ -78,16 +79,8 @@ int btrfs_is_subvolume(const char *path) + } + + +-/* Adapted from btrfsprogs */ +-int is_btrfs(const char *path) ++bool ++is_btrfs(const struct statfs *sfs) + { +- struct statfs sfs; +- int ret; +- +- ret = statfs(path, &sfs); +- if (ret == -1) +- return -1; +- +- return sfs.f_type == BTRFS_SUPER_MAGIC; ++ return sfs->f_type == BTRFS_SUPER_MAGIC; + } +- +diff --git a/lib/prototypes.h b/lib/prototypes.h +index 9a03e312..42aa2923 100644 +--- a/lib/prototypes.h ++++ b/lib/prototypes.h +@@ -23,6 +23,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -54,7 +55,7 @@ extern int isexpired (const struct passwd *, /*@null@*/const struct spwd *); + extern int btrfs_create_subvolume(const char *path); + extern int btrfs_remove_subvolume(const char *path); + extern int btrfs_is_subvolume(const char *path); +-extern int is_btrfs(const char *path); ++extern bool is_btrfs(const struct statfs *sfs); + #endif + + /* basename() renamed to Basename() to avoid libc name space confusion */ +diff --git a/src/useradd.c b/src/useradd.c +index df679d28..5ce6cd6a 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -2265,6 +2266,7 @@ static void create_home(const struct option_flags *flags) + #if WITH_BTRFS + if (subvolflg && (strlen(prefix_user_home) - (int)strlen(path)) <= 1) { + char *btrfs_check = strdup(path); ++ struct statfs sfs; + + if (!btrfs_check) { + fprintf(stderr, +@@ -2273,13 +2275,18 @@ static void create_home(const struct option_flags *flags) + fail_exit(E_HOMEDIR, process_selinux); + } + stpcpy(&btrfs_check[strlen(path) - strlen(cp) - 1], ""); +- if (is_btrfs(btrfs_check) <= 0) { ++ if (statfs(btrfs_check, &sfs) == -1) { ++ fprintf(stderr, "%s: statfs(\"%s\"): %s\n", ++ Prog, btrfs_check, strerrno()); ++ fail_exit(E_HOMEDIR, process_selinux); ++ } ++ free(btrfs_check); ++ if (!is_btrfs(&sfs)) { + fprintf(stderr, + _("%s: home directory \"%s\" must be mounted on BTRFS\n"), + Prog, path); + fail_exit(E_HOMEDIR, process_selinux); + } +- free(btrfs_check); + // make subvolume to mount for user instead of directory + if (btrfs_create_subvolume(path)) { + fprintf(stderr, +-- +2.53.0 + + +From 96460c7240264c0022cebc9ba1774993ee2594cf Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Wed, 22 Apr 2026 11:21:14 +0200 +Subject: [PATCH 3/5] lib/, src/: Move btrfs.c prototypes to lib/btrfs.h + +Signed-off-by: Alejandro Colomar +--- + lib/Makefile.am | 2 +- + lib/btrfs.c | 4 ++++ + lib/btrfs.h | 23 +++++++++++++++++++++++ + lib/prototypes.h | 9 --------- + src/useradd.c | 1 + + src/userdel.c | 1 + + src/usermod.c | 1 + + 7 files changed, 31 insertions(+), 10 deletions(-) + create mode 100644 lib/btrfs.h + +diff --git a/lib/Makefile.am b/lib/Makefile.am +index 7c488f82..0664e610 100644 +--- a/lib/Makefile.am ++++ b/lib/Makefile.am +@@ -290,7 +290,7 @@ libshadow_la_SOURCES += tcbfuncs.c tcbfuncs.h + endif + + if WITH_BTRFS +-libshadow_la_SOURCES += btrfs.c ++libshadow_la_SOURCES += btrfs.c btrfs.h + endif + + if ENABLE_LASTLOG +diff --git a/lib/btrfs.c b/lib/btrfs.c +index 065c7938..15b6b315 100644 +--- a/lib/btrfs.c ++++ b/lib/btrfs.c +@@ -1,3 +1,7 @@ ++#include "config.h" ++ ++#include "btrfs.h" ++ + #include + #include + #include +diff --git a/lib/btrfs.h b/lib/btrfs.h +new file mode 100644 +index 00000000..50b70488 +--- /dev/null ++++ b/lib/btrfs.h +@@ -0,0 +1,23 @@ ++// SPDX-FileCopyrightText: 2026, Alejandro Colomar ++// SPDX-License-Identifier: BSD-3-Clause ++ ++ ++#ifndef SHADOW_INCLUDE_LIB_BTRFS_H_ ++#define SHADOW_INCLUDE_LIB_BTRFS_H_ ++ ++ ++#include "config.h" ++ ++#include ++#include ++ ++ ++#ifdef WITH_BTRFS ++int btrfs_create_subvolume(const char *path); ++int btrfs_remove_subvolume(const char *path); ++int btrfs_is_subvolume(const char *path); ++bool is_btrfs(const struct statfs *sfs); ++#endif ++ ++ ++#endif // include guard +diff --git a/lib/prototypes.h b/lib/prototypes.h +index 42aa2923..d22c477a 100644 +--- a/lib/prototypes.h ++++ b/lib/prototypes.h +@@ -23,7 +23,6 @@ + + #include + #include +-#include + #include + #include + #include +@@ -50,14 +49,6 @@ extern int expire (const struct passwd *, /*@null@*/const struct spwd *); + /* isexpired.c */ + extern int isexpired (const struct passwd *, /*@null@*/const struct spwd *); + +-/* btrfs.c */ +-#ifdef WITH_BTRFS +-extern int btrfs_create_subvolume(const char *path); +-extern int btrfs_remove_subvolume(const char *path); +-extern int btrfs_is_subvolume(const char *path); +-extern bool is_btrfs(const struct statfs *sfs); +-#endif +- + /* basename() renamed to Basename() to avoid libc name space confusion */ + /* basename.c */ + extern /*@observer@*/const char *Basename (const char *str); +diff --git a/src/useradd.c b/src/useradd.c +index 5ce6cd6a..9bd32b11 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -34,6 +34,7 @@ + #include "alloc/malloc.h" + #include "atoi/a2i.h" + #include "atoi/getnum.h" ++#include "btrfs.h" + #include "chkname.h" + #include "defines.h" + #include "faillog.h" +diff --git a/src/userdel.c b/src/userdel.c +index 9b7d81be..ebd064c0 100644 +--- a/src/userdel.c ++++ b/src/userdel.c +@@ -20,6 +20,7 @@ + #include + #include + ++#include "btrfs.h" + #ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + #include "pam_defs.h" +diff --git a/src/usermod.c b/src/usermod.c +index 7c0321a6..3afe19ea 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -32,6 +32,7 @@ + #include "alloc/malloc.h" + #include "atoi/a2i.h" + #include "atoi/getnum.h" ++#include "btrfs.h" + #include "chkname.h" + #include "defines.h" + #include "faillog.h" +-- +2.53.0 + + +From 7be9a6540f1cad477fd4f4e83d25904a5095bb86 Mon Sep 17 00:00:00 2001 +From: Hadi Chokr +Date: Tue, 21 Apr 2026 09:18:19 +0200 +Subject: [PATCH 4/5] useradd(8): fallback to regular dir for BTRFS home on + non-BTRFS parent + +When the --btrfs-subvolume-home option is used but the parent directory +is not on a BTRFS filesystem, useradd previously failed with an error. +This is too strict; instead, fall back to creating a regular directory +and issue a warning. The subvolume creation is attempted only when the +parent is BTRFS. Otherwise, a regular directory is created and a +syslog(3) warning is logged. + +Fixes: 3e8c105 (2026-01-02; "src/useradd: Support config for creating home dirs as Btrfs subvolumes") +Co-authored-by: Hadi Chokr +Co-authored-by: Alejandro Colomar +Signed-off-by: Alejandro Colomar +--- + man/useradd.8.xml | 27 ++++++++++++++++++++++-- + src/useradd.c | 52 +++++++++++++++++++++++------------------------ + 2 files changed, 51 insertions(+), 28 deletions(-) + +diff --git a/man/useradd.8.xml b/man/useradd.8.xml +index 8a087e13..0bde6683 100644 +--- a/man/useradd.8.xml ++++ b/man/useradd.8.xml +@@ -2,6 +2,7 @@ + + + +- Note: this feature works only if the underlying filesystem supports +- Btrfs subvolumes. ++ If the parent directory of the user's home directory is ++ not on a Btrfs filesystem, ++ useradd will not create a ++ subvolume. ++ Instead, it creates a regular directory, ++ prints a warning to standard error, ++ and logs the event via syslog at level ++ LOG_WARN. ++ The user account is still created successfully. ++ ++ ++ If the filesystem type cannot be determined (e.g., because of ++ insufficient permissions, an I/O error, ++ or a ++ ++ statfs ++ 2 ++ ++ failure), ++ useradd treats this as a fatal error: ++ the home directory is not created, ++ the command exits with a non‑zero status ++ (E_HOMEDIR, 12), ++ and an error message is printed. + + + +diff --git a/src/useradd.c b/src/useradd.c +index 9bd32b11..9210379c 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -1,11 +1,11 @@ +-/* +- * SPDX-FileCopyrightText: 1991 - 1994, Julianne Frances Haugh +- * SPDX-FileCopyrightText: 1996 - 2000, Marek Michałkiewicz +- * SPDX-FileCopyrightText: 2000 - 2006, Tomasz Kłoczko +- * SPDX-FileCopyrightText: 2007 - 2012, Nicolas François +- * +- * SPDX-License-Identifier: BSD-3-Clause +- */ ++// SPDX-FileCopyrightText: 1991-1994, Julianne Frances Haugh ++// SPDX-FileCopyrightText: 1996-2000, Marek Michałkiewicz ++// SPDX-FileCopyrightText: 2000-2006, Tomasz Kłoczko ++// SPDX-FileCopyrightText: 2007-2012, Nicolas François ++// SPDX-FileCopyrightText: 2025-2026, Hadi Chokr ++// SPDX-FileCopyrightText: 2026, Alejandro Colomar ++// SPDX-License-Identifier: BSD-3-Clause ++ + + #include "config.h" + +@@ -2251,6 +2251,8 @@ static void create_home(const struct option_flags *flags) + owner root:root. + */ + for (cp = strtok(bhome, "/"); cp != NULL; cp = strtok(NULL, "/")) { ++ bool dir_created; ++ + /* Avoid turning a relative path into an absolute path. */ + if (strprefix(bhome, "/") || !streq(path, "")) + strcat(path, "/"); +@@ -2260,10 +2262,7 @@ static void create_home(const struct option_flags *flags) + continue; + } + +- /* Check if parent directory is BTRFS, fail if requesting +- subvolume but no BTRFS. The paths could be different by the +- trailing slash +- */ ++ dir_created = false; + #if WITH_BTRFS + if (subvolflg && (strlen(prefix_user_home) - (int)strlen(path)) <= 1) { + char *btrfs_check = strdup(path); +@@ -2284,25 +2283,26 @@ static void create_home(const struct option_flags *flags) + free(btrfs_check); + if (!is_btrfs(&sfs)) { + fprintf(stderr, +- _("%s: home directory \"%s\" must be mounted on BTRFS\n"), +- Prog, path); +- fail_exit(E_HOMEDIR, process_selinux); ++ _("%s: warning: \"%s\" is not on BTRFS; creating regular directory instead of subvolume\n"), ++ Prog, prefix_user_home); ++ } else { ++ if (btrfs_create_subvolume(path)) { ++ fprintf(stderr, ++ _("%s: failed to create BTRFS subvolume: %s\n"), ++ Prog, path); ++ fail_exit(E_HOMEDIR, process_selinux); ++ } ++ dir_created = true; + } +- // make subvolume to mount for user instead of directory +- if (btrfs_create_subvolume(path)) { +- fprintf(stderr, +- _("%s: failed to create BTRFS subvolume: %s\n"), ++ } ++#endif ++ if (!dir_created) { ++ if (mkdir(path, 0) != 0) { ++ fprintf(stderr, _("%s: cannot create directory %s\n"), + Prog, path); + fail_exit(E_HOMEDIR, process_selinux); + } + } +- else +-#endif +- if (mkdir(path, 0) != 0) { +- fprintf(stderr, _("%s: cannot create directory %s\n"), +- Prog, path); +- fail_exit(E_HOMEDIR, process_selinux); +- } + if (chown(path, 0, 0) < 0) { + fprintf(stderr, + _("%s: warning: chown on `%s' failed: %m\n"), +-- +2.53.0 + + +From 827f69b864461ab6d7549762bef06ab4495d2587 Mon Sep 17 00:00:00 2001 +From: Hadi Chokr +Date: Mon, 20 Apr 2026 12:27:31 +0200 +Subject: [PATCH 5/5] man/useradd.8.xml: Remove trailing spaces from + useradd.8.xml + +Signed-off-by: Hadi Chokr +Reviewed-by: Alejandro Colomar +--- + man/useradd.8.xml | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/man/useradd.8.xml b/man/useradd.8.xml +index 0bde6683..f85780e2 100644 +--- a/man/useradd.8.xml ++++ b/man/useradd.8.xml +@@ -207,7 +207,7 @@ + user's login directory. The default is to append the + LOGIN name to + BASE_DIR and use that as the +- login directory name. ++ login directory name. + The directory HOME_DIR is not created by + default. However it will be created for non-system users if either the + flag is specifed or +@@ -422,7 +422,7 @@ + + + +- Create the user's home directory if it does not exist. ++ Create the user's home directory if it does not exist. + The files and directories contained in the skeleton directory + (which can be defined with the option) + will be copied to the home directory. +@@ -512,7 +512,7 @@ + password himself. + + +- Note:Avoid this option on the command ++ Note:Avoid this option on the command + line because the password (or encrypted password) will + be visible by users listing the processes. + +-- +2.53.0 + diff --git a/shadow-utils.spec b/shadow-utils.spec index 426f19b..d381c31 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.19.3 -Release: 1%{?dist} +Release: 2%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -28,6 +28,8 @@ Patch1: shadow-4.19.0-account-tools-setuid.patch Patch2: shadow-4-19-useradd-support-btrfs.patch # https://github.com/shadow-maint/shadow/commit/6be13b2f84a2c1a0d0f4129b5258b4b443e7f86c Patch3: shadow-4.19.3-chkhash.patch +# https://github.com/shadow-maint/shadow/commit/827f69b864461ab6d7549762bef06ab4495d2587 +Patch4: shadow-4.19.3-useradd-fix-btrfs.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -277,6 +279,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Thu Apr 23 2026 Iker Pedrosa - 2:4.19.3-2 +- btrfs: simplify checks improve useradd behavior for non-btrfs + * Wed Feb 11 2026 Debarshi Ray - 2:4.19.3-1 - Rebase to version 4.19.3 Resolves: #2426288 From 4a56d06039633e31494bf759e96673dd632925a7 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Tue, 14 Apr 2026 16:25:41 +0200 Subject: [PATCH 129/134] Tests: run system tests Tests comprehensive functionality from shadow using the upstream system test suite in testing farm. - Add plans/system-tests.fmf: run upstream shadow system tests via pytest-mh. - Add tests/mhc-fedora-ci.yaml: topology configuration to connect to the test system. - Add .fmf/version: enable testing farm integration. Signed-off-by: Iker Pedrosa --- .fmf/version | 1 + plans/tier0-functional.fmf | 48 ++++++++++++++++++++++++++++++++++++++ tests/mhc-fedora-ci.yaml | 13 +++++++++++ 3 files changed, 62 insertions(+) create mode 100644 .fmf/version create mode 100644 plans/tier0-functional.fmf create mode 100644 tests/mhc-fedora-ci.yaml diff --git a/.fmf/version b/.fmf/version new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/.fmf/version @@ -0,0 +1 @@ +1 diff --git a/plans/tier0-functional.fmf b/plans/tier0-functional.fmf new file mode 100644 index 0000000..7fb6f9c --- /dev/null +++ b/plans/tier0-functional.fmf @@ -0,0 +1,48 @@ +summary: Tier 0 functional tests for shadow-utils +description: | + Run comprehensive system tests for shadow-utils. These tests validate user and group + account management functionality by testing actual system operations including user + creation, password management, group operations, and verification of system files + (i.e. /etc/passwd, /etc/shadow). + +provision: + how: virtual + image: fedora + +prepare: + - name: Install general dependencies + how: install + package: + - expect + - git + - python3-pip + + - name: Setup SSH keys for localhost testing + how: shell + script: + - ssh-keygen -t rsa -f /root/.ssh/id_rsa -N "" -q + - cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys + - chmod 600 /root/.ssh/authorized_keys + - ssh-keyscan -H localhost >> /root/.ssh/known_hosts + + - name: Clone shadow repository + how: shell + script: + - git clone https://github.com/shadow-maint/shadow.git /tmp/shadow-test + + - name: Copy test topology for Fedora CI + how: shell + script: + - cp tests/mhc-fedora-ci.yaml /tmp/shadow-test/tests/system + + - name: Install test dependencies + how: shell + script: + - pip3 install -r /tmp/shadow-test/tests/system/requirements.txt + +execute: + how: tmt + duration: 30m + script: | + cd /tmp/shadow-test/tests/system + pytest --mh-config=mhc-fedora-ci.yaml --mh-lazy-ssh -v diff --git a/tests/mhc-fedora-ci.yaml b/tests/mhc-fedora-ci.yaml new file mode 100644 index 0000000..8747e67 --- /dev/null +++ b/tests/mhc-fedora-ci.yaml @@ -0,0 +1,13 @@ +provisioned_topologies: +- shadow +domains: +- id: shadow + hosts: + - hostname: localhost + role: shadow + conn: + type: ssh + host: localhost + user: root + artifacts: + - /var/log/* From 871df3223d7cf041a69d1b19bb9d1fdf4d3220b9 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Wed, 27 May 2026 11:40:27 +0200 Subject: [PATCH 130/134] Enable use of PAM for chpasswd and newusers Resolves: #2461179 and #2283963 Signed-off-by: Iker Pedrosa --- shadow-4.19.0-account-tools-setuid.patch | 377 ----------------------- shadow-utils.spec | 14 +- 2 files changed, 9 insertions(+), 382 deletions(-) delete mode 100644 shadow-4.19.0-account-tools-setuid.patch diff --git a/shadow-4.19.0-account-tools-setuid.patch b/shadow-4.19.0-account-tools-setuid.patch deleted file mode 100644 index 9452582..0000000 --- a/shadow-4.19.0-account-tools-setuid.patch +++ /dev/null @@ -1,377 +0,0 @@ -diff -up shadow-4.19.0-rc1/src/chpasswd.c.account-tools-setuid shadow-4.19.0-rc1/src/chpasswd.c ---- shadow-4.19.0-rc1/src/chpasswd.c.account-tools-setuid 2025-12-07 16:56:38.563285789 +0100 -+++ shadow-4.19.0-rc1/src/chpasswd.c 2025-12-09 14:54:29.232282499 +0100 -@@ -466,9 +466,11 @@ int main (int argc, char **argv) - char *newpwd; - const char *salt; - -+#ifdef ACCT_TOOLS_SETUID - #ifdef USE_PAM - bool use_pam = true; - #endif /* USE_PAM */ -+#endif /* ACCT_TOOLS_SETUID */ - - bool errors = false; - intmax_t line = 0; -@@ -495,19 +497,23 @@ int main (int argc, char **argv) - process_root_flag ("-R", argc, argv); - prefix = process_prefix_flag ("-P", argc, argv); - -+#ifdef ACCT_TOOLS_SETUID - #ifdef USE_PAM - if (md5flg || eflg || cflg || prefix[0]) { - use_pam = false; - } - #endif /* USE_PAM */ -+#endif /* ACCT_TOOLS_SETUID */ - - OPENLOG (Prog); - - check_perms (); - -+#ifdef ACCT_TOOLS_SETUID - #ifdef USE_PAM - if (!use_pam) - #endif /* USE_PAM */ -+#endif /* ACCT_TOOLS_SETUID */ - { - is_shadow_pwd = spw_file_present (); - -@@ -562,6 +568,7 @@ int main (int argc, char **argv) - } - newpwd = cp; - -+#ifdef ACCT_TOOLS_SETUID - #ifdef USE_PAM - if (use_pam) { - if (do_pam_passwd_non_interactive (Prog, name, newpwd) != 0) { -@@ -572,6 +579,7 @@ int main (int argc, char **argv) - } - } else - #endif /* USE_PAM */ -+#endif /* ACCT_TOOLS_SETUID */ - { - - /* -@@ -706,9 +714,11 @@ int main (int argc, char **argv) - * password database. - */ - if (errors) { -+#ifdef ACCT_TOOLS_SETUID - #ifdef USE_PAM - if (!use_pam) - #endif /* USE_PAM */ -+#endif /* ACCT_TOOLS_SETUID */ - { - fprintf (stderr, - _("%s: error detected, changes ignored\n"), -@@ -717,9 +727,11 @@ int main (int argc, char **argv) - fail_exit (1, process_selinux); - } - -+#ifdef ACCT_TOOLS_SETUID - #ifdef USE_PAM - if (!use_pam) - #endif /* USE_PAM */ -+#endif /* ACCT_TOOLS_SETUID */ - { - /* Save the changes */ - close_files (&flags); -diff -up shadow-4.19.0-rc1/src/groupmems.c.account-tools-setuid shadow-4.19.0-rc1/src/groupmems.c ---- shadow-4.19.0-rc1/src/groupmems.c.account-tools-setuid 2025-12-07 16:56:38.564285805 +0100 -+++ shadow-4.19.0-rc1/src/groupmems.c 2025-12-09 14:57:23.767054141 +0100 -@@ -14,9 +14,11 @@ - #include - #include - #include -+#ifdef ACCT_TOOLS_SETUID - #ifdef USE_PAM - #include "pam_defs.h" - #endif /* USE_PAM */ -+#endif /* ACCT_TOOLS_SETUID */ - #include - - #include "alloc/malloc.h" -@@ -432,6 +434,7 @@ static void - check_perms(MAYBE_UNUSED bool process_selinux) - { - if (!list) { -+#ifdef ACCT_TOOLS_SETUID - #ifdef USE_PAM - pam_handle_t *pamh = NULL; - int retval; -@@ -465,7 +468,8 @@ check_perms(MAYBE_UNUSED bool process_se - fail_exit (1, process_selinux); - } - (void) pam_end (pamh, retval); --#endif -+#endif /* USE_PAM */ -+#endif /* ACCT_TOOLS_SETUID */ - } - } - -diff -up shadow-4.19.0-rc1/src/newusers.c.account-tools-setuid shadow-4.19.0-rc1/src/newusers.c ---- shadow-4.19.0-rc1/src/newusers.c.account-tools-setuid 2025-12-07 16:56:38.565285821 +0100 -+++ shadow-4.19.0-rc1/src/newusers.c 2025-12-09 15:07:40.115500988 +0100 -@@ -74,6 +74,7 @@ struct option_flags { - static const char Prog[] = "newusers"; - - static bool rflg = false; /* create a system account */ -+#ifndef ACCT_TOOLS_SETUID - #ifndef USE_PAM - static /*@null@*//*@observer@*/char *crypt_method = NULL; - #define cflg (NULL != crypt_method) -@@ -90,6 +91,7 @@ static long bcrypt_rounds = 13; - static long yescrypt_cost = 5; - #endif /* USE_YESCRYPT */ - #endif /* !USE_PAM */ -+#endif /* !ACCT_TOOLS_SETUID */ - - static bool is_shadow; - #ifdef SHADOWGRP -@@ -112,9 +114,11 @@ NORETURN static void fail_exit (int, boo - static int add_group (const char *, const char *, gid_t *, gid_t); - static int get_user_id (const char *, uid_t *); - static int add_user (const char *, uid_t, gid_t); -+#ifndef ACCT_TOOLS_SETUID - #ifndef USE_PAM - static int update_passwd (struct passwd *, const char *); - #endif /* !USE_PAM */ -+#endif /* !ACCT_TOOLS_SETUID */ - static int add_passwd (struct passwd *, const char *); - static void process_flags (int argc, char **argv, struct option_flags *flags); - static void check_flags (void); -@@ -136,6 +140,7 @@ static void usage (int status) - "Options:\n"), - Prog); - (void) fputs (_(" -b, --badname allow bad names\n"), usageout); -+#ifndef ACCT_TOOLS_SETUID - #ifndef USE_PAM - (void) fprintf (usageout, - _(" -c, --crypt-method METHOD the crypt method (one of %s)\n"), -@@ -151,9 +156,11 @@ static void usage (int status) - #endif - ); - #endif /* !USE_PAM */ -+#endif /* !ACCT_TOOLS_SETUID */ - (void) fputs (_(" -h, --help display this help message and exit\n"), usageout); - (void) fputs (_(" -r, --system create system accounts\n"), usageout); - (void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout); -+#ifndef ACCT_TOOLS_SETUID - #ifndef USE_PAM - #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) - (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT\n" -@@ -161,6 +168,7 @@ static void usage (int status) - usageout); - #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ - #endif /* !USE_PAM */ -+#endif /* !ACCT_TOOLS_SETUID */ - (void) fputs ("\n", usageout); - - exit (status); -@@ -426,6 +434,7 @@ static int add_user (const char *name, u - return (pw_update (&pwent) == 0) ? -1 : 0; - } - -+#ifndef ACCT_TOOLS_SETUID - #ifndef USE_PAM - /* - * update_passwd - update the password in the passwd entry -@@ -478,6 +487,7 @@ static int update_passwd (struct passwd - return 0; - } - #endif /* !USE_PAM */ -+#endif /* !ACCT_TOOLS_SETUID */ - - /* - * add_passwd - add or update the encrypted password -@@ -487,10 +497,13 @@ add_passwd(struct passwd *pwd, MAYBE_UNU - { - const struct spwd *sp; - struct spwd spent; -+#ifndef ACCT_TOOLS_SETUID - #ifndef USE_PAM - char *cp; - #endif /* !USE_PAM */ -+#endif /* !ACCT_TOOLS_SETUID */ - -+#ifndef ACCT_TOOLS_SETUID - #ifndef USE_PAM - void *crypt_arg = NULL; - if (NULL != crypt_method) { -@@ -528,13 +541,14 @@ add_passwd(struct passwd *pwd, MAYBE_UNU - return update_passwd (pwd, password); - } - #endif /* USE_PAM */ -+#endif /* !ACCT_TOOLS_SETUID */ - - /* - * Do the first and easiest shadow file case. The user already - * exists in the shadow password file. - */ - sp = spw_locate (pwd->pw_name); --#ifndef USE_PAM -+#if !defined(ACCT_TOOLS_SETUID) && !defined(USE_PAM) - if (NULL != sp) { - spent = *sp; - if ( (NULL != crypt_method) -@@ -571,7 +585,7 @@ add_passwd(struct passwd *pwd, MAYBE_UNU - if (!streq(pwd->pw_passwd, "x")) { - return update_passwd (pwd, password); - } --#else /* USE_PAM */ -+#else /* !ACCT_TOOLS_SETUID && !USE_PAM */ - /* - * If there is already a shadow entry, do not touch it. - * If there is already a passwd entry with a password, do not -@@ -582,14 +596,14 @@ add_passwd(struct passwd *pwd, MAYBE_UNU - || !streq(pwd->pw_passwd, "x")) { - return 0; - } --#endif /* USE_PAM */ -+#endif /* !ACCT_TOOLS_SETUID && !USE_PAM */ - - /* - * Now the really hard case - I need to create an entirely new - * shadow password file entry. - */ - spent.sp_namp = pwd->pw_name; --#ifndef USE_PAM -+#if !defined(ACCT_TOOLS_SETUID) && !defined(USE_PAM) - if ((crypt_method != NULL) && streq(crypt_method, "NONE")) { - spent.sp_pwdp = (char *)password; - } else { -@@ -647,32 +647,38 @@ add_passwd(struct passwd *pwd, MAYBE_UNU - static void process_flags (int argc, char **argv, struct option_flags *flags) - { - int c; -+#ifndef ACCT_TOOLS_SETUID - #ifndef USE_PAM - #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) - int bad_s; - #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ - #endif /* !USE_PAM */ -+#endif /* !ACCT_TOOLS_SETUID */ - static struct option long_options[] = { - {"badname", no_argument, NULL, 'b'}, -+#ifndef ACCT_TOOLS_SETUID - #ifndef USE_PAM - {"crypt-method", required_argument, NULL, 'c'}, - #endif /* !USE_PAM */ -+#endif /* !ACCT_TOOLS_SETUID */ - {"help", no_argument, NULL, 'h'}, - {"system", no_argument, NULL, 'r'}, - {"root", required_argument, NULL, 'R'}, -+#ifndef ACCT_TOOLS_SETUID - #ifndef USE_PAM - #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) - {"sha-rounds", required_argument, NULL, 's'}, - #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ - #endif /* !USE_PAM */ -+#endif /* !ACCT_TOOLS_SETUID */ - {NULL, 0, NULL, '\0'} - }; - - while ((c = getopt_long (argc, argv, --#ifndef USE_PAM -+#if !defined(ACCT_TOOLS_SETUID) && !defined(USE_PAM) - #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) - "c:bhrs:", --#else /* !USE_SHA_CRYPT && !USE_BCRYPT && !USE_YESCRYPT */ -+#else /* !ACCT_TOOLS_SETUID && !USE_PAM */ - "c:bhr", - #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ - #else /* USE_PAM */ -@@ -670,11 +690,13 @@ static void process_flags (int argc, cha - case 'b': - allow_bad_names = true; - break; -+#ifndef ACCT_TOOLS_SETUID - #ifndef USE_PAM - case 'c': - crypt_method = optarg; - break; - #endif /* !USE_PAM */ -+#endif /* !ACCT_TOOLS_SETUID */ - case 'h': - usage (EXIT_SUCCESS); - break; -@@ -684,6 +706,7 @@ static void process_flags (int argc, cha - case 'R': /* no-op, handled in process_root_flag () */ - flags->chroot = true; - break; -+#ifndef ACCT_TOOLS_SETUID - #ifndef USE_PAM - #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) - case 's': -@@ -723,6 +746,7 @@ static void process_flags (int argc, cha - break; - #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ - #endif /* !USE_PAM */ -+#endif /* !ACCT_TOOLS_SETUID */ - default: - usage (EXIT_FAILURE); - break; -@@ -755,6 +779,7 @@ static void process_flags (int argc, cha - */ - static void check_flags (void) - { -+#ifndef ACCT_TOOLS_SETUID - #ifndef USE_PAM - #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) - if (sflg && !cflg) { -@@ -787,6 +812,7 @@ static void check_flags (void) - } - } - #endif /* !USE_PAM */ -+#endif /* !ACCT_TOOLS_SETUID */ - } - - /* -@@ -1065,12 +1091,14 @@ int main (int argc, char **argv) - intmax_t line = 0; - uid_t uid; - gid_t gid; -+#ifdef ACCT_TOOLS_SETUID - #ifdef USE_PAM - intmax_t *lines = NULL; - char **usernames = NULL; - char **passwords = NULL; - size_t nusers = 0; - #endif /* USE_PAM */ -+#endif /* ACCT_TOOLS_SETUID */ - struct option_flags flags = {.chroot = false}; - bool process_selinux; - -@@ -1193,6 +1221,7 @@ int main (int argc, char **argv) - } - newpw = *pw; - -+#ifdef ACCT_TOOLS_SETUID - #ifdef USE_PAM - /* keep the list of user/password for later update by PAM */ - nusers++; -@@ -1207,6 +1236,7 @@ int main (int argc, char **argv) - usernames[nusers-1] = xstrdup(fields[0]); - passwords[nusers-1] = xstrdup(fields[1]); - #endif /* USE_PAM */ -+#endif /* ACCT_TOOLS_SETUID */ - if (!streq(fields[1], "") && add_passwd(&newpw, fields[1]) != 0) { - fprintf (stderr, - _("%s: line %jd: can't update password\n"), -@@ -1321,6 +1351,7 @@ int main (int argc, char **argv) - nscd_flush_cache ("group"); - sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP); - -+#ifdef ACCT_TOOLS_SETUID - #ifdef USE_PAM - /* Now update the passwords using PAM */ - for (size_t i = 0; i < nusers; i++) { -@@ -1334,6 +1365,7 @@ int main (int argc, char **argv) - } - } - #endif /* USE_PAM */ -+#endif /* ACCT_TOOLS_SETUID */ - - exit (EXIT_SUCCESS); - } diff --git a/shadow-utils.spec b/shadow-utils.spec index d381c31..11243dd 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.19.3 -Release: 2%{?dist} +Release: 3%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -22,8 +22,6 @@ Source7: passwd.pamd ### Patches ### # Misc manual page changes - non-upstreamable Patch0: shadow-4.15.0-manfix.patch -# Probably non-upstreamable -Patch1: shadow-4.19.0-account-tools-setuid.patch # https://github.com/shadow-maint/shadow/commit/3e8c105f0703264e947d8c034b90419794955d49 Patch2: shadow-4-19-useradd-support-btrfs.patch # https://github.com/shadow-maint/shadow/commit/6be13b2f84a2c1a0d0f4129b5258b4b443e7f86c @@ -146,6 +144,8 @@ install -d -m 755 $RPM_BUILD_ROOT%{_sysconfdir}/default install -p -c -m 0644 %{SOURCE3} $RPM_BUILD_ROOT%{_sysconfdir}/login.defs install -p -c -m 0600 %{SOURCE2} $RPM_BUILD_ROOT%{_sysconfdir}/default/useradd install -d -m 755 $RPM_BUILD_ROOT%{_pam_confdir} +install -m 644 %{SOURCE7} $RPM_BUILD_ROOT%{_pam_confdir}/chpasswd +install -m 644 %{SOURCE7} $RPM_BUILD_ROOT%{_pam_confdir}/newusers install -m 644 %{SOURCE7} $RPM_BUILD_ROOT%{_pam_confdir}/passwd @@ -194,11 +194,9 @@ rm $RPM_BUILD_ROOT%{_mandir}/*/man8/faillog.* # Remove PAM service files we don't use. rm $RPM_BUILD_ROOT%{_pam_confdir}/chfn -rm $RPM_BUILD_ROOT%{_pam_confdir}/chpasswd rm $RPM_BUILD_ROOT%{_pam_confdir}/chsh rm $RPM_BUILD_ROOT%{_pam_confdir}/groupmems rm $RPM_BUILD_ROOT%{_pam_confdir}/login -rm $RPM_BUILD_ROOT%{_pam_confdir}/newusers rm $RPM_BUILD_ROOT%{_pam_confdir}/su find $RPM_BUILD_ROOT%{_mandir} -depth -type d -empty -delete @@ -225,6 +223,8 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %license gpl-2.0.txt shadow-bsd.txt %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/login.defs %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/default/useradd +%config(noreplace) %{_pam_confdir}/chpasswd +%config(noreplace) %{_pam_confdir}/newusers %config(noreplace) %{_pam_confdir}/passwd %{_bindir}/sg %attr(4755,root,root) %{_bindir}/chage @@ -279,6 +279,10 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Wed May 27 2026 Iker Pedrosa - 2:4.19.3-3 +- Enable use of PAM for chpasswd and newusers + Resolves: #2461179 and #2283963 + * Thu Apr 23 2026 Iker Pedrosa - 2:4.19.3-2 - btrfs: simplify checks improve useradd behavior for non-btrfs From 8bd71d9f9156a632eb3850c1b2658fc21959f892 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 17 Jul 2026 06:27:57 +0000 Subject: [PATCH 131/134] Rebuilt for https://fedoraproject.org/wiki/Fedora_45_Mass_Rebuild --- shadow-utils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/shadow-utils.spec b/shadow-utils.spec index 11243dd..4f94261 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.19.3 -Release: 3%{?dist} +Release: 4%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow @@ -279,6 +279,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Fri Jul 17 2026 Fedora Release Engineering - 2:4.19.3-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_45_Mass_Rebuild + * Wed May 27 2026 Iker Pedrosa - 2:4.19.3-3 - Enable use of PAM for chpasswd and newusers Resolves: #2461179 and #2283963 From 8cb145bd7377a26dae190cc3b7ea46a293ac0a45 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Thu, 2 Jul 2026 16:26:11 +0200 Subject: [PATCH 132/134] Rebase to v4.20.0-rc3 Signed-off-by: Iker Pedrosa --- .gitignore | 4 + shadow-4-19-useradd-support-btrfs.patch | 149 ------- shadow-4.15.0-manfix.patch | 162 -------- shadow-4.19.3-chkhash.patch | 102 ----- shadow-4.19.3-useradd-fix-btrfs.patch | 492 ------------------------ shadow-utils.spec | 28 +- sources | 4 +- 7 files changed, 14 insertions(+), 927 deletions(-) delete mode 100644 shadow-4-19-useradd-support-btrfs.patch delete mode 100644 shadow-4.15.0-manfix.patch delete mode 100644 shadow-4.19.3-chkhash.patch delete mode 100644 shadow-4.19.3-useradd-fix-btrfs.patch diff --git a/.gitignore b/.gitignore index 7db552e..13adb8c 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,7 @@ shadow-4.1.4.2.tar.bz2 /shadow-4.19.2.tar.xz.asc /shadow-4.19.3.tar.xz /shadow-4.19.3.tar.xz.asc +/shadow-4.20.0-rc2.tar.xz +/shadow-4.20.0-rc2.tar.xz.asc +/shadow-4.20.0-rc3.tar.xz +/shadow-4.20.0-rc3.tar.xz.asc diff --git a/shadow-4-19-useradd-support-btrfs.patch b/shadow-4-19-useradd-support-btrfs.patch deleted file mode 100644 index b801289..0000000 --- a/shadow-4-19-useradd-support-btrfs.patch +++ /dev/null @@ -1,149 +0,0 @@ -From 3e8c105f0703264e947d8c034b90419794955d49 Mon Sep 17 00:00:00 2001 -From: Hadi Chokr -Date: Fri, 12 Dec 2025 11:18:06 +0100 -Subject: [PATCH] src/useradd: Support config for creating home dirs as Btrfs - subvolumes - -Closes: #1162 - -Co-authored-by: Neal Gompa -Signed-off-by: Hadi Chokr -Signed-off-by: Neal Gompa -Reviewed-by: Alejandro Colomar ---- - man/useradd.8.xml | 27 +++++++++++++++++++++++++++ - src/useradd.c | 24 ++++++++++++++++++++++++ - 2 files changed, 51 insertions(+) - -diff --git a/man/useradd.8.xml b/man/useradd.8.xml -index e6db7f6d..c745a620 100644 ---- a/man/useradd.8.xml -+++ b/man/useradd.8.xml -@@ -134,6 +134,33 @@ - - - -+ -+ -+ -+ -+ -+ -+ Create the user's home directory as a Btrfs subvolume. -+ -+ -+ If this option is not specified, -+ useradd will follow the default behavior -+ defined by the variable -+ in /etc/default/useradd. -+ If this variable is not set, the default value is no. -+ -+ -+ When the command-line option -+ is specified, -+ a Btrfs subvolume is created -+ regardless of any configuration file settings. -+ -+ -+ Note: this feature works only if the underlying filesystem supports -+ Btrfs subvolumes. -+ -+ -+ - - - ,  COMMENT -diff --git a/src/useradd.c b/src/useradd.c -index 899efe3c..8433ed8a 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -114,6 +114,7 @@ static const char *def_shell = "/bin/bash"; - static const char *def_template = SKEL_DIR; - static const char *def_usrtemplate = USRSKELDIR; - static const char *def_create_mail_spool = "yes"; -+static const char *def_btrfs_subvolume_home = "no"; - static const char *def_log_init = "yes"; - - static long def_inactive = -1; -@@ -222,6 +223,7 @@ static bool home_added = false; - #define DSKEL "SKEL" - #define DUSRSKEL "USRSKEL" - #define DCREATE_MAIL_SPOOL "CREATE_MAIL_SPOOL" -+#define DBTRFS_SUBVOLUME_HOME "BTRFS_SUBVOLUME_HOME" - #define DLOG_INIT "LOG_INIT" - - /* local function prototypes */ -@@ -456,6 +458,7 @@ get_defaults(const struct option_flags *flags) - def_usrtemplate = xstrdup(ccp); - } - } -+ - /* - * Create by default user mail spool or not ? - */ -@@ -466,6 +469,15 @@ get_defaults(const struct option_flags *flags) - def_create_mail_spool = xstrdup(ccp); - } - -+ /* -+ * Create home directories as Btrfs subvolumes by default? -+ */ -+ else if (streq(buf, DBTRFS_SUBVOLUME_HOME)) { -+ if (streq(ccp, "")) -+ ccp = "no"; -+ def_btrfs_subvolume_home = xstrdup(ccp); -+ } -+ - /* - * By default do we add the user to the lastlog and faillog databases ? - */ -@@ -500,6 +512,7 @@ static void show_defaults (void) - printf ("SKEL=%s\n", def_template); - printf ("USRSKEL=%s\n", def_usrtemplate); - printf ("CREATE_MAIL_SPOOL=%s\n", def_create_mail_spool); -+ printf ("BTRFS_SUBVOLUME_HOME=%s\n", def_btrfs_subvolume_home); - printf ("LOG_INIT=%s\n", def_log_init); - } - -@@ -523,6 +536,7 @@ set_defaults(void) - bool out_skel = false; - bool out_usrskel = false; - bool out_create_mail_spool = false; -+ bool out_btrfs_subvolume_home = false; - bool out_log_init = false; - char buf[1024]; - char *new_file = NULL; -@@ -639,6 +653,11 @@ set_defaults(void) - DCREATE_MAIL_SPOOL "=%s\n", - def_create_mail_spool); - out_create_mail_spool = true; -+ } else if (!out_btrfs_subvolume_home && streq(buf, DBTRFS_SUBVOLUME_HOME)) { -+ fprintf(ofp, -+ DBTRFS_SUBVOLUME_HOME "=%s\n", -+ def_btrfs_subvolume_home); -+ out_btrfs_subvolume_home = true; - } else if (!out_log_init && streq(buf, DLOG_INIT)) { - fprintf(ofp, DLOG_INIT "=%s\n", def_log_init); - out_log_init = true; -@@ -673,6 +692,8 @@ set_defaults(void) - - if (!out_create_mail_spool) - fprintf (ofp, DCREATE_MAIL_SPOOL "=%s\n", def_create_mail_spool); -+ if (!out_btrfs_subvolume_home) -+ fprintf (ofp, DBTRFS_SUBVOLUME_HOME "=%s\n", def_btrfs_subvolume_home); - if (!out_log_init) - fprintf (ofp, DLOG_INIT "=%s\n", def_log_init); - /* -@@ -1431,6 +1452,9 @@ static void process_flags (int argc, char **argv, struct option_flags *flags) - } - } - -+ if (!subvolflg && strcaseeq(def_btrfs_subvolume_home, "yes")) -+ subvolflg = true; -+ - if (!gflg && !Nflg && !Uflg) { - /* Get the settings from login.defs */ - Uflg = getdef_bool ("USERGROUPS_ENAB"); --- -2.52.0 - diff --git a/shadow-4.15.0-manfix.patch b/shadow-4.15.0-manfix.patch deleted file mode 100644 index 34e62f9..0000000 --- a/shadow-4.15.0-manfix.patch +++ /dev/null @@ -1,162 +0,0 @@ -diff -up shadow-4.15.0/man/groupmems.8.xml.manfix shadow-4.15.0/man/groupmems.8.xml ---- shadow-4.15.0/man/groupmems.8.xml.manfix 2023-05-26 04:56:11.000000000 +0200 -+++ shadow-4.15.0/man/groupmems.8.xml 2024-02-09 10:42:20.337036378 +0100 -@@ -156,20 +156,10 @@ - - SETUP - -- The groupmems executable should be in mode -- 2710 as user root and in group -- groups. The system administrator can add users to -- group groups to allow or disallow them using the -- groupmems utility to manage their own group -- membership list. -+ In this operating system the groupmems executable -+ is not setuid and regular users cannot use it to manipulate -+ the membership of their own group. - -- -- -- $ groupadd -r groups -- $ chmod 2710 groupmems -- $ chown root:groups groupmems -- $ groupmems -g groups -a gk4 -- - - - -diff -up shadow-4.15.0/man/ja/man5/login.defs.5.manfix shadow-4.15.0/man/ja/man5/login.defs.5 ---- shadow-4.15.0/man/ja/man5/login.defs.5.manfix 2023-03-13 21:58:56.000000000 +0100 -+++ shadow-4.15.0/man/ja/man5/login.defs.5 2024-02-09 10:42:20.337036378 +0100 -@@ -123,10 +123,6 @@ 以下の参照表は、 - shadow パスワード機能のどのプログラムが - どのパラメータを使用するかを示したものである。 - .na --.IP chfn 12 --CHFN_AUTH CHFN_RESTRICT --.IP chsh 12 --CHFN_AUTH - .IP groupadd 12 - GID_MAX GID_MIN - .IP newusers 12 -diff -up shadow-4.15.0/man/login.defs.5.xml.manfix shadow-4.15.0/man/login.defs.5.xml ---- shadow-4.15.0/man/login.defs.5.xml.manfix 2024-01-22 22:36:43.000000000 +0100 -+++ shadow-4.15.0/man/login.defs.5.xml 2024-02-09 10:45:49.014407259 +0100 -@@ -144,6 +144,17 @@ - long numeric parameters is machine-dependent. - - -+ -+ Please note that the parameters in this configuration file control the -+ behavior of the tools from the shadow-utils component. None of these -+ tools uses the PAM mechanism, and the utilities that use PAM (such as the -+ passwd command) should be configured elsewhere. The only values that -+ affect PAM modules are ENCRYPT_METHOD and SHA_CRYPT_MAX_ROUNDS -+ for pam_unix module, FAIL_DELAY for pam_faildelay module, -+ and UMASK for pam_umask module. Refer to -+ pam(8) for more information. -+ -+ - The following configuration items are provided: - - -@@ -240,16 +251,6 @@ - - - -- chfn -- -- -- CHFN_AUTH -- CHFN_RESTRICT -- LOGIN_STRING -- -- -- -- - chgpasswd - - -@@ -276,14 +277,6 @@ - - - -- -- chsh -- -- -- CHSH_AUTH LOGIN_STRING -- -- -- - - - -@@ -352,34 +345,6 @@ - LASTLOG_UID_MAX - - -- -- login -- -- -- CONSOLE -- CONSOLE_GROUPS DEFAULT_HOME -- ENV_HZ ENV_PATH ENV_SUPATH -- ENV_TZ ENVIRON_FILE -- ERASECHAR FAIL_DELAY -- FAILLOG_ENAB -- FAKE_SHELL -- FTMP_FILE -- HUSHLOGIN_FILE -- ISSUE_FILE -- KILLCHAR -- LASTLOG_ENAB LASTLOG_UID_MAX -- LOGIN_RETRIES -- LOGIN_STRING -- LOGIN_TIMEOUT LOG_OK_LOGINS LOG_UNKFAIL_ENAB -- MAIL_CHECK_ENAB MAIL_DIR MAIL_FILE -- MOTD_FILE NOLOGINS_FILE PORTTIME_CHECKS_ENAB -- QUOTAS_ENAB -- TTYGROUP TTYPERM TTYTYPE_FILE -- ULIMIT UMASK -- USERGROUPS_ENAB -- -- -- - - - newgrp / sg -@@ -451,32 +416,6 @@ - - - -- -- su -- -- -- CONSOLE -- CONSOLE_GROUPS DEFAULT_HOME -- ENV_HZ ENVIRON_FILE -- ENV_PATH ENV_SUPATH -- ENV_TZ LOGIN_STRING MAIL_CHECK_ENAB -- MAIL_DIR MAIL_FILE QUOTAS_ENAB -- SULOG_FILE SU_NAME -- SU_WHEEL_ONLY -- SYSLOG_SU_ENAB -- USERGROUPS_ENAB -- -- -- -- -- sulogin -- -- -- ENV_HZ -- ENV_TZ -- -- -- - - useradd - diff --git a/shadow-4.19.3-chkhash.patch b/shadow-4.19.3-chkhash.patch deleted file mode 100644 index 6dfc159..0000000 --- a/shadow-4.19.3-chkhash.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 4b2e669441438a6ae91c82a24c796894aa6a53b2 Mon Sep 17 00:00:00 2001 -From: Alejandro Colomar -Date: Thu, 15 Jan 2026 01:14:46 +0100 -Subject: [PATCH 1/3] lib/chkhash.c: is_valid_hash(): Update comment - -This checks the entire shadow(5) 2nd field, which is more than just -a hash. - -Reported-by: Tobias Stoeckmann -Signed-off-by: Alejandro Colomar -(cherry picked from commit bce404a7a831de911cf20fc8d4c548957f70bc72) ---- - lib/chkhash.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/lib/chkhash.c b/lib/chkhash.c -index 348dfe7478f8..48aaa417e9a9 100644 ---- a/lib/chkhash.c -+++ b/lib/chkhash.c -@@ -31,9 +31,7 @@ match_regex(const char *pattern, const char *string) - - - /* -- * is_valid_hash - check if the given string is a valid password hash -- * -- * Returns true if the string appears to be a valid hash, false otherwise. -+ * is_valid_hash - check if the string is a valid shadow(5) 2nd field. - * - * regex from: https://man.archlinux.org/man/crypt.5.en - */ --- -2.53.0 - - -From b72386978e0c994c5efc91d548da68a8d97088ab Mon Sep 17 00:00:00 2001 -From: Alejandro Colomar -Date: Thu, 15 Jan 2026 01:24:10 +0100 -Subject: [PATCH 2/3] lib/chkhash.c: is_valid_hash(): Comment meaning of !hash - and * - -Signed-off-by: Alejandro Colomar -(cherry picked from commit 9a86c515a1e7caeeb9e60fa63871170a2dfd98f0) ---- - lib/chkhash.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/lib/chkhash.c b/lib/chkhash.c -index 48aaa417e9a9..9123038adef0 100644 ---- a/lib/chkhash.c -+++ b/lib/chkhash.c -@@ -38,12 +38,14 @@ match_regex(const char *pattern, const char *string) - bool - is_valid_hash(const char *hash) - { -+ // Password temporarily locked - hash = strprefix(hash, "!") ?: hash; - - // Passwordless account; discouraged - if (streq(hash, "")) - return true; - -+ // Password permanently locked (and forgotten) - if (streq(hash, "*")) - return true; - --- -2.53.0 - - -From 4486e3e0f8b74e6af27b5dcb4114fd776afdd605 Mon Sep 17 00:00:00 2001 -From: Alejandro Colomar -Date: Fri, 16 Jan 2026 01:52:32 +0100 -Subject: [PATCH 3/3] man/shadow.5.xml: Document "*" - -Signed-off-by: Alejandro Colomar -(cherry picked from commit 6be13b2f84a2c1a0d0f4129b5258b4b443e7f86c) ---- - man/shadow.5.xml | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/man/shadow.5.xml b/man/shadow.5.xml -index dc7fdfde542f..d3cc03982c47 100644 ---- a/man/shadow.5.xml -+++ b/man/shadow.5.xml -@@ -82,8 +82,12 @@ - If the password field begins with an exclamation mark !, - the password is locked. - The remaining characters on the -- line represent the password field before the password was -- locked. -+ line represent the password hash. -+ -+ -+ If the password hash consists of a star *, -+ password access is effectively disallowed; -+ this is because no password can produce a hash like this. - - - Refer to crypt --- -2.53.0 - diff --git a/shadow-4.19.3-useradd-fix-btrfs.patch b/shadow-4.19.3-useradd-fix-btrfs.patch deleted file mode 100644 index 47671d9..0000000 --- a/shadow-4.19.3-useradd-fix-btrfs.patch +++ /dev/null @@ -1,492 +0,0 @@ -From 4079070c4b8ced8df9d86366ad113fc3c2e4e49c Mon Sep 17 00:00:00 2001 -From: Alejandro Colomar -Date: Wed, 22 Apr 2026 11:02:36 +0200 -Subject: [PATCH 1/5] lib/btrfs.c: btrfs_is_subvolume(): Simplify error check - -Signed-off-by: Alejandro Colomar ---- - lib/btrfs.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/lib/btrfs.c b/lib/btrfs.c -index 85ec7dbc..fe20cf30 100644 ---- a/lib/btrfs.c -+++ b/lib/btrfs.c -@@ -67,8 +67,7 @@ int btrfs_is_subvolume(const char *path) - if (ret <= 0) - return ret; - -- ret = stat(path, &st); -- if (ret == -1) -+ if (stat(path, &st) == -1) - return -1; - - if (st.st_ino != BTRFS_FIRST_FREE_OBJECTID || !S_ISDIR(st.st_mode)) { --- -2.53.0 - - -From 7a4faaaf46314547cc5e6c8264c3a11753ef9352 Mon Sep 17 00:00:00 2001 -From: Alejandro Colomar -Date: Wed, 22 Apr 2026 11:14:20 +0200 -Subject: [PATCH 2/5] lib/, src/: Move statfs(2) call out of is_btrfs() - -This simplifies the return value of is_btrfs() into a boolean. - -Signed-off-by: Alejandro Colomar ---- - lib/btrfs.c | 25 +++++++++---------------- - lib/prototypes.h | 3 ++- - src/useradd.c | 11 +++++++++-- - 3 files changed, 20 insertions(+), 19 deletions(-) - -diff --git a/lib/btrfs.c b/lib/btrfs.c -index fe20cf30..065c7938 100644 ---- a/lib/btrfs.c -+++ b/lib/btrfs.c -@@ -60,12 +60,13 @@ int btrfs_remove_subvolume(const char *path) - */ - int btrfs_is_subvolume(const char *path) - { -- struct stat st; -- int ret; -+ struct stat st; -+ struct statfs sfs; - -- ret = is_btrfs(path); -- if (ret <= 0) -- return ret; -+ if (statfs(path, &sfs) == -1) -+ return -1; -+ if (!is_btrfs(&sfs)) -+ return 0; - - if (stat(path, &st) == -1) - return -1; -@@ -78,16 +79,8 @@ int btrfs_is_subvolume(const char *path) - } - - --/* Adapted from btrfsprogs */ --int is_btrfs(const char *path) -+bool -+is_btrfs(const struct statfs *sfs) - { -- struct statfs sfs; -- int ret; -- -- ret = statfs(path, &sfs); -- if (ret == -1) -- return -1; -- -- return sfs.f_type == BTRFS_SUPER_MAGIC; -+ return sfs->f_type == BTRFS_SUPER_MAGIC; - } -- -diff --git a/lib/prototypes.h b/lib/prototypes.h -index 9a03e312..42aa2923 100644 ---- a/lib/prototypes.h -+++ b/lib/prototypes.h -@@ -23,6 +23,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -54,7 +55,7 @@ extern int isexpired (const struct passwd *, /*@null@*/const struct spwd *); - extern int btrfs_create_subvolume(const char *path); - extern int btrfs_remove_subvolume(const char *path); - extern int btrfs_is_subvolume(const char *path); --extern int is_btrfs(const char *path); -+extern bool is_btrfs(const struct statfs *sfs); - #endif - - /* basename() renamed to Basename() to avoid libc name space confusion */ -diff --git a/src/useradd.c b/src/useradd.c -index df679d28..5ce6cd6a 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -25,6 +25,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -2265,6 +2266,7 @@ static void create_home(const struct option_flags *flags) - #if WITH_BTRFS - if (subvolflg && (strlen(prefix_user_home) - (int)strlen(path)) <= 1) { - char *btrfs_check = strdup(path); -+ struct statfs sfs; - - if (!btrfs_check) { - fprintf(stderr, -@@ -2273,13 +2275,18 @@ static void create_home(const struct option_flags *flags) - fail_exit(E_HOMEDIR, process_selinux); - } - stpcpy(&btrfs_check[strlen(path) - strlen(cp) - 1], ""); -- if (is_btrfs(btrfs_check) <= 0) { -+ if (statfs(btrfs_check, &sfs) == -1) { -+ fprintf(stderr, "%s: statfs(\"%s\"): %s\n", -+ Prog, btrfs_check, strerrno()); -+ fail_exit(E_HOMEDIR, process_selinux); -+ } -+ free(btrfs_check); -+ if (!is_btrfs(&sfs)) { - fprintf(stderr, - _("%s: home directory \"%s\" must be mounted on BTRFS\n"), - Prog, path); - fail_exit(E_HOMEDIR, process_selinux); - } -- free(btrfs_check); - // make subvolume to mount for user instead of directory - if (btrfs_create_subvolume(path)) { - fprintf(stderr, --- -2.53.0 - - -From 96460c7240264c0022cebc9ba1774993ee2594cf Mon Sep 17 00:00:00 2001 -From: Alejandro Colomar -Date: Wed, 22 Apr 2026 11:21:14 +0200 -Subject: [PATCH 3/5] lib/, src/: Move btrfs.c prototypes to lib/btrfs.h - -Signed-off-by: Alejandro Colomar ---- - lib/Makefile.am | 2 +- - lib/btrfs.c | 4 ++++ - lib/btrfs.h | 23 +++++++++++++++++++++++ - lib/prototypes.h | 9 --------- - src/useradd.c | 1 + - src/userdel.c | 1 + - src/usermod.c | 1 + - 7 files changed, 31 insertions(+), 10 deletions(-) - create mode 100644 lib/btrfs.h - -diff --git a/lib/Makefile.am b/lib/Makefile.am -index 7c488f82..0664e610 100644 ---- a/lib/Makefile.am -+++ b/lib/Makefile.am -@@ -290,7 +290,7 @@ libshadow_la_SOURCES += tcbfuncs.c tcbfuncs.h - endif - - if WITH_BTRFS --libshadow_la_SOURCES += btrfs.c -+libshadow_la_SOURCES += btrfs.c btrfs.h - endif - - if ENABLE_LASTLOG -diff --git a/lib/btrfs.c b/lib/btrfs.c -index 065c7938..15b6b315 100644 ---- a/lib/btrfs.c -+++ b/lib/btrfs.c -@@ -1,3 +1,7 @@ -+#include "config.h" -+ -+#include "btrfs.h" -+ - #include - #include - #include -diff --git a/lib/btrfs.h b/lib/btrfs.h -new file mode 100644 -index 00000000..50b70488 ---- /dev/null -+++ b/lib/btrfs.h -@@ -0,0 +1,23 @@ -+// SPDX-FileCopyrightText: 2026, Alejandro Colomar -+// SPDX-License-Identifier: BSD-3-Clause -+ -+ -+#ifndef SHADOW_INCLUDE_LIB_BTRFS_H_ -+#define SHADOW_INCLUDE_LIB_BTRFS_H_ -+ -+ -+#include "config.h" -+ -+#include -+#include -+ -+ -+#ifdef WITH_BTRFS -+int btrfs_create_subvolume(const char *path); -+int btrfs_remove_subvolume(const char *path); -+int btrfs_is_subvolume(const char *path); -+bool is_btrfs(const struct statfs *sfs); -+#endif -+ -+ -+#endif // include guard -diff --git a/lib/prototypes.h b/lib/prototypes.h -index 42aa2923..d22c477a 100644 ---- a/lib/prototypes.h -+++ b/lib/prototypes.h -@@ -23,7 +23,6 @@ - - #include - #include --#include - #include - #include - #include -@@ -50,14 +49,6 @@ extern int expire (const struct passwd *, /*@null@*/const struct spwd *); - /* isexpired.c */ - extern int isexpired (const struct passwd *, /*@null@*/const struct spwd *); - --/* btrfs.c */ --#ifdef WITH_BTRFS --extern int btrfs_create_subvolume(const char *path); --extern int btrfs_remove_subvolume(const char *path); --extern int btrfs_is_subvolume(const char *path); --extern bool is_btrfs(const struct statfs *sfs); --#endif -- - /* basename() renamed to Basename() to avoid libc name space confusion */ - /* basename.c */ - extern /*@observer@*/const char *Basename (const char *str); -diff --git a/src/useradd.c b/src/useradd.c -index 5ce6cd6a..9bd32b11 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -34,6 +34,7 @@ - #include "alloc/malloc.h" - #include "atoi/a2i.h" - #include "atoi/getnum.h" -+#include "btrfs.h" - #include "chkname.h" - #include "defines.h" - #include "faillog.h" -diff --git a/src/userdel.c b/src/userdel.c -index 9b7d81be..ebd064c0 100644 ---- a/src/userdel.c -+++ b/src/userdel.c -@@ -20,6 +20,7 @@ - #include - #include - -+#include "btrfs.h" - #ifdef ACCT_TOOLS_SETUID - #ifdef USE_PAM - #include "pam_defs.h" -diff --git a/src/usermod.c b/src/usermod.c -index 7c0321a6..3afe19ea 100644 ---- a/src/usermod.c -+++ b/src/usermod.c -@@ -32,6 +32,7 @@ - #include "alloc/malloc.h" - #include "atoi/a2i.h" - #include "atoi/getnum.h" -+#include "btrfs.h" - #include "chkname.h" - #include "defines.h" - #include "faillog.h" --- -2.53.0 - - -From 7be9a6540f1cad477fd4f4e83d25904a5095bb86 Mon Sep 17 00:00:00 2001 -From: Hadi Chokr -Date: Tue, 21 Apr 2026 09:18:19 +0200 -Subject: [PATCH 4/5] useradd(8): fallback to regular dir for BTRFS home on - non-BTRFS parent - -When the --btrfs-subvolume-home option is used but the parent directory -is not on a BTRFS filesystem, useradd previously failed with an error. -This is too strict; instead, fall back to creating a regular directory -and issue a warning. The subvolume creation is attempted only when the -parent is BTRFS. Otherwise, a regular directory is created and a -syslog(3) warning is logged. - -Fixes: 3e8c105 (2026-01-02; "src/useradd: Support config for creating home dirs as Btrfs subvolumes") -Co-authored-by: Hadi Chokr -Co-authored-by: Alejandro Colomar -Signed-off-by: Alejandro Colomar ---- - man/useradd.8.xml | 27 ++++++++++++++++++++++-- - src/useradd.c | 52 +++++++++++++++++++++++------------------------ - 2 files changed, 51 insertions(+), 28 deletions(-) - -diff --git a/man/useradd.8.xml b/man/useradd.8.xml -index 8a087e13..0bde6683 100644 ---- a/man/useradd.8.xml -+++ b/man/useradd.8.xml -@@ -2,6 +2,7 @@ - - - -- Note: this feature works only if the underlying filesystem supports -- Btrfs subvolumes. -+ If the parent directory of the user's home directory is -+ not on a Btrfs filesystem, -+ useradd will not create a -+ subvolume. -+ Instead, it creates a regular directory, -+ prints a warning to standard error, -+ and logs the event via syslog at level -+ LOG_WARN. -+ The user account is still created successfully. -+ -+ -+ If the filesystem type cannot be determined (e.g., because of -+ insufficient permissions, an I/O error, -+ or a -+ -+ statfs -+ 2 -+ -+ failure), -+ useradd treats this as a fatal error: -+ the home directory is not created, -+ the command exits with a non‑zero status -+ (E_HOMEDIR, 12), -+ and an error message is printed. - - - -diff --git a/src/useradd.c b/src/useradd.c -index 9bd32b11..9210379c 100644 ---- a/src/useradd.c -+++ b/src/useradd.c -@@ -1,11 +1,11 @@ --/* -- * SPDX-FileCopyrightText: 1991 - 1994, Julianne Frances Haugh -- * SPDX-FileCopyrightText: 1996 - 2000, Marek Michałkiewicz -- * SPDX-FileCopyrightText: 2000 - 2006, Tomasz Kłoczko -- * SPDX-FileCopyrightText: 2007 - 2012, Nicolas François -- * -- * SPDX-License-Identifier: BSD-3-Clause -- */ -+// SPDX-FileCopyrightText: 1991-1994, Julianne Frances Haugh -+// SPDX-FileCopyrightText: 1996-2000, Marek Michałkiewicz -+// SPDX-FileCopyrightText: 2000-2006, Tomasz Kłoczko -+// SPDX-FileCopyrightText: 2007-2012, Nicolas François -+// SPDX-FileCopyrightText: 2025-2026, Hadi Chokr -+// SPDX-FileCopyrightText: 2026, Alejandro Colomar -+// SPDX-License-Identifier: BSD-3-Clause -+ - - #include "config.h" - -@@ -2251,6 +2251,8 @@ static void create_home(const struct option_flags *flags) - owner root:root. - */ - for (cp = strtok(bhome, "/"); cp != NULL; cp = strtok(NULL, "/")) { -+ bool dir_created; -+ - /* Avoid turning a relative path into an absolute path. */ - if (strprefix(bhome, "/") || !streq(path, "")) - strcat(path, "/"); -@@ -2260,10 +2262,7 @@ static void create_home(const struct option_flags *flags) - continue; - } - -- /* Check if parent directory is BTRFS, fail if requesting -- subvolume but no BTRFS. The paths could be different by the -- trailing slash -- */ -+ dir_created = false; - #if WITH_BTRFS - if (subvolflg && (strlen(prefix_user_home) - (int)strlen(path)) <= 1) { - char *btrfs_check = strdup(path); -@@ -2284,25 +2283,26 @@ static void create_home(const struct option_flags *flags) - free(btrfs_check); - if (!is_btrfs(&sfs)) { - fprintf(stderr, -- _("%s: home directory \"%s\" must be mounted on BTRFS\n"), -- Prog, path); -- fail_exit(E_HOMEDIR, process_selinux); -+ _("%s: warning: \"%s\" is not on BTRFS; creating regular directory instead of subvolume\n"), -+ Prog, prefix_user_home); -+ } else { -+ if (btrfs_create_subvolume(path)) { -+ fprintf(stderr, -+ _("%s: failed to create BTRFS subvolume: %s\n"), -+ Prog, path); -+ fail_exit(E_HOMEDIR, process_selinux); -+ } -+ dir_created = true; - } -- // make subvolume to mount for user instead of directory -- if (btrfs_create_subvolume(path)) { -- fprintf(stderr, -- _("%s: failed to create BTRFS subvolume: %s\n"), -+ } -+#endif -+ if (!dir_created) { -+ if (mkdir(path, 0) != 0) { -+ fprintf(stderr, _("%s: cannot create directory %s\n"), - Prog, path); - fail_exit(E_HOMEDIR, process_selinux); - } - } -- else --#endif -- if (mkdir(path, 0) != 0) { -- fprintf(stderr, _("%s: cannot create directory %s\n"), -- Prog, path); -- fail_exit(E_HOMEDIR, process_selinux); -- } - if (chown(path, 0, 0) < 0) { - fprintf(stderr, - _("%s: warning: chown on `%s' failed: %m\n"), --- -2.53.0 - - -From 827f69b864461ab6d7549762bef06ab4495d2587 Mon Sep 17 00:00:00 2001 -From: Hadi Chokr -Date: Mon, 20 Apr 2026 12:27:31 +0200 -Subject: [PATCH 5/5] man/useradd.8.xml: Remove trailing spaces from - useradd.8.xml - -Signed-off-by: Hadi Chokr -Reviewed-by: Alejandro Colomar ---- - man/useradd.8.xml | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/man/useradd.8.xml b/man/useradd.8.xml -index 0bde6683..f85780e2 100644 ---- a/man/useradd.8.xml -+++ b/man/useradd.8.xml -@@ -207,7 +207,7 @@ - user's login directory. The default is to append the - LOGIN name to - BASE_DIR and use that as the -- login directory name. -+ login directory name. - The directory HOME_DIR is not created by - default. However it will be created for non-system users if either the - flag is specifed or -@@ -422,7 +422,7 @@ - - - -- Create the user's home directory if it does not exist. -+ Create the user's home directory if it does not exist. - The files and directories contained in the skeleton directory - (which can be defined with the option) - will be copied to the home directory. -@@ -512,7 +512,7 @@ - password himself. - - -- Note:Avoid this option on the command -+ Note:Avoid this option on the command - line because the password (or encrypted password) will - be visible by users listing the processes. - --- -2.53.0 - diff --git a/shadow-utils.spec b/shadow-utils.spec index 4f94261..a56f0b7 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,12 +1,12 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils -Version: 4.19.3 -Release: 4%{?dist} +Version: 4.20.0.rc3 +Release: 1%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow -Source0: https://github.com/shadow-maint/shadow/releases/download/4.19.3/shadow-4.19.3.tar.xz -Source1: https://github.com/shadow-maint/shadow/releases/download/4.19.3/shadow-4.19.3.tar.xz.asc +Source0: https://github.com/shadow-maint/shadow/releases/download/4.20.0-rc3/shadow-4.20.0-rc3.tar.xz +Source1: https://github.com/shadow-maint/shadow/releases/download/4.20.0-rc3/shadow-4.20.0-rc3.tar.xz.asc Source2: shadow-utils.useradd Source3: shadow-utils.login.defs Source4: shadow-bsd.txt @@ -20,14 +20,6 @@ Source7: passwd.pamd %global _ld_strict_symbol_defs 1 ### Patches ### -# Misc manual page changes - non-upstreamable -Patch0: shadow-4.15.0-manfix.patch -# https://github.com/shadow-maint/shadow/commit/3e8c105f0703264e947d8c034b90419794955d49 -Patch2: shadow-4-19-useradd-support-btrfs.patch -# https://github.com/shadow-maint/shadow/commit/6be13b2f84a2c1a0d0f4129b5258b4b443e7f86c -Patch3: shadow-4.19.3-chkhash.patch -# https://github.com/shadow-maint/shadow/commit/827f69b864461ab6d7549762bef06ab4495d2587 -Patch4: shadow-4.19.3-useradd-fix-btrfs.patch ### Dependencies ### Requires: audit-libs >= 1.6.5 @@ -106,7 +98,7 @@ Requires: shadow-utils-subid = %{epoch}:%{version}-%{release} Development files for shadow-utils-subid. %prep -%autosetup -p 1 -S git -n shadow-4.19.3 +%autosetup -p 1 -S git -n shadow-4.20.0-rc3 iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -163,26 +155,20 @@ mv -v $RPM_BUILD_ROOT/usr/sbin/* $RPM_BUILD_ROOT%{_bindir}/ # Remove binaries we don't use. rm $RPM_BUILD_ROOT%{_bindir}/chfn rm $RPM_BUILD_ROOT%{_bindir}/chsh -rm $RPM_BUILD_ROOT%{_bindir}/expiry rm $RPM_BUILD_ROOT%{_bindir}/login rm $RPM_BUILD_ROOT%{_bindir}/su rm $RPM_BUILD_ROOT%{_bindir}/faillog -rm $RPM_BUILD_ROOT%{_sbindir}/logoutd rm $RPM_BUILD_ROOT%{_sbindir}/nologin rm $RPM_BUILD_ROOT%{_mandir}/man1/chfn.* rm $RPM_BUILD_ROOT%{_mandir}/*/man1/chfn.* rm $RPM_BUILD_ROOT%{_mandir}/man1/chsh.* rm $RPM_BUILD_ROOT%{_mandir}/*/man1/chsh.* -rm $RPM_BUILD_ROOT%{_mandir}/man1/expiry.* -rm $RPM_BUILD_ROOT%{_mandir}/*/man1/expiry.* rm $RPM_BUILD_ROOT%{_mandir}/man1/login.* rm $RPM_BUILD_ROOT%{_mandir}/*/man1/login.* rm $RPM_BUILD_ROOT%{_mandir}/man1/su.* rm $RPM_BUILD_ROOT%{_mandir}/*/man1/su.* rm $RPM_BUILD_ROOT%{_mandir}/man5/passwd.* rm $RPM_BUILD_ROOT%{_mandir}/*/man5/passwd.* -rm $RPM_BUILD_ROOT%{_mandir}/man8/logoutd.* -rm $RPM_BUILD_ROOT%{_mandir}/*/man8/logoutd.* rm $RPM_BUILD_ROOT%{_mandir}/man8/nologin.* rm $RPM_BUILD_ROOT%{_mandir}/*/man8/nologin.* rm $RPM_BUILD_ROOT%{_mandir}/man3/getspnam.* @@ -195,7 +181,6 @@ rm $RPM_BUILD_ROOT%{_mandir}/*/man8/faillog.* # Remove PAM service files we don't use. rm $RPM_BUILD_ROOT%{_pam_confdir}/chfn rm $RPM_BUILD_ROOT%{_pam_confdir}/chsh -rm $RPM_BUILD_ROOT%{_pam_confdir}/groupmems rm $RPM_BUILD_ROOT%{_pam_confdir}/login rm $RPM_BUILD_ROOT%{_pam_confdir}/su @@ -279,6 +264,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Wed Jul 22 2026 Iker Pedrosa - 2:4.20.0-rc3-1 +- Rebase to version 4.20.0-rc3 + * Fri Jul 17 2026 Fedora Release Engineering - 2:4.19.3-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_45_Mass_Rebuild diff --git a/sources b/sources index d12859f..d0fb76c 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (shadow-4.19.3.tar.xz) = f2b41f8186681eb98dae0da87ed1a1f03327c5005c9d4bf9500801352e318de6f5954dc5b8f30ab9aece728b1efb74b4ff8fb2720acc4c2aaef701331a4a5a05 -SHA512 (shadow-4.19.3.tar.xz.asc) = 295a6bffefd333a9ea84fa59b368f5c48d0ac5224199624b768087098110b0f0c19bef37f5c474c45277980758dcb6728e8bb17eb7ab1a57603cad41f1dd00ab +SHA512 (shadow-4.20.0-rc3.tar.xz) = 49a3662d10669c5f34af012b2397324ffe11544c1f09d89a32408a9c8928cd4d313c16ed3afaa6ff8665f8f224de139170dc0d9c5dea127986c2b9350c117d1a +SHA512 (shadow-4.20.0-rc3.tar.xz.asc) = 719b80d1331fe825c0f0279309e7eb56b0a767e61fda845ea051c60128fdbc4abc1b9e9f0569fa6b9073c7a8712ce0b144f33b472cf3eebd32e75668f745cd1c From c8aec6bdba74d16b628a0bd1c440f17ed91bd050 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Wed, 22 Jul 2026 16:44:45 +0200 Subject: [PATCH 133/134] Tests: update dependencies System test framework requires gcc, python3-devel and libssh-devel installed before pip tries to compile ansible-pylibssh. Signed-off-by: Iker Pedrosa --- plans/tier0-functional.fmf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plans/tier0-functional.fmf b/plans/tier0-functional.fmf index 7fb6f9c..a9939b5 100644 --- a/plans/tier0-functional.fmf +++ b/plans/tier0-functional.fmf @@ -14,7 +14,10 @@ prepare: how: install package: - expect + - gcc - git + - libssh-devel + - python3-devel - python3-pip - name: Setup SSH keys for localhost testing From 103ee1cc475003e8c32e3f54792aaca0cef33250 Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Wed, 29 Jul 2026 15:27:11 +0200 Subject: [PATCH 134/134] Rebase to version 4.20.0 Signed-off-by: Iker Pedrosa --- .gitignore | 2 ++ shadow-utils.spec | 11 +++++++---- sources | 4 ++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 13adb8c..3023995 100644 --- a/.gitignore +++ b/.gitignore @@ -52,3 +52,5 @@ shadow-4.1.4.2.tar.bz2 /shadow-4.20.0-rc2.tar.xz.asc /shadow-4.20.0-rc3.tar.xz /shadow-4.20.0-rc3.tar.xz.asc +/shadow-4.20.0.tar.xz +/shadow-4.20.0.tar.xz.asc diff --git a/shadow-utils.spec b/shadow-utils.spec index a56f0b7..7bc7e8b 100644 --- a/shadow-utils.spec +++ b/shadow-utils.spec @@ -1,12 +1,12 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils -Version: 4.20.0.rc3 +Version: 4.20.0 Release: 1%{?dist} Epoch: 2 License: BSD-3-Clause AND GPL-2.0-or-later URL: https://github.com/shadow-maint/shadow -Source0: https://github.com/shadow-maint/shadow/releases/download/4.20.0-rc3/shadow-4.20.0-rc3.tar.xz -Source1: https://github.com/shadow-maint/shadow/releases/download/4.20.0-rc3/shadow-4.20.0-rc3.tar.xz.asc +Source0: https://github.com/shadow-maint/shadow/releases/download/4.20.0/shadow-4.20.0.tar.xz +Source1: https://github.com/shadow-maint/shadow/releases/download/4.20.0/shadow-4.20.0.tar.xz.asc Source2: shadow-utils.useradd Source3: shadow-utils.login.defs Source4: shadow-bsd.txt @@ -98,7 +98,7 @@ Requires: shadow-utils-subid = %{epoch}:%{version}-%{release} Development files for shadow-utils-subid. %prep -%autosetup -p 1 -S git -n shadow-4.20.0-rc3 +%autosetup -p 1 -S git -n shadow-4.20.0 iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -264,6 +264,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a %{_libdir}/libsubid.so %changelog +* Wed Jul 29 2026 Iker Pedrosa - 2:4.20.0-1 +- Rebase to version 4.20.0 + * Wed Jul 22 2026 Iker Pedrosa - 2:4.20.0-rc3-1 - Rebase to version 4.20.0-rc3 diff --git a/sources b/sources index d0fb76c..7669083 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (shadow-4.20.0-rc3.tar.xz) = 49a3662d10669c5f34af012b2397324ffe11544c1f09d89a32408a9c8928cd4d313c16ed3afaa6ff8665f8f224de139170dc0d9c5dea127986c2b9350c117d1a -SHA512 (shadow-4.20.0-rc3.tar.xz.asc) = 719b80d1331fe825c0f0279309e7eb56b0a767e61fda845ea051c60128fdbc4abc1b9e9f0569fa6b9073c7a8712ce0b144f33b472cf3eebd32e75668f745cd1c +SHA512 (shadow-4.20.0.tar.xz) = 0b8afded372e4d37a78f38cb972c0ab877870ef6356cdd1c45be3c708af3d1496c6f87de6bf6a5b1d217d4d52d7e2d15c28b26530949cc6de0231a4028930406 +SHA512 (shadow-4.20.0.tar.xz.asc) = e4b134543768f323df30a1e450c22086d013020928d62bd3207db7f633beea3587b67802da5b575d5a794e8c2bebd7a0abeba6ed69d44bf08adc37df3bf352ac