]> granicus.if.org Git - shadow/commitdiff
* src/usermod.c: Split update_files() into update_lastlog() and
authornekral-guest <nekral-guest@5a98b0ae-9ef6-0310-add3-de5d479b70d7>
Fri, 11 Jul 2008 20:52:44 +0000 (20:52 +0000)
committernekral-guest <nekral-guest@5a98b0ae-9ef6-0310-add3-de5d479b70d7>
Fri, 11 Jul 2008 20:52:44 +0000 (20:52 +0000)
update_faillog(). Report errors (but don't fail) if the file
exist, but open(), lseek(), read(), write(), or close() fails.
* src/usermod.c: Add brackets and parenthesis.
* src/usermod.c: Ignore the return value of pam_end() before
exiting.
* src/usermod.c: Ignore the return value of strftime(),
snprintf(), and puts().
* src/usermod.c: Check the return value of gmtime() and asctime(),
and output the raw time_t on failures.

ChangeLog
src/usermod.c

index a5f2272e72d1fbb1372a6253fa16334b40c1baf6..6a728a01390a541d6e606c2536da46f903b93a64 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2008-07-11  Nicolas François  <nicolas.francois@centraliens.net>
+
+       * src/usermod.c: Split update_files() into update_lastlog() and
+       update_faillog(). Report errors (but don't fail) if the file
+       exist, but open(), lseek(), read(), write(), or close() fails.
+       * src/usermod.c: Add brackets and parenthesis.
+       * src/usermod.c: Ignore the return value of pam_end() before
+       exiting.
+       * src/usermod.c: Ignore the return value of strftime(),
+       snprintf(), and puts().
+       * src/usermod.c: Check the return value of gmtime() and asctime(),
+       and output the raw time_t on failures.
+
 2008-07-11  Nicolas François  <nicolas.francois@centraliens.net>
 
        * libmisc/setugid.c: Add brackets.
index 7170d8938a4bfec8628e14e43cb86920592ad242..17bb35bdbcc93a56548b86ecd18d3d9365f5dda4 100644 (file)
@@ -158,7 +158,8 @@ static void close_files (void);
 static void open_files (void);
 static void usr_update (void);
 static void move_home (void);
-static void update_files (void);
+static void update_lastlog (void);
+static void update_faillog (void);
 
 #ifndef NO_MOVE_MAILBOX
 static void move_mailbox (void);
@@ -611,8 +612,9 @@ static void update_group (void)
                        SYSLOG ((LOG_INFO, "add `%s' to group `%s'",
                                 user_newname, ngrp->gr_name));
                }
-               if (!changed)
+               if (!changed) {
                        continue;
+               }
 
                changed = false;
                if (gr_update (ngrp) == 0) {
@@ -1040,8 +1042,9 @@ static void process_flags (int argc, char **argv)
                exit (E_USAGE);
        }
 
-       if (optind != argc - 1)
+       if (optind != argc - 1) {
                usage ();
+       }
 
        if (aflg && (!Gflg)) {
                fprintf (stderr,
@@ -1296,8 +1299,9 @@ static void move_home (void)
                 * Don't try to move it if it is not a directory
                 * (but /dev/null for example).  --marekm
                 */
-               if (!S_ISDIR (sb.st_mode))
+               if (!S_ISDIR (sb.st_mode)) {
                        return;
+               }
 
                if (access (user_newhome, F_OK) == 0) {
                        fprintf (stderr, _("%s: directory %s exists\n"),
@@ -1367,40 +1371,120 @@ static void move_home (void)
 }
 
 /*
- * update_files - update the lastlog and faillog files
+ * update_lastlog - update the lastlog file
+ *
+ * Relocate the "lastlog" entries for the user. The old entry is
+ * left alone in case the UID was shared. It doesn't hurt anything
+ * to just leave it be.
  */
-static void update_files (void)
+static void update_lastlog (void)
 {
        struct lastlog ll;
-       struct faillog fl;
        int fd;
+       off_t off_uid = (off_t) user_id * sizeof ll;
+       off_t off_newuid = (off_t) user_newid * sizeof ll;
+
+       if (access (LASTLOG_FILE, F_OK) != 0) {
+               return;
+       }
 
-       /*
-        * Relocate the "lastlog" entries for the user. The old entry is
-        * left alone in case the UID was shared. It doesn't hurt anything
-        * to just leave it be.
-        */
        fd = open (LASTLOG_FILE, O_RDWR);
-       if (-1 != fd) {
-               lseek (fd, (off_t) user_id * sizeof ll, SEEK_SET);
-               if (read (fd, (char *) &ll, sizeof ll) == (ssize_t) sizeof ll) {
-                       lseek (fd, (off_t) user_newid * sizeof ll, SEEK_SET);
-                       write (fd, (char *) &ll, sizeof ll);
+
+       if (-1 == fd) {
+               fprintf (stderr,
+                        _("%s: failed to copy the lastlog entry of user %lu to user %lu: %s\n"),
+                        Prog, (unsigned long) user_id, (unsigned long) user_newid, strerror (errno));
+               return;
+       }
+
+       if (   (lseek (fd, off_uid, SEEK_SET) == off_uid)
+           && (read (fd, &ll, sizeof ll) == (ssize_t) sizeof ll)) {
+               /* Copy the old entry to its new location */
+               if (   (lseek (fd, off_newuid, SEEK_SET) != off_newuid)
+                   || (write (fd, &ll, sizeof ll) != (ssize_t) sizeof ll)
+                   || (close (fd) != 0)) {
+                       fprintf (stderr,
+                                _("%s: failed to copy the lastlog entry of user %lu to user %lu: %s\n"),
+                                Prog, (unsigned long) user_id, (unsigned long) user_newid, strerror (errno));
                }
-               close (fd);
+       } else {
+               /* Assume lseek or read failed because there is
+                * no entry for the old UID */
+
+               /* Check if the new UID already has an entry */
+               if (   (lseek (fd, off_newuid, SEEK_SET) == off_newuid)
+                   && (read (fd, &ll, sizeof ll) == (ssize_t) sizeof ll)) {
+                       /* Reset the new uid's lastlog entry */
+                       memzero (&ll, sizeof (ll));
+                       if (   (lseek (fd, off_newuid, SEEK_SET) != off_newuid)
+                           || (write (fd, &ll, sizeof ll) != (ssize_t) sizeof ll)
+                           || (close (fd) != 0)) {
+                               fprintf (stderr,
+                                        _("%s: failed to copy the lastlog entry of user %lu to user %lu: %s\n"),
+                                        Prog, (unsigned long) user_id, (unsigned long) user_newid, strerror (errno));
+                       }
+               } else {
+                       (void) close (fd);
+               }
+       }
+}
+
+/*
+ * update_faillog - update the faillog file
+ *
+ * Relocate the "faillog" entries for the user. The old entry is
+ * left alone in case the UID was shared. It doesn't hurt anything
+ * to just leave it be.
+ */
+static void update_faillog (void)
+{
+       struct faillog fl;
+       int fd;
+       off_t off_uid = (off_t) user_id * sizeof fl;
+       off_t off_newuid = (off_t) user_newid * sizeof fl;
+
+       if (access (FAILLOG_FILE, F_OK) != 0) {
+               return;
        }
 
-       /*
-        * Relocate the "faillog" entries in the same manner.
-        */
        fd = open (FAILLOG_FILE, O_RDWR);
-       if (-1 != fd) {
-               lseek (fd, (off_t) user_id * sizeof fl, SEEK_SET);
-               if (read (fd, (char *) &fl, sizeof fl) == (ssize_t) sizeof fl) {
-                       lseek (fd, (off_t) user_newid * sizeof fl, SEEK_SET);
-                       write (fd, (char *) &fl, sizeof fl);
+
+       if (-1 == fd) {
+               fprintf (stderr,
+                        _("%s: failed to copy the faillog entry of user %lu to user %lu: %s\n"),
+                        Prog, (unsigned long) user_id, (unsigned long) user_newid, strerror (errno));
+               return;
+       }
+
+       if (   (lseek (fd, off_uid, SEEK_SET) == off_uid)
+           && (read (fd, (char *) &fl, sizeof fl) == (ssize_t) sizeof fl)) {
+               /* Copy the old entry to its new location */
+               if (   (lseek (fd, off_newuid, SEEK_SET) != off_newuid)
+                   || (write (fd, &fl, sizeof fl) != (ssize_t) sizeof fl)
+                   || (close (fd) != 0)) {
+                       fprintf (stderr,
+                                _("%s: failed to copy the faillog entry of user %lu to user %lu: %s\n"),
+                                Prog, (unsigned long) user_id, (unsigned long) user_newid, strerror (errno));
+               }
+       } else {
+               /* Assume lseek or read failed because there is
+                * no entry for the old UID */
+
+               /* Check if the new UID already has an entry */
+               if (   (lseek (fd, off_newuid, SEEK_SET) == off_newuid)
+                   && (read (fd, &fl, sizeof fl) == (ssize_t) sizeof fl)) {
+                       /* Reset the new uid's lastlog entry */
+                       memzero (&fl, sizeof (fl));
+                       if (   (lseek (fd, off_newuid, SEEK_SET) != off_newuid)
+                           || (write (fd, &fl, sizeof fl) != (ssize_t) sizeof fl)
+                           || (close (fd) != 0)) {
+                               fprintf (stderr,
+                                        _("%s: failed to copy the faillog entry of user %lu to user %lu: %s\n"),
+                                        Prog, (unsigned long) user_id, (unsigned long) user_newid, strerror (errno));
+                       }
+               } else {
+                       (void) close (fd);
                }
-               close (fd);
        }
 }
 
@@ -1585,7 +1669,8 @@ int main (int argc, char **argv)
 #endif
 
        if (uflg) {
-               update_files ();
+               update_lastlog ();
+               update_faillog ();
 
                /*
                 * Change the UID on all of the files owned by `user_id' to