diff --git a/ChangeLog b/ChangeLog index 3a5102b8..a8ca2904 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-03-16 Nicolas François + + * 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 * man/chage.1.xml, man/login.defs.5.xml, man/pwck.8.xml, diff --git a/NEWS b/NEWS index 01c1df90..965f760a 100644 --- 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 diff --git a/man/faillog.8.xml b/man/faillog.8.xml index c1a6b872..93255a9e 100644 --- a/man/faillog.8.xml +++ b/man/faillog.8.xml @@ -74,6 +74,23 @@ Display (or act on) faillog records for all users having an entry in the faillog database. + + The range of users can be restricted with the + option. + + + In display mode, this is still restricted to existing users + but forces the display of the faillog entries even if they + are empty. + + + With the , , + , 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. + @@ -176,15 +193,6 @@ options are used, faillog displays the faillog record of the specified user(s). - - NOTE: in display mode, only the records of users which currently - exist in the system are displayed. In the other modes (when the - , , or - 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. - diff --git a/src/faillog.c b/src/faillog.c index 09bdbb7e..f4d6c23c 100644 --- a/src/faillog.c +++ b/src/faillog.c @@ -271,27 +271,54 @@ static void reset (void) errors = true; } } else { - /* Reset all entries in the specified range. - * Non existing entries will not be touched. - * Entries for non existing users are also reset. + /* There is no need to reset outside of the faillog + * database. */ - 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 (uidmax > 1) { + uidmax--; } if (has_umax && (uid_t)umax < uidmax) { uidmax = (uid_t)umax; } - while (uid < uidmax) { + /* Reset all entries in the specified range. + * Non existing entries will not be touched. + */ + if (aflg) { + /* Entries for non existing users are also reset. + */ + uid_t uid = 0; + + /* Make sure we stay in the umin-umax range if specified */ + if (has_umin) { + uid = (uid_t)umin; + } + + 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); }