From: Iker Pedrosa Date: Tue, 1 Jul 2025 14:14:08 +0000 (+0200) Subject: src/groupmems.c: SELinux file context for fail_exit() X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=74018ef083c646defedd9e14b9b2de298b67bb8f;p=thirdparty%2Fshadow.git src/groupmems.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/groupmems.c b/src/groupmems.c index c3de13f41..3890e023c 100644 --- a/src/groupmems.c +++ b/src/groupmems.c @@ -74,15 +74,17 @@ static bool sgr_locked = false; /* local function prototypes */ static char *whoami (void); static void add_user (const char *user, - const struct group *grp); + const struct group *grp, + bool process_selinux); static void remove_user (const char *user, - const struct group *grp); -static void purge_members (const struct group *grp); + const struct group *grp, + bool process_selinux); +static void purge_members (const struct group *grp, bool process_selinux); static void display_members (const char *const *members); NORETURN static void usage (int status); static void process_flags (int argc, char **argv, struct option_flags *flags); -static void check_perms (void); -NORETURN static void fail_exit (int code); +static void check_perms (bool process_selinux); +NORETURN static void fail_exit (int code, bool process_selinux); #define isroot() (getuid () == 0) static char *whoami (void) @@ -105,7 +107,8 @@ static char *whoami (void) * add_user - Add a user to the specified group */ static void add_user (const char *user, - const struct group *grp) + const struct group *grp, + bool process_selinux) { struct group *newgrp; @@ -114,7 +117,7 @@ static void add_user (const char *user, fprintf (stderr, _("%s: user '%s' is already a member of '%s'\n"), Prog, user, grp->gr_name); - fail_exit (EXIT_MEMBER_EXISTS); + fail_exit (EXIT_MEMBER_EXISTS, process_selinux); } newgrp = __gr_dup(grp); @@ -122,7 +125,7 @@ static void add_user (const char *user, fprintf (stderr, _("%s: Out of memory. Cannot update %s.\n"), Prog, gr_dbname ()); - fail_exit (13); + fail_exit (13, process_selinux); } /* Add the user to the /etc/group group */ @@ -152,7 +155,7 @@ static void add_user (const char *user, fprintf (stderr, _("%s: Out of memory. Cannot update %s.\n"), Prog, sgr_dbname ()); - fail_exit (13); + fail_exit (13, process_selinux); } /* Add the user to the members */ newsg->sg_mem = add_list (newsg->sg_mem, user); @@ -163,7 +166,7 @@ static void add_user (const char *user, fprintf (stderr, _("%s: failed to prepare the new %s entry '%s'\n"), Prog, sgr_dbname (), newsg->sg_namp); - fail_exit (13); + fail_exit (13, process_selinux); } } #endif @@ -172,7 +175,7 @@ static void add_user (const char *user, fprintf (stderr, _("%s: failed to prepare the new %s entry '%s'\n"), Prog, gr_dbname (), newgrp->gr_name); - fail_exit (13); + fail_exit (13, process_selinux); } } @@ -180,7 +183,8 @@ static void add_user (const char *user, * remove_user - Remove a user from a given group */ static void remove_user (const char *user, - const struct group *grp) + const struct group *grp, + bool process_selinux) { struct group *newgrp; @@ -189,7 +193,7 @@ static void remove_user (const char *user, fprintf (stderr, _("%s: user '%s' is not a member of '%s'\n"), Prog, user, grp->gr_name); - fail_exit (EXIT_NOT_MEMBER); + fail_exit (EXIT_NOT_MEMBER, process_selinux); } newgrp = __gr_dup (grp); @@ -197,7 +201,7 @@ static void remove_user (const char *user, fprintf (stderr, _("%s: Out of memory. Cannot update %s.\n"), Prog, gr_dbname ()); - fail_exit (13); + fail_exit (13, process_selinux); } /* Remove the user from the /etc/group group */ @@ -227,7 +231,7 @@ static void remove_user (const char *user, fprintf (stderr, _("%s: Out of memory. Cannot update %s.\n"), Prog, sgr_dbname ()); - fail_exit (13); + fail_exit (13, process_selinux); } /* Remove the user from the members */ newsg->sg_mem = del_list (newsg->sg_mem, user); @@ -239,7 +243,7 @@ static void remove_user (const char *user, fprintf (stderr, _("%s: failed to prepare the new %s entry '%s'\n"), Prog, sgr_dbname (), newsg->sg_namp); - fail_exit (13); + fail_exit (13, process_selinux); } } #endif @@ -248,14 +252,14 @@ static void remove_user (const char *user, fprintf (stderr, _("%s: failed to prepare the new %s entry '%s'\n"), Prog, gr_dbname (), newgrp->gr_name); - fail_exit (13); + fail_exit (13, process_selinux); } } /* * purge_members - Remove every members of the specified group */ -static void purge_members (const struct group *grp) +static void purge_members (const struct group *grp, bool process_selinux) { struct group *newgrp = __gr_dup (grp); @@ -263,7 +267,7 @@ static void purge_members (const struct group *grp) fprintf (stderr, _("%s: Out of memory. Cannot update %s.\n"), Prog, gr_dbname ()); - fail_exit (13); + fail_exit (13, process_selinux); } /* Remove all the members of the /etc/group group */ @@ -294,7 +298,7 @@ static void purge_members (const struct group *grp) fprintf (stderr, _("%s: Out of memory. Cannot update %s.\n"), Prog, sgr_dbname ()); - fail_exit (13); + fail_exit (13, process_selinux); } /* Remove all the members of the /etc/gshadow * group */ @@ -308,7 +312,7 @@ static void purge_members (const struct group *grp) fprintf (stderr, _("%s: failed to prepare the new %s entry '%s'\n"), Prog, sgr_dbname (), newsg->sg_namp); - fail_exit (13); + fail_exit (13, process_selinux); } } #endif @@ -317,7 +321,7 @@ static void purge_members (const struct group *grp) fprintf (stderr, _("%s: failed to prepare the new %s entry '%s'\n"), Prog, gr_dbname (), newgrp->gr_name); - fail_exit (13); + fail_exit (13, process_selinux); } } @@ -418,12 +422,12 @@ static void process_flags (int argc, char **argv, struct option_flags *flags) && (getpwnam (adduser) == NULL)) { fprintf (stderr, _("%s: user '%s' does not exist\n"), Prog, adduser); - fail_exit (EXIT_INVALID_USER); + fail_exit (EXIT_INVALID_USER, !flags->chroot); } } -static void check_perms (void) +static void check_perms (bool process_selinux) { if (!list) { #ifdef USE_PAM @@ -436,7 +440,7 @@ static void check_perms (void) fprintf (stderr, _("%s: Cannot determine your user name.\n"), Prog); - fail_exit (1); + fail_exit (1, process_selinux); } retval = pam_start (Prog, pampw->pw_name, &conv, &pamh); @@ -456,17 +460,17 @@ static void check_perms (void) if (NULL != pamh) { (void) pam_end (pamh, retval); } - fail_exit (1); + fail_exit (1, process_selinux); } (void) pam_end (pamh, retval); #endif } } -static void fail_exit (int code) +static void fail_exit (int code, bool process_selinux) { 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 ()); @@ -477,7 +481,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 ()); @@ -490,14 +494,14 @@ static void fail_exit (int code) exit (code); } -static void open_files (void) +static void open_files (bool process_selinux) { if (!list) { if (gr_lock () == 0) { fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, gr_dbname ()); - fail_exit (EXIT_GROUP_FILE); + fail_exit (EXIT_GROUP_FILE, process_selinux); } gr_locked = true; @@ -507,7 +511,7 @@ static void open_files (void) fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, sgr_dbname ()); - fail_exit (EXIT_GROUP_FILE); + fail_exit (EXIT_GROUP_FILE, process_selinux); } sgr_locked = true; } @@ -516,14 +520,14 @@ static void open_files (void) if (gr_open (list ? O_RDONLY : O_CREAT | O_RDWR) == 0) { fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ()); - fail_exit (EXIT_GROUP_FILE); + fail_exit (EXIT_GROUP_FILE, process_selinux); } #ifdef SHADOWGRP if (is_shadowgrp) { if (sgr_open (list ? O_RDONLY : O_CREAT | O_RDWR) == 0) { fprintf (stderr, _("%s: cannot open %s\n"), Prog, sgr_dbname ()); - fail_exit (EXIT_GROUP_FILE); + fail_exit (EXIT_GROUP_FILE, process_selinux); } } #endif @@ -538,7 +542,7 @@ static void close_files (struct option_flags *flags) if ((gr_close (process_selinux) == 0) && !list) { fprintf (stderr, _("%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_GROUP_FILE); + fail_exit (EXIT_GROUP_FILE, process_selinux); } if (gr_locked) { if (gr_unlock (process_selinux) == 0) { @@ -554,7 +558,7 @@ static void close_files (struct option_flags *flags) if ((sgr_close (process_selinux) == 0) && !list) { fprintf (stderr, _("%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_GROUP_FILE); + fail_exit (EXIT_GROUP_FILE, process_selinux); } if (sgr_locked) { if (sgr_unlock (process_selinux) == 0) { @@ -573,6 +577,7 @@ int main (int argc, char **argv) char *name; const struct group *grp; struct option_flags flags; + bool process_selinux; log_set_progname(Prog); log_set_logfd(stderr); @@ -590,40 +595,41 @@ int main (int argc, char **argv) #endif process_flags (argc, argv, &flags); + process_selinux = !flags.chroot; if (NULL == thisgroup) { name = whoami (); if (!list && (NULL == name)) { fprintf (stderr, _("%s: your groupname does not match your username\n"), Prog); - fail_exit (EXIT_NOT_PRIMARY); + fail_exit (EXIT_NOT_PRIMARY, process_selinux); } } else { name = thisgroup; if (!list && !isroot ()) { fprintf (stderr, _("%s: only root can use the -g/--group option\n"), Prog); - fail_exit (EXIT_NOT_ROOT); + fail_exit (EXIT_NOT_ROOT, process_selinux); } } - check_perms (); + check_perms (process_selinux); - open_files (); + open_files (process_selinux); grp = gr_locate (name); if (NULL == grp) { fprintf (stderr, _("%s: group '%s' does not exist in %s\n"), Prog, name, gr_dbname ()); - fail_exit (EXIT_INVALID_GROUP); + fail_exit (EXIT_INVALID_GROUP, process_selinux); } if (list) { display_members ((const char *const *)grp->gr_mem); } else if (NULL != adduser) { - add_user (adduser, grp); + add_user (adduser, grp, process_selinux); } else if (NULL != deluser) { - remove_user (deluser, grp); + remove_user (deluser, grp, process_selinux); } else if (purge) { - purge_members (grp); + purge_members (grp, process_selinux); } close_files (&flags);