Compare commits

..

5 commits

Author SHA1 Message Date
Iker Pedrosa
1a4bf4ab37 useradd: fix write_full() return value
Resolves: #2313559

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2024-10-10 09:26:04 +02:00
Iker Pedrosa
79e26c836e useradd: fix write_full() return value
Resolves: #2313559

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2024-09-30 11:51:09 +02:00
Iker Pedrosa
7aa371f299 Disable nscd
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2024-09-18 09:25:01 +02:00
Iker Pedrosa
32317ef2af Sort alphabetically configuration options
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2024-09-18 09:22:33 +02:00
Iker Pedrosa
e1a551fc5d Revert "Rebase to version 4.16.0"
This reverts commit c3bc52a4f1.
2024-09-18 09:21:56 +02:00
20 changed files with 5917 additions and 222 deletions

View file

@ -1 +0,0 @@
1

22
.gitignore vendored
View file

@ -32,25 +32,3 @@ shadow-4.1.4.2.tar.bz2
/shadow-4.15.0.tar.xz.asc
/shadow-4.15.1.tar.xz
/shadow-4.15.1.tar.xz.asc
/shadow-4.16.0.tar.xz
/shadow-4.16.0.tar.xz.asc
/shadow-4.17.0-rc1.tar.xz
/shadow-4.17.0-rc1.tar.xz.asc
/shadow-4.17.0.tar.xz
/shadow-4.17.0.tar.xz.asc
/shadow-4.17.4.tar.xz
/shadow-4.17.4.tar.xz.asc
/shadow-4.18.0.tar.xz
/shadow-4.18.0.tar.xz.asc
/shadow-4.19.0.tar.xz
/shadow-4.19.0.tar.xz.asc
/shadow-4.19.2.tar.xz
/shadow-4.19.2.tar.xz.asc
/shadow-4.19.3.tar.xz
/shadow-4.19.3.tar.xz.asc
/shadow-4.20.0-rc2.tar.xz
/shadow-4.20.0-rc2.tar.xz.asc
/shadow-4.20.0-rc3.tar.xz
/shadow-4.20.0-rc3.tar.xz.asc
/shadow-4.20.0.tar.xz
/shadow-4.20.0.tar.xz.asc

View file

@ -1,51 +0,0 @@
summary: Tier 0 functional tests for shadow-utils
description: |
Run comprehensive system tests for shadow-utils. These tests validate user and group
account management functionality by testing actual system operations including user
creation, password management, group operations, and verification of system files
(i.e. /etc/passwd, /etc/shadow).
provision:
how: virtual
image: fedora
prepare:
- name: Install general dependencies
how: install
package:
- expect
- gcc
- git
- libssh-devel
- python3-devel
- python3-pip
- name: Setup SSH keys for localhost testing
how: shell
script:
- ssh-keygen -t rsa -f /root/.ssh/id_rsa -N "" -q
- cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys
- chmod 600 /root/.ssh/authorized_keys
- ssh-keyscan -H localhost >> /root/.ssh/known_hosts
- name: Clone shadow repository
how: shell
script:
- git clone https://github.com/shadow-maint/shadow.git /tmp/shadow-test
- name: Copy test topology for Fedora CI
how: shell
script:
- cp tests/mhc-fedora-ci.yaml /tmp/shadow-test/tests/system
- name: Install test dependencies
how: shell
script:
- pip3 install -r /tmp/shadow-test/tests/system/requirements.txt
execute:
how: tmt
duration: 30m
script: |
cd /tmp/shadow-test/tests/system
pytest --mh-config=mhc-fedora-ci.yaml --mh-lazy-ssh -v

View file

@ -0,0 +1,441 @@
From 6974df39a708abf8bafbdfa2b7827e0f70f874cb Mon Sep 17 00:00:00 2001
From: Serge Hallyn <serge@hallyn.com>
Date: Mon, 6 Feb 2023 22:49:42 -0600
Subject: [PATCH] newuidmap and newgidmap: support passing pid as fd
Closes #635
newuidmap and newgidmap currently take an integner pid as
the first argument, determining the process id on which to
act. Accept also "fd:N", where N must be an open file
descriptor to the /proc/pid directory for the process to
act upon. This way, if you
exec 10</proc/99
newuidmap fd:10 100000 0 65536
and pid 99 dies and a new process happens to take pid 99 before
newuidmap happens to do its work, then since newuidmap will use
openat() using fd 10, it won't change the mapping for the new
process.
Example:
// terminal 1:
serge@jerom ~/src/nsexec$ ./nsexec -W -s 0 -S 0 -U
about to unshare with 10000000
Press any key to exec (I am 129176)
// terminal 2:
serge@jerom ~/src/shadow$ exec 10</proc/129176
serge@jerom ~/src/shadow$ sudo chown root src/newuidmap src/newgidmap
serge@jerom ~/src/shadow$ sudo chmod u+s src/newuidmap
serge@jerom ~/src/shadow$ sudo chmod u+s src/newgidmap
serge@jerom ~/src/shadow$ ./src/newuidmap fd:10 0 100000 10
serge@jerom ~/src/shadow$ ./src/newgidmap fd:10 0 100000 10
// Terminal 1:
uid=0(root) gid=0(root) groups=0(root)
Signed-off-by: Serge Hallyn <serge@hallyn.com>
---
lib/get_pid.c | 51 +++++++++++++++++++++++++++++++++++++++++++++
lib/prototypes.h | 2 ++
man/newgidmap.1.xml | 11 ++++++++++
man/newuidmap.1.xml | 11 ++++++++++
src/newgidmap.c | 41 ++++++++++++++----------------------
src/newuidmap.c | 40 +++++++++++++----------------------
6 files changed, 106 insertions(+), 50 deletions(-)
diff --git a/lib/get_pid.c b/lib/get_pid.c
index 10184bf0..ab91d158 100644
--- a/lib/get_pid.c
+++ b/lib/get_pid.c
@@ -10,6 +10,9 @@
#include "prototypes.h"
#include "defines.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
int get_pid (const char *pidstr, pid_t *pid)
{
@@ -29,3 +32,51 @@ int get_pid (const char *pidstr, pid_t *pid)
return 1;
}
+/*
+ * If use passed in fd:4 as an argument, then return the
+ * value '4', the fd to use.
+ */
+int get_pidfd_from_fd(const char *pidfdstr)
+{
+ long long int val;
+ char *endptr;
+
+ errno = 0;
+ val = strtoll (pidfdstr, &endptr, 10);
+ if ( ('\0' == *pidfdstr)
+ || ('\0' != *endptr)
+ || (ERANGE == errno)
+ || (/*@+longintegral@*/val != (pid_t)val)/*@=longintegral@*/) {
+ return 0;
+ }
+
+ return (int)val;
+}
+
+int open_pidfd(const char *pidstr)
+{
+ int proc_dir_fd;
+ int written;
+ char proc_dir_name[32];
+ pid_t target;
+
+ if (get_pid(pidstr, &target) == 0)
+ return -ENOENT;
+
+ /* max string length is 6 + 10 + 1 + 1 = 18, allocate 32 bytes */
+ written = snprintf(proc_dir_name, sizeof(proc_dir_name), "/proc/%u/",
+ target);
+ if ((written <= 0) || ((size_t)written >= sizeof(proc_dir_name))) {
+ fprintf(stderr, "snprintf of proc path failed for %u: %s\n",
+ target, strerror(errno));
+ return -EINVAL;
+ }
+
+ proc_dir_fd = open(proc_dir_name, O_DIRECTORY);
+ if (proc_dir_fd < 0) {
+ fprintf(stderr, _("Could not open proc directory for target %u: %s\n"),
+ target, strerror(errno));
+ return -EINVAL;
+ }
+ return proc_dir_fd;
+}
diff --git a/lib/prototypes.h b/lib/prototypes.h
index 400d5b97..21df6f61 100644
--- a/lib/prototypes.h
+++ b/lib/prototypes.h
@@ -160,6 +160,8 @@ extern int getlong (const char *numstr, /*@out@*/long int *result);
/* get_pid.c */
extern int get_pid (const char *pidstr, pid_t *pid);
+extern int get_pidfd_from_fd(const char *pidfdstr);
+extern int open_pidfd(const char *pidstr);
/* getrange */
extern int getrange (const char *range,
diff --git a/man/newgidmap.1.xml b/man/newgidmap.1.xml
index e4ebc69e..9b7683eb 100644
--- a/man/newgidmap.1.xml
+++ b/man/newgidmap.1.xml
@@ -116,6 +116,17 @@
<para>
Note that newgidmap may be used only once for a given process.
</para>
+ <para>
+ Instead of an integer process id, the first argument may be
+ specified as <replaceable>fd:N</replaceable>, where the integer N
+ is the file descriptor number for the calling process's opened
+ file for <filename>/proc/[pid[</filename>. In this case,
+ <command>newgidmap</command> will use
+ <refentrytitle>openat</refentrytitle><manvolnum>2</manvolnum>
+ to open the <filename>gid_map</filename> file under that
+ directory, avoiding a TOCTTOU in case the process exits and
+ the pid is immediately reused.
+ </para>
</refsect1>
diff --git a/man/newuidmap.1.xml b/man/newuidmap.1.xml
index f5cb5b48..ca917a77 100644
--- a/man/newuidmap.1.xml
+++ b/man/newuidmap.1.xml
@@ -116,6 +116,17 @@
<para>
Note that newuidmap may be used only once for a given process.
</para>
+ <para>
+ Instead of an integer process id, the first argument may be
+ specified as <replaceable>fd:N</replaceable>, where the integer N
+ is the file descriptor number for the calling process's opened
+ file for <filename>/proc/[pid[</filename>. In this case,
+ <command>newuidmap</command> will use
+ <refentrytitle>openat</refentrytitle><manvolnum>2</manvolnum>
+ to open the <filename>uid_map</filename> file under that
+ directory, avoiding a TOCTTOU in case the process exits and
+ the pid is immediately reused.
+ </para>
</refsect1>
<refsect1 id='options'>
diff --git a/src/newgidmap.c b/src/newgidmap.c
index 01d0fe90..d6d29725 100644
--- a/src/newgidmap.c
+++ b/src/newgidmap.c
@@ -69,7 +69,7 @@ static void verify_ranges(struct passwd *pw, int ranges,
static void usage(void)
{
- fprintf(stderr, _("usage: %s <pid> <gid> <lowergid> <count> [ <gid> <lowergid> <count> ] ... \n"), Prog);
+ fprintf(stderr, _("usage: %s [<pid|fd:<pidfd>] <gid> <lowergid> <count> [ <gid> <lowergid> <count> ] ... \n"), Prog);
exit(EXIT_FAILURE);
}
@@ -143,15 +143,12 @@ out:
*/
int main(int argc, char **argv)
{
- char proc_dir_name[32];
char *target_str;
- pid_t target;
int proc_dir_fd;
int ranges;
struct map_range *mappings;
struct stat st;
struct passwd *pw;
- int written;
bool allow_setgroups = false;
Prog = Basename (argv[0]);
@@ -168,25 +165,19 @@ int main(int argc, char **argv)
/* Find the process that needs its user namespace
* gid mapping set.
*/
- target_str = argv[1];
- if (!get_pid(target_str, &target))
- usage();
- /* max string length is 6 + 10 + 1 + 1 = 18, allocate 32 bytes */
- written = snprintf(proc_dir_name, sizeof(proc_dir_name), "/proc/%u/",
- target);
- if ((written <= 0) || (written >= sizeof(proc_dir_name))) {
- fprintf(stderr, "%s: snprintf of proc path failed: %s\n",
- Prog, strerror(errno));
- }
-
- proc_dir_fd = open(proc_dir_name, O_DIRECTORY);
- if (proc_dir_fd < 0) {
- fprintf(stderr, _("%s: Could not open proc directory for target %u\n"),
- Prog, target);
- return EXIT_FAILURE;
+ target_str = argv[1];
+ if (strlen(target_str) > 3 && strncmp(target_str, "fd:", 3) == 0) {
+ /* the user passed in a /proc/pid fd for the process */
+ target_str = &target_str[3];
+ proc_dir_fd = get_pidfd_from_fd(target_str);
+ if (proc_dir_fd < 0)
+ usage();
+ } else {
+ proc_dir_fd = open_pidfd(target_str);
+ if (proc_dir_fd < 0)
+ usage();
}
-
/* Who am i? */
pw = get_my_pwent ();
if (NULL == pw) {
@@ -200,8 +191,8 @@ int main(int argc, char **argv)
/* Get the effective uid and effective gid of the target process */
if (fstat(proc_dir_fd, &st) < 0) {
- fprintf(stderr, _("%s: Could not stat directory for target %u\n"),
- Prog, target);
+ fprintf(stderr, _("%s: Could not stat directory for process\n"),
+ Prog);
return EXIT_FAILURE;
}
@@ -213,8 +204,8 @@ int main(int argc, char **argv)
(!getdef_bool("GRANT_AUX_GROUP_SUBIDS") && (getgid() != pw->pw_gid)) ||
(pw->pw_uid != st.st_uid) ||
(getgid() != st.st_gid)) {
- fprintf(stderr, _( "%s: Target %u is owned by a different user: uid:%lu pw_uid:%lu st_uid:%lu, gid:%lu pw_gid:%lu st_gid:%lu\n" ),
- Prog, target,
+ fprintf(stderr, _( "%s: Target process is owned by a different user: uid:%lu pw_uid:%lu st_uid:%lu, gid:%lu pw_gid:%lu st_gid:%lu\n" ),
+ Prog,
(unsigned long int)getuid(), (unsigned long int)pw->pw_uid, (unsigned long int)st.st_uid,
(unsigned long int)getgid(), (unsigned long int)pw->pw_gid, (unsigned long int)st.st_gid);
return EXIT_FAILURE;
diff --git a/src/newuidmap.c b/src/newuidmap.c
index e8798409..e99655c9 100644
--- a/src/newuidmap.c
+++ b/src/newuidmap.c
@@ -64,7 +64,7 @@ static void verify_ranges(struct passwd *pw, int ranges,
static void usage(void)
{
- fprintf(stderr, _("usage: %s <pid> <uid> <loweruid> <count> [ <uid> <loweruid> <count> ] ... \n"), Prog);
+ fprintf(stderr, _("usage: %s [<pid>|fd:<pidfd>] <uid> <loweruid> <count> [ <uid> <loweruid> <count> ] ... \n"), Prog);
exit(EXIT_FAILURE);
}
@@ -73,15 +73,12 @@ static void usage(void)
*/
int main(int argc, char **argv)
{
- char proc_dir_name[32];
char *target_str;
- pid_t target;
int proc_dir_fd;
int ranges;
struct map_range *mappings;
struct stat st;
struct passwd *pw;
- int written;
Prog = Basename (argv[0]);
log_set_progname(Prog);
@@ -94,26 +91,20 @@ int main(int argc, char **argv)
if (argc < 2)
usage();
+ target_str = argv[1];
/* Find the process that needs its user namespace
* uid mapping set.
*/
- target_str = argv[1];
- if (!get_pid(target_str, &target))
- usage();
-
- /* max string length is 6 + 10 + 1 + 1 = 18, allocate 32 bytes */
- written = snprintf(proc_dir_name, sizeof(proc_dir_name), "/proc/%u/",
- target);
- if ((written <= 0) || (written >= sizeof(proc_dir_name))) {
- fprintf(stderr, "%s: snprintf of proc path failed: %s\n",
- Prog, strerror(errno));
- }
-
- proc_dir_fd = open(proc_dir_name, O_DIRECTORY);
- if (proc_dir_fd < 0) {
- fprintf(stderr, _("%s: Could not open proc directory for target %u\n"),
- Prog, target);
- return EXIT_FAILURE;
+ if (strlen(target_str) > 3 && strncmp(target_str, "fd:", 3) == 0) {
+ /* the user passed in a /proc/pid fd for the process */
+ target_str = &target_str[3];
+ proc_dir_fd = get_pidfd_from_fd(target_str);
+ if (proc_dir_fd < 0)
+ usage();
+ } else {
+ proc_dir_fd = open_pidfd(target_str);
+ if (proc_dir_fd < 0)
+ usage();
}
/* Who am i? */
@@ -129,8 +120,7 @@ int main(int argc, char **argv)
/* Get the effective uid and effective gid of the target process */
if (fstat(proc_dir_fd, &st) < 0) {
- fprintf(stderr, _("%s: Could not stat directory for target %u\n"),
- Prog, target);
+ fprintf(stderr, _("%s: Could not stat directory for target process\n"), Prog);
return EXIT_FAILURE;
}
@@ -142,8 +132,8 @@ int main(int argc, char **argv)
(!getdef_bool("GRANT_AUX_GROUP_SUBIDS") && (getgid() != pw->pw_gid)) ||
(pw->pw_uid != st.st_uid) ||
(getgid() != st.st_gid)) {
- fprintf(stderr, _( "%s: Target process %u is owned by a different user: uid:%lu pw_uid:%lu st_uid:%lu, gid:%lu pw_gid:%lu st_gid:%lu\n" ),
- Prog, target,
+ fprintf(stderr, _( "%s: Target process is owned by a different user: uid:%lu pw_uid:%lu st_uid:%lu, gid:%lu pw_gid:%lu st_gid:%lu\n" ),
+ Prog,
(unsigned long int)getuid(), (unsigned long int)pw->pw_uid, (unsigned long int)st.st_uid,
(unsigned long int)getgid(), (unsigned long int)pw->pw_gid, (unsigned long int)st.st_gid);
return EXIT_FAILURE;
--
2.39.2
From 7ff33fae6f9cd79c0e012671c37a172e9a681d0b Mon Sep 17 00:00:00 2001
From: Serge Hallyn <serge@hallyn.com>
Date: Fri, 24 Feb 2023 13:52:32 -0600
Subject: [PATCH] get_pidfd_from_fd: return -1 on error, not 0
Fixes: 6974df39a: newuidmap and newgidmap: support passing pid as fd
Signed-off-by: Serge Hallyn <serge@hallyn.com>
---
lib/get_pid.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/get_pid.c b/lib/get_pid.c
index ab91d158..5b6d9da4 100644
--- a/lib/get_pid.c
+++ b/lib/get_pid.c
@@ -35,6 +35,7 @@ int get_pid (const char *pidstr, pid_t *pid)
/*
* If use passed in fd:4 as an argument, then return the
* value '4', the fd to use.
+ * On error, return -1.
*/
int get_pidfd_from_fd(const char *pidfdstr)
{
@@ -47,7 +48,7 @@ int get_pidfd_from_fd(const char *pidfdstr)
|| ('\0' != *endptr)
|| (ERANGE == errno)
|| (/*@+longintegral@*/val != (pid_t)val)/*@=longintegral@*/) {
- return 0;
+ return -1;
}
return (int)val;
--
2.39.2
From 05e2adf509ba0e3779dae66a276b86927a8e1e0e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Vin=C3=ADcius=20dos=20Santos=20Oliveira?=
<vini.ipsmaker@gmail.com>
Date: Fri, 24 Feb 2023 18:06:02 -0300
Subject: [PATCH] Validate fds created by the user
write_mapping() will do the following:
openat(proc_dir_fd, map_file, O_WRONLY);
An attacker could create a directory containing a symlink named
"uid_map" pointing to any file owned by root, and thus allow him to
overwrite any root-owned file.
---
lib/get_pid.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/lib/get_pid.c b/lib/get_pid.c
index 5b6d9da4..8e5e6014 100644
--- a/lib/get_pid.c
+++ b/lib/get_pid.c
@@ -41,6 +41,8 @@ int get_pidfd_from_fd(const char *pidfdstr)
{
long long int val;
char *endptr;
+ struct stat st;
+ dev_t proc_st_dev, proc_st_rdev;
errno = 0;
val = strtoll (pidfdstr, &endptr, 10);
@@ -51,6 +53,21 @@ int get_pidfd_from_fd(const char *pidfdstr)
return -1;
}
+ if (stat("/proc/self/uid_map", &st) < 0) {
+ return -1;
+ }
+
+ proc_st_dev = st.st_dev;
+ proc_st_rdev = st.st_rdev;
+
+ if (fstat(val, &st) < 0) {
+ return -1;
+ }
+
+ if (st.st_dev != proc_st_dev || st.st_rdev != proc_st_rdev) {
+ return -1;
+ }
+
return (int)val;
}
--
2.39.2

View file

@ -0,0 +1,380 @@
diff -up shadow-4.15.0/src/chpasswd.c.account-tools-setuid shadow-4.15.0/src/chpasswd.c
--- shadow-4.15.0/src/chpasswd.c.account-tools-setuid 2024-03-08 22:27:04.000000000 +0100
+++ shadow-4.15.0/src/chpasswd.c 2024-03-11 11:21:57.561150382 +0100
@@ -443,9 +443,11 @@ int main (int argc, char **argv)
char *cp;
const char *salt;
+#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
bool use_pam = true;
#endif /* USE_PAM */
+#endif /* ACCT_TOOLS_SETUID */
int errors = 0;
int line = 0;
@@ -469,19 +471,23 @@ int main (int argc, char **argv)
process_root_flag ("-R", argc, argv);
prefix = process_prefix_flag ("-P", argc, argv);
+#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
if (md5flg || eflg || cflg || prefix[0]) {
use_pam = false;
}
#endif /* USE_PAM */
+#endif /* ACCT_TOOLS_SETUID */
OPENLOG (Prog);
check_perms ();
+#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
if (!use_pam)
#endif /* USE_PAM */
+#endif /* ACCT_TOOLS_SETUID */
{
is_shadow_pwd = spw_file_present ();
@@ -543,6 +549,7 @@ int main (int argc, char **argv)
}
newpwd = cp;
+#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
if (use_pam) {
if (do_pam_passwd_non_interactive (Prog, name, newpwd) != 0) {
@@ -553,6 +560,7 @@ int main (int argc, char **argv)
}
} else
#endif /* USE_PAM */
+#endif /* ACCT_TOOLS_SETUID */
{
const struct spwd *sp;
struct spwd newsp;
@@ -672,9 +680,11 @@ int main (int argc, char **argv)
* password database.
*/
if (0 != errors) {
+#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
if (!use_pam)
#endif /* USE_PAM */
+#endif /* ACCT_TOOLS_SETUID */
{
fprintf (stderr,
_("%s: error detected, changes ignored\n"),
@@ -683,9 +693,11 @@ int main (int argc, char **argv)
fail_exit (1);
}
+#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
if (!use_pam)
#endif /* USE_PAM */
+#endif /* ACCT_TOOLS_SETUID */
{
/* Save the changes */
close_files ();
diff -up shadow-4.15.0/src/groupmems.c.account-tools-setuid shadow-4.15.0/src/groupmems.c
--- shadow-4.15.0/src/groupmems.c.account-tools-setuid 2024-03-08 22:27:04.000000000 +0100
+++ shadow-4.15.0/src/groupmems.c 2024-03-11 11:16:18.365408572 +0100
@@ -14,9 +14,11 @@
#include <grp.h>
#include <stdio.h>
#include <sys/types.h>
+#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
#include "pam_defs.h"
#endif /* USE_PAM */
+#endif /* ACCT_TOOLS_SETUID */
#include <pwd.h>
#include "alloc.h"
@@ -430,6 +432,7 @@ static void process_flags (int argc, cha
static void check_perms (void)
{
if (!list) {
+#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
pam_handle_t *pamh = NULL;
int retval;
@@ -463,7 +466,8 @@ static void check_perms (void)
fail_exit (1);
}
(void) pam_end (pamh, retval);
-#endif
+#endif /* USE_PAM */
+#endif /* ACCT_TOOLS_SETUID */
}
}
diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/newusers.c
--- shadow-4.15.0/src/newusers.c.account-tools-setuid 2024-03-08 22:27:04.000000000 +0100
+++ shadow-4.15.0/src/newusers.c 2024-03-11 11:20:07.198909046 +0100
@@ -59,6 +59,7 @@
static const char Prog[] = "newusers";
static bool rflg = false; /* create a system account */
+#ifndef ACCT_TOOLS_SETUID
#ifndef USE_PAM
static /*@null@*//*@observer@*/char *crypt_method = NULL;
#define cflg (NULL != crypt_method)
@@ -75,6 +76,7 @@ static long bcrypt_rounds = 13;
static long yescrypt_cost = 5;
#endif /* USE_YESCRYPT */
#endif /* !USE_PAM */
+#endif /* !ACCT_TOOLS_SETUID */
static bool is_shadow;
#ifdef SHADOWGRP
@@ -97,9 +99,11 @@ NORETURN static void fail_exit (int);
static int add_group (const char *, const char *, gid_t *, gid_t);
static int get_user_id (const char *, uid_t *);
static int add_user (const char *, uid_t, gid_t);
+#ifndef ACCT_TOOLS_SETUID
#ifndef USE_PAM
static int update_passwd (struct passwd *, const char *);
#endif /* !USE_PAM */
+#endif /* !ACCT_TOOLS_SETUID */
static int add_passwd (struct passwd *, const char *);
static void process_flags (int argc, char **argv);
static void check_flags (void);
@@ -121,6 +125,7 @@ static void usage (int status)
"Options:\n"),
Prog);
(void) fputs (_(" -b, --badname allow bad names\n"), usageout);
+#ifndef ACCT_TOOLS_SETUID
#ifndef USE_PAM
(void) fprintf (usageout,
_(" -c, --crypt-method METHOD the crypt method (one of %s)\n"),
@@ -136,9 +141,11 @@ static void usage (int status)
#endif
);
#endif /* !USE_PAM */
+#endif /* !ACCT_TOOLS_SETUID */
(void) fputs (_(" -h, --help display this help message and exit\n"), usageout);
(void) fputs (_(" -r, --system create system accounts\n"), usageout);
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
+#ifndef ACCT_TOOLS_SETUID
#ifndef USE_PAM
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
(void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT\n"
@@ -146,6 +153,7 @@ static void usage (int status)
usageout);
#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
#endif /* !USE_PAM */
+#endif /* !ACCT_TOOLS_SETUID */
(void) fputs ("\n", usageout);
exit (status);
@@ -405,6 +413,7 @@ static int add_user (const char *name, u
return (pw_update (&pwent) == 0) ? -1 : 0;
}
+#ifndef ACCT_TOOLS_SETUID
#ifndef USE_PAM
/*
* update_passwd - update the password in the passwd entry
@@ -457,6 +466,7 @@ static int update_passwd (struct passwd
return 0;
}
#endif /* !USE_PAM */
+#endif /* !ACCT_TOOLS_SETUID */
/*
* add_passwd - add or update the encrypted password
@@ -465,10 +475,13 @@ static int add_passwd (struct passwd *pw
{
const struct spwd *sp;
struct spwd spent;
+#ifndef ACCT_TOOLS_SETUID
#ifndef USE_PAM
char *cp;
#endif /* !USE_PAM */
+#endif /* !ACCT_TOOLS_SETUID */
+#ifndef ACCT_TOOLS_SETUID
#ifndef USE_PAM
void *crypt_arg = NULL;
if (NULL != crypt_method) {
@@ -505,13 +518,14 @@ static int add_passwd (struct passwd *pw
return update_passwd (pwd, password);
}
#endif /* USE_PAM */
+#endif /* !ACCT_TOOLS_SETUID */
/*
* Do the first and easiest shadow file case. The user already
* exists in the shadow password file.
*/
sp = spw_locate (pwd->pw_name);
-#ifndef USE_PAM
+#if !defined(ACCT_TOOLS_SETUID) && !defined(USE_PAM)
if (NULL != sp) {
spent = *sp;
if ( (NULL != crypt_method)
@@ -547,7 +561,7 @@ static int add_passwd (struct passwd *pw
if (strcmp (pwd->pw_passwd, "x") != 0) {
return update_passwd (pwd, password);
}
-#else /* USE_PAM */
+#else /* !ACCT_TOOLS_SETUID && !USE_PAM */
/*
* If there is already a shadow entry, do not touch it.
* If there is already a passwd entry with a password, do not
@@ -558,14 +572,14 @@ static int add_passwd (struct passwd *pw
|| (strcmp (pwd->pw_passwd, "x") != 0)) {
return 0;
}
-#endif /* USE_PAM */
+#endif /* !ACCT_TOOLS_SETUID && !USE_PAM */
/*
* Now the really hard case - I need to create an entirely new
* shadow password file entry.
*/
spent.sp_namp = pwd->pw_name;
-#ifndef USE_PAM
+#if !defined(ACCT_TOOLS_SETUID) && !defined(USE_PAM)
if ((crypt_method != NULL) && (0 == strcmp(crypt_method, "NONE"))) {
spent.sp_pwdp = (char *)password;
} else {
@@ -610,35 +624,41 @@ static int add_passwd (struct passwd *pw
static void process_flags (int argc, char **argv)
{
int c;
+#ifndef ACCT_TOOLS_SETUID
#ifndef USE_PAM
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
int bad_s;
#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
#endif /* !USE_PAM */
+#endif /* !ACCT_TOOLS_SETUID */
static struct option long_options[] = {
{"badname", no_argument, NULL, 'b'},
+#ifndef ACCT_TOOLS_SETUID
#ifndef USE_PAM
{"crypt-method", required_argument, NULL, 'c'},
#endif /* !USE_PAM */
+#endif /* !ACCT_TOOLS_SETUID */
{"help", no_argument, NULL, 'h'},
{"system", no_argument, NULL, 'r'},
{"root", required_argument, NULL, 'R'},
+#ifndef ACCT_TOOLS_SETUID
#ifndef USE_PAM
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
{"sha-rounds", required_argument, NULL, 's'},
#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
#endif /* !USE_PAM */
+#endif /* !ACCT_TOOLS_SETUID */
{NULL, 0, NULL, '\0'}
};
while ((c = getopt_long (argc, argv,
-#ifndef USE_PAM
+#if !defined(ACCT_TOOLS_SETUID) && !defined(USE_PAM)
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
"c:bhrs:",
#else /* !USE_SHA_CRYPT && !USE_BCRYPT && !USE_YESCRYPT */
"c:bhr",
#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
-#else /* USE_PAM */
+#else /* !ACCT_TOOLS_SETUID && !USE_PAM */
"bhr",
#endif
long_options, NULL)) != -1) {
@@ -646,11 +666,13 @@ static void process_flags (int argc, cha
case 'b':
allow_bad_names = true;
break;
+#ifndef ACCT_TOOLS_SETUID
#ifndef USE_PAM
case 'c':
crypt_method = optarg;
break;
#endif /* !USE_PAM */
+#endif /* !ACCT_TOOLS_SETUID */
case 'h':
usage (EXIT_SUCCESS);
break;
@@ -659,6 +681,7 @@ static void process_flags (int argc, cha
break;
case 'R': /* no-op, handled in process_root_flag () */
break;
+#ifndef ACCT_TOOLS_SETUID
#ifndef USE_PAM
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
case 's':
@@ -698,6 +721,7 @@ static void process_flags (int argc, cha
break;
#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
#endif /* !USE_PAM */
+#endif /* !ACCT_TOOLS_SETUID */
default:
usage (EXIT_FAILURE);
break;
@@ -730,6 +754,7 @@ static void process_flags (int argc, cha
*/
static void check_flags (void)
{
+#ifndef ACCT_TOOLS_SETUID
#ifndef USE_PAM
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
if (sflg && !cflg) {
@@ -762,6 +787,7 @@ static void check_flags (void)
}
}
#endif /* !USE_PAM */
+#endif /* !ACCT_TOOLS_SETUID */
}
/*
@@ -1052,12 +1078,14 @@ int main (int argc, char **argv)
int line = 0;
uid_t uid;
gid_t gid;
+#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
int *lines = NULL;
char **usernames = NULL;
char **passwords = NULL;
unsigned int nusers = 0;
#endif /* USE_PAM */
+#endif /* ACCT_TOOLS_SETUID */
log_set_progname(Prog);
log_set_logfd(stderr);
@@ -1195,6 +1223,7 @@ int main (int argc, char **argv)
}
newpw = *pw;
+#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
/* keep the list of user/password for later update by PAM */
nusers++;
@@ -1211,6 +1240,7 @@ int main (int argc, char **argv)
usernames[nusers-1] = strdup (fields[0]);
passwords[nusers-1] = strdup (fields[1]);
#endif /* USE_PAM */
+#endif /* ACCT_TOOLS_SETUID */
if (add_passwd (&newpw, fields[1]) != 0) {
fprintf (stderr,
_("%s: line %d: can't update password\n"),
@@ -1327,6 +1357,7 @@ int main (int argc, char **argv)
nscd_flush_cache ("group");
sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP);
+#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
unsigned int i;
/* Now update the passwords using PAM */
@@ -1339,6 +1370,7 @@ int main (int argc, char **argv)
}
}
#endif /* USE_PAM */
+#endif /* ACCT_TOOLS_SETUID */
exit (EXIT_SUCCESS);
}

View file

@ -0,0 +1,69 @@
Index: shadow-4.5/lib/getdate.y
===================================================================
--- shadow-4.5.orig/lib/getdate.y
+++ shadow-4.5/lib/getdate.y
@@ -152,6 +152,7 @@ static int yyHaveDay;
static int yyHaveRel;
static int yyHaveTime;
static int yyHaveZone;
+static int yyHaveYear;
static int yyTimezone;
static int yyDay;
static int yyHour;
@@ -293,18 +294,21 @@ date : tUNUMBER '/' tUNUMBER {
yyDay = $3;
yyYear = $5;
}
+ yyHaveYear++;
}
| tUNUMBER tSNUMBER tSNUMBER {
/* ISO 8601 format. yyyy-mm-dd. */
yyYear = $1;
yyMonth = -$2;
yyDay = -$3;
+ yyHaveYear++;
}
| tUNUMBER tMONTH tSNUMBER {
/* e.g. 17-JUN-1992. */
yyDay = $1;
yyMonth = $2;
yyYear = -$3;
+ yyHaveYear++;
}
| tMONTH tUNUMBER {
yyMonth = $1;
@@ -314,6 +318,7 @@ date : tUNUMBER '/' tUNUMBER {
yyMonth = $1;
yyDay = $2;
yyYear = $4;
+ yyHaveYear++;
}
| tUNUMBER tMONTH {
yyMonth = $2;
@@ -323,6 +328,7 @@ date : tUNUMBER '/' tUNUMBER {
yyMonth = $2;
yyDay = $1;
yyYear = $3;
+ yyHaveYear++;
}
;
@@ -395,7 +401,8 @@ relunit : tUNUMBER tYEAR_UNIT {
number : tUNUMBER
{
- if ((yyHaveTime != 0) && (yyHaveDate != 0) && (yyHaveRel == 0))
+ if ((yyHaveTime != 0 || $1 >= 100) && !yyHaveYear
+ && (yyHaveDate != 0) && (yyHaveRel == 0))
yyYear = $1;
else
{
@@ -802,7 +809,7 @@ yylex (void)
return LookupWord (buff);
}
if (c != '(')
- return *yyInput++;
+ return (unsigned char)*yyInput++;
Count = 0;
do
{

View file

@ -0,0 +1,137 @@
From ead55e9ba8958504e23e29545f90c4dd925c7462 Mon Sep 17 00:00:00 2001
From: Serge Hallyn <serge@hallyn.com>
Date: Wed, 20 Mar 2024 17:39:46 -0500
Subject: [PATCH] getdef: avoid spurious error messages about unknown
configuration options
def_find can return NULL for unset, not just unknown, config options. So
move the decision of whether to log an error message about an unknown config
option back into def_find, which knows the difference. Only putdef_str()
will pass a char* srcfile to def_find, so only calls from putdef_str will
cause the message, which was the original intent of fa68441bc4be8.
closes #967
fixes: fa68441bc4be8 ("Improve the login.defs unknown item error message")
Signed-off-by: Serge Hallyn <serge@hallyn.com>
---
lib/getdef.c | 30 ++++++++++++++++--------------
1 file changed, 16 insertions(+), 14 deletions(-)
diff --git a/lib/getdef.c b/lib/getdef.c
index 4d4d4e19..ef2ae1f0 100644
--- a/lib/getdef.c
+++ b/lib/getdef.c
@@ -176,7 +176,7 @@ static const char* def_fname = LOGINDEFS; /* login config defs file */
static bool def_loaded = false; /* are defs already loaded? */
/* local function prototypes */
-static /*@observer@*/ /*@null@*/struct itemdef *def_find (const char *);
+static /*@observer@*/ /*@null@*/struct itemdef *def_find (const char *, const char *);
static void def_load (void);
@@ -195,7 +195,7 @@ static void def_load (void);
def_load ();
}
- d = def_find (item);
+ d = def_find (item, NULL);
return (NULL == d) ? NULL : d->value;
}
@@ -214,7 +214,7 @@ bool getdef_bool (const char *item)
def_load ();
}
- d = def_find (item);
+ d = def_find (item, NULL);
if ((NULL == d) || (NULL == d->value)) {
return false;
}
@@ -240,7 +240,7 @@ int getdef_num (const char *item, int dflt)
def_load ();
}
- d = def_find (item);
+ d = def_find (item, NULL);
if ((NULL == d) || (NULL == d->value)) {
return dflt;
}
@@ -275,7 +275,7 @@ unsigned int getdef_unum (const char *item, unsigned int dflt)
def_load ();
}
- d = def_find (item);
+ d = def_find (item, NULL);
if ((NULL == d) || (NULL == d->value)) {
return dflt;
}
@@ -310,7 +310,7 @@ long getdef_long (const char *item, long dflt)
def_load ();
}
- d = def_find (item);
+ d = def_find (item, NULL);
if ((NULL == d) || (NULL == d->value)) {
return dflt;
}
@@ -342,7 +342,7 @@ unsigned long getdef_ulong (const char *item, unsigned long dflt)
def_load ();
}
- d = def_find (item);
+ d = def_find (item, NULL);
if ((NULL == d) || (NULL == d->value)) {
return dflt;
}
@@ -375,12 +375,9 @@ int putdef_str (const char *name, const char *value, const char *srcfile)
* Locate the slot to save the value. If this parameter
* is unknown then "def_find" will print an err message.
*/
- d = def_find (name);
- if (NULL == d) {
- if (NULL != srcfile)
- SYSLOG ((LOG_CRIT, "shadow: unknown configuration item '%s' in '%s'", name, srcfile));
+ d = def_find (name, srcfile);
+ if (NULL == d)
return -1;
- }
/*
* Save off the value.
@@ -404,9 +401,12 @@ int putdef_str (const char *name, const char *value, const char *srcfile)
*
* Search through a table of configurable items to locate the
* specified configuration option.
+ *
+ * If srcfile is not NULL, and the item is not found, then report an error saying
+ * the unknown item was used in this file.
*/
-static /*@observer@*/ /*@null@*/struct itemdef *def_find (const char *name)
+static /*@observer@*/ /*@null@*/struct itemdef *def_find (const char *name, const char *srcfile)
{
struct itemdef *ptr;
@@ -432,6 +432,8 @@ static /*@observer@*/ /*@null@*/struct itemdef *def_find (const char *name)
fprintf (shadow_logfd,
_("configuration error - unknown item '%s' (notify administrator)\n"),
name);
+ if (srcfile != NULL)
+ SYSLOG ((LOG_CRIT, "shadow: unknown configuration item '%s' in '%s'", name, srcfile));
out:
return NULL;
@@ -610,7 +612,7 @@ int main (int argc, char **argv)
def_load ();
for (i = 0; i < NUMDEFS; ++i) {
- d = def_find (def_table[i].name);
+ d = def_find (def_table[i].name, NULL);
if (NULL == d) {
printf ("error - lookup '%s' failed\n",
def_table[i].name);
--
2.44.0

162
shadow-4.15.0-manfix.patch Normal file
View file

@ -0,0 +1,162 @@
diff -up shadow-4.15.0/man/groupmems.8.xml.manfix shadow-4.15.0/man/groupmems.8.xml
--- shadow-4.15.0/man/groupmems.8.xml.manfix 2023-05-26 04:56:11.000000000 +0200
+++ shadow-4.15.0/man/groupmems.8.xml 2024-02-09 10:42:20.337036378 +0100
@@ -156,20 +156,10 @@
<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.15.0/man/ja/man5/login.defs.5.manfix shadow-4.15.0/man/ja/man5/login.defs.5
--- shadow-4.15.0/man/ja/man5/login.defs.5.manfix 2023-03-13 21:58:56.000000000 +0100
+++ shadow-4.15.0/man/ja/man5/login.defs.5 2024-02-09 10:42:20.337036378 +0100
@@ -123,10 +123,6 @@ 以下の参照表は、
shadow パスワード機能のどのプログラムが
どのパラメータを使用するかを示したものである。
.na
-.IP chfn 12
-CHFN_AUTH CHFN_RESTRICT
-.IP chsh 12
-CHFN_AUTH
.IP groupadd 12
GID_MAX GID_MIN
.IP newusers 12
diff -up shadow-4.15.0/man/login.defs.5.xml.manfix shadow-4.15.0/man/login.defs.5.xml
--- shadow-4.15.0/man/login.defs.5.xml.manfix 2024-01-22 22:36:43.000000000 +0100
+++ shadow-4.15.0/man/login.defs.5.xml 2024-02-09 10:45:49.014407259 +0100
@@ -144,6 +144,17 @@
long numeric parameters is machine-dependent.
</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'>
@@ -240,16 +251,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>
@@ -276,14 +277,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>
@@ -352,34 +345,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>
@@ -451,32 +416,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 condition="no_pam">
- <term>sulogin</term>
- <listitem>
- <para>
- ENV_HZ
- ENV_TZ
- </para>
- </listitem>
- </varlistentry>
<varlistentry>
<term>useradd</term>
<listitem>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,34 @@
From 8903b94c86c978e8abef623358fd3e4629c06967 Mon Sep 17 00:00:00 2001
From: Iker Pedrosa <ipedrosa@redhat.com>
Date: Mon, 9 Sep 2024 10:36:17 +0200
Subject: [PATCH] useradd: fix write_full() return value
write_full() returns -1 on error and useradd was checking another value.
Closes: https://github.com/shadow-maint/shadow/issues/1072
Fixes: f45498a6c286 ("libmisc/write_full.c: Improve write_full()")
Reported-by: <https://github.com/brown-midas>
Suggested-by: <https://github.com/brown-midas>
Reviewed-by: Alejandro Colomar <alx@kernel.org>
Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
---
src/useradd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/useradd.c b/src/useradd.c
index 02c500d0..d64fd892 100644
--- a/src/useradd.c
+++ b/src/useradd.c
@@ -2042,7 +2042,7 @@ static void lastlog_reset (uid_t uid)
return;
}
if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
- || (write_full (fd, &ll, sizeof (ll)) != (ssize_t) sizeof (ll))
+ || (write_full (fd, &ll, sizeof (ll)) == -1)
|| (fsync (fd) != 0)) {
fprintf (stderr,
_("%s: failed to reset the lastlog entry of UID %lu: %s\n"),
--
2.46.0

View file

@ -0,0 +1,20 @@
The missing #include <gshadow.h> causes the configure check to fail
spuriously, resulting in HAVE_SHADOWGRP not being defined.
Submitted upstream: <https://github.com/shadow-maint/shadow/pull/595>
diff --git a/configure.ac b/configure.ac
index 924254a0c8171802..6c7d9839979e037d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -116,6 +116,10 @@ if test "$ac_cv_header_shadow_h" = "yes"; then
ac_cv_libc_shadowgrp,
AC_RUN_IFELSE([AC_LANG_SOURCE([
#include <shadow.h>
+ #ifdef HAVE_GSHADOW_H
+ #include <gshadow.h>
+ #endif
+ int
main()
{
struct sgrp *sg = sgetsgent("test:x::");

View file

@ -1,12 +1,12 @@
Summary: Utilities for managing accounts and shadow password files
Name: shadow-utils
Version: 4.20.0
Release: 1%{?dist}
Version: 4.15.1
Release: 12%{?dist}
Epoch: 2
License: BSD-3-Clause AND GPL-2.0-or-later
URL: https://github.com/shadow-maint/shadow
Source0: https://github.com/shadow-maint/shadow/releases/download/4.20.0/shadow-4.20.0.tar.xz
Source1: https://github.com/shadow-maint/shadow/releases/download/4.20.0/shadow-4.20.0.tar.xz.asc
Source0: https://github.com/shadow-maint/shadow/releases/download/v%{version}/shadow-%{version}.tar.xz
Source1: https://github.com/shadow-maint/shadow/releases/download/v%{version}/shadow-%{version}.tar.xz.asc
Source2: shadow-utils.useradd
Source3: shadow-utils.login.defs
Source4: shadow-bsd.txt
@ -16,10 +16,22 @@ Source7: passwd.pamd
### Globals ###
%global includesubiddir %{_includedir}/shadow
# Fail linking if there are undefined symbols.
%global _ld_strict_symbol_defs 1
### Patches ###
# Misc manual page changes - non-upstreamable
Patch0: shadow-4.15.0-manfix.patch
# Date parsing improvement - could be upstreamed
Patch1: shadow-4.15.0-date-parsing.patch
# Several patches already available upstream. PRs:#994, #996, #997
Patch2: shadow-4.15.1-sast-fixes.patch
# Audit message changes - partially upstreamed
Patch3: shadow-4.15.1-audit-update.patch
# Probably non-upstreamable
Patch4: shadow-4.15.0-account-tools-setuid.patch
# https://github.com/shadow-maint/shadow/commit/ead55e9ba8958504e23e29545f90c4dd925c7462
Patch5: shadow-4.15.0-getdef-spurious-error.patch
# https://github.com/shadow-maint/shadow/commit/8903b94c86c978e8abef623358fd3e4629c06967
Patch6: shadow-4.15.1-useradd-fix-write-full-return.patch
### Dependencies ###
Requires: audit-libs >= 1.6.5
@ -41,15 +53,12 @@ BuildRequires: git
BuildRequires: itstool
BuildRequires: libacl-devel
BuildRequires: libattr-devel
BuildRequires: libcmocka-devel
BuildRequires: libeconf-devel
BuildRequires: libselinux-devel >= 1.25.2-1
BuildRequires: libsemanage-devel
BuildRequires: libtool
BuildRequires: libxcrypt-devel
BuildRequires: libxslt
BuildRequires: make
BuildRequires: pam
BuildRequires: pam-devel
### Provides ###
@ -77,14 +86,16 @@ programs for managing user and group accounts. The pwconv command
converts passwords to the shadow password format. The pwunconv command
unconverts shadow passwords and generates a passwd file (a standard
UNIX password file). The pwck command checks the integrity of password
and shadow files. The useradd, userdel, and usermod commands are used
for managing user accounts. The groupadd, groupdel, and groupmod
commands are used for managing group accounts.
and shadow files. The lastlog command prints out the last login times
for all users. The useradd, userdel, and usermod commands are used for
managing user accounts. The groupadd, groupdel, and groupmod commands
are used for managing group accounts.
### Subpackages ###
%package subid
Summary: A library to manage subordinate uid and gid ranges
License: BSD and GPLv2+
%description subid
Utility library that provides a way to manage subid ranges.
@ -92,13 +103,14 @@ Utility library that provides a way to manage subid ranges.
%package subid-devel
Summary: Development package for shadow-utils-subid
License: BSD and GPLv2+
Requires: shadow-utils-subid = %{epoch}:%{version}-%{release}
%description subid-devel
Development files for shadow-utils-subid.
%prep
%autosetup -p 1 -S git -n shadow-4.20.0
%autosetup -p 1 -S git -n shadow-%{version}
iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8
cp -f doc/HOWTO.utf8 doc/HOWTO
@ -106,12 +118,25 @@ cp -f doc/HOWTO.utf8 doc/HOWTO
cp -a %{SOURCE4} %{SOURCE5} .
cp -a %{SOURCE6} man/login.defs.d/HOME_MODE.xml
# Force regeneration of getdate.c
rm lib/getdate.c
%build
%ifarch sparc64
#sparc64 need big PIE
export CFLAGS="$RPM_OPT_FLAGS -fPIE"
export LDFLAGS="-pie -Wl,-z,relro -Wl,-z,now"
%else
export CFLAGS="$RPM_OPT_FLAGS -fpie"
export LDFLAGS="-pie -Wl,-z,relro -Wl,-z,now"
%endif
autoreconf
%configure \
--disable-account-tools-setuid \
--enable-logind=no \
--enable-man \
--disable-account-tools-setuid \
--enable-lastlog \
--enable-logind=no \
--enable-man \
--enable-shadowgrp \
--enable-shared \
--with-audit \
@ -123,21 +148,16 @@ autoreconf
--with-yescrypt \
--without-libbsd \
--without-libcrack \
--without-nscd \
--without-nscd \
--without-sssd
%make_build
%check
make check
%install
%make_install gnulocaledir=$RPM_BUILD_ROOT%{_datadir}/locale MKINSTALLDIRS=`pwd`/mkinstalldirs
install -d -m 755 $RPM_BUILD_ROOT%{_sysconfdir}/default
install -p -c -m 0644 %{SOURCE3} $RPM_BUILD_ROOT%{_sysconfdir}/login.defs
install -p -c -m 0600 %{SOURCE2} $RPM_BUILD_ROOT%{_sysconfdir}/default/useradd
install -d -m 755 $RPM_BUILD_ROOT%{_pam_confdir}
install -m 644 %{SOURCE7} $RPM_BUILD_ROOT%{_pam_confdir}/chpasswd
install -m 644 %{SOURCE7} $RPM_BUILD_ROOT%{_pam_confdir}/newusers
install -m 644 %{SOURCE7} $RPM_BUILD_ROOT%{_pam_confdir}/passwd
@ -155,20 +175,31 @@ mv -v $RPM_BUILD_ROOT/usr/sbin/* $RPM_BUILD_ROOT%{_bindir}/
# Remove binaries we don't use.
rm $RPM_BUILD_ROOT%{_bindir}/chfn
rm $RPM_BUILD_ROOT%{_bindir}/chsh
rm $RPM_BUILD_ROOT%{_bindir}/expiry
rm $RPM_BUILD_ROOT%{_bindir}/groups
rm $RPM_BUILD_ROOT%{_bindir}/login
rm $RPM_BUILD_ROOT%{_bindir}/su
rm $RPM_BUILD_ROOT%{_bindir}/faillog
rm $RPM_BUILD_ROOT%{_sbindir}/logoutd
rm $RPM_BUILD_ROOT%{_sbindir}/nologin
rm $RPM_BUILD_ROOT%{_mandir}/man1/chfn.*
rm $RPM_BUILD_ROOT%{_mandir}/*/man1/chfn.*
rm $RPM_BUILD_ROOT%{_mandir}/man1/chsh.*
rm $RPM_BUILD_ROOT%{_mandir}/*/man1/chsh.*
rm $RPM_BUILD_ROOT%{_mandir}/man1/expiry.*
rm $RPM_BUILD_ROOT%{_mandir}/*/man1/expiry.*
rm $RPM_BUILD_ROOT%{_mandir}/man1/groups.*
rm $RPM_BUILD_ROOT%{_mandir}/*/man1/groups.*
rm $RPM_BUILD_ROOT%{_mandir}/man1/login.*
rm $RPM_BUILD_ROOT%{_mandir}/*/man1/login.*
rm $RPM_BUILD_ROOT%{_mandir}/man1/su.*
rm $RPM_BUILD_ROOT%{_mandir}/*/man1/su.*
rm $RPM_BUILD_ROOT%{_mandir}/man5/passwd.*
rm $RPM_BUILD_ROOT%{_mandir}/*/man5/passwd.*
rm $RPM_BUILD_ROOT%{_mandir}/man5/suauth.*
rm $RPM_BUILD_ROOT%{_mandir}/*/man5/suauth.*
rm $RPM_BUILD_ROOT%{_mandir}/man8/logoutd.*
rm $RPM_BUILD_ROOT%{_mandir}/*/man8/logoutd.*
rm $RPM_BUILD_ROOT%{_mandir}/man8/nologin.*
rm $RPM_BUILD_ROOT%{_mandir}/*/man8/nologin.*
rm $RPM_BUILD_ROOT%{_mandir}/man3/getspnam.*
@ -180,8 +211,11 @@ rm $RPM_BUILD_ROOT%{_mandir}/*/man8/faillog.*
# Remove PAM service files we don't use.
rm $RPM_BUILD_ROOT%{_pam_confdir}/chfn
rm $RPM_BUILD_ROOT%{_pam_confdir}/chpasswd
rm $RPM_BUILD_ROOT%{_pam_confdir}/chsh
rm $RPM_BUILD_ROOT%{_pam_confdir}/groupmems
rm $RPM_BUILD_ROOT%{_pam_confdir}/login
rm $RPM_BUILD_ROOT%{_pam_confdir}/newusers
rm $RPM_BUILD_ROOT%{_pam_confdir}/su
find $RPM_BUILD_ROOT%{_mandir} -depth -type d -empty -delete
@ -208,12 +242,11 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a
%license gpl-2.0.txt shadow-bsd.txt
%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/login.defs
%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/default/useradd
%config(noreplace) %{_pam_confdir}/chpasswd
%config(noreplace) %{_pam_confdir}/newusers
%config(noreplace) %{_pam_confdir}/passwd
%{_bindir}/sg
%attr(4755,root,root) %{_bindir}/chage
%attr(4755,root,root) %{_bindir}/gpasswd
%{_bindir}/lastlog
%attr(4755,root,root) %{_bindir}/newgrp
%attr(0755,root,root) %caps(cap_setgid=ep) %{_bindir}/newgidmap
%attr(0755,root,root) %caps(cap_setuid=ep) %{_bindir}/newuidmap
@ -251,6 +284,7 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a
%{_mandir}/man8/chgpasswd.8*
%{_mandir}/man8/newusers.8*
%{_mandir}/man8/*conv.8*
%{_mandir}/man8/lastlog.8*
%{_mandir}/man8/vipw.8*
%{_mandir}/man8/vigr.8*
@ -264,119 +298,12 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a
%{_libdir}/libsubid.so
%changelog
* Wed Jul 29 2026 Iker Pedrosa <ipedrosa@redhat.com> - 2:4.20.0-1
- Rebase to version 4.20.0
* Wed Jul 22 2026 Iker Pedrosa <ipedrosa@redhat.com> - 2:4.20.0-rc3-1
- Rebase to version 4.20.0-rc3
* Fri Jul 17 2026 Fedora Release Engineering <releng@fedoraproject.org> - 2:4.19.3-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_45_Mass_Rebuild
* Wed May 27 2026 Iker Pedrosa <ipedrosa@redhat.com> - 2:4.19.3-3
- Enable use of PAM for chpasswd and newusers
Resolves: #2461179 and #2283963
* Thu Apr 23 2026 Iker Pedrosa <ipedrosa@redhat.com> - 2:4.19.3-2
- btrfs: simplify checks improve useradd behavior for non-btrfs
* Wed Feb 11 2026 Debarshi Ray <rishi@fedoraproject.org> - 2:4.19.3-1
- Rebase to version 4.19.3
Resolves: #2426288
* Tue Jan 27 2026 Adam Williamson <awilliam@redhat.com> - 2:4.19.0-6
- chkhash.c: fix escaping in SHA-256 / SHA-512 / MD5 regexes
* Mon Jan 26 2026 Iker Pedrosa <ipedrosa@redhat.com> - 2:4.19.0-5
- chkhash.c: fix support for ! and * in hashes
- usermod.c: add back optimizations
* Sat Jan 17 2026 Fedora Release Engineering <releng@fedoraproject.org> - 2:4.19.0-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild
* Mon Jan 12 2026 Iker Pedrosa <ipedrosa@redhat.com> - 2:4.19.0-3
- useradd: Support config for creating home dirs as Btrfs subvolumes
* Fri Jan 9 2026 Iker Pedrosa <ipedrosa@redhat.com> - 2:4.19.0-2
- Enable unit-tests
* Fri Jan 9 2026 Iker Pedrosa <ipedrosa@redhat.com> - 2:4.19.0-1
- Rebase to version 4.19.0
Resolves: #2426288 and #2249524
* Tue Nov 25 2025 Adam Williamson <awilliam@redhat.com> - 2:4.18.0-7
- Also revert changes from -4 (last known good was -3)
* Tue Nov 25 2025 Adam Williamson <awilliam@redhat.com> - 2:4.18.0-6
- Revert changes from -5 (they were only meant for testing)
* Tue Nov 25 2025 Iker Pedrosa <ipedrosa@redhat.com> - 2:4.18.0-5
- Test CI
* Fri Oct 31 2025 Iker Pedrosa <ipedrosa@redhat.com> - 2:4.18.0-4
- Stop setting SELinux labels in chroot and prefix environments
Resolves: #2249524
* Tue Jul 29 2025 Alexey Tikhonov <atikhono@redhat.com> - 2:4.18.0-3
- Revert "Stop assigning subids by default"
Resolves: #2382662
* Fri Jul 25 2025 Fedora Release Engineering <releng@fedoraproject.org> - 2:4.18.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild
* Tue Jul 22 2025 Iker Pedrosa <ipedrosa@redhat.com> - 2:4.18.0-1
- Rebase to version 4.18.0. Resolves: #2374710
* Fri Jul 18 2025 Iker Pedrosa <ipedrosa@redhat.com> - 2:4.17.4-5
- Stop assigning subids by default
Resolves: CVE-2024-56433 and #2334168
* Tue Jul 15 2025 Iker Pedrosa <ipedrosa@redhat.com> - 2:4.17.4-4
- FSWC: Migrate to lastlog2
Link: <https://fedoraproject.org/wiki/Changes/Migrate_to_lastlog2>
Resolves: #2361588
* Tue Mar 25 2025 Iker Pedrosa <ipedrosa@redhat.com> - 2:4.17.4-2
- Add pam dependency for _pam_confdir missing macro. Resolves: #2354806
* Thu Mar 20 2025 Iker Pedrosa <ipedrosa@redhat.com> - 2:4.17.4-1
- Rebase to version 4.17.4. Resolves: #2353491
- Fixes problems with expiration dates
* Sat Feb 01 2025 Björn Esser <besser82@fedoraproject.org> - 2:4.17.0-5
- Add explicit BR: libxcrypt-devel
* Sun Jan 19 2025 Fedora Release Engineering <releng@fedoraproject.org> - 2:4.17.0-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild
* Sun Jan 12 2025 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 2:4.17.0-3
- Rebuilt for the bin-sbin merge (2nd attempt)
* Thu Dec 26 2024 Iker Pedrosa <ipedrosa@redhat.com> - 2:4.17.0
- Rebase to version 4.17.0. Resolves: #2293678
* Sun Dec 22 2024 Björn Esser <besser82@fedoraproject.org> - 2:4.17.0~rc1-2
- Remove potentially dangerous {C,LD}FLAGS shenanigans
- Fail linking if there are undefined symbols at link-time
* Mon Dec 9 2024 Iker Pedrosa <ipedrosa@redhat.com> - 2:4.17.0~rc1-1
- Rebase to version 4.17.0-rc1
* Tue Nov 12 2024 Iker Pedrosa <ipedrosa@redhat.com> - 2:4.16.0-7
- SPDX license migration for subpackages
* Wed Oct 16 2024 Iker Pedrosa <ipedrosa@redhat.com> - 2:4.16.0-6
- Rebuilt for libeconf soname bump
* Mon Oct 7 2024 Iker Pedrosa <ipedrosa@redhat.com> - 2:4.16.0-5
* Thu Oct 10 2024 Iker Pedrosa <ipedrosa@redhat.com> - 2:4.15.1-12
- useradd: fix write_full() return value. Resolves: #2313559
* Fri Sep 13 2024 Iker Pedrosa <ipedrosa@redhat.com> - 2:4.16.0-3
* Wed Sep 18 2024 Iker Pedrosa <ipedrosa@redhat.com> - 2:4.15.1-10
- Disable nscd
* Wed Aug 28 2024 Iker Pedrosa <ipedrosa@redhat.com> - 2:4.16.0-2
- Rebase to version 4.16.0 (#2293678)
* Tue Jul 23 2024 Kevin Fenzi <kevin@scrye.com> - 2:4.15.1-9
- Revert chpasswd: use PAM again for now.

View file

@ -1,2 +1,2 @@
SHA512 (shadow-4.20.0.tar.xz) = 0b8afded372e4d37a78f38cb972c0ab877870ef6356cdd1c45be3c708af3d1496c6f87de6bf6a5b1d217d4d52d7e2d15c28b26530949cc6de0231a4028930406
SHA512 (shadow-4.20.0.tar.xz.asc) = e4b134543768f323df30a1e450c22086d013020928d62bd3207db7f633beea3587b67802da5b575d5a794e8c2bebd7a0abeba6ed69d44bf08adc37df3bf352ac
SHA512 (shadow-4.15.1.tar.xz) = 2667a1d781066adce42e684463329c3f32d28c07b7b79b628525bffcd61c078f6ff430be3d42976d0509d9f9a55cd80f5a50d479b85155476cee7f00f06708d8
SHA512 (shadow-4.15.1.tar.xz.asc) = 0a39d6a45b7d8df12aade89ed9fc9d481c91297dbd34e85fe831426c1d0051cbcf8478759306b8871cd6b1835604c5836decf398d0165c50ac52fee365561446

View file

@ -1,13 +0,0 @@
provisioned_topologies:
- shadow
domains:
- id: shadow
hosts:
- hostname: localhost
role: shadow
conn:
type: ssh
host: localhost
user: root
artifacts:
- /var/log/*

77
tests/sanity/Makefile Normal file
View file

@ -0,0 +1,77 @@
# Copyright (c) 2006 Red Hat, Inc. All rights reserved. This copyrighted material
# is made available to anyone wishing to use, modify, copy, or
# redistribute it subject to the terms and conditions of the GNU General
# Public License v.2.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# Author: Jakub Hrozek
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Example Makefile for RHTS #
# This example is geared towards a test for a specific package #
# It does most of the work for you, but may require further coding #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# The toplevel namespace within which the test lives.
TOPLEVEL_NAMESPACE=CoreOS
# The name of the package under test:
PACKAGE_NAME=shadow-utils
# The path of the test below the package:
RELATIVE_PATH=sanity
# Version of the Test. Used with make tag.
export TESTVERSION=1.1
# The combined namespace of the test.
export TEST=/$(TOPLEVEL_NAMESPACE)/$(PACKAGE_NAME)/$(RELATIVE_PATH)
# A phony target is one that is not really the name of a file.
# It is just a name for some commands to be executed when you
# make an explicit request. There are two reasons to use a
# phony target: to avoid a conflict with a file of the same
# name, and to improve performance.
.PHONY: all install download clean
# Executables to be built should be added here, they will be generated on the system under test.
BUILT_FILES=
# Data files, .c files, scripts anything needed to either compile the test and/or run it.
FILES=$(METADATA) Makefile PURPOSE sanity_test.py runtest.sh
run: $(FILES) build
./runtest.sh
build: $(BUILT_FILES)
chmod a+x ./sanity_test.py
chmod a+x ./runtest.sh
clean:
rm -f *~ *.rpm $(BUILT_FILES)
# Include Common Makefile
include /usr/share/rhts/lib/rhts-make.include
# Generate the testinfo.desc here:
$(METADATA): Makefile
@touch $(METADATA)
@echo "Owner: Jakub Hrozek <jhrozek@redhat.com>" > $(METADATA)
@echo "Name: $(TEST)" >> $(METADATA)
@echo "Path: $(TEST_DIR)" >> $(METADATA)
@echo "TestVersion: $(TESTVERSION)" >> $(METADATA)
@echo "License: GNU GPL" >> $(METADATA)
@echo "Description: Basic sanity test for shadow-utils" >> $(METADATA)
@echo "TestTime: 5m" >> $(METADATA)
@echo "RunFor: $(PACKAGE_NAME)" >> $(METADATA)
@echo "Requires: $(PACKAGE_NAME)" >> $(METADATA)
@echo "Requires: python" >> $(METADATA)
rhts-lint $(METADATA)

10
tests/sanity/PURPOSE Normal file
View file

@ -0,0 +1,10 @@
This is a basic sanity test for the shadow-utils package. It is implemented
in python on top of the unittesting.py module.
Its purpose is to ensure that the binaries in the shadow-utils package behave
as expected and its switches/options work correctly.
For the most part, every binary in the shadow-utils package is represented by
a single class named Test<BinaryName>, i.e. TestUsermod etc. There are some
exceptions, like TestUseraddWeirdNameTest though.

24
tests/sanity/runtest.sh Executable file
View file

@ -0,0 +1,24 @@
#!/bin/bash
. /usr/bin/rhts-environment.sh
. /usr/share/beakerlib/beakerlib.sh || exit 1
rlJournalStart
rlFileBackup --clean /etc/default/useradd- /etc/default/useradd
setenforce 0
python sanity_test.py -v
setenforce 1
rlFileRestore
EXIT=$?
if [[ $EXIT -eq 0 ]]; then
RESULT="PASS"
else
RESULT="FAIL"
fi
rlJournalEnd
echo "Result: $RESULT"
echo "Exit: $EXIT"
report_result $TEST $RESULT $EXIT

1013
tests/sanity/sanity_test.py Executable file

File diff suppressed because it is too large Load diff

13
tests/tests.yml Normal file
View file

@ -0,0 +1,13 @@
---
# This first play always runs on the local staging system
- hosts: localhost
roles:
- role: standard-test-beakerlib
tags:
- classic
- atomic
tests:
- sanity
required_packages:
- shadow-utils # sanity test needs shadow-utils
- python # sanity test needs python