]> git.ipfire.org Git - thirdparty/shadow.git/commitdiff
src/useradd.c: SELinux file context for fail_exit()
authorIker Pedrosa <ipedrosa@redhat.com>
Tue, 1 Jul 2025 11:23:08 +0000 (13:23 +0200)
committerIker Pedrosa <ipedrosa@redhat.com>
Tue, 7 Oct 2025 09:04:39 +0000 (11:04 +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/useradd.c

index 8b7d3405d0eaaab23b7f9b5ee569f747b3c9d0bf..28338cf518b52d9f7e342686ff7e9df8d82b57ba 100644 (file)
@@ -224,31 +224,32 @@ static bool home_added = false;
 #define DLOG_INIT              "LOG_INIT"
 
 /* local function prototypes */
-NORETURN static void fail_exit (int);
+NORETURN static void fail_exit (int, bool);
 static void get_defaults (struct option_flags *);
 static void show_defaults (void);
 static int set_defaults (void);
 static int get_groups (char *, struct option_flags *);
-static struct group * get_local_group (char * grp_name);
+static struct group * get_local_group (char * grp_name, bool process_selinux);
 NORETURN static void usage (int status);
 static void new_pwent (struct passwd *);
 
 static void new_spent (struct spwd *);
-static void grp_update (void);
+static void grp_update (bool);
 
 static void process_flags (int argc, char **argv, struct option_flags *flags);
 static void close_files (struct option_flags *flags);
 static void close_group_files (bool process_selinux);
 static void unlock_group_files (bool process_selinux);
-static void open_files (void);
-static void open_group_files (void);
-static void open_shadow (void);
+static void open_files (bool process_selinux);
+static void open_group_files (bool process_selinux);
+static void open_shadow (bool process_selinux);
 static void faillog_reset (uid_t);
 #ifdef ENABLE_LASTLOG
 static void lastlog_reset (uid_t);
 #endif /* ENABLE_LASTLOG */
 static void tallylog_reset (const char *);
-static void usr_update (unsigned long subuid_count, unsigned long subgid_count);
+static void usr_update (unsigned long subuid_count, unsigned long subgid_count,
+                        struct option_flags *flags);
 static void create_home (struct option_flags *flags);
 static void create_mail (struct option_flags *flags);
 static void check_uid_range(int rflg, uid_t user_id);
@@ -257,7 +258,7 @@ static void check_uid_range(int rflg, uid_t user_id);
 /*
  * fail_exit - undo as much as possible
  */
-static void fail_exit (int code)
+static void fail_exit (int code, bool process_selinux)
 {
 #ifdef WITH_AUDIT
        int type;
@@ -270,35 +271,35 @@ static void fail_exit (int code)
                SYSLOG((LOG_ERR, "failed to remove %s", prefix_user_home));
        }
 
-       if (spw_locked && spw_unlock(true) == 0) {
+       if (spw_locked && 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 && pw_unlock(true) == 0) {
+       if (pw_locked && 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 && gr_unlock(true) == 0) {
+       if (gr_locked && 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 */
        }
 #ifdef SHADOWGRP
-       if (sgr_locked && sgr_unlock(true) == 0) {
+       if (sgr_locked && 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 */
        }
 #endif
 #ifdef ENABLE_SUBIDS
-       if (sub_uid_locked && sub_uid_unlock(true) == 0) {
+       if (sub_uid_locked && 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 && sub_gid_unlock(true) == 0) {
+       if (sub_gid_locked && 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 */
@@ -766,7 +767,7 @@ static int get_groups (char *list, struct option_flags *flags)
        /*
         * Open the group files
         */
-       open_group_files ();
+       open_group_files (process_selinux);
 
        /*
         * So long as there is some data to be converted, strip off
@@ -785,7 +786,7 @@ static int get_groups (char *list, struct option_flags *flags)
                 * Names starting with digits are treated as numerical
                 * GID values, otherwise the string is looked up as is.
                 */
-               grp = get_local_group(g);
+               grp = get_local_group(g, process_selinux);
 
                /*
                 * There must be a match, either by GID value or by
@@ -845,7 +846,7 @@ static int get_groups (char *list, struct option_flags *flags)
  *     If the name exists the group information is returned, otherwise NULL is
  *     returned.
  */
-static struct group * get_local_group(char * grp_name)
+static struct group * get_local_group(char * grp_name, bool process_selinux)
 {
        gid_t               gid;
        struct group        *result_grp = NULL;
@@ -862,7 +863,7 @@ static struct group * get_local_group(char * grp_name)
                        fprintf (stderr,
                                        _("%s: Out of memory. Cannot find group '%s'.\n"),
                                        Prog, grp_name);
-                       fail_exit (E_GRP_UPDATE);
+                       fail_exit (E_GRP_UPDATE, process_selinux);
                }
        }
 
@@ -994,7 +995,7 @@ static void new_spent (struct spwd *spent)
  *     close_files() should be called afterwards to commit the changes
  *     and unlocking the group files.
  */
-static void grp_update (void)
+static void grp_update (bool process_selinux)
 {
        const struct group *grp;
        struct group *ngrp;
@@ -1030,7 +1031,7 @@ static void grp_update (void)
                                 _("%s: Out of memory. Cannot update %s.\n"),
                                 Prog, gr_dbname ());
                        SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", gr_dbname (), user_name));
-                       fail_exit (E_GRP_UPDATE);       /* XXX */
+                       fail_exit (E_GRP_UPDATE, process_selinux);      /* XXX */
                }
 
                /*
@@ -1043,7 +1044,7 @@ static void grp_update (void)
                                 _("%s: failed to prepare the new %s entry '%s'\n"),
                                 Prog, gr_dbname (), ngrp->gr_name);
                        SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", gr_dbname (), user_name));
-                       fail_exit (E_GRP_UPDATE);
+                       fail_exit (E_GRP_UPDATE, process_selinux);
                }
 #ifdef WITH_AUDIT
                audit_logger_with_group (AUDIT_USER_MGMT,
@@ -1093,7 +1094,7 @@ static void grp_update (void)
                                 _("%s: Out of memory. Cannot update %s.\n"),
                                 Prog, sgr_dbname ());
                        SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", sgr_dbname (), user_name));
-                       fail_exit (E_GRP_UPDATE);       /* XXX */
+                       fail_exit (E_GRP_UPDATE, process_selinux);      /* XXX */
                }
 
                /*
@@ -1107,7 +1108,7 @@ static void grp_update (void)
                                 Prog, sgr_dbname (), nsgrp->sg_namp);
                        SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", sgr_dbname (), user_name));
 
-                       fail_exit (E_GRP_UPDATE);
+                       fail_exit (E_GRP_UPDATE, process_selinux);
                }
 #ifdef WITH_AUDIT
                audit_logger_with_group (AUDIT_USER_MGMT,
@@ -1581,13 +1582,13 @@ 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 (E_PW_UPDATE);
+               fail_exit (E_PW_UPDATE, process_selinux);
        }
        if (is_shadow_pwd && (spw_close (process_selinux) == 0)) {
                fprintf (stderr,
                         _("%s: failure while writing changes to %s\n"), Prog, spw_dbname ());
                SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ()));
-               fail_exit (E_PW_UPDATE);
+               fail_exit (E_PW_UPDATE, process_selinux);
        }
 
        close_group_files (process_selinux);
@@ -1597,13 +1598,13 @@ static void close_files (struct option_flags *flags)
                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 (E_SUB_UID_UPDATE);
+               fail_exit (E_SUB_UID_UPDATE, 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 (E_SUB_GID_UPDATE);
+               fail_exit (E_SUB_GID_UPDATE, process_selinux);
        }
 #endif                         /* ENABLE_SUBIDS */
        if (is_shadow_pwd) {
@@ -1683,7 +1684,7 @@ static void close_group_files (bool process_selinux)
                        _("%s: failure while writing changes to %s\n"),
                        Prog, gr_dbname());
                SYSLOG((LOG_ERR, "failure while writing changes to %s", gr_dbname()));
-               fail_exit(E_GRP_UPDATE);
+               fail_exit(E_GRP_UPDATE, process_selinux);
        }
 #ifdef SHADOWGRP
        if (is_shadow_grp && sgr_close(process_selinux) == 0) {
@@ -1691,7 +1692,7 @@ static void close_group_files (bool process_selinux)
                        _("%s: failure while writing changes to %s\n"),
                        Prog, sgr_dbname());
                SYSLOG((LOG_ERR, "failure while writing changes to %s", sgr_dbname()));
-               fail_exit(E_GRP_UPDATE);
+               fail_exit(E_GRP_UPDATE, process_selinux);
        }
 #endif /* SHADOWGRP */
 }
@@ -1739,7 +1740,7 @@ static void unlock_group_files (bool process_selinux)
  *
  *     open_files() opens the two password files.
  */
-static void open_files (void)
+static void open_files (bool process_selinux)
 {
        if (pw_lock () == 0) {
                fprintf (stderr,
@@ -1750,12 +1751,12 @@ static void open_files (void)
        pw_locked = true;
        if (pw_open (O_CREAT | O_RDWR) == 0) {
                fprintf (stderr, _("%s: cannot open %s\n"), Prog, pw_dbname ());
-               fail_exit (E_PW_UPDATE);
+               fail_exit (E_PW_UPDATE, process_selinux);
        }
 
        /* shadow file will be opened by open_shadow(); */
 
-       open_group_files ();
+       open_group_files (process_selinux);
 
 #ifdef ENABLE_SUBIDS
        if (is_sub_uid) {
@@ -1763,14 +1764,14 @@ static void open_files (void)
                        fprintf (stderr,
                                 _("%s: cannot lock %s; try again later.\n"),
                                 Prog, sub_uid_dbname ());
-                       fail_exit (E_SUB_UID_UPDATE);
+                       fail_exit (E_SUB_UID_UPDATE, process_selinux);
                }
                sub_uid_locked = true;
                if (sub_uid_open (O_CREAT | O_RDWR) == 0) {
                        fprintf (stderr,
                                 _("%s: cannot open %s\n"),
                                 Prog, sub_uid_dbname ());
-                       fail_exit (E_SUB_UID_UPDATE);
+                       fail_exit (E_SUB_UID_UPDATE, process_selinux);
                }
        }
        if (is_sub_gid) {
@@ -1778,31 +1779,31 @@ static void open_files (void)
                        fprintf (stderr,
                                 _("%s: cannot lock %s; try again later.\n"),
                                 Prog, sub_gid_dbname ());
-                       fail_exit (E_SUB_GID_UPDATE);
+                       fail_exit (E_SUB_GID_UPDATE, process_selinux);
                }
                sub_gid_locked = true;
                if (sub_gid_open (O_CREAT | O_RDWR) == 0) {
                        fprintf (stderr,
                                 _("%s: cannot open %s\n"),
                                 Prog, sub_gid_dbname ());
-                       fail_exit (E_SUB_GID_UPDATE);
+                       fail_exit (E_SUB_GID_UPDATE, process_selinux);
                }
        }
 #endif                         /* ENABLE_SUBIDS */
 }
 
-static void open_group_files (void)
+static void open_group_files (bool process_selinux)
 {
        if (gr_lock () == 0) {
                fprintf (stderr,
                         _("%s: cannot lock %s; try again later.\n"),
                         Prog, gr_dbname ());
-               fail_exit (E_GRP_UPDATE);
+               fail_exit (E_GRP_UPDATE, process_selinux);
        }
        gr_locked = true;
        if (gr_open (O_CREAT | O_RDWR) == 0) {
                fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ());
-               fail_exit (E_GRP_UPDATE);
+               fail_exit (E_GRP_UPDATE, process_selinux);
        }
 
 #ifdef  SHADOWGRP
@@ -1811,20 +1812,20 @@ static void open_group_files (void)
                        fprintf (stderr,
                                 _("%s: cannot lock %s; try again later.\n"),
                                 Prog, sgr_dbname ());
-                       fail_exit (E_GRP_UPDATE);
+                       fail_exit (E_GRP_UPDATE, process_selinux);
                }
                sgr_locked = true;
                if (sgr_open (O_CREAT | O_RDWR) == 0) {
                        fprintf (stderr,
                                 _("%s: cannot open %s\n"),
                                 Prog, sgr_dbname ());
-                       fail_exit (E_GRP_UPDATE);
+                       fail_exit (E_GRP_UPDATE, process_selinux);
                }
        }
 #endif /* SHADOWGRP */
 }
 
-static void open_shadow (void)
+static void open_shadow (bool process_selinux)
 {
        if (!is_shadow_pwd) {
                return;
@@ -1833,14 +1834,14 @@ static void open_shadow (void)
                fprintf (stderr,
                         _("%s: cannot lock %s; try again later.\n"),
                         Prog, spw_dbname ());
-               fail_exit (E_PW_UPDATE);
+               fail_exit (E_PW_UPDATE, 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 (E_PW_UPDATE);
+               fail_exit (E_PW_UPDATE, process_selinux);
        }
 }
 
@@ -1894,7 +1895,7 @@ static void new_sgent (struct sgrp *sgent)
  *      grp_add() writes the new records to the group files.
  */
 
-static void grp_add (void)
+static void grp_add (bool process_selinux)
 {
        struct group grp;
 
@@ -1923,7 +1924,7 @@ static void grp_add (void)
                              grp.gr_name, AUDIT_NO_ID,
                              SHADOW_AUDIT_FAILURE);
 #endif
-               fail_exit (E_GRP_UPDATE);
+               fail_exit (E_GRP_UPDATE, process_selinux);
        }
 #ifdef  SHADOWGRP
        /*
@@ -1939,7 +1940,7 @@ static void grp_add (void)
                              grp.gr_name, AUDIT_NO_ID,
                              SHADOW_AUDIT_FAILURE);
 #endif
-               fail_exit (E_GRP_UPDATE);
+               fail_exit (E_GRP_UPDATE, process_selinux);
        }
 #endif                         /* SHADOWGRP */
        SYSLOG ((LOG_INFO, "new group: name=%s, GID=%u", user_name, user_gid));
@@ -2088,11 +2089,16 @@ static void tallylog_reset (const char *user_name)
  *     usr_update() creates the password file entries for this user
  *     and will update the group entries if required.
  */
-static void usr_update (unsigned long subuid_count, unsigned long subgid_count)
+static void
+usr_update (unsigned long subuid_count, unsigned long subgid_count,
+            struct option_flags *flags)
 {
        struct passwd pwent;
        struct spwd spent;
        char *tty;
+       bool process_selinux;
+
+       process_selinux = !flags->chroot && !flags->prefix;
 
        /*
         * Fill in the password structure with any new fields, making
@@ -2133,7 +2139,7 @@ static void usr_update (unsigned long subuid_count, unsigned long subgid_count)
                fprintf (stderr,
                         _("%s: failed to prepare the new %s entry '%s'\n"),
                         Prog, pw_dbname (), pwent.pw_name);
-               fail_exit (E_PW_UPDATE);
+               fail_exit (E_PW_UPDATE, process_selinux);
        }
 
        /*
@@ -2143,7 +2149,7 @@ static void usr_update (unsigned long subuid_count, unsigned long subgid_count)
                fprintf (stderr,
                         _("%s: failed to prepare the new %s entry '%s'\n"),
                         Prog, spw_dbname (), spent.sp_namp);
-               fail_exit (E_PW_UPDATE);
+               fail_exit (E_PW_UPDATE, process_selinux);
        }
 #ifdef ENABLE_SUBIDS
        if (is_sub_uid && !local_sub_uid_assigned(user_name) &&
@@ -2151,14 +2157,14 @@ static void usr_update (unsigned long subuid_count, unsigned long subgid_count)
                fprintf (stderr,
                         _("%s: failed to prepare the new %s entry\n"),
                         Prog, sub_uid_dbname ());
-               fail_exit (E_SUB_UID_UPDATE);
+               fail_exit (E_SUB_UID_UPDATE, process_selinux);
        }
        if (is_sub_gid && !local_sub_gid_assigned(user_name) &&
            (sub_gid_add(user_name, sub_gid_start, subgid_count) == 0)) {
                fprintf (stderr,
                         _("%s: failed to prepare the new %s entry\n"),
                         Prog, sub_uid_dbname ());
-               fail_exit (E_SUB_GID_UPDATE);
+               fail_exit (E_SUB_GID_UPDATE, process_selinux);
        }
 #endif                         /* ENABLE_SUBIDS */
 
@@ -2177,7 +2183,7 @@ static void usr_update (unsigned long subuid_count, unsigned long subgid_count)
         * Do any group file updates for this user.
         */
        if (do_grp_update) {
-               grp_update ();
+               grp_update (process_selinux);
        }
 }
 
@@ -2206,7 +2212,7 @@ static void create_home (struct option_flags *flags)
                fprintf(stderr,
                        _("%s: error while duplicating string %s\n"),
                        Prog, user_home);
-               fail_exit(E_HOMEDIR);
+               fail_exit(E_HOMEDIR, process_selinux);
        }
 
 #ifdef WITH_SELINUX
@@ -2215,7 +2221,7 @@ static void create_home (struct option_flags *flags)
                        fprintf(stderr,
                                _("%s: cannot set SELinux context for home directory %s\n"),
                                Prog, user_home);
-                       fail_exit(E_HOMEDIR);
+                       fail_exit(E_HOMEDIR, process_selinux);
                }
        }
 #endif
@@ -2246,14 +2252,14 @@ static void create_home (struct option_flags *flags)
                                fprintf(stderr,
                                        _("%s: error while duplicating string in BTRFS check %s\n"),
                                        Prog, path);
-                               fail_exit(E_HOMEDIR);
+                               fail_exit(E_HOMEDIR, process_selinux);
                        }
                        stpcpy(&btrfs_check[strlen(path) - strlen(cp) - 1], "");
                        if (is_btrfs(btrfs_check) <= 0) {
                                fprintf(stderr,
                                        _("%s: home directory \"%s\" must be mounted on BTRFS\n"),
                                        Prog, path);
-                               fail_exit(E_HOMEDIR);
+                               fail_exit(E_HOMEDIR, process_selinux);
                        }
                        free(btrfs_check);
                        // make subvolume to mount for user instead of directory
@@ -2261,7 +2267,7 @@ static void create_home (struct option_flags *flags)
                                fprintf(stderr,
                                        _("%s: failed to create BTRFS subvolume: %s\n"),
                                        Prog, path);
-                               fail_exit(E_HOMEDIR);
+                               fail_exit(E_HOMEDIR, process_selinux);
                        }
                }
                else
@@ -2269,7 +2275,7 @@ static void create_home (struct option_flags *flags)
                if (mkdir(path, 0) != 0) {
                        fprintf(stderr, _("%s: cannot create directory %s\n"),
                                Prog, path);
-                       fail_exit(E_HOMEDIR);
+                       fail_exit(E_HOMEDIR, process_selinux);
                }
                if (chown(path, 0, 0) < 0) {
                        fprintf(stderr,
@@ -2303,7 +2309,7 @@ static void create_home (struct option_flags *flags)
                        fprintf(stderr,
                                _("%s: cannot reset SELinux file creation context\n"),
                                Prog);
-                       fail_exit(E_HOMEDIR);
+                       fail_exit(E_HOMEDIR, process_selinux);
                }
        }
 #endif
@@ -2326,6 +2332,8 @@ static void create_mail (struct option_flags *flags)
        struct group  *gr;
        bool          process_selinux;
 
+       process_selinux = !flags->chroot && !flags->prefix;
+
        if (!strcaseeq(create_mail_spool, "yes"))
                return;
 
@@ -2349,7 +2357,7 @@ static void create_mail (struct option_flags *flags)
                        fprintf(stderr,
                                        _("%s: cannot set SELinux context for mailbox file %s\n"),
                                        Prog, file);
-                       fail_exit(E_MAILBOXFILE);
+                       fail_exit(E_MAILBOXFILE, process_selinux);
                }
        }
 #endif
@@ -2392,7 +2400,7 @@ static void create_mail (struct option_flags *flags)
                        fprintf(stderr,
                                        _("%s: cannot reset SELinux file creation context\n"),
                                        Prog);
-                       fail_exit(E_MAILBOXFILE);
+                       fail_exit(E_MAILBOXFILE, process_selinux);
                }
        }
 #endif
@@ -2436,6 +2444,7 @@ int main (int argc, char **argv)
        unsigned long subuid_count = 0;
        unsigned long subgid_count = 0;
        struct option_flags  flags;
+       bool process_selinux;
 
        log_set_progname(Prog);
        log_set_logfd(stderr);
@@ -2469,6 +2478,7 @@ int main (int argc, char **argv)
        get_defaults (&flags);
 
        process_flags (argc, argv, &flags);
+       process_selinux = !flags.chroot && !flags.prefix;
 
 #ifdef ENABLE_SUBIDS
        uid_min = getdef_ulong ("UID_MIN", 1000UL);
@@ -2499,7 +2509,7 @@ int main (int argc, char **argv)
                        fprintf (stderr,
                                 _("%s: Cannot determine your user name.\n"),
                                 Prog);
-                       fail_exit (1);
+                       fail_exit (1, process_selinux);
                }
 
                retval = pam_start (Prog, pampw?pampw->pw_name:"root", &conv, &pamh);
@@ -2520,7 +2530,7 @@ int main (int argc, char **argv)
                if (NULL != pamh) {
                        (void) pam_end (pamh, retval);
                }
-               fail_exit (1);
+               fail_exit (1, process_selinux);
        }
        (void) pam_end (pamh, retval);
 #endif                         /* USE_PAM */
@@ -2544,7 +2554,7 @@ int main (int argc, char **argv)
         */
        if (prefix_getpwnam (user_name) != NULL) { /* local, no need for xgetpwnam */
                fprintf (stderr, _("%s: user '%s' already exists\n"), Prog, user_name);
-               fail_exit (E_NAME_IN_USE);
+               fail_exit (E_NAME_IN_USE, process_selinux);
        }
 
        /*
@@ -2559,7 +2569,7 @@ int main (int argc, char **argv)
                        fprintf (stderr,
                                 _("%s: group %s exists - if you want to add this user to that group, use -g.\n"),
                                 Prog, user_name);
-                       fail_exit (E_NAME_IN_USE);
+                       fail_exit (E_NAME_IN_USE, process_selinux);
                }
        }
 
@@ -2572,7 +2582,7 @@ int main (int argc, char **argv)
         * - flush nscd caches for passwd and group services,
         * - then close and update the files.
         */
-       open_files ();
+       open_files (process_selinux);
 
        if (!oflg) {
                /* first, seek for a valid uid to use for this user.
@@ -2581,14 +2591,14 @@ int main (int argc, char **argv)
                if (!uflg) {
                        if (find_new_uid (rflg, &user_id, NULL) < 0) {
                                fprintf (stderr, _("%s: can't create user\n"), Prog);
-                               fail_exit (E_UID_IN_USE);
+                               fail_exit (E_UID_IN_USE, process_selinux);
                        }
                } else {
                        if (prefix_getpwuid (user_id) != NULL) {
                                fprintf (stderr,
                                         _("%s: UID %lu is not unique\n"),
                                         Prog, (unsigned long) user_id);
-                               fail_exit (E_UID_IN_USE);
+                               fail_exit (E_UID_IN_USE, process_selinux);
                        }
                }
        }
@@ -2601,11 +2611,11 @@ int main (int argc, char **argv)
                        fprintf (stderr,
                                 _("%s: Failed to create tcb directory for %s\n"),
                                 Prog, user_name);
-                       fail_exit (E_UID_IN_USE);
+                       fail_exit (E_UID_IN_USE, process_selinux);
                }
        }
 #endif
-       open_shadow ();
+       open_shadow (process_selinux);
 
        /* do we have to add a group for that user? This is why we need to
         * open the group files in the open_files() function  --gafton */
@@ -2614,9 +2624,9 @@ int main (int argc, char **argv)
                        fprintf (stderr,
                                 _("%s: can't create group\n"),
                                 Prog);
-                       fail_exit (4);
+                       fail_exit (4, process_selinux);
                }
-               grp_add ();
+               grp_add (process_selinux);
        }
 
 #ifdef ENABLE_SUBIDS
@@ -2625,7 +2635,7 @@ int main (int argc, char **argv)
                        fprintf (stderr,
                                 _("%s: can't create subordinate user IDs\n"),
                                 Prog);
-                       fail_exit(E_SUB_UID_UPDATE);
+                       fail_exit(E_SUB_UID_UPDATE, process_selinux);
                }
        }
        if (is_sub_gid && subgid_count != 0) {
@@ -2633,12 +2643,12 @@ int main (int argc, char **argv)
                        fprintf (stderr,
                                 _("%s: can't create subordinate group IDs\n"),
                                 Prog);
-                       fail_exit(E_SUB_GID_UPDATE);
+                       fail_exit(E_SUB_GID_UPDATE, process_selinux);
                }
        }
 #endif                         /* ENABLE_SUBIDS */
 
-       usr_update (subuid_count, subgid_count);
+       usr_update (subuid_count, subgid_count, &flags);
 
        close_files (&flags);
 
@@ -2666,7 +2676,7 @@ int main (int argc, char **argv)
                                      "add-selinux-user-mapping",
                                      user_name, user_id, SHADOW_AUDIT_FAILURE);
 #endif                         /* WITH_AUDIT */
-                       fail_exit (E_SE_UPDATE);
+                       fail_exit (E_SE_UPDATE, process_selinux);
                }
        }
 #endif                         /* WITH_SELINUX */