]> granicus.if.org Git - shadow/commitdiff
* man/faillog.8.xml: Document the behavior in display mode of the
authornekral-guest <nekral-guest@5a98b0ae-9ef6-0310-add3-de5d479b70d7>
Tue, 16 Mar 2010 19:15:22 +0000 (19:15 +0000)
committernekral-guest <nekral-guest@5a98b0ae-9ef6-0310-add3-de5d479b70d7>
Tue, 16 Mar 2010 19:15:22 +0000 (19:15 +0000)
-a option.
* NEWS, man/faillog.8.xml, src/faillog.c: Extend the -a option to
the non-display mode. This changes the default behavior of the -l,
-m, -r, -t options when -a is not specified (restrict to existing
users).

ChangeLog
NEWS
man/faillog.8.xml
src/faillog.c

index 3a5102b8df31c06239ef77937384f60eb8500ebf..a8ca2904134c6c5a2d6f35fdb7b2d928bdc4b41c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2010-03-16  Nicolas François  <nicolas.francois@centraliens.net>
+
+       * man/faillog.8.xml: Document the behavior in display mode of the
+       -a option.
+       * NEWS, man/faillog.8.xml, src/faillog.c: Extend the -a option to
+       the non-display mode. This changes the default behavior of the -l,
+       -m, -r, -t options when -a is not specified (restrict to existing
+       users).
+
 2010-03-15  Nicolas François  <nicolas.francois@centraliens.net>
 
        * man/chage.1.xml, man/login.defs.5.xml, man/pwck.8.xml,
diff --git a/NEWS b/NEWS
index 01c1df90745130aa63952a5041fea32605f352d2..965f760a783d6c331edfdde6345cea4f7cf2c5f8 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,9 @@ shadow-4.1.4.2 -> shadow-4.1.4.3                                        UNRELEASED
     zero) when explicitly requested (e.g. with --help).
   * initial support for tcb (http://openwall.com/tcb/).
 
+- faillog
+  * The -l, -m, -r, -t options only act on the existing users, unless -a is
+    specified.
 - groupmod
   * Fixed groupmod when configured with --enable-account-tools-setuid.
 - su
index c1a6b87259080bd93edad45f1fc9d073242dee9b..93255a9e3fcfe1577c911e22170b326ebde1e524 100644 (file)
            Display (or act on) faillog records for all users having an
            entry in the <filename>faillog</filename> database.
          </para>
+         <para>
+           The range of users can be restricted with the
+           <option>-u</option> option.
+         </para>
+         <para>
+           In display mode, this is still restricted to existing users
+           but forces the display of the faillog entries even if they
+           are empty.
+         </para>
+         <para>
+           With the <option>-l</option>, <option>-m</option>,
+           <option>-r</option>, <option>-t</option> options, the users'
+           records are changed, even if the user does not exist on the
+           system. This is useful to reset records of users that have
+           been deleted or to set a policy in advance for a range of
+           users.
+         </para>
        </listitem>
       </varlistentry>
       <varlistentry>
       <option>-r</option> options are used, <command>faillog</command>
       displays the faillog record of the specified user(s).
     </para>
-    <para>
-      NOTE: in display mode, only the records of users which currently
-      exist in the system are displayed.  In the other modes (when the
-      <option>-l</option>, <option>-m</option>, or <option>-r</option>
-      options are used), the records of the user, or the range of users,
-      or all the users that may have an entry in the faillog database will
-      be changed.  This is useful to reset records of users that have been
-      deleted or set a policy in advance for a range of users.
-    </para>
   </refsect1>
 
   <refsect1 id='caveats'>
index 09bdbb7e92541874c619371bf657ea84c15928eb..f4d6c23cf64c143133289eab5c241ce82da85610 100644 (file)
@@ -271,27 +271,54 @@ static void reset (void)
                        errors = true;
                }
        } else {
+               /* There is no need to reset outside of the faillog
+                * database.
+                */
+               uid_t uidmax = statbuf.st_size / sizeof (struct faillog);
+               if (uidmax > 1) {
+                       uidmax--;
+               }
+               if (has_umax && (uid_t)umax < uidmax) {
+                       uidmax = (uid_t)umax;
+               }
+
                /* Reset all entries in the specified range.
                 * Non existing entries will not be touched.
-                * Entries for non existing users are also reset.
                 */
+               if (aflg) {
+                       /* Entries for non existing users are also reset.
+                        */
                uid_t uid = 0;
-               uid_t uidmax = statbuf.st_size / sizeof (struct faillog);
 
                /* Make sure we stay in the umin-umax range if specified */
                if (has_umin) {
                        uid = (uid_t)umin;
                }
-               if (has_umax && (uid_t)umax < uidmax) {
-                       uidmax = (uid_t)umax;
-               }
 
-               while (uid < uidmax) {
+               while (uid <= uidmax) {
                        if (reset_one (uid)) {
                                errors = true;
                        }
                        uid++;
                }
+               } else {
+                       /* Only reset records for existing users.
+                        */
+                       struct passwd *pwent;
+
+                       setpwent ();
+                       while ( (pwent = getpwent ()) != NULL ) {
+                               if (   uflg
+                                   && (   (has_umin && (pwent->pw_uid < (uid_t)umin))
+                                       || (pwent->pw_uid > (uid_t)uidmax))) {
+                                       continue;
+                               }
+                               if (reset_one (pwent->pw_uid)) {
+                                       errors = true;
+                               }
+                       }
+                       endpwent ();
+               }
        }
 }
 
@@ -359,30 +386,56 @@ static void setmax (int max)
                        errors = true;
                }
        } else {
-               /* Set max for all entries in the specified range.
+               /* Set max for entries in the specified range.
                 * If max is unchanged for an entry, the entry is not touched.
                 * If max is null, and no entries exist for this user, no
                 * entries will be created.
-                * Entries for non existing user are also taken into
+                */
+               if (aflg) {
+               /* Entries for non existing user are also taken into
                 * account (in order to define policy for future users).
                 */
                uid_t uid = 0;
+               /* The default umax value is based on the size of the
+                * faillog database.
+                */
                uid_t uidmax = statbuf.st_size / sizeof (struct faillog);
+               if (uidmax > 1) {
+                       uidmax--;
+               }
 
                /* Make sure we stay in the umin-umax range if specified */
                if (has_umin) {
                        uid = (uid_t)umin;
                }
-               if (has_umax && (uid_t)umax < uidmax) {
+               if (has_umax) {
                        uidmax = (uid_t)umax;
                }
 
-               while (uid < uidmax) {
+               while (uid <= uidmax) {
                        if (setmax_one (uid, max)) {
                                errors = true;
                        }
                        uid++;
                }
+               } else {
+                       /* Only change records for existing users.
+                        */
+                       struct passwd *pwent;
+
+                       setpwent ();
+                       while ( (pwent = getpwent ()) != NULL ) {
+                               if (   uflg
+                                   && (   (has_umin && (pwent->pw_uid < (uid_t)umin))
+                                       || (has_umax && (pwent->pw_uid > (uid_t)umax)))) {
+                                       continue;
+                               }
+                               if (setmax_one (pwent->pw_uid, max)) {
+                                       errors = true;
+                               }
+                       }
+                       endpwent ();
+               }
        }
 }
 
@@ -450,30 +503,56 @@ static void set_locktime (long locktime)
                        errors = true;
                }
        } else {
-               /* Set locktime for all entries in the specified range.
+               /* Set locktime for entries in the specified range.
                 * If locktime is unchanged for an entry, the entry is not touched.
                 * If locktime is null, and no entries exist for this user, no
                 * entries will be created.
-                * Entries for non existing user are also taken into
+                */
+               if (aflg) {
+               /* Entries for non existing user are also taken into
                 * account (in order to define policy for future users).
                 */
                uid_t uid = 0;
+               /* The default umax value is based on the size of the
+                * faillog database.
+                */
                uid_t uidmax = statbuf.st_size / sizeof (struct faillog);
+               if (uidmax > 1) {
+                       uidmax--;
+               }
 
                /* Make sure we stay in the umin-umax range if specified */
                if (has_umin) {
                        uid = (uid_t)umin;
                }
-               if (has_umax && (uid_t)umax < uidmax) {
+               if (has_umax) {
                        uidmax = (uid_t)umax;
                }
 
-               while (uid < uidmax) {
+               while (uid <= uidmax) {
                        if (set_locktime_one (uid, locktime)) {
                                errors = true;
                        }
                        uid++;
                }
+               } else {
+                       /* Only change records for existing users.
+                        */
+                       struct passwd *pwent;
+
+                       setpwent ();
+                       while ( (pwent = getpwent ()) != NULL ) {
+                               if (   uflg
+                                   && (   (has_umin && (pwent->pw_uid < (uid_t)umin))
+                                       || (has_umax && (pwent->pw_uid > (uid_t)umax)))) {
+                                       continue;
+                               }
+                               if (set_locktime_one (pwent->pw_uid, locktime)) {
+                                       errors = true;
+                               }
+                       }
+                       endpwent ();
+               }
        }
 }
 
@@ -578,9 +657,6 @@ int main (int argc, char **argv)
                }
        }
 
-       if (aflg && uflg) {
-               usage (E_USAGE);
-       }
        if (tflg && (lflg || mflg || rflg)) {
                usage (E_USAGE);
        }