Rebase to version 4.9

usermod: allow all group types with -G option (#1975327)
Clean spec file

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
This commit is contained in:
Iker Pedrosa 2021-08-04 10:14:14 +02:00
parent 58090e11f1
commit 94f04f9e71
45 changed files with 643 additions and 11716 deletions

2
.gitignore vendored
View File

@ -14,3 +14,5 @@ shadow-4.1.4.2.tar.bz2
/shadow-4.8.tar.xz.asc /shadow-4.8.tar.xz.asc
/shadow-4.8.1.tar.xz /shadow-4.8.1.tar.xz
/shadow-4.8.1.tar.xz.asc /shadow-4.8.1.tar.xz.asc
/shadow-4.9.tar.xz
/shadow-4.9.tar.xz.asc

View File

@ -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 @@
<para>
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.
</para>
<para>
If the home directory of an existing user is changed,

View File

@ -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);
}

View File

@ -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);

View File

@ -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;
}
}

View File

@ -1,58 +0,0 @@
From c93897a8d71b9b1790caf3b2dee38dbe62518ae3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org>
Date: Thu, 24 Jun 2021 12:39:27 +0200
Subject: [PATCH] lib/defines.h: Include <crypt.h> if present on the system.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The functions crypt(3), crypt_gensalt(3), and their
feature test macros may be defined in there.
Signed-off-by: Björn Esser <besser82@fedoraproject.org>
---
configure.ac | 2 +-
lib/defines.h | 10 ++++++++++
2 files changed, 11 insertions(+), 1 deletion(-)
Index: shadow-4.8.1/configure.ac
===================================================================
--- shadow-4.8.1.orig/configure.ac
+++ shadow-4.8.1/configure.ac
@@ -32,7 +32,7 @@ AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_HEADER_STDBOOL
-AC_CHECK_HEADERS(errno.h fcntl.h limits.h unistd.h sys/time.h utmp.h \
+AC_CHECK_HEADERS(crypt.h errno.h fcntl.h limits.h unistd.h sys/time.h utmp.h \
utmpx.h termios.h termio.h sgtty.h sys/ioctl.h syslog.h paths.h \
utime.h ulimit.h sys/capability.h sys/resource.h gshadow.h lastlog.h \
locale.h rpc/key_prot.h netdb.h acl/libacl.h attr/libattr.h \
Index: shadow-4.8.1/lib/defines.h
===================================================================
--- shadow-4.8.1.orig/lib/defines.h
+++ shadow-4.8.1/lib/defines.h
@@ -4,6 +4,8 @@
#ifndef _DEFINES_H_
#define _DEFINES_H_
+#include "config.h"
+
#if HAVE_STDBOOL_H
# include <stdbool.h>
#else
@@ -94,6 +96,14 @@ char *strchr (), *strrchr (), *strtok ();
# include <unistd.h>
#endif
+/*
+ * crypt(3), crypt_gensalt(3), and their
+ * feature test macros may be defined in here.
+ */
+#if HAVE_CRYPT_H
+# include <crypt.h>
+#endif
+
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>

View File

@ -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;
}

View File

@ -1,61 +0,0 @@
From 4dc62ebcf37d7568be1d4ca54367215eba8b8a28 Mon Sep 17 00:00:00 2001
From: ikerexxe <ipedrosa@redhat.com>
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

View File

@ -1,642 +0,0 @@
From 140510de9de4771feb3af1d859c09604043a4c9b Mon Sep 17 00:00:00 2001
From: ikerexxe <ipedrosa@redhat.com>
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 <ipedrosa@redhat.com>
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

View File

@ -1,39 +0,0 @@
From fb0f702cbf958a5ee9097c1611212c9880b347ce Mon Sep 17 00:00:00 2001
From: ikerexxe <ipedrosa@redhat.com>
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

View File

@ -1,793 +0,0 @@
From fd9d79a1a3438ba7703939cfcd45fc266782c64e Mon Sep 17 00:00:00 2001
From: whzhe <wanghongzhe@huawei.com>
Date: Thu, 17 Dec 2020 03:27:15 -0500
Subject: [PATCH] useradd.c:fix memleak in get_groups
Signed-off-by: whzhe <wanghongzhe@huawei.com>
---
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 <whzhe51@126.com>
Date: Sat, 19 Dec 2020 04:29:06 -0500
Subject: [PATCH] useradd.c:fix memleaks of grp Signed-off-by: whzhe51
<wanghongzhe@huawei.com>
---
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 <ipedrosa@redhat.com>
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 <ipedrosa@redhat.com>
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 <ipedrosa@redhat.com>
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 <ipedrosa@redhat.com>
---
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 <ipedrosa@redhat.com>
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

View File

@ -1,310 +0,0 @@
From ea04eb301d08c0c58f1120f87d4ec184d3983ce5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org>
Date: Tue, 15 Jun 2021 14:23:42 +0200
Subject: [PATCH] libmisc/salt.c: Use crypt_gensalt(), if available in
libcrypt.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Most Linux distributions, including Fedora and RHEL 8, are shipping
with libxcrypt >= 4.0.
Since that version of libxcrypt the provided family of crypt_gensalt()
functions are able to use automatic entropy drawn from secure system
ressources, like arc4random(), getentropy() or getrandom().
Anyways, the settings generated by crypt_gensalt() are always
guaranteed to works with the crypt() function.
Using crypt_gensalt() is also needed to make proper use of newer
hashing methods, like yescrypt, provided by libxcrypt.
Signed-off-by: Björn Esser <besser82@fedoraproject.org>
---
libmisc/salt.c | 132 +++++++++++++++++++++++++++++++++++++++----------
1 file changed, 105 insertions(+), 27 deletions(-)
diff --git a/libmisc/salt.c b/libmisc/salt.c
index 13408a53..9fd34332 100644
--- a/libmisc/salt.c
+++ b/libmisc/salt.c
@@ -22,6 +22,13 @@
#include "defines.h"
#include "getdef.h"
+#if (defined CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY && \
+ CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY)
+#define USE_XCRYPT_GENSALT 1
+#else
+#define USE_XCRYPT_GENSALT 0
+#endif
+
/* Add the salt prefix. */
#define MAGNUM(array,ch) (array)[0]=(array)[2]='$',(array)[1]=(ch),(array)[3]='\0'
@@ -77,21 +84,26 @@
/* local function prototypes */
static long read_random_bytes (void);
+#if !USE_XCRYPT_GENSALT
static /*@observer@*/const char *gensalt (size_t salt_size);
+#endif /* !USE_XCRYPT_GENSALT */
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
static long shadow_random (long min, long max);
#endif /* USE_SHA_CRYPT || USE_BCRYPT */
#ifdef USE_SHA_CRYPT
-static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, /*@null@*/int *prefered_rounds);
+static /*@observer@*/const unsigned long SHA_get_salt_rounds (/*@null@*/int *prefered_rounds);
+static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, unsigned long rounds);
#endif /* USE_SHA_CRYPT */
#ifdef USE_BCRYPT
-static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, /*@null@*/int *prefered_rounds);
+static /*@observer@*/const unsigned long BCRYPT_get_salt_rounds (/*@null@*/int *prefered_rounds);
+static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, unsigned long rounds);
#endif /* USE_BCRYPT */
#ifdef USE_YESCRYPT
-static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, /*@null@*/int *prefered_cost);
+static /*@observer@*/const unsigned long YESCRYPT_get_salt_cost (/*@null@*/int *prefered_cost);
+static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, unsigned long cost);
#endif /* USE_YESCRYPT */
-#ifndef HAVE_L64A
+#if !USE_XCRYPT_GENSALT && !defined(HAVE_L64A)
static /*@observer@*/char *l64a (long value)
{
static char buf[8];
@@ -125,7 +137,7 @@ static /*@observer@*/char *l64a (long value)
return buf;
}
-#endif /* !HAVE_L64A */
+#endif /* !USE_XCRYPT_GENSALT && !defined(HAVE_L64A) */
/* Read sizeof (long) random bytes from /dev/urandom. */
static long read_random_bytes (void)
@@ -199,14 +211,10 @@ static long shadow_random (long min, long max)
#endif /* USE_SHA_CRYPT || USE_BCRYPT */
#ifdef USE_SHA_CRYPT
-/*
- * Fill a salt prefix specifying the rounds number for the SHA crypt methods
- * to a buffer.
- */
-static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, /*@null@*/int *prefered_rounds)
+/* Return the the rounds number for the SHA crypt methods. */
+static /*@observer@*/const unsigned long SHA_get_salt_rounds (/*@null@*/int *prefered_rounds)
{
unsigned long rounds;
- const size_t buf_begin = strlen (buf);
if (NULL == prefered_rounds) {
long min_rounds = getdef_long ("SHA_CRYPT_MIN_ROUNDS", -1);
@@ -245,6 +253,17 @@ static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, /*@null@*/int *pref
rounds = SHA_ROUNDS_MAX;
}
+ return rounds;
+}
+
+/*
+ * Fill a salt prefix specifying the rounds number for the SHA crypt methods
+ * to a buffer.
+ */
+static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, unsigned long rounds)
+{
+ const size_t buf_begin = strlen (buf);
+
/* Nothing to do here if SHA_ROUNDS_DEFAULT is used. */
if (rounds == SHA_ROUNDS_DEFAULT) {
return;
@@ -265,14 +284,10 @@ static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, /*@null@*/int *pref
#endif /* USE_SHA_CRYPT */
#ifdef USE_BCRYPT
-/*
- * Fill a salt prefix specifying the rounds number for the BCRYPT method
- * to a buffer.
- */
-static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, /*@null@*/int *prefered_rounds)
+/* Return the the rounds number for the BCRYPT method. */
+static /*@observer@*/const unsigned long BCRYPT_get_salt_rounds (/*@null@*/int *prefered_rounds)
{
unsigned long rounds;
- const size_t buf_begin = strlen (buf);
if (NULL == prefered_rounds) {
long min_rounds = getdef_long ("BCRYPT_MIN_ROUNDS", -1);
@@ -306,6 +321,11 @@ static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, /*@null@*/int *p
rounds = B_ROUNDS_MIN;
}
+#if USE_XCRYPT_GENSALT
+ if (rounds > B_ROUNDS_MAX) {
+ rounds = B_ROUNDS_MAX;
+ }
+#else /* USE_XCRYPT_GENSALT */
/*
* Use 19 as an upper bound for now,
* because musl doesn't allow rounds >= 20.
@@ -314,6 +334,18 @@ static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, /*@null@*/int *p
/* rounds = B_ROUNDS_MAX; */
rounds = 19;
}
+#endif /* USE_XCRYPT_GENSALT */
+
+ return rounds;
+}
+
+/*
+ * Fill a salt prefix specifying the rounds number for the BCRYPT method
+ * to a buffer.
+ */
+static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, unsigned long rounds)
+{
+ const size_t buf_begin = strlen (buf);
/*
* Check if the result buffer is long enough.
@@ -330,14 +362,10 @@ static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, /*@null@*/int *p
#endif /* USE_BCRYPT */
#ifdef USE_YESCRYPT
-/*
- * Fill a salt prefix specifying the cost for the YESCRYPT method
- * to a buffer.
- */
-static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, /*@null@*/int *prefered_cost)
+/* Return the the cost number for the YESCRYPT method. */
+static /*@observer@*/const unsigned long YESCRYPT_get_salt_cost (/*@null@*/int *prefered_cost)
{
unsigned long cost;
- const size_t buf_begin = strlen (buf);
if (NULL == prefered_cost) {
cost = getdef_num ("YESCRYPT_COST_FACTOR", Y_COST_DEFAULT);
@@ -356,6 +384,17 @@ static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, /*@null@*/int *p
cost = Y_COST_MAX;
}
+ return cost;
+}
+
+/*
+ * Fill a salt prefix specifying the cost for the YESCRYPT method
+ * to a buffer.
+ */
+static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, unsigned long cost)
+{
+ const size_t buf_begin = strlen (buf);
+
/*
* Check if the result buffer is long enough.
* We are going to write four bytes,
@@ -380,6 +419,7 @@ static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, /*@null@*/int *p
}
#endif /* USE_YESCRYPT */
+#if !USE_XCRYPT_GENSALT
static /*@observer@*/const char *gensalt (size_t salt_size)
{
static char salt[MAX_SALT_SIZE + 6];
@@ -397,6 +437,7 @@ static /*@observer@*/const char *gensalt (size_t salt_size)
return salt;
}
+#endif /* !USE_XCRYPT_GENSALT */
/*
* Generate 8 base64 ASCII characters of random salt. If MD5_CRYPT_ENAB
@@ -420,6 +461,7 @@ static /*@observer@*/const char *gensalt (size_t salt_size)
static char result[GENSALT_SETTING_SIZE];
size_t salt_len = MAX_SALT_SIZE;
const char *method;
+ unsigned long rounds = 0;
memset (result, '\0', GENSALT_SETTING_SIZE);
@@ -435,27 +477,32 @@ static /*@observer@*/const char *gensalt (size_t salt_size)
if (0 == strcmp (method, "MD5")) {
MAGNUM(result, '1');
salt_len = MD5_CRYPT_SALT_SIZE;
+ rounds = 0;
#ifdef USE_BCRYPT
} else if (0 == strcmp (method, "BCRYPT")) {
BCRYPTMAGNUM(result);
salt_len = BCRYPT_SALT_SIZE;
- BCRYPT_salt_rounds_to_buf (result, (int *) arg);
+ rounds = BCRYPT_get_salt_rounds ((int *) arg);
+ BCRYPT_salt_rounds_to_buf (result, rounds);
#endif /* USE_BCRYPT */
#ifdef USE_YESCRYPT
} else if (0 == strcmp (method, "YESCRYPT")) {
MAGNUM(result, 'y');
salt_len = YESCRYPT_SALT_SIZE;
- YESCRYPT_salt_cost_to_buf (result, (int *) arg);
+ rounds = YESCRYPT_get_salt_cost ((int *) arg);
+ YESCRYPT_salt_cost_to_buf (result, rounds);
#endif /* USE_YESCRYPT */
#ifdef USE_SHA_CRYPT
} else if (0 == strcmp (method, "SHA256")) {
MAGNUM(result, '5');
salt_len = SHA_CRYPT_SALT_SIZE;
- SHA_salt_rounds_to_buf (result, (int *) arg);
+ rounds = SHA_get_salt_rounds ((int *) arg);
+ SHA_salt_rounds_to_buf (result, rounds);
} else if (0 == strcmp (method, "SHA512")) {
MAGNUM(result, '6');
salt_len = SHA_CRYPT_SALT_SIZE;
- SHA_salt_rounds_to_buf (result, (int *) arg);
+ rounds = SHA_get_salt_rounds ((int *) arg);
+ SHA_salt_rounds_to_buf (result, rounds);
#endif /* USE_SHA_CRYPT */
} else if (0 != strcmp (method, "DES")) {
fprintf (shadow_logfd,
@@ -463,9 +510,39 @@ static /*@observer@*/const char *gensalt (size_t salt_size)
"Defaulting to DES.\n"),
method);
salt_len = MAX_SALT_SIZE;
+ rounds = 0;
memset (result, '\0', GENSALT_SETTING_SIZE);
}
+#if USE_XCRYPT_GENSALT
+ /*
+ * Prepare DES setting for crypt_gensalt(), if result
+ * has not been filled with anything previously.
+ */
+ if ('\0' == result[0]) {
+ /* Avoid -Wunused-but-set-variable. */
+ salt_len = GENSALT_SETTING_SIZE - 1;
+ rounds = 0;
+ memset (result, '.', salt_len);
+ result[salt_len] = '\0';
+ }
+
+ char *retval = crypt_gensalt (result, rounds, NULL, 0);
+
+ /* Should not happen, but... */
+ if (NULL == retval) {
+ fprintf (shadow_logfd,
+ _("Unable to generate a salt from setting "
+ "\"%s\", check your settings in "
+ "ENCRYPT_METHOD and the corresponding "
+ "configuration for your selected hash "
+ "method.\n"), result);
+
+ exit (1);
+ }
+
+ return retval;
+#else /* USE_XCRYPT_GENSALT */
/* Check if the result buffer is long enough. */
assert (GENSALT_SETTING_SIZE > strlen (result) + salt_len);
@@ -474,4 +551,5 @@ static /*@observer@*/const char *gensalt (size_t salt_size)
GENSALT_SETTING_SIZE - strlen (result) - 1);
return result;
+#endif /* USE_XCRYPT_GENSALT */
}

View File

@ -1,39 +0,0 @@
From 8d987bc55ccb65a3ef3a541cc5e351cfcbef0c90 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org>
Date: Sat, 12 Jun 2021 19:05:07 +0200
Subject: [PATCH] libmisc/salt.c: Use int pointer for YESCRYPT_salt_cost().
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The corresponding functions for the other hash methods all take
a pointer to an integer value as the only paramater, so this
particular function should do so as well.
Signed-off-by: Björn Esser <besser82@fedoraproject.org>
---
libmisc/salt.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libmisc/salt.c b/libmisc/salt.c
index c35c6797..1bfa015b 100644
--- a/libmisc/salt.c
+++ b/libmisc/salt.c
@@ -34,7 +34,7 @@ static /*@observer@*/const char *BCRYPT_salt_rounds (/*@null@*/int *prefered_rou
#endif /* USE_BCRYPT */
#ifdef USE_YESCRYPT
static /*@observer@*/const char *gensalt_yescrypt (void);
-static /*@observer@*/const char *YESCRYPT_salt_cost (/*@null@*/long *prefered_rounds);
+static /*@observer@*/const char *YESCRYPT_salt_cost (/*@null@*/int *prefered_cost);
#endif /* USE_YESCRYPT */
#ifndef HAVE_L64A
@@ -277,7 +277,7 @@ static /*@observer@*/const char *gensalt_bcrypt (void)
/*
* Return a salt prefix specifying the cost for the YESCRYPT method.
*/
-static /*@observer@*/const char *YESCRYPT_salt_cost (/*@null@*/long *prefered_cost)
+static /*@observer@*/const char *YESCRYPT_salt_cost (/*@null@*/int *prefered_cost)
{
static char cost_prefix[5];
long cost;

View File

@ -1,35 +0,0 @@
From 738d92a4bd99a2038aa5f97b2fc85daa7011e403 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org>
Date: Sat, 12 Jun 2021 13:54:14 +0200
Subject: [PATCH] libmisc/salt.c: bcrypt should use $2b$ as prefix for setting.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This prefix is the recommended one for new bcrypt hashes
for a long time.
Signed-off-by: Björn Esser <besser82@fedoraproject.org>
---
libmisc/salt.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/libmisc/salt.c b/libmisc/salt.c
index 1bfa015b..5dc521ef 100644
--- a/libmisc/salt.c
+++ b/libmisc/salt.c
@@ -90,12 +90,8 @@ static void seedRNG (void)
*/
#define MAGNUM(array,ch) (array)[0]=(array)[2]='$',(array)[1]=(ch),(array)[3]='\0'
#ifdef USE_BCRYPT
-/*
- * Using the Prefix $2a$ to enable an anti-collision safety measure in musl libc.
- * Negatively affects a subset of passwords containing the '\xff' character,
- * which is not valid UTF-8 (so "unlikely to cause much annoyance").
- */
-#define BCRYPTMAGNUM(array) (array)[0]=(array)[3]='$',(array)[1]='2',(array)[2]='a',(array)[4]='\0'
+/* Use $2b$ as prefix for compatibility with OpenBSD's bcrypt. */
+#define BCRYPTMAGNUM(array) (array)[0]=(array)[3]='$',(array)[1]='2',(array)[2]='b',(array)[4]='\0'
#endif /* USE_BCRYPT */
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)

View File

@ -1,123 +0,0 @@
From c82ed0c15e0e9e47df0b4c22672b72e35f061a9d
From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org>
Date: Sun, 4 Jul 2021 12:10:11 +0200
Subject: [PATCH] libmisc/salt.c: Use secure system ressources to obtain random
bytes.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In a previous commit we introduced /dev/urandom as a source to obtain
random bytes from. This may not be available on all systems, or when
operating inside of a chroot.
Almost all systems provide functions to obtain random bytes from
secure system ressources. Thus we should prefer to use these, and
fall back to /dev/urandom, if there is no such function present, as
a last resort.
Signed-off-by: Björn Esser <besser82@fedoraproject.org>
---
configure.ac | 17 +++++++++--------
libmisc/salt.c | 42 ++++++++++++++++++++++++++++++++++++------
2 files changed, 45 insertions(+), 14 deletions(-)
Index: shadow-4.8.1/configure.ac
===================================================================
--- shadow-4.8.1.orig/configure.ac
+++ shadow-4.8.1/configure.ac
@@ -44,18 +44,19 @@ AC_HEADER_STDBOOL
AC_CHECK_HEADERS(crypt.h errno.h fcntl.h limits.h unistd.h sys/time.h utmp.h \
utmpx.h termios.h termio.h sgtty.h sys/ioctl.h syslog.h paths.h \
- utime.h ulimit.h sys/capability.h sys/resource.h gshadow.h lastlog.h \
- locale.h rpc/key_prot.h netdb.h acl/libacl.h attr/libattr.h \
- attr/error_context.h)
+ utime.h ulimit.h sys/capability.h sys/random.h sys/resource.h \
+ gshadow.h lastlog.h locale.h rpc/key_prot.h netdb.h acl/libacl.h \
+ attr/libattr.h attr/error_context.h)
dnl shadow now uses the libc's shadow implementation
AC_CHECK_HEADER([shadow.h],,[AC_MSG_ERROR([You need a libc with shadow.h])])
-AC_CHECK_FUNCS(l64a fchmod fchown fsync futimes getgroups gethostname getspnam \
- gettimeofday getusershell getutent initgroups lchown lckpwdf lstat \
- lutimes memcpy memset setgroups sigaction strchr updwtmp updwtmpx innetgr \
- getpwnam_r getpwuid_r getgrnam_r getgrgid_r getspnam_r getaddrinfo \
- ruserok dlopen)
+AC_CHECK_FUNCS(arc4random_buf l64a fchmod fchown fsync futimes getgroups \
+ gethostname getentropy getrandom getspnam gettimeofday getusershell \
+ getutent initgroups lchown lckpwdf lstat lutimes memcpy memset \
+ setgroups sigaction strchr updwtmp updwtmpx innetgr getpwnam_r \
+ getpwuid_r getgrnam_r getgrgid_r getspnam_r getaddrinfo ruserok \
+ dlopen)
AC_SYS_LARGEFILE
dnl Checks for typedefs, structures, and compiler characteristics.
Index: shadow-4.8.1/libmisc/salt.c
===================================================================
--- shadow-4.8.1.orig/libmisc/salt.c
+++ shadow-4.8.1/libmisc/salt.c
@@ -15,6 +15,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#if HAVE_SYS_RANDOM_H
+#include <sys/random.h>
+#endif
#include "prototypes.h"
#include "defines.h"
#include "getdef.h"
@@ -128,19 +131,46 @@ static /*@observer@*/char *l64a (long va
static long read_random_bytes (void)
{
long randval = 0;
- FILE *f = fopen ("/dev/urandom", "r");
- if (fread (&randval, sizeof (randval), 1, f) != sizeof (randval))
- {
- fprintf (shadow_logfd,
- _("Unable to read from /dev/urandom.\n"));
+#ifdef HAVE_ARC4RANDOM_BUF
+ /* arc4random_buf, if it exists, can never fail. */
+ arc4random_buf (&randval, sizeof (randval));
+ goto end;
+
+#elif defined(HAVE_GETENTROPY)
+ /* getentropy may exist but lack kernel support. */
+ if (getentropy (&randval, sizeof (randval))) {
+ goto fail;
+ }
+
+ goto end;
+
+#elif defined(HAVE_GETRANDOM)
+ /* Likewise getrandom. */
+ if ((size_t) getrandom (&randval, sizeof (randval), 0) != sizeof (randval)) {
+ goto fail;
+ }
+ goto end;
+
+#else
+ FILE *f = fopen ("/dev/urandom", "r");
+
+ if (fread (&randval, sizeof (randval), 1, f) != sizeof (randval)) {
fclose(f);
- exit (1);
+ goto fail;
}
fclose(f);
+ goto end;
+#endif
+
+fail:
+ fprintf (shadow_logfd,
+ _("Unable to obtain random bytes.\n"));
+ exit (1);
+end:
return randval;
}

File diff suppressed because it is too large Load Diff

View File

@ -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) {

View File

@ -1,40 +0,0 @@
From b0e86b959fe5c086ffb5e7eaf3c1b1e9219411e9 Mon Sep 17 00:00:00 2001
From: Serge Hallyn <serge@hallyn.com>
Date: Sun, 23 May 2021 08:03:10 -0500
Subject: [PATCH] libsubid_init: don't print messages on error
Signed-off-by: Serge Hallyn <serge@hallyn.com>
---
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

View File

@ -1,37 +0,0 @@
From e34f49c1966fcaa9390a544a0136ec189a3c870e Mon Sep 17 00:00:00 2001
From: Serge Hallyn <serge@hallyn.com>
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 <serge@hallyn.com>
Cc: Alexey Tikhonov <atikhono@redhat.com>
---
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

View File

@ -1,41 +0,0 @@
From 1d767fb779d7b203ad609540d1dc605cf62d1050 Mon Sep 17 00:00:00 2001
From: Serge Hallyn <serge@hallyn.com>
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 <serge@hallyn.com>
---
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 <sys/types.h>
+#include <stdio.h>
#include <stdbool.h>
#ifndef SUBID_RANGE_DEFINED
--
2.31.1

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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 <stdio.h>
#include "commonio.h"
#include "subordinateio.h"
+#include "../libsubid/subid.h"
#include <sys/types.h>
#include <pwd.h>
#include <ctype.h>
@@ -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;

View File

@ -1,33 +0,0 @@
From df6ec1d1693c8c80c323b40d6fc82bb549363db3 Mon Sep 17 00:00:00 2001
From: Iker Pedrosa <ipedrosa@redhat.com>
Date: Mon, 29 Mar 2021 05:26:28 +0200
Subject: [PATCH] man: include lastlog file caveat (#313)
man/lastlog.8.xml: add another point to the caveats section regarding
the handling of the lastlog file by external tools.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=951564
---
man/lastlog.8.xml | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/man/lastlog.8.xml b/man/lastlog.8.xml
index fc096c8f..7e68282f 100644
--- a/man/lastlog.8.xml
+++ b/man/lastlog.8.xml
@@ -233,5 +233,12 @@
is no entries for users with UID between 170 and 800 lastlog will appear
to hang as it processes entries with UIDs 171-799).
</para>
+ <para>
+ Having high UIDs can create problems when handling the <term><filename>
+ /var/log/lastlog</filename></term> with external tools. Although the
+ actual file is sparse and does not use too much space, certain
+ applications are not designed to identify sparse files by default and may
+ require a specific option to handle them.
+ </para>
</refsect1>
</refentry>
--
2.30.2

View File

@ -1,44 +0,0 @@
From 186b1b7ac1a68d0fcc618a22da1a99232b420911 Mon Sep 17 00:00:00 2001
From: Serge Hallyn <serge@hallyn.com>
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 <serge@hallyn.com>
---
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 @@
<title>DESCRIPTION</title>
<para>
The <command>newgidmap</command> sets <filename>/proc/[pid]/gid_map</filename> based on its
- command line arguments and the gids allowed in <filename>/etc/subgid</filename>.
+ command line arguments and the gids allowed (either in <filename>/etc/subgid</filename> or
+ through the configured NSS subid module).
Note that the root user is not exempted from the requirement for a valid
<filename>/etc/subgid</filename> entry.
</para>
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 @@
<title>DESCRIPTION</title>
<para>
The <command>newuidmap</command> sets <filename>/proc/[pid]/uid_map</filename> based on its
- command line arguments and the uids allowed in <filename>/etc/subuid</filename>.
+ command line arguments and the uids allowed (either in <filename>/etc/subuid</filename> or
+ through the configured NSS subid module).
Note that the root user is not exempted from the requirement for a valid
<filename>/etc/subuid</filename> entry.
</para>
--
2.30.2

View File

@ -1,246 +0,0 @@
From d5b15f8633d0eabed885cd16feda224ec2d59072 Mon Sep 17 00:00:00 2001
From: Iker Pedrosa <ipedrosa@redhat.com>
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 @@
<title>DESCRIPTION</title>
<para>
The <command>newgidmap</command> sets <filename>/proc/[pid]/gid_map</filename> based on its
- command line arguments and the gids allowed (either in <filename>/etc/subgid</filename> 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
+ (<filename>/etc/subgid</filename>) 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
+ <command>groupadd</command> is executed, then the command will fail and the entry will not be
+ created in <filename>/etc/subgid</filename>.
+ </para>
+
+ <para>
+ Note that the root group is not exempted from the requirement for a valid
<filename>/etc/subgid</filename> entry.
</para>
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 @@
<title>DESCRIPTION</title>
<para>
The <command>newuidmap</command> sets <filename>/proc/[pid]/uid_map</filename> based on its
- command line arguments and the uids allowed (either in <filename>/etc/subuid</filename> or
- through the configured NSS subid module).
+ command line arguments and the uids allowed. The subid delegation can come either from files
+ (<filename>/etc/subuid</filename>) 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
+ <command>useradd</command> is executed, then the command will fail and the entry will not be
+ created in <filename>/etc/subuid</filename>.
+ </para>
+
+ <para>
Note that the root user is not exempted from the requirement for a valid
<filename>/etc/subuid</filename> entry.
</para>
--
2.30.2
From 68ebbf936038e4e4c8b5105bd3246ef9709b6354 Mon Sep 17 00:00:00 2001
From: Iker Pedrosa <ipedrosa@redhat.com>
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 @@
<refsect1 id='description'>
<title>DESCRIPTION</title>
<para>
- The <command>newgidmap</command> sets <filename>/proc/[pid]/gid_map</filename> based on its
- command line arguments and the gids allowed. The subid delegation can come either from files
- (<filename>/etc/subgid</filename>) 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
- <command>groupadd</command> is executed, then the command will fail and the entry will not be
- created in <filename>/etc/subgid</filename>.
+ The <command>newgidmap</command> sets <filename>/proc/[pid]/gid_map</filename>
+ based on its command line arguments and the gids allowed. Subgid
+ delegation can either be managed via <filename>/etc/subgid</filename>
+ or through the configured NSS subid module. These options are mutually
+ exclusive.
</para>
<para>
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 @@
<refsect1 id='description'>
<title>DESCRIPTION</title>
<para>
- The <command>newuidmap</command> sets <filename>/proc/[pid]/uid_map</filename> based on its
- command line arguments and the uids allowed. The subid delegation can come either from files
- (<filename>/etc/subuid</filename>) 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
- <command>useradd</command> is executed, then the command will fail and the entry will not be
- created in <filename>/etc/subuid</filename>.
+ The <command>newuidmap</command> sets <filename>/proc/[pid]/uid_map</filename>
+ based on its command line arguments and the uids allowed. Subuid
+ delegation can either be managed via <filename>/etc/subuid</filename> or
+ through the configured NSS subid module. These options are mutually
+ exclusive.
</para>
<para>
--
2.31.1
From 0faec51bf0ec24e6e3d098cc55ed42584dd24efe Mon Sep 17 00:00:00 2001
From: Iker Pedrosa <ipedrosa@redhat.com>
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 @@
<surname>Biederman</surname>
<contrib>Creation, 2013</contrib>
</author>
+ <author>
+ <firstname>Iker</firstname>
+ <surname>Pedrosa</surname>
+ <contrib>Developer, 2021</contrib>
+ </author>
</refentryinfo>
<refmeta>
<refentrytitle>subgid</refentrytitle>
@@ -48,11 +53,36 @@
</refmeta>
<refnamediv id='name'>
<refname>subgid</refname>
- <refpurpose>the subordinate gid file</refpurpose>
+ <refpurpose>the configuration for subordinate group ids</refpurpose>
</refnamediv>
<refsect1 id='description'>
<title>DESCRIPTION</title>
+ <para>
+ Subgid authorizes a group id to map ranges of group ids from its namespace
+ into child namespaces.
+ </para>
+ <para>
+ The delegation of the subordinate gids can be configured via the
+ <replaceable>subid</replaceable> field in
+ <filename>/etc/nsswitch.conf</filename> file. Only one value can be set
+ as the delegation source. Setting this field to
+ <replaceable>files</replaceable> configures the delegation of gids to
+ <filename>/etc/subgid</filename>. Setting any other value treats
+ the delegation as a plugin following with a name of the form
+ <replaceable>libsubid_$value.so</replaceable>. If the value or plugin is
+ missing, then the subordinate gid delegation falls back to
+ <replaceable>files</replaceable>.
+ </para>
+ <para>
+ Note, that <command>groupadd</command> will only create entries in
+ <filename>/etc/subgid</filename> if subid delegation is managed via subid
+ files.
+ </para>
+ </refsect1>
+
+ <refsect1 id='local-subordinate-delegation'>
+ <title>LOCAL SUBORDINATE DELEGATION</title>
<para>
Each line in <filename>/etc/subgid</filename> 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 @@
<surname>Biederman</surname>
<contrib>Creation, 2013</contrib>
</author>
+ <author>
+ <firstname>Iker</firstname>
+ <surname>Pedrosa</surname>
+ <contrib>Developer, 2021</contrib>
+ </author>
</refentryinfo>
<refmeta>
<refentrytitle>subuid</refentrytitle>
@@ -48,11 +53,36 @@
</refmeta>
<refnamediv id='name'>
<refname>subuid</refname>
- <refpurpose>the subordinate uid file</refpurpose>
+ <refpurpose>the configuration for subordinate user ids</refpurpose>
</refnamediv>
<refsect1 id='description'>
<title>DESCRIPTION</title>
+ <para>
+ Subuid authorizes a user id to map ranges of user ids from its namespace
+ into child namespaces.
+ </para>
+ <para>
+ The delegation of the subordinate uids can be configured via the
+ <replaceable>subid</replaceable> field in
+ <filename>/etc/nsswitch.conf</filename> file. Only one value can be set
+ as the delegation source. Setting this field to
+ <replaceable>files</replaceable> configures the delegation of uids to
+ <filename>/etc/subuid</filename>. Setting any other value treats
+ the delegation as a plugin following with a name of the form
+ <replaceable>libsubid_$value.so</replaceable>. If the value or plugin is
+ missing, then the subordinate uid delegation falls back to
+ <replaceable>files</replaceable>.
+ </para>
+ <para>
+ Note, that <command>useradd</command> will only create entries in
+ <filename>/etc/subuid</filename> if subid delegation is managed via subid
+ files.
+ </para>
+ </refsect1>
+
+ <refsect1 id='local-subordinate-delegation'>
+ <title>LOCAL SUBORDINATE DELEGATION</title>
<para>
Each line in <filename>/etc/subuid</filename> contains
a user name and a range of subordinate user ids that user
--
2.31.1

View File

@ -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 <replaceable>LAST_DAY</replaceable> is set to
+ <emphasis>0</emphasis> the user is forced to change his password
+ on the next log on.
</para>
</listitem>
</varlistentry>
@@ -119,6 +122,13 @@
system again.
</para>
<para>
+ For example the following can be used to set an account to expire
+ in 180 days:
+ </para>
+ <programlisting>
+ chage -E $(date -d +180days +%Y-%m-%d)
+ </programlisting>
+ <para>
Passing the number <emphasis remap='I'>-1</emphasis> as the
<replaceable>EXPIRE_DATE</replaceable> will remove an account
expiration date.
@@ -239,6 +249,18 @@
The <command>chage</command> program requires a shadow password file to
be available.
</para>
+ <para>
+ 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.
+ </para>
+ <para>
+ The <command>chage</command> program will also not report any
+ inconsistency between the shadow and passwd files (e.g. missing x in
+ the passwd file). The <command>pwck</command> can be used to check
+ for this kind of inconsistencies.
+ </para>
<para>The <command>chage</command> command is restricted to the root
user, except for the <option>-l</option> 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 @@
<varlistentry>
<term><replaceable>4</replaceable></term>
<listitem>
- <para>GID not unique (when <option>-o</option> not used)</para>
+ <para>GID is already used (when called without <option>-o</option>)</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable>9</replaceable></term>
<listitem>
- <para>group name not unique</para>
+ <para>group name is already used</para>
</listitem>
</varlistentry>
<varlistentry>
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 @@
<refsect1 id='setup'>
<title>SETUP</title>
<para>
- The <command>groupmems</command> executable should be in mode
- <literal>2710</literal> as user <emphasis>root</emphasis> and in group
- <emphasis>groups</emphasis>. The system administrator can add users to
- group <emphasis>groups</emphasis> to allow or disallow them using the
- <command>groupmems</command> utility to manage their own group
- membership list.
+ In this operating system the <command>groupmems</command> executable
+ is not setuid and regular users cannot use it to manipulate
+ the membership of their own group.
</para>
-
- <programlisting>
- $ groupadd -r groups
- $ chmod 2710 groupmems
- $ chown root.groups groupmems
- $ groupmems -g groups -a gk4
- </programlisting>
</refsect1>
<refsect1 id='configuration'>
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.
</para>
+ <para>
+ 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 <emphasis>ENCRYPT_METHOD</emphasis> and <emphasis>SHA_CRYPT_MAX_ROUNDS</emphasis>
+ for pam_unix module, <emphasis>FAIL_DELAY</emphasis> for pam_faildelay module,
+ and <emphasis>UMASK</emphasis> for pam_umask module. Refer to
+ pam(8) for more information.
+ </para>
+
<para>The following configuration items are provided:</para>
<variablelist remap='IP'>
@@ -256,16 +267,6 @@
</listitem>
</varlistentry>
<varlistentry>
- <term>chfn</term>
- <listitem>
- <para>
- <phrase condition="no_pam">CHFN_AUTH</phrase>
- CHFN_RESTRICT
- <phrase condition="no_pam">LOGIN_STRING</phrase>
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
<term>chgpasswd</term>
<listitem>
<para>
@@ -286,14 +287,6 @@
</para>
</listitem>
</varlistentry>
- <varlistentry condition="no_pam">
- <term>chsh</term>
- <listitem>
- <para>
- CHSH_AUTH LOGIN_STRING
- </para>
- </listitem>
- </varlistentry>
<!-- expiry: no variables (CONSOLE_GROUPS linked, but not used) -->
<!-- faillog: no variables -->
<varlistentry>
@@ -359,34 +352,6 @@
<para>LASTLOG_UID_MAX</para>
</listitem>
</varlistentry>
- <varlistentry>
- <term>login</term>
- <listitem>
- <para>
- <phrase condition="no_pam">CONSOLE</phrase>
- CONSOLE_GROUPS DEFAULT_HOME
- <phrase condition="no_pam">ENV_HZ ENV_PATH ENV_SUPATH
- ENV_TZ ENVIRON_FILE</phrase>
- ERASECHAR FAIL_DELAY
- <phrase condition="no_pam">FAILLOG_ENAB</phrase>
- FAKE_SHELL
- <phrase condition="no_pam">FTMP_FILE</phrase>
- HUSHLOGIN_FILE
- <phrase condition="no_pam">ISSUE_FILE</phrase>
- KILLCHAR
- <phrase condition="no_pam">LASTLOG_ENAB LASTLOG_UID_MAX</phrase>
- LOGIN_RETRIES
- <phrase condition="no_pam">LOGIN_STRING</phrase>
- LOGIN_TIMEOUT LOG_OK_LOGINS LOG_UNKFAIL_ENAB
- <phrase condition="no_pam">MAIL_CHECK_ENAB MAIL_DIR MAIL_FILE
- MOTD_FILE NOLOGINS_FILE PORTTIME_CHECKS_ENAB
- QUOTAS_ENAB</phrase>
- TTYGROUP TTYPERM TTYTYPE_FILE
- <phrase condition="no_pam">ULIMIT UMASK</phrase>
- USERGROUPS_ENAB
- </para>
- </listitem>
- </varlistentry>
<!-- logoutd: no variables -->
<varlistentry>
<term>newgrp / sg</term>
@@ -415,17 +380,6 @@
</listitem>
</varlistentry>
<!-- nologin: no variables -->
- <varlistentry condition="no_pam">
- <term>passwd</term>
- <listitem>
- <para>
- ENCRYPT_METHOD MD5_CRYPT_ENAB OBSCURE_CHECKS_ENAB
- PASS_ALWAYS_WARN PASS_CHANGE_TRIES PASS_MAX_LEN PASS_MIN_LEN
- <phrase condition="sha_crypt">SHA_CRYPT_MAX_ROUNDS
- SHA_CRYPT_MIN_ROUNDS</phrase>
- </para>
- </listitem>
- </varlistentry>
<varlistentry>
<term>pwck</term>
<listitem>
@@ -452,32 +406,6 @@
</para>
</listitem>
</varlistentry>
- <varlistentry>
- <term>su</term>
- <listitem>
- <para>
- <phrase condition="no_pam">CONSOLE</phrase>
- CONSOLE_GROUPS DEFAULT_HOME
- <phrase condition="no_pam">ENV_HZ ENVIRON_FILE</phrase>
- ENV_PATH ENV_SUPATH
- <phrase condition="no_pam">ENV_TZ LOGIN_STRING MAIL_CHECK_ENAB
- MAIL_DIR MAIL_FILE QUOTAS_ENAB</phrase>
- SULOG_FILE SU_NAME
- <phrase condition="no_pam">SU_WHEEL_ONLY</phrase>
- SYSLOG_SU_ENAB
- <phrase condition="no_pam">USERGROUPS_ENAB</phrase>
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>sulogin</term>
- <listitem>
- <para>
- ENV_HZ
- <phrase condition="no_pam">ENV_TZ</phrase>
- </para>
- </listitem>
- </varlistentry>
<varlistentry>
<term>useradd</term>
<listitem>
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 @@
<listitem>
<para>
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.
</para>
<para>
The value 0 has a special meaning, which is that the user
@@ -208,8 +208,8 @@
</para>
<para>
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.
</para>
<para>
An empty field means that there are no enforcement of an
@@ -224,7 +224,7 @@
<listitem>
<para>
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.
</para>
<para>
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 @@
<option>CREATE_HOME</option> is not enabled, no home
directories are created.
</para>
+ <para>
+ 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.
+ </para>
</listitem>
</varlistentry>
<varlistentry>
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>-m</option>
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.
</para>
</listitem>
</varlistentry>
@@ -205,6 +206,12 @@
The group ownership of files outside of the user's home directory
must be fixed manually.
</para>
+ <para>
+ 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 <filename>/</filename>.
+ </para>
</listitem>
</varlistentry>
<varlistentry>
@@ -267,7 +274,8 @@
<listitem>
<para>
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.
</para>
<para>
This option is only valid in combination with the
@@ -381,6 +389,12 @@
must be fixed manually.
</para>
<para>
+ 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 <filename>/</filename>.
+ </para>
+ <para>
No checks will be performed with regard to the
<option>UID_MIN</option>, <option>UID_MAX</option>,
<option>SYS_UID_MIN</option>, or <option>SYS_UID_MAX</option>

View File

@ -1,75 +0,0 @@
From dbf230e4cf823dd6b6a3bad6d29dfad4f0ffa8fc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org>
Date: Mon, 14 Jun 2021 23:28:28 +0200
Subject: [PATCH] libmisc/salt.c: Add comments how the minmum buffer length is
computed.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In the previous commit we refactored the functions converting the
rounds number into a string for use with the crypt() function, to
not require any static buffer anymore.
Add some clarifying comments about how the minimum required buffer
length is computed inside of these functions.
Signed-off-by: Björn Esser <besser82@fedoraproject.org>
---
libmisc/salt.c | 29 +++++++++++++++++++++++++----
1 file changed, 25 insertions(+), 4 deletions(-)
diff --git a/libmisc/salt.c b/libmisc/salt.c
index 98982ed1..e17093fc 100644
--- a/libmisc/salt.c
+++ b/libmisc/salt.c
@@ -216,7 +216,14 @@ static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, /*@null@*/int *pref
return;
}
- /* Check if the result buffer is long enough. */
+ /*
+ * Check if the result buffer is long enough.
+ * We are going to write a maximum of 17 bytes,
+ * plus one byte for the terminator.
+ * rounds=XXXXXXXXX$
+ * 00000000011111111
+ * 12345678901234567
+ */
assert (GENSALT_SETTING_SIZE > buf_begin + 17);
(void) snprintf (buf + buf_begin, 18, "rounds=%lu$", rounds);
@@ -274,7 +281,14 @@ static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, /*@null@*/int *p
rounds = 19;
}
- /* Check if the result buffer is long enough. */
+ /*
+ * Check if the result buffer is long enough.
+ * We are going to write three bytes,
+ * plus one byte for the terminator.
+ * XX$
+ * 000
+ * 123
+ */
assert (GENSALT_SETTING_SIZE > buf_begin + 3);
(void) snprintf (buf + buf_begin, 4, "%2.2lu$", rounds);
@@ -308,8 +322,15 @@ static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, /*@null@*/int *p
cost = Y_COST_MAX;
}
- /* Check if the result buffer is long enough. */
- assert (GENSALT_SETTING_SIZE > buf_begin + 3);
+ /*
+ * Check if the result buffer is long enough.
+ * We are going to write four bytes,
+ * plus one byte for the terminator.
+ * jXX$
+ * 0000
+ * 1234
+ */
+ assert (GENSALT_SETTING_SIZE > buf_begin + 4);
buf[buf_begin + 0] = 'j';
if (cost < 3) {

View File

@ -1,29 +0,0 @@
From ffd35d89021a9b8375a9246082afc6fc270a93ee Mon Sep 17 00:00:00 2001
From: steven Y Gui <guiyao@huawei.com>
Date: Wed, 14 Jul 2021 16:17:48 +0800
Subject: [PATCH] fread returns element count, not element size
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Björn Esser <besser82@fedoraproject.org>
---
libmisc/salt.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libmisc/salt.c b/libmisc/salt.c
index 9fd34332..91d528fd 100644
--- a/libmisc/salt.c
+++ b/libmisc/salt.c
@@ -168,7 +168,7 @@ static long read_random_bytes (void)
#else
FILE *f = fopen ("/dev/urandom", "r");
- if (fread (&randval, sizeof (randval), 1, f) != sizeof (randval)) {
+ if (fread (&randval, sizeof (randval), 1, f) != 1) {
fclose(f);
goto fail;
}
--
2.31.1

View File

@ -1,555 +0,0 @@
From 14b108728a5d55c3d478a170c39f0e2ffd4de1b0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org>
Date: Mon, 14 Jun 2021 23:28:28 +0200
Subject: [PATCH] libmisc/salt.c: Sanitize code.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Move all pre-processor defines to the top of the file.
* Unify the gensalt() function to be useable for all supported
hash methods.
* Drop the gensalt_{b,yes}crypt() functions in favor of the
previous change.
* Refactor the functions converting the rounds number into
a string for use with the crypt() function, to not require
any static buffer anymore.
* Clarify the comment about how crypt_make_salt() chooses the used
hash method from the settings in the login.defs file.
* Use memset() to fill static buffers with zero before using them.
* Use a fixed amount of 16 random base64-chars for the
sha{256,512}crypt hash methods, which is effectively still less
than the recommendation from NIST (>= 128 bits), but the maximum
those methods can effectively use (approx. 90 bits).
* Rename ROUNDS_{MIN,MAX} to SHA_ROUNDS_{MIN,MAX}.
* Bugfixes in the logic of setting rounds in BCRYPT_salt_rounds().
* Likewise for YESCRYPT_salt_cost().
* Fix formatting and white-space errors.
Signed-off-by: Björn Esser <besser82@fedoraproject.org>
---
libmisc/salt.c | 332 ++++++++++++++++++++++---------------------------
1 file changed, 147 insertions(+), 185 deletions(-)
diff --git a/libmisc/salt.c b/libmisc/salt.c
index 5dc521ef..98982ed1 100644
--- a/libmisc/salt.c
+++ b/libmisc/salt.c
@@ -12,6 +12,7 @@
#ident "$Id$"
#include <sys/time.h>
+#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
@@ -19,6 +20,59 @@
#include "defines.h"
#include "getdef.h"
+/* Add the salt prefix. */
+#define MAGNUM(array,ch) (array)[0]=(array)[2]='$',(array)[1]=(ch),(array)[3]='\0'
+
+#ifdef USE_BCRYPT
+/* Use $2b$ as prefix for compatibility with OpenBSD's bcrypt. */
+#define BCRYPTMAGNUM(array) (array)[0]=(array)[3]='$',(array)[1]='2',(array)[2]='b',(array)[4]='\0'
+#define BCRYPT_SALT_SIZE 22
+/* Default number of rounds if not explicitly specified. */
+#define B_ROUNDS_DEFAULT 13
+/* Minimum number of rounds. */
+#define B_ROUNDS_MIN 4
+/* Maximum number of rounds. */
+#define B_ROUNDS_MAX 31
+#endif /* USE_BCRYPT */
+
+#ifdef USE_SHA_CRYPT
+/* Fixed salt len for sha{256,512}crypt. */
+#define SHA_CRYPT_SALT_SIZE 16
+/* Default number of rounds if not explicitly specified. */
+#define SHA_ROUNDS_DEFAULT 5000
+/* Minimum number of rounds. */
+#define SHA_ROUNDS_MIN 1000
+/* Maximum number of rounds. */
+#define SHA_ROUNDS_MAX 999999999
+#endif
+
+#ifdef USE_YESCRYPT
+/*
+ * Default number of base64 characters used for the salt.
+ * 24 characters gives a 144 bits (18 bytes) salt. Unlike the more
+ * traditional 128 bits (16 bytes) salt, this 144 bits salt is always
+ * represented by the same number of base64 characters without padding
+ * issue, even with a non-standard base64 encoding scheme.
+ */
+#define YESCRYPT_SALT_SIZE 24
+/* Default cost if not explicitly specified. */
+#define Y_COST_DEFAULT 5
+/* Minimum cost. */
+#define Y_COST_MIN 1
+/* Maximum cost. */
+#define Y_COST_MAX 11
+#endif
+
+/* Fixed salt len for md5crypt. */
+#define MD5_CRYPT_SALT_SIZE 8
+
+/* Generate salt of size salt_size. */
+#define MAX_SALT_SIZE 44
+#define MIN_SALT_SIZE 8
+
+/* Maximum size of the generated salt string. */
+#define GENSALT_SETTING_SIZE 100
+
/* local function prototypes */
static void seedRNG (void);
static /*@observer@*/const char *gensalt (size_t salt_size);
@@ -26,19 +80,17 @@ static /*@observer@*/const char *gensalt (size_t salt_size);
static long shadow_random (long min, long max);
#endif /* USE_SHA_CRYPT || USE_BCRYPT */
#ifdef USE_SHA_CRYPT
-static /*@observer@*/const char *SHA_salt_rounds (/*@null@*/int *prefered_rounds);
+static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, /*@null@*/int *prefered_rounds);
#endif /* USE_SHA_CRYPT */
#ifdef USE_BCRYPT
-static /*@observer@*/const char *gensalt_bcrypt (void);
-static /*@observer@*/const char *BCRYPT_salt_rounds (/*@null@*/int *prefered_rounds);
+static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, /*@null@*/int *prefered_rounds);
#endif /* USE_BCRYPT */
#ifdef USE_YESCRYPT
-static /*@observer@*/const char *gensalt_yescrypt (void);
-static /*@observer@*/const char *YESCRYPT_salt_cost (/*@null@*/int *prefered_cost);
+static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, /*@null@*/int *prefered_cost);
#endif /* USE_YESCRYPT */
#ifndef HAVE_L64A
-static /*@observer@*/char *l64a(long value)
+static /*@observer@*/char *l64a (long value)
{
static char buf[8];
char *s = buf;
@@ -69,7 +121,7 @@ static /*@observer@*/char *l64a(long value)
*s = '\0';
- return(buf);
+ return buf;
}
#endif /* !HAVE_L64A */
@@ -85,15 +137,6 @@ static void seedRNG (void)
}
}
-/*
- * Add the salt prefix.
- */
-#define MAGNUM(array,ch) (array)[0]=(array)[2]='$',(array)[1]=(ch),(array)[3]='\0'
-#ifdef USE_BCRYPT
-/* Use $2b$ as prefix for compatibility with OpenBSD's bcrypt. */
-#define BCRYPTMAGNUM(array) (array)[0]=(array)[3]='$',(array)[1]='2',(array)[2]='b',(array)[4]='\0'
-#endif /* USE_BCRYPT */
-
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
/* It is not clear what is the maximum value of random().
* We assume 2^31-1.*/
@@ -122,26 +165,21 @@ static long shadow_random (long min, long max)
#endif /* USE_SHA_CRYPT || USE_BCRYPT */
#ifdef USE_SHA_CRYPT
-/* Default number of rounds if not explicitly specified. */
-#define ROUNDS_DEFAULT 5000
-/* Minimum number of rounds. */
-#define ROUNDS_MIN 1000
-/* Maximum number of rounds. */
-#define ROUNDS_MAX 999999999
/*
- * Return a salt prefix specifying the rounds number for the SHA crypt methods.
+ * Fill a salt prefix specifying the rounds number for the SHA crypt methods
+ * to a buffer.
*/
-static /*@observer@*/const char *SHA_salt_rounds (/*@null@*/int *prefered_rounds)
+static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, /*@null@*/int *prefered_rounds)
{
- static char rounds_prefix[18]; /* Max size: rounds=999999999$ */
- long rounds;
+ unsigned long rounds;
+ const size_t buf_begin = strlen (buf);
if (NULL == prefered_rounds) {
long min_rounds = getdef_long ("SHA_CRYPT_MIN_ROUNDS", -1);
long max_rounds = getdef_long ("SHA_CRYPT_MAX_ROUNDS", -1);
if ((-1 == min_rounds) && (-1 == max_rounds)) {
- return "";
+ rounds = SHA_ROUNDS_DEFAULT;
}
if (-1 == min_rounds) {
@@ -156,196 +194,142 @@ static /*@observer@*/const char *SHA_salt_rounds (/*@null@*/int *prefered_rounds
max_rounds = min_rounds;
}
- rounds = shadow_random (min_rounds, max_rounds);
+ rounds = (unsigned long) shadow_random (min_rounds, max_rounds);
} else if (0 == *prefered_rounds) {
- return "";
+ rounds = SHA_ROUNDS_DEFAULT;
} else {
- rounds = *prefered_rounds;
+ rounds = (unsigned long) *prefered_rounds;
}
/* Sanity checks. The libc should also check this, but this
* protects against a rounds_prefix overflow. */
- if (rounds < ROUNDS_MIN) {
- rounds = ROUNDS_MIN;
+ if (rounds < SHA_ROUNDS_MIN) {
+ rounds = SHA_ROUNDS_MIN;
+ }
+
+ if (rounds > SHA_ROUNDS_MAX) {
+ rounds = SHA_ROUNDS_MAX;
}
- if (rounds > ROUNDS_MAX) {
- rounds = ROUNDS_MAX;
+ /* Nothing to do here if SHA_ROUNDS_DEFAULT is used. */
+ if (rounds == SHA_ROUNDS_DEFAULT) {
+ return;
}
- (void) snprintf (rounds_prefix, sizeof rounds_prefix,
- "rounds=%ld$", rounds);
+ /* Check if the result buffer is long enough. */
+ assert (GENSALT_SETTING_SIZE > buf_begin + 17);
- return rounds_prefix;
+ (void) snprintf (buf + buf_begin, 18, "rounds=%lu$", rounds);
}
#endif /* USE_SHA_CRYPT */
#ifdef USE_BCRYPT
-/* Default number of rounds if not explicitly specified. */
-#define B_ROUNDS_DEFAULT 13
-/* Minimum number of rounds. */
-#define B_ROUNDS_MIN 4
-/* Maximum number of rounds. */
-#define B_ROUNDS_MAX 31
/*
- * Return a salt prefix specifying the rounds number for the BCRYPT method.
+ * Fill a salt prefix specifying the rounds number for the BCRYPT method
+ * to a buffer.
*/
-static /*@observer@*/const char *BCRYPT_salt_rounds (/*@null@*/int *prefered_rounds)
+static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, /*@null@*/int *prefered_rounds)
{
- static char rounds_prefix[4]; /* Max size: 31$ */
- long rounds;
+ unsigned long rounds;
+ const size_t buf_begin = strlen (buf);
if (NULL == prefered_rounds) {
long min_rounds = getdef_long ("BCRYPT_MIN_ROUNDS", -1);
long max_rounds = getdef_long ("BCRYPT_MAX_ROUNDS", -1);
- if (((-1 == min_rounds) && (-1 == max_rounds)) || (0 == *prefered_rounds)) {
+ if ((-1 == min_rounds) && (-1 == max_rounds)) {
rounds = B_ROUNDS_DEFAULT;
- }
- else {
+ } else {
if (-1 == min_rounds) {
min_rounds = max_rounds;
}
-
+
if (-1 == max_rounds) {
max_rounds = min_rounds;
}
-
+
if (min_rounds > max_rounds) {
max_rounds = min_rounds;
}
-
- rounds = shadow_random (min_rounds, max_rounds);
+
+ rounds = (unsigned long) shadow_random (min_rounds, max_rounds);
}
+ } else if (0 == *prefered_rounds) {
+ rounds = B_ROUNDS_DEFAULT;
} else {
- rounds = *prefered_rounds;
+ rounds = (unsigned long) *prefered_rounds;
}
- /*
- * Sanity checks.
- * Use 19 as an upper bound for now,
- * because musl doesn't allow rounds >= 20.
- */
+ /* Sanity checks. */
if (rounds < B_ROUNDS_MIN) {
rounds = B_ROUNDS_MIN;
}
+ /*
+ * Use 19 as an upper bound for now,
+ * because musl doesn't allow rounds >= 20.
+ */
if (rounds > 19) {
/* rounds = B_ROUNDS_MAX; */
rounds = 19;
}
- (void) snprintf (rounds_prefix, sizeof rounds_prefix,
- "%2.2ld$", rounds);
-
- return rounds_prefix;
-}
-
-#define BCRYPT_SALT_SIZE 22
-/*
- * Generate a 22 character salt string for bcrypt.
- */
-static /*@observer@*/const char *gensalt_bcrypt (void)
-{
- static char salt[32];
-
- salt[0] = '\0';
+ /* Check if the result buffer is long enough. */
+ assert (GENSALT_SETTING_SIZE > buf_begin + 3);
- seedRNG ();
- strcat (salt, l64a (random()));
- do {
- strcat (salt, l64a (random()));
- } while (strlen (salt) < BCRYPT_SALT_SIZE);
-
- salt[BCRYPT_SALT_SIZE] = '\0';
-
- return salt;
+ (void) snprintf (buf + buf_begin, 4, "%2.2lu$", rounds);
}
#endif /* USE_BCRYPT */
#ifdef USE_YESCRYPT
-/* Default cost if not explicitly specified. */
-#define Y_COST_DEFAULT 5
-/* Minimum cost. */
-#define Y_COST_MIN 1
-/* Maximum cost. */
-#define Y_COST_MAX 11
/*
- * Return a salt prefix specifying the cost for the YESCRYPT method.
+ * Fill a salt prefix specifying the cost for the YESCRYPT method
+ * to a buffer.
*/
-static /*@observer@*/const char *YESCRYPT_salt_cost (/*@null@*/int *prefered_cost)
+static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, /*@null@*/int *prefered_cost)
{
- static char cost_prefix[5];
- long cost;
+ unsigned long cost;
+ const size_t buf_begin = strlen (buf);
if (NULL == prefered_cost) {
cost = getdef_num ("YESCRYPT_COST_FACTOR", Y_COST_DEFAULT);
+ } else if (0 == *prefered_cost) {
+ cost = Y_COST_DEFAULT;
} else {
- cost = *prefered_cost;
+ cost = (unsigned long) *prefered_cost;
}
+ /* Sanity checks. */
if (cost < Y_COST_MIN) {
cost = Y_COST_MIN;
}
+
if (cost > Y_COST_MAX) {
cost = Y_COST_MAX;
}
- cost_prefix[0] = 'j';
+ /* Check if the result buffer is long enough. */
+ assert (GENSALT_SETTING_SIZE > buf_begin + 3);
+
+ buf[buf_begin + 0] = 'j';
if (cost < 3) {
- cost_prefix[1] = 0x36 + cost;
+ buf[buf_begin + 1] = 0x36 + cost;
} else if (cost < 6) {
- cost_prefix[1] = 0x34 + cost;
+ buf[buf_begin + 1] = 0x34 + cost;
} else {
- cost_prefix[1] = 0x3b + cost;
+ buf[buf_begin + 1] = 0x3b + cost;
}
- cost_prefix[2] = cost >= 3 ? 'T' : '5';
- cost_prefix[3] = '$';
- cost_prefix[4] = 0;
-
- return cost_prefix;
-}
-
-/*
- * Default number of base64 characters used for the salt.
- * 24 characters gives a 144 bits (18 bytes) salt. Unlike the more
- * traditional 128 bits (16 bytes) salt, this 144 bits salt is always
- * represented by the same number of base64 characters without padding
- * issue, even with a non-standard base64 encoding scheme.
- */
-#define YESCRYPT_SALT_SIZE 24
-/*
- * Generate a 22 character salt string for yescrypt.
- */
-static /*@observer@*/const char *gensalt_yescrypt (void)
-{
- static char salt[32];
-
- salt[0] = '\0';
-
- seedRNG ();
- strcat (salt, l64a (random()));
- do {
- strcat (salt, l64a (random()));
- } while (strlen (salt) < YESCRYPT_SALT_SIZE);
-
- salt[YESCRYPT_SALT_SIZE] = '\0';
-
- return salt;
+ buf[buf_begin + 2] = cost >= 3 ? 'T' : '5';
+ buf[buf_begin + 3] = '$';
+ buf[buf_begin + 4] = '\0';
}
#endif /* USE_YESCRYPT */
-/*
- * Generate salt of size salt_size.
- */
-#define MAX_SALT_SIZE 16
-#define MIN_SALT_SIZE 8
-
static /*@observer@*/const char *gensalt (size_t salt_size)
{
- static char salt[32];
+ static char salt[MAX_SALT_SIZE + 6];
- salt[0] = '\0';
+ memset (salt, '\0', MAX_SALT_SIZE + 6);
assert (salt_size >= MIN_SALT_SIZE &&
salt_size <= MAX_SALT_SIZE);
@@ -368,8 +352,9 @@ static /*@observer@*/const char *gensalt (size_t salt_size)
* Other methods can be set with ENCRYPT_METHOD
*
* The method can be forced with the meth parameter.
- * If NULL, the method will be defined according to the MD5_CRYPT_ENAB and
- * ENCRYPT_METHOD login.defs variables.
+ * If NULL, the method will be defined according to the ENCRYPT_METHOD
+ * variable, and if not set according to the MD5_CRYPT_ENAB variable,
+ * which can both be set inside the login.defs file.
*
* If meth is specified, an additional parameter can be provided.
* * For the SHA256 and SHA512 method, this specifies the number of rounds
@@ -378,17 +363,11 @@ static /*@observer@*/const char *gensalt (size_t salt_size)
*/
/*@observer@*/const char *crypt_make_salt (/*@null@*//*@observer@*/const char *meth, /*@null@*/void *arg)
{
- /* Max result size for the SHA methods:
- * +3 $5$
- * +17 rounds=999999999$
- * +16 salt
- * +1 \0
- */
- static char result[40];
- size_t salt_len = 8;
+ static char result[GENSALT_SETTING_SIZE];
+ size_t salt_len = MAX_SALT_SIZE;
const char *method;
- result[0] = '\0';
+ memset (result, '\0', GENSALT_SETTING_SIZE);
if (NULL != meth)
method = meth;
@@ -401,61 +380,44 @@ static /*@observer@*/const char *gensalt (size_t salt_size)
if (0 == strcmp (method, "MD5")) {
MAGNUM(result, '1');
+ salt_len = MD5_CRYPT_SALT_SIZE;
#ifdef USE_BCRYPT
} else if (0 == strcmp (method, "BCRYPT")) {
BCRYPTMAGNUM(result);
- strcat(result, BCRYPT_salt_rounds((int *)arg));
+ salt_len = BCRYPT_SALT_SIZE;
+ BCRYPT_salt_rounds_to_buf (result, (int *) arg);
#endif /* USE_BCRYPT */
#ifdef USE_YESCRYPT
} else if (0 == strcmp (method, "YESCRYPT")) {
MAGNUM(result, 'y');
- strcat(result, YESCRYPT_salt_cost((int *)arg));
+ salt_len = YESCRYPT_SALT_SIZE;
+ YESCRYPT_salt_cost_to_buf (result, (int *) arg);
#endif /* USE_YESCRYPT */
#ifdef USE_SHA_CRYPT
} else if (0 == strcmp (method, "SHA256")) {
MAGNUM(result, '5');
- strcat(result, SHA_salt_rounds((int *)arg));
- salt_len = (size_t) shadow_random (8, 16);
+ salt_len = SHA_CRYPT_SALT_SIZE;
+ SHA_salt_rounds_to_buf (result, (int *) arg);
} else if (0 == strcmp (method, "SHA512")) {
MAGNUM(result, '6');
- strcat(result, SHA_salt_rounds((int *)arg));
- salt_len = (size_t) shadow_random (8, 16);
+ salt_len = SHA_CRYPT_SALT_SIZE;
+ SHA_salt_rounds_to_buf (result, (int *) arg);
#endif /* USE_SHA_CRYPT */
} else if (0 != strcmp (method, "DES")) {
fprintf (shadow_logfd,
_("Invalid ENCRYPT_METHOD value: '%s'.\n"
"Defaulting to DES.\n"),
method);
- result[0] = '\0';
+ salt_len = MAX_SALT_SIZE;
+ memset (result, '\0', GENSALT_SETTING_SIZE);
}
- /*
- * Concatenate a pseudo random salt.
- */
- assert (sizeof (result) > strlen (result) + salt_len);
-#ifdef USE_BCRYPT
- if (0 == strcmp (method, "BCRYPT")) {
- strncat (result, gensalt_bcrypt (),
- sizeof (result) - strlen (result) - 1);
- return result;
- } else {
-#endif /* USE_BCRYPT */
-#ifdef USE_YESCRYPT
- if (0 == strcmp (method, "YESCRYPT")) {
- strncat (result, gensalt_yescrypt (),
- sizeof (result) - strlen (result) - 1);
- return result;
- } else {
-#endif /* USE_YESCRYPT */
- strncat (result, gensalt (salt_len),
- sizeof (result) - strlen (result) - 1);
-#ifdef USE_YESCRYPT
- }
-#endif /* USE_YESCRYPT */
-#ifdef USE_BCRYPT
- }
-#endif /* USE_BCRYPT */
+ /* Check if the result buffer is long enough. */
+ assert (GENSALT_SETTING_SIZE > strlen (result) + salt_len);
+
+ /* Concatenate a pseudo random salt. */
+ strncat (result, gensalt (salt_len),
+ GENSALT_SETTING_SIZE - strlen (result) - 1);
return result;
}
-

View File

@ -1,114 +0,0 @@
From bc8257cf73328e450511b13cbd35e1994feccb30 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org>
Date: Wed, 23 Jun 2021 16:06:47 +0200
Subject: [PATCH] libmisc/salt.c: Obtain random bytes from /dev/urandom.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Using the random() function to obtain pseudo-random bytes
for generating salt strings is considered to be dangerous.
See CWE-327.
We really should use a more reliable source for obtaining
pseudo-random bytes like /dev/urandom.
Fixes #376.
Signed-off-by: Björn Esser <besser82@fedoraproject.org>
---
libmisc/salt.c | 45 ++++++++++++++++++++++++---------------------
1 file changed, 24 insertions(+), 21 deletions(-)
diff --git a/libmisc/salt.c b/libmisc/salt.c
index e17093fc..af9f011f 100644
--- a/libmisc/salt.c
+++ b/libmisc/salt.c
@@ -11,11 +11,10 @@
#ident "$Id$"
-#include <sys/time.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include "prototypes.h"
#include "defines.h"
#include "getdef.h"
@@ -74,7 +73,7 @@
#define GENSALT_SETTING_SIZE 100
/* local function prototypes */
-static void seedRNG (void);
+static long read_random_bytes (void);
static /*@observer@*/const char *gensalt (size_t salt_size);
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
static long shadow_random (long min, long max);
@@ -125,23 +124,27 @@ static /*@observer@*/char *l64a (long value)
}
#endif /* !HAVE_L64A */
-static void seedRNG (void)
+/* Read sizeof (long) random bytes from /dev/urandom. */
+static long read_random_bytes (void)
{
- struct timeval tv;
- static int seeded = 0;
+ long randval = 0;
+ FILE *f = fopen ("/dev/urandom", "r");
- if (0 == seeded) {
- (void) gettimeofday (&tv, NULL);
- srandom (tv.tv_sec ^ tv.tv_usec ^ getpid ());
- seeded = 1;
+ if (fread (&randval, sizeof (randval), 1, f) != sizeof (randval))
+ {
+ fprintf (shadow_logfd,
+ _("Unable to read from /dev/urandom.\n"));
+
+ fclose(f);
+ exit (1);
}
+
+ fclose(f);
+
+ return randval;
}
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
-/* It is not clear what is the maximum value of random().
- * We assume 2^31-1.*/
-#define RANDOM_MAX 0x7FFFFFFF
-
/*
* Return a random number between min and max (both included).
*
@@ -151,8 +154,9 @@ static long shadow_random (long min, long max)
{
double drand;
long ret;
- seedRNG ();
- drand = (double) (max - min + 1) * random () / RANDOM_MAX;
+
+ drand = (double) (read_random_bytes () & RAND_MAX) / (double) RAND_MAX;
+ drand *= (double) (max - min + 1);
/* On systems were this is not random() range is lower, we favor
* higher numbers of salt. */
ret = (long) (max + 1 - drand);
@@ -354,10 +358,9 @@ static /*@observer@*/const char *gensalt (size_t salt_size)
assert (salt_size >= MIN_SALT_SIZE &&
salt_size <= MAX_SALT_SIZE);
- seedRNG ();
- strcat (salt, l64a (random()));
+ strcat (salt, l64a (read_random_bytes ()));
do {
- strcat (salt, l64a (random()));
+ strcat (salt, l64a (read_random_bytes ()));
} while (strlen (salt) < salt_size);
salt[salt_size] = '\0';

View File

@ -1,35 +0,0 @@
From 6543c600d841e4f7779269412d470e50eae25b13 Mon Sep 17 00:00:00 2001
From: ikerexxe <ipedrosa@redhat.com>
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
<replaceable>LOGIN</replaceable> name to
<replaceable>BASE_DIR</replaceable> and use that as the login
- directory name. The directory <replaceable>HOME_DIR</replaceable>
- does not have to exist but will not be created if it is missing.
+ directory name. If the directory
+ <replaceable>HOME_DIR</replaceable> does not exist, then it
+ will be created unless the <option>-M</option> option is
+ specified.
</para>
</listitem>
</varlistentry>
--
2.25.1

View File

@ -1,44 +0,0 @@
From 663824ef4ca927aa2b4319b69e0bfa68282ec719 Mon Sep 17 00:00:00 2001
From: Serge Hallyn <serge@hallyn.com>
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 <serge@hallyn.com>
---
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

View File

@ -1,24 +0,0 @@
diff -up shadow-4.8.1/src/useradd.c.useradd_create_relative_home_path_correctly shadow-4.8.1/src/useradd.c
--- shadow-4.8.1/src/useradd.c.useradd_create_relative_home_path_correctly 2021-06-28 16:10:23.928435372 +0200
+++ shadow-4.8.1/src/useradd.c 2021-06-28 16:11:30.784495046 +0200
@@ -2140,7 +2140,6 @@ static void create_home (void)
Prog, user_home);
fail_exit (E_HOMEDIR);
}
- ++bhome;
#ifdef WITH_SELINUX
if (set_selinux_file_context (prefix_user_home, NULL) != 0) {
@@ -2157,7 +2156,11 @@ static void create_home (void)
*/
cp = strtok (bhome, "/");
while (cp) {
- strcat (path, "/");
+ /* Avoid turning a relative path into an absolute path.
+ */
+ if (bhome[0] == '/' || strlen (path) != 0) {
+ strcat (path, "/");
+ }
strcat (path, cp);
if (access (path, F_OK) != 0) {
/* Check if parent directory is BTRFS, fail if requesting

View File

@ -1,960 +0,0 @@
From 5cd04d03f94622c12220d4a6352824af081b8531 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rodolphe=20Br=C3=A9ard?= <rodolphe@what.tf>
Date: Sun, 27 Dec 2020 21:09:25 +0100
Subject: [PATCH] Add yescrypt support
---
configure.ac | 13 +++++
etc/login.defs | 14 +++++
lib/encrypt.c | 3 ++
lib/getdef.c | 3 ++
libmisc/obscure.c | 3 ++
libmisc/salt.c | 94 +++++++++++++++++++++++++++++++-
src/chgpasswd.c | 113 ++++++++++++++++++++------------------
src/chpasswd.c | 107 +++++++++++++++++++-----------------
src/newusers.c | 134 +++++++++++++++++++++++++---------------------
src/passwd.c | 3 ++
10 files changed, 322 insertions(+), 165 deletions(-)
Index: shadow-4.8.1/configure.ac
===================================================================
--- shadow-4.8.1.orig/configure.ac
+++ shadow-4.8.1/configure.ac
@@ -290,6 +290,9 @@ AC_ARG_WITH(sha-crypt,
AC_ARG_WITH(bcrypt,
[AC_HELP_STRING([--with-bcrypt], [allow the bcrypt password encryption algorithm @<:@default=no@:>@])],
[with_bcrypt=$withval], [with_bcrypt=no])
+AC_ARG_WITH(yescrypt,
+ [AC_HELP_STRING([--with-yescrypt], [allow the yescrypt password encryption algorithm @<:@default=no@:>@])],
+ [with_yescrypt=$withval], [with_yescrypt=no])
AC_ARG_WITH(nscd,
[AC_HELP_STRING([--with-nscd], [enable support for nscd @<:@default=yes@:>@])],
[with_nscd=$withval], [with_nscd=yes])
@@ -322,6 +325,11 @@ if test "$with_bcrypt" = "yes"; then
AC_DEFINE(USE_BCRYPT, 1, [Define to allow the bcrypt password encryption algorithm])
fi
+AM_CONDITIONAL(USE_YESCRYPT, test "x$with_yescrypt" = "xyes")
+if test "$with_yescrypt" = "yes"; then
+ AC_DEFINE(USE_YESCRYPT, 1, [Define to allow the yescrypt password encryption algorithm])
+fi
+
if test "$with_nscd" = "yes"; then
AC_CHECK_FUNC(posix_spawn,
[AC_DEFINE(USE_NSCD, 1, [Define to support flushing of nscd caches])],
@@ -402,6 +410,10 @@ AC_SUBST(LIBCRYPT)
AC_CHECK_LIB(crypt, crypt, [LIBCRYPT=-lcrypt],
[AC_MSG_ERROR([crypt() not found])])
+AC_SUBST(LIYESCRYPT)
+AC_CHECK_LIB(crypt, crypt, [LIYESCRYPT=-lcrypt],
+ [AC_MSG_ERROR([crypt() not found])])
+
AC_SUBST(LIBACL)
if test "$with_acl" != "no"; then
AC_CHECK_HEADERS(acl/libacl.h attr/error_context.h, [acl_header="yes"], [acl_header="no"])
@@ -752,6 +764,7 @@ echo " shadow group support: $enable_sh
echo " S/Key support: $with_skey"
echo " SHA passwords encryption: $with_sha_crypt"
echo " bcrypt passwords encryption: $with_bcrypt"
+echo " yescrypt passwords encryption: $with_yescrypt"
echo " nscd support: $with_nscd"
echo " sssd support: $with_sssd"
echo " subordinate IDs support: $enable_subids"
Index: shadow-4.8.1/etc/login.defs
===================================================================
--- shadow-4.8.1.orig/etc/login.defs
+++ shadow-4.8.1/etc/login.defs
@@ -326,6 +326,7 @@ CHFN_RESTRICT rwh
# If set to SHA256, SHA256-based algorithm will be used for encrypting password
# If set to SHA512, SHA512-based algorithm will be used for encrypting password
# If set to BCRYPT, BCRYPT-based algorithm will be used for encrypting password
+# If set to YESCRYPT, YESCRYPT-based algorithm will be used for encrypting password
# If set to DES, DES-based algorithm will be used for encrypting password (default)
# Overrides the MD5_CRYPT_ENAB option
#
@@ -366,6 +367,19 @@ CHFN_RESTRICT rwh
#BCRYPT_MAX_ROUNDS 13
#
+# Only works if ENCRYPT_METHOD is set to YESCRYPT.
+#
+# Define the YESCRYPT cost factor.
+# With a higher cost factor, it is more difficult to brute-force the password.
+# However, more CPU time and more memory will be needed to authenticate users
+# if this value is increased.
+#
+# If not specified, a cost factor of 5 will be used.
+# The value must be within the 1-11 range.
+#
+#YESCRYPT_COST_FACTOR 5
+
+#
# List of groups to add to the user's supplementary group set
# when logging in from the console (as determined by the CONSOLE
# setting). Default is none.
Index: shadow-4.8.1/lib/encrypt.c
===================================================================
--- shadow-4.8.1.orig/lib/encrypt.c
+++ shadow-4.8.1/lib/encrypt.c
@@ -74,6 +74,9 @@
case '6':
method = "SHA512";
break;
+ case 'y':
+ method = "YESCRYPT";
+ break;
default:
{
static char nummethod[4] = "$x$";
Index: shadow-4.8.1/lib/getdef.c
===================================================================
--- shadow-4.8.1.orig/lib/getdef.c
+++ shadow-4.8.1/lib/getdef.c
@@ -117,6 +117,9 @@ static struct itemdef def_table[] = {
{"BCRYPT_MAX_ROUNDS", NULL},
{"BCRYPT_MIN_ROUNDS", NULL},
#endif
+#ifdef USE_YESCRYPT
+ {"YESCRYPT_COST_FACTOR", NULL},
+#endif
{"SUB_GID_COUNT", NULL},
{"SUB_GID_MAX", NULL},
{"SUB_GID_MIN", NULL},
Index: shadow-4.8.1/libmisc/obscure.c
===================================================================
--- shadow-4.8.1.orig/libmisc/obscure.c
+++ shadow-4.8.1/libmisc/obscure.c
@@ -272,6 +272,9 @@ static /*@observer@*//*@null@*/const cha
#ifdef USE_BCRYPT
|| (strcmp (result, "BCRYPT") == 0)
#endif
+#ifdef USE_YESCRYPT
+ || (strcmp (result, "YESCRYPT") == 0)
+#endif
) {
return NULL;
}
Index: shadow-4.8.1/libmisc/salt.c
===================================================================
--- shadow-4.8.1.orig/libmisc/salt.c
+++ shadow-4.8.1/libmisc/salt.c
@@ -32,6 +32,10 @@ static /*@observer@*/const char *SHA_sal
static /*@observer@*/const char *gensalt_bcrypt (void);
static /*@observer@*/const char *BCRYPT_salt_rounds (/*@null@*/int *prefered_rounds);
#endif /* USE_BCRYPT */
+#ifdef USE_YESCRYPT
+static /*@observer@*/const char *gensalt_yescrypt (void);
+static /*@observer@*/const char *YESCRYPT_salt_cost (/*@null@*/long *prefered_rounds);
+#endif /* USE_YESCRYPT */
#ifndef HAVE_L64A
static /*@observer@*/char *l64a(long value)
@@ -263,6 +267,78 @@ static /*@observer@*/const char *gensalt
}
#endif /* USE_BCRYPT */
+#ifdef USE_YESCRYPT
+/* Default cost if not explicitly specified. */
+#define Y_COST_DEFAULT 5
+/* Minimum cost. */
+#define Y_COST_MIN 1
+/* Maximum cost. */
+#define Y_COST_MAX 11
+/*
+ * Return a salt prefix specifying the cost for the YESCRYPT method.
+ */
+static /*@observer@*/const char *YESCRYPT_salt_cost (/*@null@*/long *prefered_cost)
+{
+ static char cost_prefix[5];
+ long cost;
+
+ if (NULL == prefered_cost) {
+ cost = getdef_num ("YESCRYPT_COST_FACTOR", Y_COST_DEFAULT);
+ } else {
+ cost = *prefered_cost;
+ }
+
+ if (cost < Y_COST_MIN) {
+ cost = Y_COST_MIN;
+ }
+ if (cost > Y_COST_MAX) {
+ cost = Y_COST_MAX;
+ }
+
+ cost_prefix[0] = 'j';
+ if (cost < 3) {
+ cost_prefix[1] = 0x36 + cost;
+ } else if (cost < 6) {
+ cost_prefix[1] = 0x34 + cost;
+ } else {
+ cost_prefix[1] = 0x3b + cost;
+ }
+ cost_prefix[2] = cost >= 3 ? 'T' : '5';
+ cost_prefix[3] = '$';
+ cost_prefix[4] = 0;
+
+ return cost_prefix;
+}
+
+/*
+ * Default number of base64 characters used for the salt.
+ * 24 characters gives a 144 bits (18 bytes) salt. Unlike the more
+ * traditional 128 bits (16 bytes) salt, this 144 bits salt is always
+ * represented by the same number of base64 characters without padding
+ * issue, even with a non-standard base64 encoding scheme.
+ */
+#define YESCRYPT_SALT_SIZE 24
+/*
+ * Generate a 22 character salt string for yescrypt.
+ */
+static /*@observer@*/const char *gensalt_yescrypt (void)
+{
+ static char salt[32];
+
+ salt[0] = '\0';
+
+ seedRNG ();
+ strcat (salt, l64a (random()));
+ do {
+ strcat (salt, l64a (random()));
+ } while (strlen (salt) < YESCRYPT_SALT_SIZE);
+
+ salt[YESCRYPT_SALT_SIZE] = '\0';
+
+ return salt;
+}
+#endif /* USE_YESCRYPT */
+
/*
* Generate salt of size salt_size.
*/
@@ -302,6 +378,7 @@ static /*@observer@*/const char *gensalt
* If meth is specified, an additional parameter can be provided.
* * For the SHA256 and SHA512 method, this specifies the number of rounds
* (if not NULL).
+ * * For the YESCRYPT method, this specifies the cost factor (if not NULL).
*/
/*@observer@*/const char *crypt_make_salt (/*@null@*//*@observer@*/const char *meth, /*@null@*/void *arg)
{
@@ -333,6 +410,11 @@ static /*@observer@*/const char *gensalt
BCRYPTMAGNUM(result);
strcat(result, BCRYPT_salt_rounds((int *)arg));
#endif /* USE_BCRYPT */
+#ifdef USE_YESCRYPT
+ } else if (0 == strcmp (method, "YESCRYPT")) {
+ MAGNUM(result, 'y');
+ strcat(result, YESCRYPT_salt_cost((int *)arg));
+#endif /* USE_YESCRYPT */
#ifdef USE_SHA_CRYPT
} else if (0 == strcmp (method, "SHA256")) {
MAGNUM(result, '5');
@@ -362,11 +444,21 @@ static /*@observer@*/const char *gensalt
return result;
} else {
#endif /* USE_BCRYPT */
+#ifdef USE_YESCRYPT
+ if (0 == strcmp (method, "YESCRYPT")) {
+ strncat (result, gensalt_yescrypt (),
+ sizeof (result) - strlen (result) - 1);
+ return result;
+ } else {
+#endif /* USE_YESCRYPT */
strncat (result, gensalt (salt_len),
sizeof (result) - strlen (result) - 1);
+#ifdef USE_YESCRYPT
+ }
+#endif /* USE_YESCRYPT */
#ifdef USE_BCRYPT
}
-#endif /* USE_BCRYPT */
+#endif /* USE_BCRYPT */
return result;
}
Index: shadow-4.8.1/src/chgpasswd.c
===================================================================
--- shadow-4.8.1.orig/src/chgpasswd.c
+++ shadow-4.8.1/src/chgpasswd.c
@@ -69,9 +69,9 @@ const char *Prog;
FILE *shadow_logfd = NULL;
static bool eflg = false;
static bool md5flg = false;
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
static bool sflg = false;
-#endif /* USE_SHA_CRYPT || USE_BCRYPT */
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
static /*@null@*//*@observer@*/const char *crypt_method = NULL;
#define cflg (NULL != crypt_method)
@@ -81,6 +81,9 @@ static long sha_rounds = 5000;
#ifdef USE_BCRYPT
static long bcrypt_rounds = 13;
#endif
+#ifdef USE_YESCRYPT
+static long yescrypt_cost = 5;
+#endif
#ifdef SHADOWGRP
static bool is_shadow_grp;
@@ -139,14 +142,15 @@ static /*@noreturn@*/void usage (int sta
Prog);
(void) fprintf (usageout,
_(" -c, --crypt-method METHOD the crypt method (one of %s)\n"),
-#if !defined(USE_SHA_CRYPT) && !defined(USE_BCRYPT)
"NONE DES MD5"
-#elif defined(USE_SHA_CRYPT) && defined(USE_BCRYPT)
- "NONE DES MD5 SHA256 SHA512 BCRYPT"
-#elif defined(USE_SHA_CRYPT)
- "NONE DES MD5 SHA256 SHA512"
-#else
- "NONE DES MD5 BCRYPT"
+#if defined(USE_SHA_CRYPT)
+ " SHA256 SHA512"
+#endif
+#if defined(USE_BCRYPT)
+ " BCRYPT"
+#endif
+#if defined(USE_YESCRYPT)
+ " YESCRYPT"
#endif
);
(void) fputs (_(" -e, --encrypted supplied passwords are encrypted\n"), usageout);
@@ -155,11 +159,11 @@ static /*@noreturn@*/void usage (int sta
" the MD5 algorithm\n"),
usageout);
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
- (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA or BCRYPT\n"
- " crypt algorithms\n"),
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
+ (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT\n"
+ " or YESCRYPT crypt algorithms\n"),
usageout);
-#endif /* USE_SHA_CRYPT || USE_BCRYPT */
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
(void) fputs ("\n", usageout);
exit (status);
@@ -173,19 +177,22 @@ static /*@noreturn@*/void usage (int sta
static void process_flags (int argc, char **argv)
{
int c;
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
+ int bad_s;
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
static struct option long_options[] = {
{"crypt-method", required_argument, NULL, 'c'},
{"encrypted", no_argument, NULL, 'e'},
{"help", no_argument, NULL, 'h'},
{"md5", no_argument, NULL, 'm'},
{"root", required_argument, NULL, 'R'},
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
{"sha-rounds", required_argument, NULL, 's'},
-#endif /* USE_SHA_CRYPT || USE_BCRYPT */
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
{NULL, 0, NULL, '\0'}
};
while ((c = getopt_long (argc, argv,
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
"c:ehmR:s:",
#else
"c:ehmR:",
@@ -206,40 +213,36 @@ static void process_flags (int argc, cha
break;
case 'R': /* no-op, handled in process_root_flag () */
break;
-#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
case 's':
sflg = true;
+ bad_s = 0;
+#if defined(USE_SHA_CRYPT)
if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512")))
- && (0 == getlong(optarg, &sha_rounds)))
- || ( (0 == strcmp (crypt_method, "BCRYPT"))
+ && (0 == getlong(optarg, &sha_rounds)))) {
+ bad_s = 1;
+ }
+#endif /* USE_SHA_CRYPT */
+#if defined(USE_BCRYPT)
+ if (( (0 == strcmp (crypt_method, "BCRYPT"))
&& (0 == getlong(optarg, &bcrypt_rounds)))) {
+ bad_s = 1;
+ }
+#endif /* USE_BCRYPT */
+#if defined(USE_YESCRYPT)
+ if (( (0 == strcmp (crypt_method, "YESCRYPT"))
+ && (0 == getlong(optarg, &yescrypt_cost)))) {
+ bad_s = 1;
+ }
+#endif /* USE_YESCRYPT */
+ if (bad_s != 0) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
Prog, optarg);
usage (E_USAGE);
}
break;
-#elif defined(USE_SHA_CRYPT)
- case 's':
- sflg = true;
- if (0 == getlong(optarg, &sha_rounds)) {
- fprintf (stderr,
- _("%s: invalid numeric argument '%s'\n"),
- Prog, optarg);
- usage (E_USAGE);
- }
- break;
-#elif defined(USE_BCRYPT)
- case 's':
- sflg = true;
- if (0 == getlong(optarg, &bcrypt_rounds)) {
- fprintf (stderr,
- _("%s: invalid numeric argument '%s'\n"),
- Prog, optarg);
- usage (E_USAGE);
- }
- break;
-#endif
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
default:
usage (E_USAGE);
@@ -258,7 +261,7 @@ static void process_flags (int argc, cha
*/
static void check_flags (void)
{
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
if (sflg && !cflg) {
fprintf (stderr,
_("%s: %s flag is only allowed with the %s flag\n"),
@@ -282,10 +285,13 @@ static void check_flags (void)
#ifdef USE_SHA_CRYPT
&& (0 != strcmp (crypt_method, "SHA256"))
&& (0 != strcmp (crypt_method, "SHA512"))
-#endif
+#endif /* USE_SHA_CRYPT */
#ifdef USE_BCRYPT
&& (0 != strcmp (crypt_method, "BCRYPT"))
-#endif
+#endif /* USE_BCRYPT */
+#ifdef USE_YESCRYPT
+ && (0 != strcmp (crypt_method, "YESCRYPT"))
+#endif /* USE_YESCRYPT */
) {
fprintf (stderr,
_("%s: unsupported crypt method: %s\n"),
@@ -592,23 +598,24 @@ int main (int argc, char **argv)
if (md5flg) {
crypt_method = "MD5";
}
-#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
if (sflg) {
+#if defined(USE_SHA_CRYPT)
if ( (0 == strcmp (crypt_method, "SHA256"))
|| (0 == strcmp (crypt_method, "SHA512"))) {
arg = &sha_rounds;
}
- else if (0 == strcmp (crypt_method, "BCRYPT")) {
+#endif /* USE_SHA_CRYPT */
+#if defined(USE_BCRYPT)
+ if (0 == strcmp (crypt_method, "BCRYPT")) {
arg = &bcrypt_rounds;
}
- }
-#elif defined(USE_SHA_CRYPT)
- if (sflg) {
- arg = &sha_rounds;
- }
-#elif defined(USE_BCRYPT)
- if (sflg) {
- arg = &bcrypt_rounds;
+#endif /* USE_BCRYPT */
+#if defined(USE_YESCRYPT)
+ if (0 == strcmp (crypt_method, "YESCRYPT")) {
+ arg = &yescrypt_cost;
+ }
+#endif /* USE_YESCRYPT */
}
#endif
salt = crypt_make_salt (crypt_method, arg);
Index: shadow-4.8.1/src/chpasswd.c
===================================================================
--- shadow-4.8.1.orig/src/chpasswd.c
+++ shadow-4.8.1/src/chpasswd.c
@@ -66,7 +66,7 @@ const char *Prog;
FILE *shadow_logfd = NULL;
static bool eflg = false;
static bool md5flg = false;
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
static bool sflg = false;
#endif
@@ -78,6 +78,9 @@ static long sha_rounds = 5000;
#ifdef USE_BCRYPT
static long bcrypt_rounds = 13;
#endif
+#ifdef USE_YESCRYPT
+static long yescrypt_cost = 5;
+#endif
static bool is_shadow_pwd;
static bool pw_locked = false;
@@ -129,14 +132,15 @@ static /*@noreturn@*/void usage (int sta
Prog);
(void) fprintf (usageout,
_(" -c, --crypt-method METHOD the crypt method (one of %s)\n"),
-#if !defined(USE_SHA_CRYPT) && !defined(USE_BCRYPT)
"NONE DES MD5"
-#elif defined(USE_SHA_CRYPT) && defined(USE_BCRYPT)
- "NONE DES MD5 SHA256 SHA512 BCRYPT"
-#elif defined(USE_SHA_CRYPT)
- "NONE DES MD5 SHA256 SHA512"
-#else
- "NONE DES MD5 BCRYPT"
+#if defined(USE_SHA_CRYPT)
+ " SHA256 SHA512"
+#endif
+#if defined(USE_BCRYPT)
+ " BCRYPT"
+#endif
+#if defined(USE_YESCRYPT)
+ " YESCRYPT"
#endif
);
(void) fputs (_(" -e, --encrypted supplied passwords are encrypted\n"), usageout);
@@ -145,11 +149,11 @@ static /*@noreturn@*/void usage (int sta
" the MD5 algorithm\n"),
usageout);
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
- (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA or BCRYPT\n"
- " crypt algorithms\n"),
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
+ (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT\n"
+ " or YESCRYPT crypt algorithms\n"),
usageout);
-#endif /* USE_SHA_CRYPT || USE_BCRYPT */
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
(void) fputs ("\n", usageout);
exit (status);
@@ -163,20 +167,23 @@ static /*@noreturn@*/void usage (int sta
static void process_flags (int argc, char **argv)
{
int c;
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
+ int bad_s;
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
static struct option long_options[] = {
{"crypt-method", required_argument, NULL, 'c'},
{"encrypted", no_argument, NULL, 'e'},
{"help", no_argument, NULL, 'h'},
{"md5", no_argument, NULL, 'm'},
{"root", required_argument, NULL, 'R'},
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
{"sha-rounds", required_argument, NULL, 's'},
-#endif /* USE_SHA_CRYPT || USE_BCRYPT */
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
{NULL, 0, NULL, '\0'}
};
while ((c = getopt_long (argc, argv,
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
"c:ehmR:s:",
#else
"c:ehmR:",
@@ -197,40 +204,36 @@ static void process_flags (int argc, cha
break;
case 'R': /* no-op, handled in process_root_flag () */
break;
-#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
case 's':
sflg = true;
+ bad_s = 0;
+#if defined(USE_SHA_CRYPT)
if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512")))
- && (0 == getlong(optarg, &sha_rounds)))
- || ( (0 == strcmp (crypt_method, "BCRYPT"))
+ && (0 == getlong(optarg, &sha_rounds)))) {
+ bad_s = 1;
+ }
+#endif /* USE_SHA_CRYPT */
+#if defined(USE_BCRYPT)
+ if (( (0 == strcmp (crypt_method, "BCRYPT"))
&& (0 == getlong(optarg, &bcrypt_rounds)))) {
+ bad_s = 1;
+ }
+#endif /* USE_BCRYPT */
+#if defined(USE_YESCRYPT)
+ if (( (0 == strcmp (crypt_method, "YESCRYPT"))
+ && (0 == getlong(optarg, &yescrypt_cost)))) {
+ bad_s = 1;
+ }
+#endif /* USE_YESCRYPT */
+ if (bad_s != 0) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
Prog, optarg);
usage (E_USAGE);
}
break;
-#elif defined(USE_SHA_CRYPT)
- case 's':
- sflg = true;
- if (0 == getlong(optarg, &sha_rounds)) {
- fprintf (stderr,
- _("%s: invalid numeric argument '%s'\n"),
- Prog, optarg);
- usage (E_USAGE);
- }
- break;
-#elif defined(USE_BCRYPT)
- case 's':
- sflg = true;
- if (0 == getlong(optarg, &bcrypt_rounds)) {
- fprintf (stderr,
- _("%s: invalid numeric argument '%s'\n"),
- Prog, optarg);
- usage (E_USAGE);
- }
- break;
-#endif
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
default:
usage (E_USAGE);
@@ -249,7 +252,7 @@ static void process_flags (int argc, cha
*/
static void check_flags (void)
{
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
if (sflg && !cflg) {
fprintf (stderr,
_("%s: %s flag is only allowed with the %s flag\n"),
@@ -277,6 +280,9 @@ static void check_flags (void)
#ifdef USE_BCRYPT
&& (0 != strcmp (crypt_method, "BCRYPT"))
#endif /* USE_BCRYPT */
+#ifdef USE_YESCRYPT
+ && (0 != strcmp (crypt_method, "YESCRYPT"))
+#endif /* USE_YESCRYPT */
) {
fprintf (stderr,
_("%s: unsupported crypt method: %s\n"),
@@ -604,23 +610,24 @@ int main (int argc, char **argv)
if (md5flg) {
crypt_method = "MD5";
}
-#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
if (sflg) {
+#if defined(USE_SHA_CRYPT)
if ( (0 == strcmp (crypt_method, "SHA256"))
|| (0 == strcmp (crypt_method, "SHA512"))) {
arg = &sha_rounds;
}
- else if (0 == strcmp (crypt_method, "BCRYPT")) {
+#endif /* USE_SHA_CRYPT */
+#if defined(USE_BCRYPT)
+ if (0 == strcmp (crypt_method, "BCRYPT")) {
arg = &bcrypt_rounds;
}
- }
-#elif defined(USE_SHA_CRYPT)
- if (sflg) {
- arg = &sha_rounds;
- }
-#elif defined(USE_BCRYPT)
- if (sflg) {
- arg = &bcrypt_rounds;
+#endif /* USE_BCRYPT */
+#if defined(USE_YESCRYPT)
+ if (0 == strcmp (crypt_method, "YESCRYPT")) {
+ arg = &yescrypt_cost;
+ }
+#endif /* USE_YESCRYPT */
}
#endif
salt = crypt_make_salt (crypt_method, arg);
Index: shadow-4.8.1/src/newusers.c
===================================================================
--- shadow-4.8.1.orig/src/newusers.c
+++ shadow-4.8.1/src/newusers.c
@@ -90,6 +90,9 @@ static long sha_rounds = 5000;
#ifdef USE_BCRYPT
static long bcrypt_rounds = 13;
#endif /* USE_BCRYPT */
+#ifdef USE_YESCRYPT
+static long yescrypt_cost = 5;
+#endif /* USE_YESCRYPT */
#endif /* !USE_PAM */
static bool is_shadow;
@@ -140,14 +143,15 @@ static void usage (int status)
#ifndef USE_PAM
(void) fprintf (usageout,
_(" -c, --crypt-method METHOD the crypt method (one of %s)\n"),
-#if !defined(USE_SHA_CRYPT) && !defined(USE_BCRYPT)
- "NONE DES MD5"
-#elif defined(USE_SHA_CRYPT) && defined(USE_BCRYPT)
- "NONE DES MD5 SHA256 SHA512 BCRYPT"
-#elif defined(USE_SHA_CRYPT)
- "NONE DES MD5 SHA256 SHA512"
-#else
- "NONE DES MD5 BCRYPT"
+ "NONE DES MD5"
+#if defined(USE_SHA_CRYPT)
+ " SHA256 SHA512"
+#endif
+#if defined(USE_BCRYPT)
+ " BCRYPT"
+#endif
+#if defined(USE_YESCRYPT)
+ " YESCRYPT"
#endif
);
#endif /* !USE_PAM */
@@ -155,11 +159,11 @@ static void usage (int status)
(void) fputs (_(" -r, --system create system accounts\n"), usageout);
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
#ifndef USE_PAM
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
- (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA or BCRYPT\n"
- " crypt algorithms\n"),
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
+ (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT\n"
+ " or YESCRYPT crypt algorithms\n"),
usageout);
-#endif /* USE_SHA_CRYPT || USE_BCRYPT */
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
#endif /* !USE_PAM */
(void) fputs ("\n", usageout);
@@ -434,25 +438,28 @@ static int update_passwd (struct passwd
void *crypt_arg = NULL;
char *cp;
if (NULL != crypt_method) {
-#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT)
+#if defined(USE_SHA_CRYPT)
if (sflg) {
if ( (0 == strcmp (crypt_method, "SHA256"))
|| (0 == strcmp (crypt_method, "SHA512"))) {
crypt_arg = &sha_rounds;
}
- else if (0 == strcmp (crypt_method, "BCRYPT")) {
- crypt_arg = &bcrypt_rounds;
- }
}
-#elif defined(USE_SHA_CRYPT)
+#endif /* USE_SHA_CRYPT */
+#if defined(USE_BCRYPT)
if (sflg) {
- crypt_arg = &sha_rounds;
+ if (0 == strcmp (crypt_method, "BCRYPT")) {
+ crypt_arg = &bcrypt_rounds;
+ }
}
-#elif defined(USE_BCRYPT)
+#endif /* USE_BCRYPT */
+#if defined(USE_YESCRYPT)
if (sflg) {
- crypt_arg = &bcrypt_rounds;
+ if (0 == strcmp (crypt_method, "YESCRYPT")) {
+ crypt_arg = &yescrypt_cost;
+ }
}
-#endif
+#endif /* USE_YESCRYPT */
}
if ((NULL != crypt_method) && (0 == strcmp(crypt_method, "NONE"))) {
@@ -485,25 +492,28 @@ static int add_passwd (struct passwd *pw
#ifndef USE_PAM
void *crypt_arg = NULL;
if (NULL != crypt_method) {
-#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT)
+#if defined(USE_SHA_CRYPT)
if (sflg) {
if ( (0 == strcmp (crypt_method, "SHA256"))
|| (0 == strcmp (crypt_method, "SHA512"))) {
crypt_arg = &sha_rounds;
}
- else if (0 == strcmp (crypt_method, "BCRYPT")) {
- crypt_arg = &bcrypt_rounds;
- }
}
-#elif defined(USE_SHA_CRYPT)
+#endif /* USE_SHA_CRYPT */
+#if defined(USE_BCRYPT)
if (sflg) {
- crypt_arg = &sha_rounds;
+ if (0 == strcmp (crypt_method, "BCRYPT")) {
+ crypt_arg = &bcrypt_rounds;
+ }
}
-#elif defined(USE_BCRYPT)
+#endif /* USE_BCRYPT */
+#if defined(USE_YESCRYPT)
if (sflg) {
- crypt_arg = &bcrypt_rounds;
+ if (0 == strcmp (crypt_method, "YESCRYPT")) {
+ crypt_arg = &yescrypt_cost;
+ }
}
-#endif
+#endif /* USE_PAM */
}
/*
@@ -620,6 +630,9 @@ static int add_passwd (struct passwd *pw
static void process_flags (int argc, char **argv)
{
int c;
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
+ int bad_s;
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
static struct option long_options[] = {
{"badnames", no_argument, NULL, 'b'},
#ifndef USE_PAM
@@ -629,20 +642,20 @@ static void process_flags (int argc, cha
{"system", no_argument, NULL, 'r'},
{"root", required_argument, NULL, 'R'},
#ifndef USE_PAM
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
{"sha-rounds", required_argument, NULL, 's'},
-#endif /* USE_SHA_CRYPT || USE_BCRYPT */
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
#endif /* !USE_PAM */
{NULL, 0, NULL, '\0'}
};
while ((c = getopt_long (argc, argv,
#ifndef USE_PAM
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
"c:bhrs:",
-#else /* !USE_SHA_CRYPT && !USE_BCRYPT */
+#else /* !USE_SHA_CRYPT && !USE_BCRYPT && !USE_YESCRYPT */
"c:bhr",
-#endif /* USE_SHA_CRYPT || USE_BCRYPT */
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
#else /* USE_PAM */
"bhr",
#endif
@@ -665,40 +678,36 @@ static void process_flags (int argc, cha
case 'R': /* no-op, handled in process_root_flag () */
break;
#ifndef USE_PAM
-#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
case 's':
sflg = true;
+ bad_s = 0;
+#if defined(USE_SHA_CRYPT)
if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512")))
- && (0 == getlong(optarg, &sha_rounds)))
- || ( (0 == strcmp (crypt_method, "BCRYPT"))
+ && (0 == getlong(optarg, &sha_rounds)))) {
+ bad_s = 1;
+ }
+#endif /* USE_SHA_CRYPT */
+#if defined(USE_BCRYPT)
+ if (( (0 == strcmp (crypt_method, "BCRYPT"))
&& (0 == getlong(optarg, &bcrypt_rounds)))) {
+ bad_s = 1;
+ }
+#endif /* USE_BCRYPT */
+#if defined(USE_YESCRYPT)
+ if (( (0 == strcmp (crypt_method, "YESCRYPT"))
+ && (0 == getlong(optarg, &yescrypt_cost)))) {
+ bad_s = 1;
+ }
+#endif /* USE_YESCRYPT */
+ if (bad_s != 0) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
Prog, optarg);
usage (EXIT_FAILURE);
}
break;
-#elif defined(USE_SHA_CRYPT)
- case 's':
- sflg = true;
- if (0 == getlong(optarg, &sha_rounds)) {
- fprintf (stderr,
- _("%s: invalid numeric argument '%s'\n"),
- Prog, optarg);
- usage (EXIT_FAILURE);
- }
- break;
-#elif defined(USE_BCRYPT)
- case 's':
- sflg = true;
- if (0 == getlong(optarg, &bcrypt_rounds)) {
- fprintf (stderr,
- _("%s: invalid numeric argument '%s'\n"),
- Prog, optarg);
- usage (EXIT_FAILURE);
- }
- break;
-#endif
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
#endif /* !USE_PAM */
default:
usage (EXIT_FAILURE);
@@ -732,14 +741,14 @@ static void process_flags (int argc, cha
static void check_flags (void)
{
#ifndef USE_PAM
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
if (sflg && !cflg) {
fprintf (stderr,
_("%s: %s flag is only allowed with the %s flag\n"),
Prog, "-s", "-c");
usage (EXIT_FAILURE);
}
-#endif
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
if (cflg) {
if ( (0 != strcmp (crypt_method, "DES"))
@@ -752,6 +761,9 @@ static void check_flags (void)
#ifdef USE_BCRYPT
&& (0 != strcmp (crypt_method, "BCRYPT"))
#endif /* USE_BCRYPT */
+#ifdef USE_YESCRYPT
+ && (0 != strcmp (crypt_method, "YESCRYPT"))
+#endif /* USE_YESCRYPT */
) {
fprintf (stderr,
_("%s: unsupported crypt method: %s\n"),
Index: shadow-4.8.1/src/passwd.c
===================================================================
--- shadow-4.8.1.orig/src/passwd.c
+++ shadow-4.8.1/src/passwd.c
@@ -283,7 +283,10 @@ static int new_password (const struct pa
#endif /* USE_SHA_CRYPT */
#ifdef USE_BCRYPT
|| (strcmp (method, "BCRYPT") == 0)
-#endif /* USE_SHA_CRYPT */
+#endif /* USE_BCRYPT*/
+#ifdef USE_YESCRYPT
+ || (strcmp (method, "YESCRYPT") == 0)
+#endif /* USE_YESCRYPT*/
) {
pass_max_len = -1;

View File

@ -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, user_name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE); SHADOW_AUDIT_FAILURE);
#endif #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) @@ -1622,7 +1570,7 @@ static void close_files (void)
SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ()));
#ifdef WITH_AUDIT #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) { if (chown (path, 0, 0) < 0) {
@@ -2168,8 +2109,8 @@ static void create_home (void) @@ -2168,8 +2109,8 @@ static void create_home (void)
chmod (prefix_user_home, mode); }
home_added = true; home_added = true;
#ifdef WITH_AUDIT #ifdef WITH_AUDIT
- audit_logger (AUDIT_ADD_USER, Prog, - 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, + user_name, (unsigned int) user_id,
+ SHADOW_AUDIT_FAILURE); + SHADOW_AUDIT_FAILURE);
#endif /* WITH_AUDIT */ #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 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.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 +++ shadow-4.8.1/src/userdel.c 2020-03-17 16:53:44.373943325 +0100

View File

@ -1,7 +1,6 @@
Index: 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.5.orig/lib/semanage.c +++ shadow-4.9/lib/semanage.c 2021-08-02 12:43:16.822817392 +0200
+++ shadow-4.5/lib/semanage.c
@@ -143,6 +143,7 @@ static int semanage_user_mod (semanage_h @@ -143,6 +143,7 @@ static int semanage_user_mod (semanage_h
goto done; goto done;
} }
@ -9,7 +8,7 @@ Index: shadow-4.5/lib/semanage.c
+#if 0 +#if 0
ret = semanage_seuser_set_mlsrange (handle, seuser, DEFAULT_SERANGE); ret = semanage_seuser_set_mlsrange (handle, seuser, DEFAULT_SERANGE);
if (ret != 0) { if (ret != 0) {
fprintf (stderr, fprintf (shadow_logfd,
@@ -150,6 +151,7 @@ static int semanage_user_mod (semanage_h @@ -150,6 +151,7 @@ static int semanage_user_mod (semanage_h
ret = 1; ret = 1;
goto done; goto done;
@ -25,7 +24,7 @@ Index: shadow-4.5/lib/semanage.c
+#if 0 +#if 0
ret = semanage_seuser_set_mlsrange (handle, seuser, DEFAULT_SERANGE); ret = semanage_seuser_set_mlsrange (handle, seuser, DEFAULT_SERANGE);
if (ret != 0) { if (ret != 0) {
fprintf (stderr, fprintf (shadow_logfd,
@@ -208,6 +211,7 @@ static int semanage_user_add (semanage_h @@ -208,6 +211,7 @@ static int semanage_user_add (semanage_h
ret = 1; ret = 1;
goto done; goto done;

180
shadow-4.9-manfix.patch Normal file
View File

@ -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 @@
<refsect1 id='setup'>
<title>SETUP</title>
<para>
- The <command>groupmems</command> executable should be in mode
- <literal>2710</literal> as user <emphasis>root</emphasis> and in group
- <emphasis>groups</emphasis>. The system administrator can add users to
- group <emphasis>groups</emphasis> to allow or disallow them using the
- <command>groupmems</command> utility to manage their own group
- membership list.
+ In this operating system the <command>groupmems</command> executable
+ is not setuid and regular users cannot use it to manipulate
+ the membership of their own group.
</para>
-
- <programlisting>
- $ groupadd -r groups
- $ chmod 2710 groupmems
- $ chown root.groups groupmems
- $ groupmems -g groups -a gk4
- </programlisting>
</refsect1>
<refsect1 id='configuration'>
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.
</para>
+ <para>
+ 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 <emphasis>ENCRYPT_METHOD</emphasis> and <emphasis>SHA_CRYPT_MAX_ROUNDS</emphasis>
+ for pam_unix module, <emphasis>FAIL_DELAY</emphasis> for pam_faildelay module,
+ and <emphasis>UMASK</emphasis> for pam_umask module. Refer to
+ pam(8) for more information.
+ </para>
+
<para>The following configuration items are provided:</para>
<variablelist remap='IP'>
@@ -256,16 +267,6 @@
</listitem>
</varlistentry>
<varlistentry>
- <term>chfn</term>
- <listitem>
- <para>
- <phrase condition="no_pam">CHFN_AUTH</phrase>
- CHFN_RESTRICT
- <phrase condition="no_pam">LOGIN_STRING</phrase>
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
<term>chgpasswd</term>
<listitem>
<para>
@@ -286,14 +287,6 @@
</para>
</listitem>
</varlistentry>
- <varlistentry condition="no_pam">
- <term>chsh</term>
- <listitem>
- <para>
- CHSH_AUTH LOGIN_STRING
- </para>
- </listitem>
- </varlistentry>
<!-- expiry: no variables (CONSOLE_GROUPS linked, but not used) -->
<!-- faillog: no variables -->
<varlistentry>
@@ -359,34 +352,6 @@
<para>LASTLOG_UID_MAX</para>
</listitem>
</varlistentry>
- <varlistentry>
- <term>login</term>
- <listitem>
- <para>
- <phrase condition="no_pam">CONSOLE</phrase>
- CONSOLE_GROUPS DEFAULT_HOME
- <phrase condition="no_pam">ENV_HZ ENV_PATH ENV_SUPATH
- ENV_TZ ENVIRON_FILE</phrase>
- ERASECHAR FAIL_DELAY
- <phrase condition="no_pam">FAILLOG_ENAB</phrase>
- FAKE_SHELL
- <phrase condition="no_pam">FTMP_FILE</phrase>
- HUSHLOGIN_FILE
- <phrase condition="no_pam">ISSUE_FILE</phrase>
- KILLCHAR
- <phrase condition="no_pam">LASTLOG_ENAB LASTLOG_UID_MAX</phrase>
- LOGIN_RETRIES
- <phrase condition="no_pam">LOGIN_STRING</phrase>
- LOGIN_TIMEOUT LOG_OK_LOGINS LOG_UNKFAIL_ENAB
- <phrase condition="no_pam">MAIL_CHECK_ENAB MAIL_DIR MAIL_FILE
- MOTD_FILE NOLOGINS_FILE PORTTIME_CHECKS_ENAB
- QUOTAS_ENAB</phrase>
- TTYGROUP TTYPERM TTYTYPE_FILE
- <phrase condition="no_pam">ULIMIT UMASK</phrase>
- USERGROUPS_ENAB
- </para>
- </listitem>
- </varlistentry>
<!-- logoutd: no variables -->
<varlistentry>
<term>newgrp / sg</term>
@@ -415,17 +380,6 @@
</listitem>
</varlistentry>
<!-- nologin: no variables -->
- <varlistentry condition="no_pam">
- <term>passwd</term>
- <listitem>
- <para>
- ENCRYPT_METHOD MD5_CRYPT_ENAB OBSCURE_CHECKS_ENAB
- PASS_ALWAYS_WARN PASS_CHANGE_TRIES PASS_MAX_LEN PASS_MIN_LEN
- <phrase condition="sha_crypt">SHA_CRYPT_MAX_ROUNDS
- SHA_CRYPT_MIN_ROUNDS</phrase>
- </para>
- </listitem>
- </varlistentry>
<varlistentry>
<term>pwck</term>
<listitem>
@@ -452,32 +406,6 @@
</para>
</listitem>
</varlistentry>
- <varlistentry>
- <term>su</term>
- <listitem>
- <para>
- <phrase condition="no_pam">CONSOLE</phrase>
- CONSOLE_GROUPS DEFAULT_HOME
- <phrase condition="no_pam">ENV_HZ ENVIRON_FILE</phrase>
- ENV_PATH ENV_SUPATH
- <phrase condition="no_pam">ENV_TZ LOGIN_STRING MAIL_CHECK_ENAB
- MAIL_DIR MAIL_FILE QUOTAS_ENAB</phrase>
- SULOG_FILE SU_NAME
- <phrase condition="no_pam">SU_WHEEL_ONLY</phrase>
- SYSLOG_SU_ENAB
- <phrase condition="no_pam">USERGROUPS_ENAB</phrase>
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>sulogin</term>
- <listitem>
- <para>
- ENV_HZ
- <phrase condition="no_pam">ENV_TZ</phrase>
- </para>
- </listitem>
- </varlistentry>
<varlistentry>
<term>useradd</term>
<listitem>

View File

@ -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;
}

View File

@ -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)

View File

@ -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 Index: shadow-4.5/src/chage.c
=================================================================== ===================================================================
--- shadow-4.5.orig/src/chage.c --- shadow-4.5.orig/src/chage.c

View File

@ -1,16 +1,16 @@
diff -up shadow-4.6/src/useradd.c.redhat shadow-4.6/src/useradd.c diff -up shadow-4.9/src/useradd.c.redhat shadow-4.9/src/useradd.c
--- shadow-4.6/src/useradd.c.redhat 2018-04-29 18:42:37.000000000 +0200 --- shadow-4.9/src/useradd.c.redhat 2021-07-22 23:55:35.000000000 +0200
+++ shadow-4.6/src/useradd.c 2018-05-28 13:37:16.695651258 +0200 +++ shadow-4.9/src/useradd.c 2021-08-02 11:45:11.942867250 +0200
@@ -98,7 +98,7 @@ const char *Prog; @@ -104,7 +104,7 @@ FILE *shadow_logfd = NULL;
static gid_t def_group = 100; static gid_t def_group = 1000;
static const char *def_gname = "other"; static const char *def_gname = "other";
static const char *def_home = "/home"; 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_shell = "/sbin/nologin";
static const char *def_template = SKEL_DIR; 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)) #define VALID(s) (strcspn (s, ":\n") == strlen (s))
static const char *user_name = ""; 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 uid_t user_id;
static gid_t user_gid; static gid_t user_gid;
static const char *user_comment = ""; 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, while ((c = getopt_long (argc, argv,
#ifdef WITH_SELINUX #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 */ #endif /* !WITH_SELINUX */
long_options, NULL)) != -1) { long_options, NULL)) != -1) {
switch (c) { 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': case 'M':
Mflg = true; Mflg = true;
break; break;

View File

@ -0,0 +1,322 @@
From e481437ab9ebe9a8bf8fbaabe986d42b2f765991 Mon Sep 17 00:00:00 2001
From: Iker Pedrosa <ipedrosa@redhat.com>
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 <ipedrosa@redhat.com>
---
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

View File

@ -1,7 +1,7 @@
Summary: Utilities for managing accounts and shadow password files Summary: Utilities for managing accounts and shadow password files
Name: shadow-utils Name: shadow-utils
Version: 4.8.1 Version: 4.9
Release: 20%{?dist} Release: 1%{?dist}
Epoch: 2 Epoch: 2
URL: https://github.com/shadow-maint/shadow URL: https://github.com/shadow-maint/shadow
Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz
@ -17,111 +17,37 @@ Source6: shadow-utils.HOME_MODE.xml
### Patches ### ### Patches ###
# Misc small changes - most probably non-upstreamable # 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 # Be more lenient with acceptable user/group names - non upstreamable
Patch1: shadow-4.8-goodname.patch Patch1: shadow-4.8-goodname.patch
# https://github.com/shadow-maint/shadow/commit/7384865775b0203b9cf5337a047744f0a4555868 # Move create home to the end of main - upstreamability unknown
Patch2: shadow-4.1.5.1-info-parent-dir.patch Patch2: shadow-4.9-move-create-home.patch
# Misc SElinux related changes - upstreamability unknown
Patch6: shadow-4.8-selinux.patch
# https://github.com/shadow-maint/shadow/commit/a8361e741040cd926c9c93aac89820052531b1a3
Patch11: shadow-4.1.5.1-logmsg.patch
# SElinux related - upstreamability unknown # SElinux related - upstreamability unknown
Patch14: shadow-4.1.5.1-default-range.patch Patch3: shadow-4.9-default-range.patch
# Misc manual page changes # Misc manual page changes - non-upstreamable
# https://github.com/shadow-maint/shadow/commit/c0818ab01d1896784245eedec9495e1e6e0260af Patch4: shadow-4.9-manfix.patch
# Changes in man/groupmems.8.xml, man/ja/man5/login.defs.5 and man/login.defs.5.xml not upstreamed
Patch15: shadow-4.8.1-manfix.patch
# https://github.com/shadow-maint/shadow/commit/f4cbf38ad7801bab6fae50e9b5a2effc3c48a1ea
Patch17: shadow-4.1.5.1-userdel-helpfix.patch
# Date parsing improvement - could be upstreamed # 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 # 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 # 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 # 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 # 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 # Handle NULL return from *time funcs - could be upstreamed
Patch29: shadow-4.2.1-null-tm.patch Patch10: shadow-4.9-null-tm.patch
# SElinux related - upstreamability unknown
Patch31: shadow-4.6-getenforce.patch
# https://github.com/shadow-maint/shadow/commit/c93897a8d71b9b1790caf3b2dee38dbe62518ae3
Patch32: shadow-4.8-crypt_h.patch
# Handle /etc/passwd corruption - could be upstreamed # 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 # 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 # Ignore LOGIN_PLAIN_PROMPT in login.defs - upstreamability unknown
Patch40: shadow-4.8-ignore-login-prompt.patch Patch13: shadow-4.8-ignore-login-prompt.patch
# Generate /var/spool/mail/$USER with the proper SELinux user identity - already upstreamed # https://github.com/shadow-maint/shadow/pull/395
Patch42: shadow-4.8-useradd-selinux-mail.patch Patch14: shadow-4.9-newuidmap-libeconf-dependency.patch
# Clarify useradd man regarding "-d" parameter - already upstreamed # https://github.com/shadow-maint/shadow/pull/397
Patch43: shadow-4.8.1-useradd-man-clarification.patch Patch15: shadow-4.9-usermod-allow-all-group-types.patch
# https://github.com/shadow-maint/shadow/commit/140510de9de4771feb3af1d859c09604043a4c9b
# https://github.com/shadow-maint/shadow/commit/8762f465d487a52bf68f9c0b7c3c1eb3caea7bc9
Patch44: shadow-4.8.1-check-local-groups.patch
# https://github.com/shadow-maint/shadow/commit/599cc003daf833bffdc9cbe0d33dc8b3e7ec74c8
Patch45: shadow-4.8.1-commonio-force-lock-file-sync.patch
# https://github.com/shadow-maint/shadow/commit/df6ec1d1693c8c80c323b40d6fc82bb549363db3
Patch46: shadow-4.8.1-man-include-lastlog-file-caveat.patch
# https://github.com/shadow-maint/shadow/commit/0a7888b1fad613a052b988b01a71933b67296e68
# https://github.com/shadow-maint/shadow/commit/607f1dd549cf9abc87af1cf29275f0d2d11eea29
# https://github.com/shadow-maint/shadow/commit/b5fb1b38eea2fb0489ed088c82daf6700e72363e
# https://github.com/shadow-maint/shadow/commit/43a917cce54019799a8de037fd63780a2b640afc
Patch47: shadow-4.8.1-libsubid_creation.patch
# https://github.com/shadow-maint/shadow/commit/514c1328b6c90d817ae0a9f7addfb3c9a11a275a
# https://github.com/shadow-maint/shadow/commit/8492dee6632e340dee76eee895c3e30877bebf45
# https://github.com/shadow-maint/shadow/commit/0f4347d1483191b2142546416a9eefe0c9459600
Patch48: shadow-4.8.1-libsubid_nsswitch_support.patch
# https://github.com/shadow-maint/shadow/commit/186b1b7ac1a68d0fcc618a22da1a99232b420911
Patch49: shadow-4.8.1-man-mention-nss-in-newuidmap.patch
# https://github.com/shadow-maint/shadow/commit/f9831a4a1a20b0e8fe47cc72ec20018ec04dbb90
Patch50: shadow-4.8.1-libsubid_not_print_error_messages.patch
# https://github.com/shadow-maint/shadow/commit/c6cab4a7bafa18d9d65a333cac1261e7b5e32bc9
Patch51: shadow-4.8.1-libsubid_init_return_false.patch
# https://github.com/shadow-maint/shadow/commit/2f1f45d64fc7c10e7a3cbe00e89f63714343e526
Patch52: shadow-4.8.1-useradd_SUB_UID_COUNT-0.patch
# https://github.com/shadow-maint/shadow/commit/ea7af4e1543c63590d4107ae075fea385028997d
Patch53: shadow-4.8.1-libsubid_simplify_ranges_variable.patch
# https://github.com/shadow-maint/shadow/commit/0fe42f571c69f0105d31305f995c9887aeb9525e
Patch54: shadow-4.8.1-libsubid_init_not_print_error_messages.patch
# https://github.com/shadow-maint/shadow/commit/ec1951c181faed188464396b2cfdd2efb726c7f3
Patch55: shadow-4.8.1-libsubid_fix_newusers_nss_provides_subids.patch
# https://github.com/shadow-maint/shadow/commit/087112244327be50abc24f9ec8afbf60ae8b2dec
# https://github.com/shadow-maint/shadow/pull/353
Patch56: shadow-4.8.1-man_clarify_subid_delegation.patch
# https://github.com/shadow-maint/shadow/commit/bd920ab36a6c641e4a8769f8c7f8ca738ec61820
Patch57: shadow-4.8.1-libsubid_make_logfd_not_extern.patch
# https://github.com/shadow-maint/shadow/commit/5cd04d03f94622c12220d4a6352824af081b8531
Patch58: shadow-4.8.1-yescrypt-support.patch
# https://github.com/shadow-maint/shadow/commit/7a3bb4d0ea8166acc539c788a8ce943acf4a6aa7
Patch59: shadow-4.8.1-fix_YESCRYPT_salt_cost_param_type.patch
# https://github.com/shadow-maint/shadow/commit/c44b71cec25d60efc51aec9de3abce1f6efbfcf5
# https://github.com/shadow-maint/shadow/commit/fd9d79a1a3438ba7703939cfcd45fc266782c64e
# https://github.com/shadow-maint/shadow/commit/8281c82e324b57b3a4b520afad26b43ce128d521
# https://github.com/shadow-maint/shadow/commit/1aed7ae945aafaeb253fc89a7ecedeaedf72654e
# https://github.com/shadow-maint/shadow/commit/5d0d7841971cc53d9a9d1aefe12f00204115bf6a
# https://github.com/shadow-maint/shadow/commit/e65cc6aebcb4132fa413f00a905216a5b35b3d57
Patch60: shadow-4.8.1-covscan_fixes.patch
# https://github.com/shadow-maint/shadow/commit/738d92a4bd99a2038aa5f97b2fc85daa7011e403
Patch61: shadow-4.8.1-fix_bcrypt_prefix.patch
# https://github.com/shadow-maint/shadow/commit/14b108728a5d55c3d478a170c39f0e2ffd4de1b0
Patch62: shadow-4.8.1-salt_c_sanitize_code.patch
# https://github.com/shadow-maint/shadow/commit/dbf230e4cf823dd6b6a3bad6d29dfad4f0ffa8fc
Patch63: shadow-4.8.1-salt_c_comments.patch
# https://github.com/shadow-maint/shadow/commit/bc8257cf73328e450511b13cbd35e1994feccb30
Patch64: shadow-4.8.1-salt_c_use_dev_urandom.patch
# https://github.com/shadow-maint/shadow/commit/2c542f6c65f858b3dba20f58db4da56572f67a54
Patch65: shadow-4.8.1-useradd_create_relative_home_path_correctly.patch
# https://github.com/shadow-maint/shadow/commit/c82ed0c15e0e9e47df0b4c22672b72e35f061a9d
Patch66: shadow-4.8.1-getentropy_random_bytes.patch
# https://github.com/shadow-maint/shadow/commit/ea04eb301d08c0c58f1120f87d4ec184d3983ce5
Patch67: shadow-4.8.1-crypt_gensalt.patch
# https://github.com/shadow-maint/shadow/commit/ffd35d89021a9b8375a9246082afc6fc270a93ee
Patch68: shadow-4.8.1-salt_c_fix_fread.patch
License: BSD and GPLv2+ License: BSD and GPLv2+
BuildRequires: make BuildRequires: make
@ -171,50 +97,20 @@ Development files for shadow-utils-subid.
%setup -q -n shadow-%{version} %setup -q -n shadow-%{version}
%patch0 -p1 -b .redhat %patch0 -p1 -b .redhat
%patch1 -p1 -b .goodname %patch1 -p1 -b .goodname
%patch2 -p1 -b .info-parent-dir %patch2 -p1 -b .move-create-home
%patch6 -p1 -b .selinux %patch3 -p1 -b .default-range
%patch11 -p1 -b .logmsg %patch4 -p1 -b .manfix
%patch14 -p1 -b .default-range %patch5 -p1 -b .date-parsing
%patch15 -p1 -b .manfix %patch6 -p1 -b .move-home
%patch17 -p1 -b .userdel %patch7 -p1 -b .audit-update
%patch19 -p1 -b .date-parsing %patch8 -p1 -b .unlock
%patch21 -p1 -b .move-home %patch9 -p1 -b .selinux-perms
%patch22 -p1 -b .audit-update %patch10 -p1 -b .null-tm
%patch23 -p1 -b .unlock %patch11 -p1 -b .long-entry
%patch28 -p1 -b .selinux-perms %patch12 -p1 -b .sysugid-min-limit
%patch29 -p1 -b .null-tm %patch13 -p1 -b .login-prompt
%patch31 -p1 -b .getenforce %patch14 -p1 -b .newuidmap-libeconf-dependency
%patch32 -p1 -b .crypt_h %patch15 -p1 -b .usermod-allow-all-group-types
%patch33 -p1 -b .long-entry
%patch38 -p1 -b .sysugid-min-limit
%patch40 -p1 -b .login-prompt
%patch42 -p1 -b .useradd-selinux-mail
%patch43 -p1 -b .useradd-man-clarification
%patch44 -p1 -b .check-local-groups
%patch45 -p1 -b .commonio-force-lock-file-sync
%patch46 -p1 -b .man-include-lastlog-file-caveat
%patch47 -p1 -b .libsubid_creation
%patch48 -p1 -b .libsubid_nsswitch_support
%patch49 -p1 -b .man-mention-nss-in-newuidmap
%patch50 -p1 -b .libsubid_not_print_error_messages
%patch51 -p1 -b .libsubid_init_return_false
%patch52 -p1 -b .useradd_SUB_UID_COUNT-0
%patch53 -p1 -b .libsubid_simplify_ranges_variable
%patch54 -p1 -b .libsubid_init_not_print_error_messages
%patch55 -p1 -b .libsubid_fix_newusers_nss_provides_subids
%patch56 -p1 -b .man_clarify_subid_delegation
%patch57 -p1 -b .libsubid_make_logfd_not_extern
%patch58 -p1 -b .yescrypt
%patch59 -p1 -b .YESCRYPT_salt_cost_param_type
%patch60 -p1 -b .covscan_fixes
%patch61 -p1 -b .bcrypt_prefix
%patch62 -p1 -b .sanitize_code
%patch63 -p1 -b .comments
%patch64 -p1 -b .use_dev_urandom
%patch65 -p1 -b .useradd_create_relative_home_path_correctly
%patch66 -p1 -b .getentropy_random_bytes
%patch67 -p1 -b .crypt_gensalt
%patch68 -p1 -b .fix_fread
iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8
cp -f doc/HOWTO.utf8 doc/HOWTO cp -f doc/HOWTO.utf8 doc/HOWTO
@ -385,6 +281,11 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la
%{_libdir}/libsubid.so %{_libdir}/libsubid.so
%changelog %changelog
* Wed Aug 4 2021 Iker Pedrosa <ipedrosa@redhat.com> - 2:4.9-1
- Rebase to version 4.9
- usermod: allow all group types with -G option (#1975327)
- Clean spec file
* Fri Jul 23 2021 Fedora Release Engineering <releng@fedoraproject.org> - 2:4.8.1-20 * Fri Jul 23 2021 Fedora Release Engineering <releng@fedoraproject.org> - 2:4.8.1-20
- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild

View File

@ -1,2 +1,2 @@
SHA512 (shadow-4.8.1.tar.xz) = 780a983483d847ed3c91c82064a0fa902b6f4185225978241bc3bc03fcc3aa143975b46aee43151c6ba43efcfdb1819516b76ba7ad3d1d3c34fcc38ea42e917b SHA512 (shadow-4.9.tar.xz) = 254cda49bb14505a7604821e7fa898bf4bf317d648e9ddc881ab80a6860d52053dfffacad6feab87c7d16608c35ed6b6cee99e7757eac930da3a7b31cdcd4b95
SHA512 (shadow-4.8.1.tar.xz.asc) = ec7686263c81d3feb8ee4314c3323a9a3ada74aafaaf99f4f0d9af9b1341f8c5ff5477ecf98dd94dbb7d921f532d655b0b6a87d94c71893f35dc9bc54c84dd42 SHA512 (shadow-4.9.tar.xz.asc) = 16c0ff7be263c9d471b05656c9a1d14da8ec9b17544910323ca6ab854126d1a03ece221e0caf610e65a9b1d080b4cd1b8b46973f20e3ae45ea0e5581ce6c90d9