]> granicus.if.org Git - shadow/commitdiff
userdel: Add support for removing subordinate user and group ids.
authorEric W. Biederman <ebiederm@xmission.com>
Tue, 22 Jan 2013 09:16:51 +0000 (01:16 -0800)
committerSerge Hallyn <serge.hallyn@ubuntu.com>
Mon, 5 Aug 2013 15:08:45 +0000 (10:08 -0500)
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
src/userdel.c

index addb8c690794b7c635a0a138bb2e05fea7cfc0bd..3e4ca46683b7285390a8748ddaa4c5cc0c5705a2 100644 (file)
@@ -65,6 +65,7 @@
 #endif                         /* WITH_TCB */
 /*@-exitarg@*/
 #include "exitcodes.h"
+#include "subordinateio.h"
 
 /*
  * exit status values
@@ -75,6 +76,8 @@
 #define E_GRP_UPDATE   10      /* can't update group file */
 #define E_HOMEDIR      12      /* can't remove home directory */
 #define E_SE_UPDATE    14      /* can't update SELinux user mapping */
+#define E_SUB_UID_UPDATE 16    /* can't update the subordinate uid file */
+#define E_SUB_GID_UPDATE 18    /* can't update the subordinate gid file */
 
 /*
  * Global variables
@@ -96,9 +99,13 @@ static bool is_shadow_pwd;
 static bool is_shadow_grp;
 static bool sgr_locked = false;
 #endif                         /* SHADOWGRP */
+static bool is_sub_uid;
+static bool is_sub_gid;
 static bool pw_locked  = false;
 static bool gr_locked   = false;
 static bool spw_locked  = false;
+static bool sub_uid_locked = false;
+static bool sub_gid_locked = false;
 
 /* local function prototypes */
 static void usage (int status);
@@ -437,6 +444,34 @@ static void close_files (void)
                sgr_locked = false;
        }
 #endif                         /* SHADOWGRP */
+
+       if (is_sub_uid) {
+               if (sub_uid_close () == 0) {
+                       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);
+               }
+               if (sub_uid_unlock () == 0) {
+                       fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ());
+                       SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ()));
+                       /* continue */
+               }
+               sub_uid_locked = false;
+       }
+
+       if (is_sub_gid) {
+               if (sub_gid_close () == 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);
+               }
+               if (sub_gid_unlock () == 0) {
+                       fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ());
+                       SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ()));
+                       /* continue */
+               }
+               sub_gid_locked = false;
+       }
 }
 
 /*
@@ -474,6 +509,20 @@ static void fail_exit (int code)
                }
        }
 #endif                         /* SHADOWGRP */
+       if (sub_uid_locked) {
+               if (sub_uid_unlock () == 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) {
+               if (sub_gid_unlock () == 0) {
+                       fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ());
+                       SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ()));
+                       /* continue */
+               }
+       }
 
 #ifdef WITH_AUDIT
        audit_logger (AUDIT_DEL_USER, Prog,
@@ -595,6 +644,58 @@ static void open_files (void)
                }
        }
 #endif                         /* SHADOWGRP */
+       if (is_sub_uid) {
+               if (sub_uid_lock () == 0) {
+                       fprintf (stderr,
+                               _("%s: cannot lock %s; try again later.\n"),
+                               Prog, sub_uid_dbname ());
+#ifdef WITH_AUDIT
+                       audit_logger (AUDIT_DEL_USER, Prog,
+                               "locking subordinate user file",
+                               user_name, (unsigned int) user_id,
+                               SHADOW_AUDIT_FAILURE);
+#endif                         /* WITH_AUDIT */
+                       fail_exit (E_SUB_UID_UPDATE);
+               }
+               sub_uid_locked = true;
+               if (sub_uid_open (O_RDWR) == 0) {
+                       fprintf (stderr,
+                               _("%s: cannot open %s\n"), Prog, sub_uid_dbname ());
+#ifdef WITH_AUDIT
+                       audit_logger (AUDIT_DEL_USER, Prog,
+                               "opening subordinate user file",
+                               user_name, (unsigned int) user_id,
+                               SHADOW_AUDIT_FAILURE);
+#endif                         /* WITH_AUDIT */
+                       fail_exit (E_SUB_UID_UPDATE);
+               }
+       }
+       if (is_sub_gid) {
+               if (sub_gid_lock () == 0) {
+                       fprintf (stderr,
+                               _("%s: cannot lock %s; try again later.\n"),
+                               Prog, sub_gid_dbname ());
+#ifdef WITH_AUDIT
+                       audit_logger (AUDIT_DEL_USER, Prog,
+                               "locking subordinate group file",
+                               user_name, (unsigned int) user_id,
+                               SHADOW_AUDIT_FAILURE);
+#endif                         /* WITH_AUDIT */
+                       fail_exit (E_SUB_GID_UPDATE);
+               }
+               sub_gid_locked = true;
+               if (sub_gid_open (O_RDWR) == 0) {
+                       fprintf (stderr,
+                               _("%s: cannot open %s\n"), Prog, sub_gid_dbname ());
+#ifdef WITH_AUDIT
+                       audit_logger (AUDIT_DEL_USER, Prog,
+                               "opening subordinate group file",
+                               user_name, (unsigned int) user_id,
+                               SHADOW_AUDIT_FAILURE);
+#endif                         /* WITH_AUDIT */
+                       fail_exit (E_SUB_GID_UPDATE);
+               }
+       }
 }
 
 /*
@@ -619,6 +720,18 @@ static void update_user (void)
                         Prog, user_name, spw_dbname ());
                fail_exit (E_PW_UPDATE);
        }
+       if (is_sub_uid && sub_uid_remove(user_name, 0, ULONG_MAX) == 0) {
+               fprintf (stderr,
+                       _("%s: cannot remove entry %lu from %s\n"),
+                       Prog, (unsigned long)user_id, sub_uid_dbname ());
+               fail_exit (E_SUB_UID_UPDATE);
+       }
+       if (is_sub_gid && sub_gid_remove(user_name, 0, ULONG_MAX) == 0) {
+               fprintf (stderr,
+                       _("%s: cannot remove entry %lu from %s\n"),
+                       Prog, (unsigned long)user_id, sub_gid_dbname ());
+               fail_exit (E_SUB_GID_UPDATE);
+       }
 #ifdef WITH_AUDIT
        audit_logger (AUDIT_DEL_USER, Prog,
                      "deleting user entries",
@@ -966,6 +1079,8 @@ int main (int argc, char **argv)
 #ifdef SHADOWGRP
        is_shadow_grp = sgr_file_present ();
 #endif                         /* SHADOWGRP */
+       is_sub_uid = sub_uid_file_present ();
+       is_sub_gid = sub_gid_file_present ();
 
        /*
         * Start with a quick check to see if the user exists.