]> git.ipfire.org Git - thirdparty/shadow.git/commitdiff
src/chpasswd.c: SELinux file context for fail_exit()
authorIker Pedrosa <ipedrosa@redhat.com>
Thu, 3 Jul 2025 09:56:13 +0000 (11:56 +0200)
committerIker Pedrosa <ipedrosa@redhat.com>
Tue, 7 Oct 2025 09:05:38 +0000 (11:05 +0200)
Do not process SELinux file context when running fail_exit() when chroot
or prefix options are selected.

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
src/chpasswd.c

index 20de560522c8fc9a00639cdcdd8afbadd0da7bf7..91da42d0abd8170245a0e80a8a1720dd6a641e11 100644 (file)
@@ -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