From: Iker Pedrosa Date: Thu, 3 Jul 2025 09:45:29 +0000 (+0200) Subject: src/chfn.c: chroot or prefix SELinux file context X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=961aec9a1548b947f3448a8f2e0d327776d44066;p=thirdparty%2Fshadow.git src/chfn.c: chroot or prefix SELinux file context Do not process SELinux file context during file closure when chroot or prefix options are selected. Signed-off-by: Iker Pedrosa --- diff --git a/src/chfn.c b/src/chfn.c index b0e7c315d..0d3825155 100644 --- a/src/chfn.c +++ b/src/chfn.c @@ -40,6 +40,9 @@ #include "string/strcpy/strtcpy.h" #include "string/strdup/xstrdup.h" +struct option_flags { + bool chroot; +}; /* * Global variables. @@ -68,9 +71,9 @@ NORETURN static void fail_exit (int code); NORETURN static void usage (int status); static bool may_change_field (int); static void new_fields (void); -static void process_flags (int argc, char **argv); +static void process_flags (int argc, char **argv, struct option_flags *flags); static void check_perms (const struct passwd *pw); -static void update_gecos (const char *user, char *gecos); +static void update_gecos (const char *user, char *gecos, struct option_flags *flags); static void get_old_fields (const char *gecos); /* @@ -210,7 +213,7 @@ static void new_fields (void) * * It will not return if an error is encountered. */ -static void process_flags (int argc, char **argv) +static void process_flags (int argc, char **argv, struct option_flags *flags) { int c; /* flag currently being processed */ static struct option long_options[] = { @@ -276,6 +279,7 @@ static void process_flags (int argc, char **argv) STRTCPY(roomno, optarg); break; case 'R': /* no-op, handled in process_root_flag () */ + flags->chroot = true; break; case 'u': usage (E_SUCCESS); @@ -383,10 +387,13 @@ static void check_perms (const struct passwd *pw) * * Commit the user's entry after changing her gecos field. */ -static void update_gecos (const char *user, char *gecos) +static void update_gecos (const char *user, char *gecos, struct option_flags *flags) { const struct passwd *pw; /* The user's password file entry */ struct passwd pwent; /* modified password file entry */ + bool process_selinux; + + process_selinux = !flags->chroot; /* * Before going any further, raise the ulimit to prevent colliding @@ -453,12 +460,12 @@ static void update_gecos (const char *user, char *gecos) /* * Changes have all been made, so commit them and unlock the file. */ - if (pw_close (true) == 0) { + 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 (E_NOPERM); } - 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 */ @@ -565,6 +572,7 @@ int main (int argc, char **argv) char new_gecos[80]; char *user, *p, *e; const struct passwd *pw; + struct option_flags flags; sanitize_env (); check_fds (); @@ -587,7 +595,7 @@ int main (int argc, char **argv) OPENLOG (Prog); /* parse the command line options */ - process_flags (argc, argv); + process_flags (argc, argv, &flags); /* * Get the name of the user to check. It is either the command line @@ -656,7 +664,7 @@ int main (int argc, char **argv) } /* Rewrite the user's gecos in the passwd file */ - update_gecos (user, new_gecos); + update_gecos (user, new_gecos, &flags); SYSLOG ((LOG_INFO, "changed user '%s' information", user));