From: Iker Pedrosa Date: Tue, 1 Jul 2025 13:55:54 +0000 (+0200) Subject: src/newusers.c: SELinux file context for fail_exit() X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=df9c80e713cbc88140a0034d2cab38c0b735ac8f;p=thirdparty%2Fshadow.git src/newusers.c: SELinux file context for fail_exit() Do not process SELinux file context when running fail_exit() when chroot or prefix options are selected. Signed-off-by: Iker Pedrosa --- diff --git a/src/newusers.c b/src/newusers.c index 0a744952b..d60c92f74 100644 --- a/src/newusers.c +++ b/src/newusers.c @@ -106,7 +106,7 @@ static bool sub_gid_locked = false; /* local function prototypes */ NORETURN static void usage (int status); -NORETURN static void fail_exit (int); +NORETURN static void fail_exit (int, bool); static int add_group (const char *, const char *, gid_t *, gid_t); static int get_user_id (const char *, uid_t *); static int add_user (const char *, uid_t, gid_t); @@ -116,8 +116,8 @@ static int update_passwd (struct passwd *, const char *); static int add_passwd (struct passwd *, const char *); static void process_flags (int argc, char **argv, struct option_flags *flags); static void check_flags (void); -static void check_perms (void); -static void open_files (void); +static void check_perms (struct option_flags *flags); +static void open_files (bool process_selinux); static void close_files (struct option_flags *flags); extern int allow_bad_names; @@ -167,24 +167,24 @@ static void usage (int status) /* * fail_exit - undo as much as possible */ -static void fail_exit (int code) +static void fail_exit (int code, bool process_selinux) { if (spw_locked) { - if (spw_unlock (true) == 0) { + if (spw_unlock (process_selinux) == 0) { fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); /* continue */ } } if (pw_locked) { - if (pw_unlock (true) == 0) { + if (pw_unlock (process_selinux) == 0) { fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); /* continue */ } } if (gr_locked) { - if (gr_unlock (true) == 0) { + if (gr_unlock (process_selinux) == 0) { fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ()); SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); /* continue */ @@ -192,7 +192,7 @@ static void fail_exit (int code) } #ifdef SHADOWGRP if (sgr_locked) { - if (sgr_unlock (true) == 0) { + if (sgr_unlock (process_selinux) == 0) { fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ()); SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); /* continue */ @@ -201,14 +201,14 @@ static void fail_exit (int code) #endif #ifdef ENABLE_SUBIDS if (sub_uid_locked) { - if (sub_uid_unlock (true) == 0) { + if (sub_uid_unlock (process_selinux) == 0) { fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); /* continue */ } } if (sub_gid_locked) { - if (sub_gid_unlock (true) == 0) { + if (sub_gid_unlock (process_selinux) == 0) { fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ()); SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); /* continue */ @@ -737,7 +737,7 @@ static void process_flags (int argc, char **argv, struct option_flags *flags) SNPRINTF(buf, "%s: %s", Prog, argv[1]); perror (buf); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, !flags->chroot); } } @@ -796,20 +796,23 @@ static void check_flags (void) * * It will not return if the user is not allowed. */ -static void check_perms (void) +static void check_perms (struct option_flags *flags) { #ifdef ACCT_TOOLS_SETUID #ifdef USE_PAM pam_handle_t *pamh = NULL; int retval; struct passwd *pampw; + bool process_selinux; + + process_selinux = !flags->chroot; pampw = getpwuid (getuid ()); /* local, no need for xgetpwuid */ if (NULL == pampw) { fprintf (stderr, _("%s: Cannot determine your user name.\n"), Prog); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } retval = pam_start ("newusers", pampw->pw_name, &conv, &pamh); @@ -829,7 +832,7 @@ static void check_perms (void) if (NULL != pamh) { (void) pam_end (pamh, retval); } - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } (void) pam_end (pamh, retval); #endif /* USE_PAM */ @@ -839,7 +842,7 @@ static void check_perms (void) /* * open_files - lock and open the password, group and shadow databases */ -static void open_files (void) +static void open_files (bool process_selinux) { /* * Lock the password files and open them for update. This will bring @@ -851,7 +854,7 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, pw_dbname ()); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } pw_locked = true; if (is_shadow) { @@ -859,7 +862,7 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, spw_dbname ()); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } spw_locked = true; } @@ -867,7 +870,7 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, gr_dbname ()); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } gr_locked = true; #ifdef SHADOWGRP @@ -876,7 +879,7 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, sgr_dbname ()); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } sgr_locked = true; } @@ -887,7 +890,7 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, sub_uid_dbname ()); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } sub_uid_locked = true; } @@ -896,7 +899,7 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, sub_gid_dbname ()); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } sub_gid_locked = true; } @@ -904,20 +907,20 @@ static void open_files (void) if (pw_open (O_CREAT | O_RDWR) == 0) { fprintf (stderr, _("%s: cannot open %s\n"), Prog, pw_dbname ()); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } if (is_shadow && (spw_open (O_CREAT | O_RDWR) == 0)) { fprintf (stderr, _("%s: cannot open %s\n"), Prog, spw_dbname ()); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } if (gr_open (O_CREAT | O_RDWR) == 0) { fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ()); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } #ifdef SHADOWGRP if (is_shadow_grp && (sgr_open (O_CREAT | O_RDWR) == 0)) { fprintf (stderr, _("%s: cannot open %s\n"), Prog, sgr_dbname ()); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } #endif #ifdef ENABLE_SUBIDS @@ -926,7 +929,7 @@ static void open_files (void) fprintf (stderr, _("%s: cannot open %s\n"), Prog, sub_uid_dbname ()); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } } if (is_sub_gid) { @@ -934,7 +937,7 @@ static void open_files (void) fprintf (stderr, _("%s: cannot open %s\n"), Prog, sub_gid_dbname ()); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } } #endif /* ENABLE_SUBIDS */ @@ -952,7 +955,7 @@ static void close_files (struct option_flags *flags) if (pw_close (process_selinux) == 0) { fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, pw_dbname ()); SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } if (pw_unlock (process_selinux) == 0) { fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); @@ -967,7 +970,7 @@ static void close_files (struct option_flags *flags) _("%s: failure while writing changes to %s\n"), Prog, spw_dbname ()); SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ())); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } if (spw_unlock (process_selinux) == 0) { fprintf (stderr, @@ -984,20 +987,20 @@ static void close_files (struct option_flags *flags) _("%s: failure while writing changes to %s\n"), Prog, gr_dbname ()); SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ())); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } #ifdef ENABLE_SUBIDS if (is_sub_uid && (sub_uid_close (process_selinux) == 0)) { fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sub_uid_dbname ()); SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_uid_dbname ())); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } if (is_sub_gid && (sub_gid_close (process_selinux) == 0)) { fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sub_gid_dbname ()); SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_gid_dbname ())); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } #endif /* ENABLE_SUBIDS */ @@ -1017,7 +1020,7 @@ static void close_files (struct option_flags *flags) _("%s: failure while writing changes to %s\n"), Prog, sgr_dbname ()); SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ())); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } if (sgr_unlock (process_selinux) == 0) { fprintf (stderr, @@ -1065,6 +1068,7 @@ int main (int argc, char **argv) size_t nusers = 0; #endif /* USE_PAM */ struct option_flags flags; + bool process_selinux; log_set_progname(Prog); log_set_logfd(stderr); @@ -1079,8 +1083,9 @@ int main (int argc, char **argv) OPENLOG ("newusers"); process_flags (argc, argv, &flags); + process_selinux = !flags.chroot; - check_perms (); + check_perms (&flags); is_shadow = spw_file_present (); @@ -1092,7 +1097,7 @@ int main (int argc, char **argv) is_sub_gid = want_subgid_file() && sub_gid_file_present() && !rflg; #endif /* ENABLE_SUBIDS */ - open_files (); + open_files (process_selinux); /* * Read each line. The line has the same format as a password file @@ -1108,13 +1113,13 @@ int main (int argc, char **argv) if (stpsep(buf, "\n") == NULL && feof(stdin) == 0) { fprintf (stderr, _("%s: line %jd: line too long\n"), Prog, line); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } if (STRSEP2ARR(buf, ":", fields) == -1) { fprintf (stderr, _("%s: line %jd: invalid line\n"), Prog, line); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } /* @@ -1126,14 +1131,14 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: cannot update the entry of user %s (not in the passwd database)\n"), Prog, fields[0]); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } if (NULL == pw && get_user_id(fields[2], &uid) != 0) { fprintf (stderr, _("%s: line %jd: can't create user\n"), Prog, line); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } /* @@ -1153,7 +1158,7 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: line %jd: can't create group\n"), Prog, line); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } /* @@ -1168,7 +1173,7 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: line %jd: can't create user\n"), Prog, line); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } /* @@ -1180,7 +1185,7 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: line %jd: user '%s' does not exist in %s\n"), Prog, line, fields[0], pw_dbname ()); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } newpw = *pw; @@ -1194,7 +1199,7 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: line %jd: %s\n"), Prog, line, strerror(errno)); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } lines[nusers-1] = line; usernames[nusers-1] = xstrdup(fields[0]); @@ -1204,7 +1209,7 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: line %jd: can't update password\n"), Prog, line); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } if (!streq(fields[4], "")) { newpw.pw_gecos = fields[4]; @@ -1227,7 +1232,7 @@ int main (int argc, char **argv) fprintf(stderr, _("%s: line %jd: homedir must be an absolute path\n"), Prog, line); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } if (mkdir (newpw.pw_dir, mode) != 0) { fprintf (stderr, @@ -1235,7 +1240,7 @@ int main (int argc, char **argv) Prog, line, newpw.pw_dir, strerror (errno)); if (errno != EEXIST) { - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } } if (chown(newpw.pw_dir, newpw.pw_uid, newpw.pw_gid) != 0) @@ -1244,7 +1249,7 @@ int main (int argc, char **argv) _("%s: line %jd: chown %s failed: %s\n"), Prog, line, newpw.pw_dir, strerror (errno)); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } } @@ -1255,7 +1260,7 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: line %jd: can't update entry\n"), Prog, line); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } #ifdef ENABLE_SUBIDS @@ -1270,14 +1275,14 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: can't find subordinate user range\n"), Prog); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } if (sub_uid_add(fields[0], sub_uid_start, sub_uid_count) == 0) { fprintf (stderr, _("%s: failed to prepare new %s entry\n"), Prog, sub_uid_dbname ()); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } } @@ -1291,13 +1296,13 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: can't find subordinate group range\n"), Prog); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } if (sub_gid_add(fields[0], sub_gid_start, sub_gid_count) == 0) { fprintf (stderr, _("%s: failed to prepare new %s entry\n"), Prog, sub_uid_dbname ()); - fail_exit (EXIT_FAILURE); + fail_exit (EXIT_FAILURE, process_selinux); } } #endif /* ENABLE_SUBIDS */