]> granicus.if.org Git - shadow/commitdiff
* NEWS, src/userdel.c: Report errors to remove the user's mailbox.
authornekral-guest <nekral-guest@5a98b0ae-9ef6-0310-add3-de5d479b70d7>
Fri, 22 May 2009 10:41:10 +0000 (10:41 +0000)
committernekral-guest <nekral-guest@5a98b0ae-9ef6-0310-add3-de5d479b70d7>
Fri, 22 May 2009 10:41:10 +0000 (10:41 +0000)
* NEWS, src/userdel.c: When USERGROUPS_ENAB is enabled, remove the
user's group when the user was the only member. This is still not
complete, as the user could have been specified twice in the
members.
* NEWS, src/userdel.c: Do not fail when -r is used and the home
directory does not exist.

ChangeLog
NEWS
src/userdel.c

index 491f6dfedbd7f8270a0a0e35860dad522ff72f71..93534fadc2daa5cf8283f64ad4890d3bd34087d1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,14 @@
-2009-05-21  Nicolas François  <nicolas.francois@centraliens.net>
+2009-05-22  Nicolas François  <nicolas.francois@centraliens.net>
+
+       * NEWS, src/userdel.c: Report errors to remove the user's mailbox.
+       * NEWS, src/userdel.c: When USERGROUPS_ENAB is enabled, remove the
+       user's group when the user was the only member. This is still not
+       complete, as the user could have been specified twice in the
+       members.
+       * NEWS, src/userdel.c: Do not fail when -r is used and the home
+       directory does not exist.
+
+2009-05-22  Nicolas François  <nicolas.francois@centraliens.net>
 
        * libmisc/copydir.c: Added warning for relative symlinks.
        * libmisc/copydir.c (remove_tree): There is no need to check if
diff --git a/NEWS b/NEWS
index f6c74220f8376677d493f6d3bfa69aac4c2df83f..76d4bae9ec95432d9e76eb7d13140f5b3286c664 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,10 @@ shadow-4.1.4 -> shadow-4.1.4.1                                               UNRELEASED
     the user is running some processes.
   * If not on Linux, continue to search for an utmp record, but make sure
     the process recorded in the utmp entry is still running.
+  * Report failures to remove the user's mailbox
+  * When USERGROUPS_ENAB is enabled, remove the user's group when the
+    user was the only member.
+  * Do not fail when -r is used and the home directory does not exist.
 - usermod
   * Check if the user is busy when the user's UID, name or home directory
     is changed.
index 7752fc74de00a6a631741c9b168627fce677bd2d..bfa91292fcb95c6651c41d52c9d1a7dee814fbd0 100644 (file)
@@ -106,7 +106,7 @@ static void user_cancel (const char *);
 static bool path_prefix (const char *, const char *);
 #endif
 static int is_owner (uid_t, const char *);
-static void remove_mailbox (void);
+static int remove_mailbox (void);
 
 /*
  * usage - display usage message and exit
@@ -196,11 +196,16 @@ static void update_groups (void)
         * we've removed their name from all the groups above, so
         * now if they have a group with the same name as their
         * user name, with no members, we delete it.
+        * FIXME: below, the check for grp->gr_mem[0] is not sufficient.
+        *        We should retrieve the group with gr_locate and check
+        *        that gr_mem is empty.
         */
        grp = xgetgrnam (user_name);
        if (   (NULL != grp)
            && getdef_bool ("USERGROUPS_ENAB")
-           && (NULL == grp->gr_mem[0])) {
+           && (   (NULL == grp->gr_mem[0])
+               || (   (NULL == grp->gr_mem[1])
+                   && (strcmp (grp->gr_mem[0], user_name) == 0)))) {
 
                pwd = NULL;
                if (!fflg) {
@@ -615,21 +620,36 @@ static bool path_prefix (const char *s1, const char *s2)
 }
 #endif
 
+/*
+ * is_owner - Check if path is owned by uid
+ *
+ * Return
+ *  1: path exists and is owned by uid
+ *  0: path is not owned by uid, or a failure occured
+ * -1: path does not exist
+ */
 static int is_owner (uid_t uid, const char *path)
 {
        struct stat st;
 
+       errno = 0;
        if (stat (path, &st) != 0) {
-               return -1;
+               if ((ENOENT == errno) || (ENOTDIR == errno)) {
+                       /* The file or directory does not exist */
+                       return -1;
+               } else {
+                       return 0;
+               }
        }
        return (st.st_uid == uid);
 }
 
-static void remove_mailbox (void)
+static int remove_mailbox (void)
 {
        const char *maildir;
        char mailfile[1024];
        int i;
+       int errors = 0;
 
        maildir = getdef_str ("MAIL_DIR");
 #ifdef MAIL_SPOOL_DIR
@@ -638,12 +658,14 @@ static void remove_mailbox (void)
        }
 #endif
        if (NULL == maildir) {
-               return;
+               return 0;
        }
        snprintf (mailfile, sizeof mailfile, "%s/%s", maildir, user_name);
        if (fflg) {
                if (unlink (mailfile) != 0) {
-                       fprintf (stderr, _("%s: warning: can't remove %s: %s"), Prog, mailfile, strerror (errno));
+                       fprintf (stderr,
+                                _("%s: warning: can't remove %s: %s\n"),
+                                Prog, mailfile, strerror (errno));
                        SYSLOG ((LOG_ERR, "Cannot remove %s: %s", mailfile, strerror (errno)));
 #ifdef WITH_AUDIT
                        audit_logger (AUDIT_DEL_USER, Prog,
@@ -651,6 +673,7 @@ static void remove_mailbox (void)
                                      user_name, (unsigned int) user_id,
                                      SHADOW_AUDIT_FAILURE);
 #endif
+                       errors = 1;
                        /* continue */
                }
 #ifdef WITH_AUDIT
@@ -662,26 +685,30 @@ static void remove_mailbox (void)
                                      SHADOW_AUDIT_SUCCESS);
                }
 #endif
-               return;
+               return errors;
        }
        i = is_owner (user_id, mailfile);
        if (i == 0) {
                fprintf (stderr,
                         _("%s: %s not owned by %s, not removing\n"),
                         Prog, mailfile, user_name);
-               SYSLOG ((LOG_ERR, "%s not owned by %s, not removed", mailfile, strerror (errno)));
+               SYSLOG ((LOG_ERR,
+                        "%s not owned by %s, not removed",
+                        mailfile, strerror (errno)));
 #ifdef WITH_AUDIT
                audit_logger (AUDIT_DEL_USER, Prog,
                              "deleting mail file",
                              user_name, (unsigned int) user_id,
                              SHADOW_AUDIT_FAILURE);
 #endif
-               return;
+               return 1;
        } else if (i == -1) {
-               return;         /* mailbox doesn't exist */
+               return 0;               /* mailbox doesn't exist */
        }
        if (unlink (mailfile) != 0) {
-               fprintf (stderr, _("%s: warning: can't remove %s: %s"), Prog, mailfile, strerror (errno));
+               fprintf (stderr,
+                        _("%s: warning: can't remove %s: %s\n"),
+                        Prog, mailfile, strerror (errno));
                SYSLOG ((LOG_ERR, "Cannot remove %s: %s", mailfile, strerror (errno)));
 #ifdef WITH_AUDIT
                audit_logger (AUDIT_DEL_USER, Prog,
@@ -689,6 +716,7 @@ static void remove_mailbox (void)
                              user_name, (unsigned int) user_id,
                              SHADOW_AUDIT_FAILURE);
 #endif
+               errors = 1;
                /* continue */
        }
 #ifdef WITH_AUDIT
@@ -700,6 +728,7 @@ static void remove_mailbox (void)
                              SHADOW_AUDIT_SUCCESS);
        }
 #endif
+       return errors;
 }
 
 /*
@@ -868,15 +897,23 @@ int main (int argc, char **argv)
        update_groups ();
 
        if (rflg) {
-               remove_mailbox ();
+               errors += remove_mailbox ();
        }
-       if (rflg && !fflg && (is_owner (user_id, user_home) == 0)) {
-               fprintf (stderr,
-                        _("%s: %s not owned by %s, not removing\n"),
-                        Prog, user_home, user_name);
-               rflg = 0;
-               errors++;
-               /* continue */
+       if (rflg) {
+               int home_owned = is_owner (user_id, user_home);
+               if (-1 == home_owned) {
+                       fprintf (stderr,
+                                _("%s: %s home directory (%s) not found\n"),
+                                Prog, user_name, user_home);
+                       rflg = 0;
+               } else if ((0 == home_owned) && !fflg) {
+                       fprintf (stderr,
+                                _("%s: %s not owned by %s, not removing\n"),
+                                Prog, user_home, user_name);
+                       rflg = 0;
+                       errors++;
+                       /* continue */
+               }
        }
 
 #ifdef EXTRA_CHECK_HOME_DIR