From 88503aebb1ad061d0c243fa6864358577c0ac95b Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Thu, 3 Jul 2025 11:56:13 +0200 Subject: [PATCH] src/chpasswd.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 --- src/chpasswd.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/chpasswd.c b/src/chpasswd.c index 20de56052..91da42d0a 100644 --- a/src/chpasswd.c +++ b/src/chpasswd.c @@ -74,21 +74,21 @@ static bool pw_locked = false; static bool spw_locked = false; /* local function prototypes */ -NORETURN static void fail_exit (int code); +NORETURN static void fail_exit (int code, bool process_selinux); NORETURN static void usage (int status); 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 open_files (struct option_flags *flags); static void close_files (struct option_flags *flags); /* * fail_exit - exit with a failure code after unlocking the files */ -static void fail_exit (int code) +static void fail_exit (int code, bool process_selinux) { 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 */ @@ -96,7 +96,7 @@ static void fail_exit (int code) } 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 */ @@ -344,8 +344,12 @@ static void check_perms (void) /* * open_files - lock and open the password databases */ -static void open_files (void) +static void open_files (struct option_flags *flags) { + bool process_selinux; + + process_selinux = !flags->chroot && !flags->prefix; + /* * Lock the password file and open it for reading and writing. This * will bring all of the entries into memory where they may be updated. @@ -354,13 +358,13 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, pw_dbname ()); - fail_exit (1); + fail_exit (1, process_selinux); } pw_locked = true; if (pw_open (O_CREAT | O_RDWR) == 0) { fprintf (stderr, _("%s: cannot open %s\n"), Prog, pw_dbname ()); - fail_exit (1); + fail_exit (1, process_selinux); } /* Do the same for the shadowed database, if it exist */ @@ -369,14 +373,14 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, spw_dbname ()); - fail_exit (1); + fail_exit (1, process_selinux); } spw_locked = true; if (spw_open (O_CREAT | O_RDWR) == 0) { fprintf (stderr, _("%s: cannot open %s\n"), Prog, spw_dbname ()); - fail_exit (1); + fail_exit (1, process_selinux); } } } @@ -396,7 +400,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 (1); + fail_exit (1, process_selinux); } if (spw_unlock (process_selinux) == 0) { fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); @@ -411,7 +415,7 @@ static void close_files (struct option_flags *flags) _("%s: failure while writing changes to %s\n"), Prog, pw_dbname ()); SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ())); - fail_exit (1); + fail_exit (1, process_selinux); } if (pw_unlock (process_selinux) == 0) { fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); @@ -468,6 +472,7 @@ int main (int argc, char **argv) bool errors = false; intmax_t line = 0; struct option_flags flags; + bool process_selinux; log_set_progname(Prog); log_set_logfd(stderr); @@ -483,6 +488,7 @@ int main (int argc, char **argv) #endif /* WITH_SELINUX */ process_flags (argc, argv, &flags); + process_selinux = !flags.chroot && !flags.prefix; salt = get_salt(); process_root_flag ("-R", argc, argv); @@ -504,7 +510,7 @@ int main (int argc, char **argv) { is_shadow_pwd = spw_file_present (); - open_files (); + open_files (&flags); } /* @@ -592,7 +598,7 @@ int main (int argc, char **argv) fprintf (stderr, _("%s: failed to crypt password with salt '%s': %s\n"), Prog, salt, strerror (errno)); - fail_exit (1); + fail_exit (1, process_selinux); } } @@ -707,7 +713,7 @@ int main (int argc, char **argv) _("%s: error detected, changes ignored\n"), Prog); } - fail_exit (1); + fail_exit (1, process_selinux); } #ifdef USE_PAM -- 2.47.3