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