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 e2704e8..0000000
--- a/shadow-4.8-crypt_h.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-diff -up shadow-4.8/configure.ac.crypt_h shadow-4.8/configure.ac
---- shadow-4.8/configure.ac.crypt_h 2020-01-13 10:26:17.400481712 +0100
-+++ shadow-4.8/configure.ac 2020-01-13 10:29:11.563529093 +0100
-@@ -32,7 +32,7 @@ AC_HEADER_STDC
- AC_HEADER_SYS_WAIT
- AC_HEADER_STDBOOL
-
--AC_CHECK_HEADERS(errno.h fcntl.h limits.h unistd.h sys/time.h utmp.h \
-+AC_CHECK_HEADERS(crypt.h errno.h fcntl.h limits.h unistd.h sys/time.h utmp.h \
- utmpx.h termios.h termio.h sgtty.h sys/ioctl.h syslog.h paths.h \
- utime.h ulimit.h sys/capability.h sys/resource.h gshadow.h lastlog.h \
- locale.h rpc/key_prot.h netdb.h acl/libacl.h attr/libattr.h \
-diff -up shadow-4.8/lib/defines.h.crypt_h shadow-4.8/lib/defines.h
---- shadow-4.8/lib/defines.h.crypt_h 2019-07-23 17:26:08.000000000 +0200
-+++ shadow-4.8/lib/defines.h 2020-01-13 10:26:17.400481712 +0100
-@@ -4,6 +4,8 @@
- #ifndef _DEFINES_H_
- #define _DEFINES_H_
-
-+#include "config.h"
-+
- #if HAVE_STDBOOL_H
- # include
- #else
-@@ -94,6 +96,10 @@ char *strchr (), *strrchr (), *strtok ()
- # include
- #endif
-
-+#if HAVE_CRYPT_H
-+# include /* crypt(3) may be defined in here */
-+#endif
-+
- #if TIME_WITH_SYS_TIME
- # include
- # include
diff --git a/shadow-4.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 ddad268..0000000
--- a/shadow-4.8.1-covscan_fixes.patch
+++ /dev/null
@@ -1,817 +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 -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-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-login_defs_HMAC_CRYPTO_ALGO.patch b/shadow-4.8.1-login_defs_HMAC_CRYPTO_ALGO.patch
deleted file mode 100644
index 4a63100..0000000
--- a/shadow-4.8.1-login_defs_HMAC_CRYPTO_ALGO.patch
+++ /dev/null
@@ -1,89 +0,0 @@
-diff -up shadow-4.8.1/lib/getdef.c.login_defs_HMAC_CRYPTO_ALGO shadow-4.8.1/lib/getdef.c
---- shadow-4.8.1/lib/getdef.c.login_defs_HMAC_CRYPTO_ALGO 2021-06-24 15:55:32.960558932 +0200
-+++ shadow-4.8.1/lib/getdef.c 2021-06-24 15:55:32.975559187 +0200
-@@ -61,6 +61,7 @@ struct itemdef {
- {"ENV_TZ", NULL}, \
- {"FAILLOG_ENAB", NULL}, \
- {"FTMP_FILE", NULL}, \
-+ {"HMAC_CRYPTO_ALGO", NULL}, \
- {"ISSUE_FILE", NULL}, \
- {"LASTLOG_ENAB", NULL}, \
- {"LOGIN_STRING", NULL}, \
-diff -up shadow-4.8.1/man/login.defs.5.xml.login_defs_HMAC_CRYPTO_ALGO shadow-4.8.1/man/login.defs.5.xml
---- shadow-4.8.1/man/login.defs.5.xml.login_defs_HMAC_CRYPTO_ALGO 2021-06-24 15:55:32.929558405 +0200
-+++ shadow-4.8.1/man/login.defs.5.xml 2021-06-24 15:55:32.975559187 +0200
-@@ -50,6 +50,7 @@
-
-
-
-+
-
-
-
-@@ -197,6 +198,7 @@
- &FAKE_SHELL;
- &FTMP_FILE;
- &GID_MAX;
-+ &HMAC_CRYPTO_ALGO;
- &HOME_MODE;
- &HUSHLOGIN_FILE;
- &ISSUE_FILE;
-diff -up shadow-4.8.1/man/login.defs.d/HMAC_CRYPTO_ALGO.xml.login_defs_HMAC_CRYPTO_ALGO shadow-4.8.1/man/login.defs.d/HMAC_CRYPTO_ALGO.xml
---- shadow-4.8.1/man/login.defs.d/HMAC_CRYPTO_ALGO.xml.login_defs_HMAC_CRYPTO_ALGO 2021-06-24 15:55:32.975559187 +0200
-+++ shadow-4.8.1/man/login.defs.d/HMAC_CRYPTO_ALGO.xml 2021-06-24 15:55:32.975559187 +0200
-@@ -0,0 +1,44 @@
-+
-+
-+ (string)
-+
-+
-+ Used to select the HMAC cryptography algorithm that the pam_timestamp
-+ module is going to use to calculate the keyed-hash message authentication
-+ code.
-+
-+
-+ Note: Check hmac3
-+ to see the possible algorithms that are available in your system.
-+
-+
-+
-diff -up shadow-4.8.1/man/Makefile.am.login_defs_HMAC_CRYPTO_ALGO shadow-4.8.1/man/Makefile.am
---- shadow-4.8.1/man/Makefile.am.login_defs_HMAC_CRYPTO_ALGO 2021-06-24 15:55:32.975559187 +0200
-+++ shadow-4.8.1/man/Makefile.am 2021-06-24 15:57:11.231229970 +0200
-@@ -136,6 +136,7 @@ login_defs_v = \
- FAKE_SHELL.xml \
- FTMP_FILE.xml \
- GID_MAX.xml \
-+ HMAC_CRYPTO_ALGO.xml \
- HUSHLOGIN_FILE.xml \
- ISSUE_FILE.xml \
- KILLCHAR.xml \
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-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-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-useradd-avoid-generating-empty-subid-range.patch b/shadow-4.9-useradd-avoid-generating-empty-subid-range.patch
new file mode 100644
index 0000000..b94fd60
--- /dev/null
+++ b/shadow-4.9-useradd-avoid-generating-empty-subid-range.patch
@@ -0,0 +1,79 @@
+diff --git a/src/useradd.c b/src/useradd.c
+index baeffb35..9abeea6e 100644
+--- a/src/useradd.c
++++ b/src/useradd.c
+@@ -142,9 +142,7 @@ static bool is_sub_gid = false;
+ static bool sub_uid_locked = false;
+ static bool sub_gid_locked = false;
+ static uid_t sub_uid_start; /* New subordinate uid range */
+-static unsigned long sub_uid_count;
+ static gid_t sub_gid_start; /* New subordinate gid range */
+-static unsigned long sub_gid_count;
+ #endif /* ENABLE_SUBIDS */
+ static bool pw_locked = false;
+ static bool gr_locked = false;
+@@ -234,7 +232,7 @@ static void open_shadow (void);
+ static void faillog_reset (uid_t);
+ static void lastlog_reset (uid_t);
+ static void tallylog_reset (const char *);
+-static void usr_update (void);
++static void usr_update (unsigned long subuid_count, unsigned long subgid_count);
+ static void create_home (void);
+ static void create_mail (void);
+ static void check_uid_range(int rflg, uid_t user_id);
+@@ -2092,7 +2090,7 @@ static void tallylog_reset (const char *user_name)
+ * usr_update() creates the password file entries for this user
+ * and will update the group entries if required.
+ */
+-static void usr_update (void)
++static void usr_update (unsigned long subuid_count, unsigned long subgid_count)
+ {
+ struct passwd pwent;
+ struct spwd spent;
+@@ -2155,14 +2153,14 @@ static void usr_update (void)
+ }
+ #ifdef ENABLE_SUBIDS
+ if (is_sub_uid &&
+- (sub_uid_add(user_name, sub_uid_start, sub_uid_count) == 0)) {
++ (sub_uid_add(user_name, sub_uid_start, subuid_count) == 0)) {
+ fprintf (stderr,
+ _("%s: failed to prepare the new %s entry\n"),
+ Prog, sub_uid_dbname ());
+ fail_exit (E_SUB_UID_UPDATE);
+ }
+ if (is_sub_gid &&
+- (sub_gid_add(user_name, sub_gid_start, sub_gid_count) == 0)) {
++ (sub_gid_add(user_name, sub_gid_start, subgid_count) == 0)) {
+ fprintf (stderr,
+ _("%s: failed to prepare the new %s entry\n"),
+ Prog, sub_uid_dbname ());
+@@ -2624,16 +2622,16 @@ int main (int argc, char **argv)
+ }
+
+ #ifdef ENABLE_SUBIDS
+- if (is_sub_uid && sub_uid_count != 0) {
+- if (find_new_sub_uids(&sub_uid_start, &sub_uid_count) < 0) {
++ if (is_sub_uid && subuid_count != 0) {
++ if (find_new_sub_uids(&sub_uid_start, &subuid_count) < 0) {
+ fprintf (stderr,
+ _("%s: can't create subordinate user IDs\n"),
+ Prog);
+ fail_exit(E_SUB_UID_UPDATE);
+ }
+ }
+- if (is_sub_gid && sub_gid_count != 0) {
+- if (find_new_sub_gids(&sub_gid_start, &sub_gid_count) < 0) {
++ if (is_sub_gid && subgid_count != 0) {
++ if (find_new_sub_gids(&sub_gid_start, &subgid_count) < 0) {
+ fprintf (stderr,
+ _("%s: can't create subordinate group IDs\n"),
+ Prog);
+@@ -2642,7 +2640,7 @@ int main (int argc, char **argv)
+ }
+ #endif /* ENABLE_SUBIDS */
+
+- usr_update ();
++ usr_update (subuid_count, subgid_count);
+
+ close_files ();
+
diff --git a/shadow-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 9007657..6892b75 100644
--- a/shadow-utils.spec
+++ b/shadow-utils.spec
@@ -1,7 +1,7 @@
Summary: Utilities for managing accounts and shadow password files
Name: shadow-utils
-Version: 4.8.1
-Release: 12%{?dist}
+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,90 +17,39 @@ 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
-# Docfix for newusers - could be upstreamed
-Patch2: shadow-4.1.5.1-info-parent-dir.patch
-# Misc SElinux related changes - upstreamability unknown
-Patch6: shadow-4.8-selinux.patch
-# Syslog message change - could be upstreamed
-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 - only some of them could be upstreamed
-Patch15: shadow-4.8.1-manfix.patch
-# Userdel usage message change - could be upstreamed
-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
-# Handle include of crypt.h - could be upstreamed
-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/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
-Patch46: 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
-Patch47: shadow-4.8.1-libsubid_nsswitch_support.patch
-# https://github.com/shadow-maint/shadow/commit/186b1b7ac1a68d0fcc618a22da1a99232b420911
-Patch48: shadow-4.8.1-man-mention-nss-in-newuidmap.patch
-# https://github.com/shadow-maint/shadow/commit/f9831a4a1a20b0e8fe47cc72ec20018ec04dbb90
-Patch49: shadow-4.8.1-libsubid_not_print_error_messages.patch
-# https://github.com/shadow-maint/shadow/commit/c6cab4a7bafa18d9d65a333cac1261e7b5e32bc9
-Patch50: shadow-4.8.1-libsubid_init_return_false.patch
-# https://github.com/shadow-maint/shadow/commit/2f1f45d64fc7c10e7a3cbe00e89f63714343e526
-Patch51: shadow-4.8.1-useradd_SUB_UID_COUNT-0.patch
-# https://github.com/shadow-maint/shadow/commit/ea7af4e1543c63590d4107ae075fea385028997d
-Patch52: shadow-4.8.1-libsubid_simplify_ranges_variable.patch
-# https://github.com/shadow-maint/shadow/commit/0fe42f571c69f0105d31305f995c9887aeb9525e
-Patch53: shadow-4.8.1-libsubid_init_not_print_error_messages.patch
-# https://github.com/shadow-maint/shadow/commit/ec1951c181faed188464396b2cfdd2efb726c7f3
-Patch54: 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/commit/5939e066db2db487e9cc7f6d6ccac18386ab9422
-Patch55: shadow-4.8.1-man_clarify_subid_delegation.patch
-# https://github.com/shadow-maint/shadow/commit/bd920ab36a6c641e4a8769f8c7f8ca738ec61820
-Patch56: shadow-4.8.1-libsubid_make_logfd_not_extern.patch
-# https://github.com/shadow-maint/shadow/commit/b8cbc2c11369c1391832452e6ce0522c81bcf726
-Patch57: shadow-4.8.1-login_defs_HMAC_CRYPTO_ALGO.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
-# https://github.com/shadow-maint/shadow/commit/2c542f6c65f858b3dba20f58db4da56572f67a54
-Patch58: shadow-4.8.1-covscan_fixes.patch
+Patch13: shadow-4.8-ignore-login-prompt.patch
+# https://github.com/shadow-maint/shadow/commit/c6847011e8b656adacd9a0d2a78418cad0de34cb
+Patch14: shadow-4.9-newuidmap-libeconf-dependency.patch
+# https://github.com/shadow-maint/shadow/commit/e481437ab9ebe9a8bf8fbaabe986d42b2f765991
+Patch15: shadow-4.9-usermod-allow-all-group-types.patch
+# https://github.com/shadow-maint/shadow/pull/399
+Patch16: shadow-4.9-useradd-avoid-generating-empty-subid-range.patch
License: BSD and GPLv2+
BuildRequires: make
@@ -150,40 +99,21 @@ 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 .libsubid_creation
-%patch47 -p1 -b .libsubid_nsswitch_support
-%patch48 -p1 -b .man-mention-nss-in-newuidmap
-%patch49 -p1 -b .libsubid_not_print_error_messages
-%patch50 -p1 -b .libsubid_init_return_false
-%patch51 -p1 -b .useradd_SUB_UID_COUNT-0
-%patch52 -p1 -b .libsubid_simplify_ranges_variable
-%patch53 -p1 -b .libsubid_init_not_print_error_messages
-%patch54 -p1 -b .libsubid_fix_newusers_nss_provides_subids
-%patch55 -p1 -b .man_clarify_subid_delegation
-%patch56 -p1 -b .libsubid_make_logfd_not_extern
-%patch57 -p1 -b .login_defs_HMAC_CRYPTO_ALGO
-%patch58 -p1 -b .covscan_fixes
+%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
+%patch16 -p1 -b .useradd-avoid-generating-empty-subid-range
iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8
cp -f doc/HOWTO.utf8 doc/HOWTO
@@ -352,6 +282,12 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la
%{_libdir}/libsubid.so
%changelog
+* Thu Aug 12 2021 Iker Pedrosa - 2:4.9-1
+- Rebase to version 4.9. Resolves: #1989556
+- usermod: allow all group types with -G option. Resolves: #1975329
+- useradd: avoid generating an empty subid range
+- Clean spec file
+
* Tue Aug 10 2021 Mohan Boddu - 2:4.8.1-12
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688
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