2007-10-07 17:14:02 +05:30
|
|
|
/*
|
2008-04-27 06:10:09 +05:30
|
|
|
* Copyright (c) 1989 - 1993, Julianne Frances Haugh
|
|
|
|
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
|
|
|
|
* Copyright (c) 2002 - 2006, Tomasz Kłoczko
|
2011-07-23 05:29:57 +05:30
|
|
|
* Copyright (c) 2007 - 2011, Nicolas François
|
2007-10-07 17:14:02 +05:30
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
2008-04-27 06:10:09 +05:30
|
|
|
* 3. The name of the copyright holders or contributors may not be used to
|
|
|
|
* endorse or promote products derived from this software without
|
|
|
|
* specific prior written permission.
|
2007-10-07 17:14:02 +05:30
|
|
|
*
|
2008-04-27 06:10:09 +05:30
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
|
|
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
|
|
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
2007-11-11 05:16:11 +05:30
|
|
|
#ident "$Id$"
|
2007-10-07 17:17:01 +05:30
|
|
|
|
2007-10-07 17:16:52 +05:30
|
|
|
#include <getopt.h>
|
2007-10-07 17:14:02 +05:30
|
|
|
#include <pwd.h>
|
2007-10-07 17:16:52 +05:30
|
|
|
#include <stdio.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/types.h>
|
2007-10-07 17:14:02 +05:30
|
|
|
#include <time.h>
|
2009-03-14 04:19:20 +05:30
|
|
|
#include <assert.h>
|
2007-10-07 17:14:02 +05:30
|
|
|
#include "defines.h"
|
|
|
|
#include "faillog.h"
|
2007-10-07 17:16:52 +05:30
|
|
|
#include "prototypes.h"
|
* src/newgrp.c, src/chfn.c, src/groupmems.c, src/usermod.c,
src/userdel.c, src/chpasswd.c, src/grpck.c, src/gpasswd.c,
src/groupdel.c, src/chgpasswd.c, src/vipw.c, src/useradd.c,
src/su.c, src/groupmod.c, src/passwd.c, src/pwck.c,
src/groupadd.c, src/chage.c, src/login.c, src/faillog.c,
src/sulogin.c, src/chsh.c, src/pwconv.c: Added splint annotations.
* src/userdel.c, src/pwconv.c, src/lastlog.c, src/grpck.c,
src/vipw.c, src/groupmod.c, src/passwd.c, src/pwck.c, src/login.c,
src/sulogin.c, src/usermod.c: Use return instead of exit at the
end of main().
* src/gpasswd.c, src/passwd.c, src/faillog.c: Use the exitcodes.h
exit codes.
* src/chpasswd.c: Added missing ||.
* src/nologin.c: Do not include exitcodes.h.
* src/nologin.c: Added brackets.
* src/nologin.c: Avoid assignments in comparisons.
2009-05-01 03:09:38 +05:30
|
|
|
/*@-exitarg@*/
|
|
|
|
#include "exitcodes.h"
|
|
|
|
|
* NEWS, src/userdel.c, src/lastlog.c, src/gpasswd.c,
src/newusers.c, src/chpasswd.c, src/groupmems.c, src/usermod.c,
src/chgpasswd.c, src/vipw.c, src/su.c, src/useradd.c,
src/groupmod.c, src/passwd.c, src/groupadd.c, src/chage.c,
src/faillog.c, src/chsh.c: If someone uses the -h/--help options,
the usage should not go to stderr nor should the utility exit with
non-zero status. All of the shadow utils do just this
unfortunately, so convert them over to sanity.
* man/groupmems.8.xml, man/gpasswd.1.xml: Added option -h/--help.
2009-09-05 04:32:33 +05:30
|
|
|
/* local function prototypes */
|
2011-07-23 05:29:57 +05:30
|
|
|
static /*@noreturn@*/void usage (int status);
|
* NEWS, src/userdel.c, src/lastlog.c, src/gpasswd.c,
src/newusers.c, src/chpasswd.c, src/groupmems.c, src/usermod.c,
src/chgpasswd.c, src/vipw.c, src/su.c, src/useradd.c,
src/groupmod.c, src/passwd.c, src/groupadd.c, src/chage.c,
src/faillog.c, src/chsh.c: If someone uses the -h/--help options,
the usage should not go to stderr nor should the utility exit with
non-zero status. All of the shadow utils do just this
unfortunately, so convert them over to sanity.
* man/groupmems.8.xml, man/gpasswd.1.xml: Added option -h/--help.
2009-09-05 04:32:33 +05:30
|
|
|
static void print_one (/*@null@*/const struct passwd *pw, bool force);
|
|
|
|
static void set_locktime (long locktime);
|
|
|
|
static bool set_locktime_one (uid_t uid, long locktime);
|
2011-11-20 03:14:34 +05:30
|
|
|
static void setmax (short max);
|
|
|
|
static bool setmax_one (uid_t uid, short max);
|
* NEWS, src/userdel.c, src/lastlog.c, src/gpasswd.c,
src/newusers.c, src/chpasswd.c, src/groupmems.c, src/usermod.c,
src/chgpasswd.c, src/vipw.c, src/su.c, src/useradd.c,
src/groupmod.c, src/passwd.c, src/groupadd.c, src/chage.c,
src/faillog.c, src/chsh.c: If someone uses the -h/--help options,
the usage should not go to stderr nor should the utility exit with
non-zero status. All of the shadow utils do just this
unfortunately, so convert them over to sanity.
* man/groupmems.8.xml, man/gpasswd.1.xml: Added option -h/--help.
2009-09-05 04:32:33 +05:30
|
|
|
static void print (void);
|
|
|
|
static bool reset_one (uid_t uid);
|
|
|
|
static void reset (void);
|
|
|
|
|
2007-10-07 17:17:01 +05:30
|
|
|
/*
|
|
|
|
* Global variables
|
|
|
|
*/
|
2011-11-07 00:09:03 +05:30
|
|
|
const char *Prog; /* Program name */
|
2007-10-07 17:14:59 +05:30
|
|
|
static FILE *fail; /* failure file stream */
|
|
|
|
static time_t seconds; /* that number of days in seconds */
|
2009-03-14 04:19:20 +05:30
|
|
|
static unsigned long umin; /* if uflg and has_umin, only display users with uid >= umin */
|
|
|
|
static bool has_umin = false;
|
|
|
|
static unsigned long umax; /* if uflg and has_umax, only display users with uid <= umax */
|
|
|
|
static bool has_umax = false;
|
|
|
|
static bool errors = false;
|
|
|
|
|
|
|
|
static bool aflg = false; /* set if all users are to be printed always */
|
|
|
|
static bool uflg = false; /* set if user is a valid user id */
|
|
|
|
static bool tflg = false; /* print is restricted to most recent days */
|
|
|
|
static bool lflg = false; /* set the locktime */
|
|
|
|
static bool mflg = false; /* set maximum failed login counters */
|
|
|
|
static bool rflg = false; /* reset the counters of login failures */
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
static struct stat statbuf; /* fstat buffer for file size */
|
|
|
|
|
|
|
|
#define NOW (time((time_t *) 0))
|
|
|
|
|
2011-07-23 05:29:57 +05:30
|
|
|
static /*@noreturn@*/void usage (int status)
|
2007-10-07 17:14:02 +05:30
|
|
|
{
|
* src/userdel.c, src/lastlog.c, src/gpasswd.c, src/newusers.c,
src/chpasswd.c, src/groupmems.c, src/usermod.c, src/chgpasswd.c,
src/vipw.c, src/su.c, src/useradd.c, src/groupmod.c, src/passwd.c,
src/groupadd.c, src/chage.c, src/faillog.c, src/chsh.c: Use
booleans for tests.
* src/userdel.c, src/gpasswd.c, src/groupmems.c, src/usermod.c,
src/groupmod.c, src/passwd.c: Use a break even after usage().
2009-09-06 04:01:29 +05:30
|
|
|
FILE *usageout = (E_SUCCESS != status) ? stderr : stdout;
|
* NEWS, src/userdel.c, src/lastlog.c, src/gpasswd.c,
src/newusers.c, src/chpasswd.c, src/groupmems.c, src/usermod.c,
src/chgpasswd.c, src/vipw.c, src/su.c, src/useradd.c,
src/groupmod.c, src/passwd.c, src/groupadd.c, src/chage.c,
src/faillog.c, src/chsh.c: If someone uses the -h/--help options,
the usage should not go to stderr nor should the utility exit with
non-zero status. All of the shadow utils do just this
unfortunately, so convert them over to sanity.
* man/groupmems.8.xml, man/gpasswd.1.xml: Added option -h/--help.
2009-09-05 04:32:33 +05:30
|
|
|
(void) fprintf (usageout,
|
2009-06-06 03:46:56 +05:30
|
|
|
_("Usage: %s [options]\n"
|
|
|
|
"\n"
|
|
|
|
"Options:\n"),
|
2011-11-07 00:09:03 +05:30
|
|
|
Prog);
|
* NEWS, src/userdel.c, src/lastlog.c, src/gpasswd.c,
src/newusers.c, src/chpasswd.c, src/groupmems.c, src/usermod.c,
src/chgpasswd.c, src/vipw.c, src/su.c, src/useradd.c,
src/groupmod.c, src/passwd.c, src/groupadd.c, src/chage.c,
src/faillog.c, src/chsh.c: If someone uses the -h/--help options,
the usage should not go to stderr nor should the utility exit with
non-zero status. All of the shadow utils do just this
unfortunately, so convert them over to sanity.
* man/groupmems.8.xml, man/gpasswd.1.xml: Added option -h/--help.
2009-09-05 04:32:33 +05:30
|
|
|
(void) fputs (_(" -a, --all display faillog records for all users\n"), usageout);
|
|
|
|
(void) fputs (_(" -h, --help display this help message and exit\n"), usageout);
|
2009-10-18 02:10:53 +05:30
|
|
|
(void) fputs (_(" -l, --lock-secs SEC after failed login lock account for SEC seconds\n"), usageout);
|
* NEWS, src/userdel.c, src/lastlog.c, src/gpasswd.c,
src/newusers.c, src/chpasswd.c, src/groupmems.c, src/usermod.c,
src/chgpasswd.c, src/vipw.c, src/su.c, src/useradd.c,
src/groupmod.c, src/passwd.c, src/groupadd.c, src/chage.c,
src/faillog.c, src/chsh.c: If someone uses the -h/--help options,
the usage should not go to stderr nor should the utility exit with
non-zero status. All of the shadow utils do just this
unfortunately, so convert them over to sanity.
* man/groupmems.8.xml, man/gpasswd.1.xml: Added option -h/--help.
2009-09-05 04:32:33 +05:30
|
|
|
(void) fputs (_(" -m, --maximum MAX set maximum failed login counters to MAX\n"), usageout);
|
|
|
|
(void) fputs (_(" -r, --reset reset the counters of login failures\n"), usageout);
|
2011-11-07 00:09:03 +05:30
|
|
|
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
|
* NEWS, src/userdel.c, src/lastlog.c, src/gpasswd.c,
src/newusers.c, src/chpasswd.c, src/groupmems.c, src/usermod.c,
src/chgpasswd.c, src/vipw.c, src/su.c, src/useradd.c,
src/groupmod.c, src/passwd.c, src/groupadd.c, src/chage.c,
src/faillog.c, src/chsh.c: If someone uses the -h/--help options,
the usage should not go to stderr nor should the utility exit with
non-zero status. All of the shadow utils do just this
unfortunately, so convert them over to sanity.
* man/groupmems.8.xml, man/gpasswd.1.xml: Added option -h/--help.
2009-09-05 04:32:33 +05:30
|
|
|
(void) fputs (_(" -t, --time DAYS display faillog records more recent than DAYS\n"), usageout);
|
2009-06-06 03:46:56 +05:30
|
|
|
(void) fputs (_(" -u, --user LOGIN/RANGE display faillog record or maintains failure\n"
|
|
|
|
" counters and limits (if used with -r, -m,\n"
|
* NEWS, src/userdel.c, src/lastlog.c, src/gpasswd.c,
src/newusers.c, src/chpasswd.c, src/groupmems.c, src/usermod.c,
src/chgpasswd.c, src/vipw.c, src/su.c, src/useradd.c,
src/groupmod.c, src/passwd.c, src/groupadd.c, src/chage.c,
src/faillog.c, src/chsh.c: If someone uses the -h/--help options,
the usage should not go to stderr nor should the utility exit with
non-zero status. All of the shadow utils do just this
unfortunately, so convert them over to sanity.
* man/groupmems.8.xml, man/gpasswd.1.xml: Added option -h/--help.
2009-09-05 04:32:33 +05:30
|
|
|
" or -l) only for the specified LOGIN(s)\n"), usageout);
|
|
|
|
(void) fputs ("\n", usageout);
|
|
|
|
exit (status);
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
|
2009-04-23 16:53:53 +05:30
|
|
|
static void print_one (/*@null@*/const struct passwd *pw, bool force)
|
2007-10-07 17:14:02 +05:30
|
|
|
{
|
2008-06-11 00:46:02 +05:30
|
|
|
static bool once = false;
|
2007-10-07 17:14:59 +05:30
|
|
|
struct tm *tm;
|
2009-03-14 04:19:20 +05:30
|
|
|
off_t offset;
|
|
|
|
struct faillog fl;
|
2007-10-07 17:14:02 +05:30
|
|
|
time_t now;
|
2007-10-07 17:14:59 +05:30
|
|
|
|
2007-10-07 17:14:02 +05:30
|
|
|
#ifdef HAVE_STRFTIME
|
2009-03-14 04:19:20 +05:30
|
|
|
char *cp;
|
2007-10-07 17:14:02 +05:30
|
|
|
char ptime[80];
|
|
|
|
#endif
|
|
|
|
|
2009-03-14 04:19:20 +05:30
|
|
|
if (NULL == pw) {
|
|
|
|
return;
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
2009-03-14 04:19:20 +05:30
|
|
|
|
2011-06-03 01:56:30 +05:30
|
|
|
offset = (off_t) pw->pw_uid * sizeof (fl);
|
|
|
|
if (offset + sizeof (fl) <= statbuf.st_size) {
|
2009-03-14 04:19:20 +05:30
|
|
|
/* fseeko errors are not really relevant for us. */
|
2009-04-25 03:57:09 +05:30
|
|
|
int err = fseeko (fail, offset, SEEK_SET);
|
|
|
|
assert (0 == err);
|
2009-03-14 04:19:20 +05:30
|
|
|
/* faillog is a sparse file. Even if no entries were
|
|
|
|
* entered for this user, which should be able to get the
|
|
|
|
* empty entry in this case.
|
|
|
|
*/
|
|
|
|
if (fread ((char *) &fl, sizeof (fl), 1, fail) != 1) {
|
|
|
|
fprintf (stderr,
|
2011-11-07 00:09:03 +05:30
|
|
|
_("%s: Failed to get the entry for UID %lu\n"),
|
|
|
|
Prog, (unsigned long int)pw->pw_uid);
|
2009-03-14 04:19:20 +05:30
|
|
|
return;
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
2009-03-14 04:19:20 +05:30
|
|
|
} else {
|
|
|
|
/* Outsize of the faillog file.
|
|
|
|
* Behave as if there were a missing entry (same behavior
|
|
|
|
* as if we were reading an non existing entry in the
|
|
|
|
* sparse faillog file).
|
|
|
|
*/
|
|
|
|
memzero (&fl, sizeof (fl));
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
|
2009-03-14 04:19:20 +05:30
|
|
|
/* Nothing to report */
|
|
|
|
if (!force && (0 == fl.fail_time)) {
|
|
|
|
return;
|
2008-06-11 00:46:02 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2009-03-14 04:19:20 +05:30
|
|
|
(void) time(&now);
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2009-03-14 04:19:20 +05:30
|
|
|
/* Filter out entries that do not match with the -t option */
|
|
|
|
if (tflg && ((now - fl.fail_time) > seconds)) {
|
|
|
|
return;
|
2008-06-11 00:46:02 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2009-03-14 04:19:20 +05:30
|
|
|
/* Print the header only once */
|
|
|
|
if (!once) {
|
|
|
|
puts (_("Login Failures Maximum Latest On\n"));
|
|
|
|
once = true;
|
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2009-03-14 04:19:20 +05:30
|
|
|
tm = localtime (&fl.fail_time);
|
|
|
|
#ifdef HAVE_STRFTIME
|
|
|
|
strftime (ptime, sizeof (ptime), "%D %H:%M:%S %z", tm);
|
|
|
|
cp = ptime;
|
|
|
|
#endif
|
|
|
|
printf ("%-9s %5d %5d ",
|
|
|
|
pw->pw_name, fl.fail_cnt, fl.fail_max);
|
|
|
|
/* FIXME: cp is not defined ifndef HAVE_STRFTIME */
|
|
|
|
printf ("%s %s", cp, fl.fail_line);
|
|
|
|
if (0 != fl.fail_locktime) {
|
|
|
|
if ( ((fl.fail_time + fl.fail_locktime) > now)
|
|
|
|
&& (0 != fl.fail_cnt)) {
|
|
|
|
printf (_(" [%lus left]"),
|
|
|
|
(unsigned long) fl.fail_time + fl.fail_locktime - now);
|
|
|
|
} else {
|
|
|
|
printf (_(" [%lds lock]"),
|
|
|
|
fl.fail_locktime);
|
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
2009-03-14 04:19:20 +05:30
|
|
|
putchar ('\n');
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
|
2009-03-14 04:19:20 +05:30
|
|
|
static void print (void)
|
2007-10-07 17:14:02 +05:30
|
|
|
{
|
2009-03-14 04:19:20 +05:30
|
|
|
if (uflg && has_umin && has_umax && (umin==umax)) {
|
|
|
|
print_one (getpwuid ((uid_t)umin), true);
|
2008-08-31 00:03:37 +05:30
|
|
|
} else {
|
2009-03-14 04:19:20 +05:30
|
|
|
/* We only print records for existing users.
|
|
|
|
* Loop based on the user database instead of reading the
|
|
|
|
* whole file. We will have to query the database anyway
|
|
|
|
* so except for very small ranges and large user
|
|
|
|
* database, this should not be a performance issue.
|
|
|
|
*/
|
2008-03-05 05:40:25 +05:30
|
|
|
struct passwd *pwent;
|
|
|
|
|
|
|
|
setpwent ();
|
2008-03-18 04:35:59 +05:30
|
|
|
while ( (pwent = getpwent ()) != NULL ) {
|
2009-03-14 04:19:20 +05:30
|
|
|
if ( uflg
|
|
|
|
&& ( (has_umin && (pwent->pw_uid < (uid_t)umin))
|
|
|
|
|| (has_umax && (pwent->pw_uid > (uid_t)umax)))) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
print_one (pwent, aflg);
|
2008-03-05 05:40:25 +05:30
|
|
|
}
|
Ensure that getpwent() is used in setpwent(), getpwent(),
endpwend() sequences (ditto for getgrent(), getspent(), and
getsgent()). The only real (minor) issue was in login, which kept
the passwd file open.
* libmisc/entry.c: Remove unneeded setspent() and endspent() (only
getspnam is called in the middle).
* libmisc/find_new_ids.c: Make sure to close the password and
group files with endpwent() and endgrent().
* libmisc/pwdcheck.c: Remove unneeded endspent() (only getspnam()
is called before).
* src/lastlog.c, src/passwd.c, src/groupmod.c, src/faillog.c,
src/groups.c: Make sure to close
the password file with endpwent().
* src/login.c: Remove unneeded setpwent() (only xgetpwnam is
called before).
* src/login.c, src/newgrp.c: Fix typos in comments.
2008-04-17 03:22:46 +05:30
|
|
|
endpwent ();
|
2008-03-05 05:40:25 +05:30
|
|
|
}
|
2007-10-07 17:15:58 +05:30
|
|
|
}
|
|
|
|
|
2009-03-14 04:19:20 +05:30
|
|
|
/*
|
|
|
|
* reset_one - Reset the fail count for one user
|
|
|
|
*
|
|
|
|
* This returns a boolean indicating if an error occurred.
|
|
|
|
*/
|
|
|
|
static bool reset_one (uid_t uid)
|
2007-10-07 17:15:58 +05:30
|
|
|
{
|
|
|
|
off_t offset;
|
2009-03-14 04:19:20 +05:30
|
|
|
struct faillog fl;
|
|
|
|
|
2011-06-03 01:56:30 +05:30
|
|
|
offset = (off_t) uid * sizeof (fl);
|
|
|
|
if (offset + sizeof (fl) <= statbuf.st_size) {
|
2009-03-14 04:19:20 +05:30
|
|
|
/* fseeko errors are not really relevant for us. */
|
2009-04-25 03:57:09 +05:30
|
|
|
int err = fseeko (fail, offset, SEEK_SET);
|
|
|
|
assert (0 == err);
|
2009-03-14 04:19:20 +05:30
|
|
|
/* faillog is a sparse file. Even if no entries were
|
|
|
|
* entered for this user, which should be able to get the
|
|
|
|
* empty entry in this case.
|
|
|
|
*/
|
|
|
|
if (fread ((char *) &fl, sizeof (fl), 1, fail) != 1) {
|
|
|
|
fprintf (stderr,
|
2011-11-07 00:09:03 +05:30
|
|
|
_("%s: Failed to get the entry for UID %lu\n"),
|
|
|
|
Prog, (unsigned long int)uid);
|
2009-03-14 04:19:20 +05:30
|
|
|
return true;
|
2008-08-31 00:03:37 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
} else {
|
2009-03-14 04:19:20 +05:30
|
|
|
/* Outsize of the faillog file.
|
|
|
|
* Behave as if there were a missing entry (same behavior
|
|
|
|
* as if we were reading an non existing entry in the
|
|
|
|
* sparse faillog file).
|
|
|
|
*/
|
|
|
|
memzero (&fl, sizeof (fl));
|
|
|
|
}
|
2007-10-07 17:15:58 +05:30
|
|
|
|
2009-03-14 04:19:20 +05:30
|
|
|
if (0 == fl.fail_cnt) {
|
|
|
|
/* If the count is already null, do not write in the file.
|
|
|
|
* This avoids writing 0 when no entries were present for
|
|
|
|
* the user.
|
|
|
|
*/
|
|
|
|
return false;
|
|
|
|
}
|
2007-10-07 17:15:58 +05:30
|
|
|
|
2009-03-14 04:19:20 +05:30
|
|
|
fl.fail_cnt = 0;
|
2007-10-07 17:15:58 +05:30
|
|
|
|
2009-03-14 04:19:20 +05:30
|
|
|
if ( (fseeko (fail, offset, SEEK_SET) == 0)
|
|
|
|
&& (fwrite ((char *) &fl, sizeof (fl), 1, fail) == 1)) {
|
|
|
|
(void) fflush (fail);
|
|
|
|
return false;
|
|
|
|
}
|
2007-10-07 17:15:58 +05:30
|
|
|
|
2009-03-14 04:19:20 +05:30
|
|
|
fprintf (stderr,
|
2011-11-07 00:09:03 +05:30
|
|
|
_("%s: Failed to reset fail count for UID %lu\n"),
|
|
|
|
Prog, (unsigned long int)uid);
|
2009-03-14 04:19:20 +05:30
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void reset (void)
|
|
|
|
{
|
|
|
|
if (uflg && has_umin && has_umax && (umin==umax)) {
|
|
|
|
if (reset_one ((uid_t)umin)) {
|
|
|
|
errors = true;
|
|
|
|
}
|
|
|
|
} else {
|
2010-03-17 00:45:22 +05:30
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
2009-03-14 04:19:20 +05:30
|
|
|
/* Reset all entries in the specified range.
|
|
|
|
* Non existing entries will not be touched.
|
|
|
|
*/
|
2010-03-17 00:45:22 +05:30
|
|
|
if (aflg) {
|
|
|
|
/* Entries for non existing users are also reset.
|
|
|
|
*/
|
2010-03-18 05:37:00 +05:30
|
|
|
uid_t uid = 0;
|
2009-03-14 04:19:20 +05:30
|
|
|
|
2010-03-18 05:37:00 +05:30
|
|
|
/* Make sure we stay in the umin-umax range if specified */
|
|
|
|
if (has_umin) {
|
|
|
|
uid = (uid_t)umin;
|
|
|
|
}
|
2009-03-14 04:19:20 +05:30
|
|
|
|
2010-03-18 05:37:00 +05:30
|
|
|
while (uid <= uidmax) {
|
|
|
|
if (reset_one (uid)) {
|
|
|
|
errors = true;
|
|
|
|
}
|
|
|
|
uid++;
|
2009-03-14 04:19:20 +05:30
|
|
|
}
|
2010-03-17 00:45:22 +05:30
|
|
|
} 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 ();
|
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-03-14 04:19:20 +05:30
|
|
|
/*
|
|
|
|
* setmax_one - Set the maximum failed login counter for one user
|
|
|
|
*
|
|
|
|
* This returns a boolean indicating if an error occurred.
|
|
|
|
*/
|
2011-11-20 03:14:34 +05:30
|
|
|
static bool setmax_one (uid_t uid, short max)
|
2007-10-07 17:14:02 +05:30
|
|
|
{
|
2007-10-07 17:14:59 +05:30
|
|
|
off_t offset;
|
2009-03-14 04:19:20 +05:30
|
|
|
struct faillog fl;
|
|
|
|
|
|
|
|
offset = (off_t) uid * sizeof (fl);
|
2011-06-03 01:56:30 +05:30
|
|
|
if (offset + sizeof (fl) <= statbuf.st_size) {
|
2009-03-14 04:19:20 +05:30
|
|
|
/* fseeko errors are not really relevant for us. */
|
2009-04-25 03:57:09 +05:30
|
|
|
int err = fseeko (fail, offset, SEEK_SET);
|
|
|
|
assert (0 == err);
|
2009-03-14 04:19:20 +05:30
|
|
|
/* faillog is a sparse file. Even if no entries were
|
|
|
|
* entered for this user, which should be able to get the
|
|
|
|
* empty entry in this case.
|
|
|
|
*/
|
|
|
|
if (fread ((char *) &fl, sizeof (fl), 1, fail) != 1) {
|
|
|
|
fprintf (stderr,
|
2011-11-07 00:09:03 +05:30
|
|
|
_("%s: Failed to get the entry for UID %lu\n"),
|
|
|
|
Prog, (unsigned long int)uid);
|
2009-03-14 04:19:20 +05:30
|
|
|
return true;
|
2008-06-11 00:46:02 +05:30
|
|
|
}
|
2009-03-14 04:19:20 +05:30
|
|
|
} else {
|
|
|
|
/* Outsize of the faillog file.
|
|
|
|
* Behave as if there were a missing entry (same behavior
|
|
|
|
* as if we were reading an non existing entry in the
|
|
|
|
* sparse faillog file).
|
|
|
|
*/
|
|
|
|
memzero (&fl, sizeof (fl));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (max == fl.fail_max) {
|
|
|
|
/* If the max is already set to the right value, do not
|
|
|
|
* write in the file.
|
|
|
|
* This avoids writing 0 when no entries were present for
|
|
|
|
* the user and the max argument is 0.
|
|
|
|
*/
|
|
|
|
return false;
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
2009-03-14 04:19:20 +05:30
|
|
|
|
|
|
|
fl.fail_max = max;
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2008-06-11 00:48:44 +05:30
|
|
|
if ( (fseeko (fail, offset, SEEK_SET) == 0)
|
2009-03-14 04:19:20 +05:30
|
|
|
&& (fwrite ((char *) &fl, sizeof (fl), 1, fail) == 1)) {
|
2009-04-23 16:53:53 +05:30
|
|
|
(void) fflush (fail);
|
2009-03-14 04:19:20 +05:30
|
|
|
return false;
|
2008-06-11 00:46:02 +05:30
|
|
|
}
|
2009-03-14 04:19:20 +05:30
|
|
|
|
|
|
|
fprintf (stderr,
|
2011-11-07 00:09:03 +05:30
|
|
|
_("%s: Failed to set max for UID %lu\n"),
|
|
|
|
Prog, (unsigned long int)uid);
|
2009-03-14 04:19:20 +05:30
|
|
|
return true;
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
|
2011-11-20 03:14:34 +05:30
|
|
|
static void setmax (short max)
|
2007-10-07 17:14:02 +05:30
|
|
|
{
|
2009-03-14 04:19:20 +05:30
|
|
|
if (uflg && has_umin && has_umax && (umin==umax)) {
|
|
|
|
if (setmax_one ((uid_t)umin, max)) {
|
|
|
|
errors = true;
|
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
} else {
|
2010-03-17 00:45:22 +05:30
|
|
|
/* Set max for entries in the specified range.
|
2009-03-14 04:19:20 +05:30
|
|
|
* 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.
|
2010-03-17 00:45:22 +05:30
|
|
|
*/
|
|
|
|
if (aflg) {
|
2010-03-18 05:37:00 +05:30
|
|
|
/* 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--;
|
|
|
|
}
|
2009-03-14 04:19:20 +05:30
|
|
|
|
2010-03-18 05:37:00 +05:30
|
|
|
/* Make sure we stay in the umin-umax range if specified */
|
|
|
|
if (has_umin) {
|
|
|
|
uid = (uid_t)umin;
|
|
|
|
}
|
|
|
|
if (has_umax) {
|
|
|
|
uidmax = (uid_t)umax;
|
|
|
|
}
|
2009-03-14 04:19:20 +05:30
|
|
|
|
2010-03-18 05:37:00 +05:30
|
|
|
while (uid <= uidmax) {
|
|
|
|
if (setmax_one (uid, max)) {
|
|
|
|
errors = true;
|
|
|
|
}
|
|
|
|
uid++;
|
2009-03-14 04:19:20 +05:30
|
|
|
}
|
2010-03-17 00:45:22 +05:30
|
|
|
} 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 ();
|
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-03-14 04:19:20 +05:30
|
|
|
/*
|
|
|
|
* set_locktime_one - Set the locktime for one user
|
|
|
|
*
|
|
|
|
* This returns a boolean indicating if an error occurred.
|
|
|
|
*/
|
|
|
|
static bool set_locktime_one (uid_t uid, long locktime)
|
2007-10-07 17:14:02 +05:30
|
|
|
{
|
2007-10-07 17:14:59 +05:30
|
|
|
off_t offset;
|
2009-03-14 04:19:20 +05:30
|
|
|
struct faillog fl;
|
|
|
|
|
|
|
|
offset = (off_t) uid * sizeof (fl);
|
2011-06-03 01:56:30 +05:30
|
|
|
if (offset + sizeof (fl) <= statbuf.st_size) {
|
2009-03-14 04:19:20 +05:30
|
|
|
/* fseeko errors are not really relevant for us. */
|
2009-04-25 03:57:09 +05:30
|
|
|
int err = fseeko (fail, offset, SEEK_SET);
|
|
|
|
assert (0 == err);
|
2009-03-14 04:19:20 +05:30
|
|
|
/* faillog is a sparse file. Even if no entries were
|
|
|
|
* entered for this user, which should be able to get the
|
|
|
|
* empty entry in this case.
|
|
|
|
*/
|
|
|
|
if (fread ((char *) &fl, sizeof (fl), 1, fail) != 1) {
|
|
|
|
fprintf (stderr,
|
2011-11-07 00:09:03 +05:30
|
|
|
_("%s: Failed to get the entry for UID %lu\n"),
|
|
|
|
Prog, (unsigned long int)uid);
|
2009-03-14 04:19:20 +05:30
|
|
|
return true;
|
2008-06-11 00:46:02 +05:30
|
|
|
}
|
2009-03-14 04:19:20 +05:30
|
|
|
} else {
|
|
|
|
/* Outsize of the faillog file.
|
|
|
|
* Behave as if there were a missing entry (same behavior
|
|
|
|
* as if we were reading an non existing entry in the
|
|
|
|
* sparse faillog file).
|
|
|
|
*/
|
|
|
|
memzero (&fl, sizeof (fl));
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
2009-03-14 04:19:20 +05:30
|
|
|
|
|
|
|
if (locktime == fl.fail_locktime) {
|
2011-11-20 03:14:34 +05:30
|
|
|
/* If the locktime is already set to the right value, do not
|
2009-03-14 04:19:20 +05:30
|
|
|
* write in the file.
|
|
|
|
* This avoids writing 0 when no entries were present for
|
2011-11-20 03:14:34 +05:30
|
|
|
* the user and the locktime argument is 0.
|
2009-03-14 04:19:20 +05:30
|
|
|
*/
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
fl.fail_locktime = locktime;
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2009-04-23 16:53:53 +05:30
|
|
|
if ( (fseeko (fail, offset, SEEK_SET) == 0)
|
|
|
|
&& (fwrite ((char *) &fl, sizeof (fl), 1, fail) == 1)) {
|
|
|
|
(void) fflush (fail);
|
2009-03-14 04:19:20 +05:30
|
|
|
return false;
|
2008-06-11 00:46:02 +05:30
|
|
|
}
|
2009-03-14 04:19:20 +05:30
|
|
|
|
|
|
|
fprintf (stderr,
|
2011-11-07 00:09:03 +05:30
|
|
|
_("%s: Failed to set locktime for UID %lu\n"),
|
|
|
|
Prog, (unsigned long int)uid);
|
2009-03-14 04:19:20 +05:30
|
|
|
return true;
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
2007-10-07 17:15:58 +05:30
|
|
|
|
|
|
|
static void set_locktime (long locktime)
|
|
|
|
{
|
2009-03-14 04:19:20 +05:30
|
|
|
if (uflg && has_umin && has_umax && (umin==umax)) {
|
|
|
|
if (set_locktime_one ((uid_t)umin, locktime)) {
|
|
|
|
errors = true;
|
|
|
|
}
|
2007-10-07 17:15:58 +05:30
|
|
|
} else {
|
2010-03-17 00:45:22 +05:30
|
|
|
/* Set locktime for entries in the specified range.
|
2009-03-14 04:19:20 +05:30
|
|
|
* 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.
|
2010-03-17 00:45:22 +05:30
|
|
|
*/
|
|
|
|
if (aflg) {
|
2010-03-18 05:37:00 +05:30
|
|
|
/* 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--;
|
|
|
|
}
|
2009-03-14 04:19:20 +05:30
|
|
|
|
2010-03-18 05:37:00 +05:30
|
|
|
/* Make sure we stay in the umin-umax range if specified */
|
|
|
|
if (has_umin) {
|
|
|
|
uid = (uid_t)umin;
|
|
|
|
}
|
|
|
|
if (has_umax) {
|
|
|
|
uidmax = (uid_t)umax;
|
|
|
|
}
|
2009-03-14 04:19:20 +05:30
|
|
|
|
2010-03-18 05:37:00 +05:30
|
|
|
while (uid <= uidmax) {
|
|
|
|
if (set_locktime_one (uid, locktime)) {
|
|
|
|
errors = true;
|
|
|
|
}
|
|
|
|
uid++;
|
2009-03-14 04:19:20 +05:30
|
|
|
}
|
2010-03-17 00:45:22 +05:30
|
|
|
} 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 ();
|
|
|
|
}
|
2007-10-07 17:15:58 +05:30
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int main (int argc, char **argv)
|
|
|
|
{
|
2009-03-14 04:19:20 +05:30
|
|
|
long fail_locktime;
|
2011-11-20 03:14:34 +05:30
|
|
|
short fail_max;
|
2009-03-14 04:19:20 +05:30
|
|
|
long days;
|
2007-10-07 17:15:58 +05:30
|
|
|
|
2011-11-07 00:09:03 +05:30
|
|
|
/*
|
|
|
|
* Get the program name. The program name is used as a prefix to
|
|
|
|
* most error messages.
|
|
|
|
*/
|
|
|
|
Prog = Basename (argv[0]);
|
|
|
|
|
2008-06-11 00:46:02 +05:30
|
|
|
(void) setlocale (LC_ALL, "");
|
|
|
|
(void) bindtextdomain (PACKAGE, LOCALEDIR);
|
|
|
|
(void) textdomain (PACKAGE);
|
2007-10-07 17:15:58 +05:30
|
|
|
|
2011-11-07 00:09:03 +05:30
|
|
|
process_root_flag ("-R", argc, argv);
|
|
|
|
|
2007-10-07 17:15:58 +05:30
|
|
|
{
|
|
|
|
int c;
|
|
|
|
static struct option long_options[] = {
|
* src/chage.c, src/chgpasswd.c, src/chpasswd.c, src/chsh.c,
src/faillog.c, src/gpasswd.c, src/groupadd.c, src/groupdel.c,
src/groupmems.c, src/groupmod.c, src/grpconv.c, src/grpunconv.c,
src/lastlog.c, src/newusers.c, src/passwd.c, src/pwconv.c,
src/pwunconv.c, src/su.c, src/useradd.c, src/userdel.c,
src/usermod.c, src/vipw.c: Align and sort options.
2011-11-07 00:09:59 +05:30
|
|
|
{"all", no_argument, NULL, 'a'},
|
|
|
|
{"help", no_argument, NULL, 'h'},
|
2007-10-07 17:17:45 +05:30
|
|
|
{"lock-secs", required_argument, NULL, 'l'},
|
* src/chage.c, src/chgpasswd.c, src/chpasswd.c, src/chsh.c,
src/faillog.c, src/gpasswd.c, src/groupadd.c, src/groupdel.c,
src/groupmems.c, src/groupmod.c, src/grpconv.c, src/grpunconv.c,
src/lastlog.c, src/newusers.c, src/passwd.c, src/pwconv.c,
src/pwunconv.c, src/su.c, src/useradd.c, src/userdel.c,
src/usermod.c, src/vipw.c: Align and sort options.
2011-11-07 00:09:59 +05:30
|
|
|
{"maximum", required_argument, NULL, 'm'},
|
|
|
|
{"reset", no_argument, NULL, 'r'},
|
|
|
|
{"root", required_argument, NULL, 'R'},
|
|
|
|
{"time", required_argument, NULL, 't'},
|
|
|
|
{"user", required_argument, NULL, 'u'},
|
2007-10-07 17:15:58 +05:30
|
|
|
{NULL, 0, NULL, '\0'}
|
|
|
|
};
|
2011-11-07 00:09:03 +05:30
|
|
|
while ((c = getopt_long (argc, argv, "ahl:m:rR:t:u:",
|
2011-11-07 00:08:45 +05:30
|
|
|
long_options, NULL)) != -1) {
|
2007-10-07 17:16:07 +05:30
|
|
|
switch (c) {
|
2007-10-07 17:15:58 +05:30
|
|
|
case 'a':
|
2008-06-11 00:46:02 +05:30
|
|
|
aflg = true;
|
2007-10-07 17:15:58 +05:30
|
|
|
break;
|
2007-10-07 17:16:07 +05:30
|
|
|
case 'h':
|
* NEWS, src/userdel.c, src/lastlog.c, src/gpasswd.c,
src/newusers.c, src/chpasswd.c, src/groupmems.c, src/usermod.c,
src/chgpasswd.c, src/vipw.c, src/su.c, src/useradd.c,
src/groupmod.c, src/passwd.c, src/groupadd.c, src/chage.c,
src/faillog.c, src/chsh.c: If someone uses the -h/--help options,
the usage should not go to stderr nor should the utility exit with
non-zero status. All of the shadow utils do just this
unfortunately, so convert them over to sanity.
* man/groupmems.8.xml, man/gpasswd.1.xml: Added option -h/--help.
2009-09-05 04:32:33 +05:30
|
|
|
usage (E_SUCCESS);
|
2011-07-23 05:29:57 +05:30
|
|
|
/*@notreached@*/break;
|
2007-10-07 17:15:58 +05:30
|
|
|
case 'l':
|
2009-03-14 04:19:20 +05:30
|
|
|
if (getlong (optarg, &fail_locktime) == 0) {
|
|
|
|
fprintf (stderr,
|
|
|
|
_("%s: invalid numeric argument '%s'\n"),
|
2011-11-07 00:09:03 +05:30
|
|
|
Prog, optarg);
|
* src/newgrp.c, src/chfn.c, src/groupmems.c, src/usermod.c,
src/userdel.c, src/chpasswd.c, src/grpck.c, src/gpasswd.c,
src/groupdel.c, src/chgpasswd.c, src/vipw.c, src/useradd.c,
src/su.c, src/groupmod.c, src/passwd.c, src/pwck.c,
src/groupadd.c, src/chage.c, src/login.c, src/faillog.c,
src/sulogin.c, src/chsh.c, src/pwconv.c: Added splint annotations.
* src/userdel.c, src/pwconv.c, src/lastlog.c, src/grpck.c,
src/vipw.c, src/groupmod.c, src/passwd.c, src/pwck.c, src/login.c,
src/sulogin.c, src/usermod.c: Use return instead of exit at the
end of main().
* src/gpasswd.c, src/passwd.c, src/faillog.c: Use the exitcodes.h
exit codes.
* src/chpasswd.c: Added missing ||.
* src/nologin.c: Do not include exitcodes.h.
* src/nologin.c: Added brackets.
* src/nologin.c: Avoid assignments in comparisons.
2009-05-01 03:09:38 +05:30
|
|
|
exit (E_BAD_ARG);
|
2009-03-14 04:19:20 +05:30
|
|
|
}
|
|
|
|
lflg = true;
|
2007-10-07 17:15:58 +05:30
|
|
|
break;
|
|
|
|
case 'm':
|
2011-11-20 03:14:34 +05:30
|
|
|
{
|
|
|
|
long int lmax;
|
|
|
|
if ( (getlong (optarg, &lmax) == 0)
|
|
|
|
|| ((long int)(short) lmax != lmax)) {
|
2009-03-14 04:19:20 +05:30
|
|
|
fprintf (stderr,
|
|
|
|
_("%s: invalid numeric argument '%s'\n"),
|
2011-11-07 00:09:03 +05:30
|
|
|
Prog, optarg);
|
* src/newgrp.c, src/chfn.c, src/groupmems.c, src/usermod.c,
src/userdel.c, src/chpasswd.c, src/grpck.c, src/gpasswd.c,
src/groupdel.c, src/chgpasswd.c, src/vipw.c, src/useradd.c,
src/su.c, src/groupmod.c, src/passwd.c, src/pwck.c,
src/groupadd.c, src/chage.c, src/login.c, src/faillog.c,
src/sulogin.c, src/chsh.c, src/pwconv.c: Added splint annotations.
* src/userdel.c, src/pwconv.c, src/lastlog.c, src/grpck.c,
src/vipw.c, src/groupmod.c, src/passwd.c, src/pwck.c, src/login.c,
src/sulogin.c, src/usermod.c: Use return instead of exit at the
end of main().
* src/gpasswd.c, src/passwd.c, src/faillog.c: Use the exitcodes.h
exit codes.
* src/chpasswd.c: Added missing ||.
* src/nologin.c: Do not include exitcodes.h.
* src/nologin.c: Added brackets.
* src/nologin.c: Avoid assignments in comparisons.
2009-05-01 03:09:38 +05:30
|
|
|
exit (E_BAD_ARG);
|
2009-03-14 04:19:20 +05:30
|
|
|
}
|
2011-11-20 03:14:34 +05:30
|
|
|
fail_max = (short) lmax;
|
2009-03-14 04:19:20 +05:30
|
|
|
mflg = true;
|
2007-10-07 17:15:58 +05:30
|
|
|
break;
|
2011-11-20 03:14:34 +05:30
|
|
|
}
|
2007-10-07 17:15:58 +05:30
|
|
|
case 'r':
|
2009-03-14 04:19:20 +05:30
|
|
|
rflg = true;
|
2007-10-07 17:15:58 +05:30
|
|
|
break;
|
2011-11-07 00:09:03 +05:30
|
|
|
case 'R': /* no-op, handled in process_root_flag () */
|
|
|
|
break;
|
2007-10-07 17:16:07 +05:30
|
|
|
case 't':
|
2009-03-14 04:19:20 +05:30
|
|
|
if (getlong (optarg, &days) == 0) {
|
|
|
|
fprintf (stderr,
|
|
|
|
_("%s: invalid numeric argument '%s'\n"),
|
2011-11-07 00:09:03 +05:30
|
|
|
Prog, optarg);
|
* src/newgrp.c, src/chfn.c, src/groupmems.c, src/usermod.c,
src/userdel.c, src/chpasswd.c, src/grpck.c, src/gpasswd.c,
src/groupdel.c, src/chgpasswd.c, src/vipw.c, src/useradd.c,
src/su.c, src/groupmod.c, src/passwd.c, src/pwck.c,
src/groupadd.c, src/chage.c, src/login.c, src/faillog.c,
src/sulogin.c, src/chsh.c, src/pwconv.c: Added splint annotations.
* src/userdel.c, src/pwconv.c, src/lastlog.c, src/grpck.c,
src/vipw.c, src/groupmod.c, src/passwd.c, src/pwck.c, src/login.c,
src/sulogin.c, src/usermod.c: Use return instead of exit at the
end of main().
* src/gpasswd.c, src/passwd.c, src/faillog.c: Use the exitcodes.h
exit codes.
* src/chpasswd.c: Added missing ||.
* src/nologin.c: Do not include exitcodes.h.
* src/nologin.c: Added brackets.
* src/nologin.c: Avoid assignments in comparisons.
2009-05-01 03:09:38 +05:30
|
|
|
exit (E_BAD_ARG);
|
2009-03-14 04:19:20 +05:30
|
|
|
}
|
2008-06-14 02:58:11 +05:30
|
|
|
seconds = (time_t) days * DAY;
|
2008-06-11 00:46:02 +05:30
|
|
|
tflg = true;
|
2007-10-07 17:16:07 +05:30
|
|
|
break;
|
2007-10-07 17:15:58 +05:30
|
|
|
case 'u':
|
* lib/prototypes.h, configure.in, libmisc/Makefile.am,
libmisc/xgetXXbyYY.c, libmisc/xgetpwnam.c, libmisc/xgetpwuid.c,
libmisc/xgetgrnam.c, libmisc/xgetgrgid.c, libmisc/xgetspnam.c:
Added functions xgetpwnam(), xgetpwuid(), xgetgrnam(),
xgetgrgid(), and xgetspnam(). They allocate memory for the
returned structure and are more robust to successive calls. They
are implemented with the libc's getxxyyy_r() functions if
available.
* libmisc/limits.c, libmisc/entry.c, libmisc/chowntty.c,
libmisc/addgrps.c, libmisc/myname.c, libmisc/rlogin.c,
libmisc/pwdcheck.c, src/newgrp.c, src/login_nopam.c,
src/userdel.c, src/lastlog.c, src/grpck.c, src/gpasswd.c,
src/newusers.c, src/chpasswd.c, src/chfn.c, src/groupmems.c,
src/usermod.c, src/expiry.c, src/groupdel.c, src/chgpasswd.c,
src/su.c, src/useradd.c, src/groupmod.c, src/passwd.c, src/pwck.c,
src/groupadd.c, src/chage.c, src/login.c, src/suauth.c,
src/faillog.c, src/groups.c, src/chsh.c, src/id.c: Review all the
usage of one of the getpwnam(), getpwuid(), getgrnam(),
getgrgid(), and getspnam() functions. It was noticed on
http://bugs.debian.org/341230 that chfn and chsh use a passwd
structure after calling a pam function, which result in using
information from the passwd structure requested by pam, not the
original one. It is much easier to use the new xget... functions
to avoid these issues. I've checked which call to the original
get... functions could be left (reducing the scope of the
structure if possible), and I've left comments to ease future
reviews (e.g. /* local, no need for xgetpwnam */).
Note: the getpwent/getgrent calls should probably be checked also.
* src/groupdel.c, src/expiry.c: Fix typos in comments.
* src/groupmod.c: Re-indent.
* libmisc/Makefile.am, lib/groupmem.c, lib/groupio.c, lib/pwmem.c,
lib/pwio.c, lib/shadowmem.c, lib/shadowio.c: Move the __<xx>_dup
functions (used by the xget... functions) from the <xx>io.c files
to the new <xx>mem.c files. This avoid linking some utils against
the SELinux library.
2007-11-19 04:45:26 +05:30
|
|
|
{
|
2009-03-14 04:19:20 +05:30
|
|
|
/*
|
|
|
|
* The user can be:
|
|
|
|
* - a login name
|
|
|
|
* - numerical
|
|
|
|
* - a numerical login ID
|
|
|
|
* - a range (-x, x-, x-y)
|
|
|
|
*/
|
* lib/prototypes.h, configure.in, libmisc/Makefile.am,
libmisc/xgetXXbyYY.c, libmisc/xgetpwnam.c, libmisc/xgetpwuid.c,
libmisc/xgetgrnam.c, libmisc/xgetgrgid.c, libmisc/xgetspnam.c:
Added functions xgetpwnam(), xgetpwuid(), xgetgrnam(),
xgetgrgid(), and xgetspnam(). They allocate memory for the
returned structure and are more robust to successive calls. They
are implemented with the libc's getxxyyy_r() functions if
available.
* libmisc/limits.c, libmisc/entry.c, libmisc/chowntty.c,
libmisc/addgrps.c, libmisc/myname.c, libmisc/rlogin.c,
libmisc/pwdcheck.c, src/newgrp.c, src/login_nopam.c,
src/userdel.c, src/lastlog.c, src/grpck.c, src/gpasswd.c,
src/newusers.c, src/chpasswd.c, src/chfn.c, src/groupmems.c,
src/usermod.c, src/expiry.c, src/groupdel.c, src/chgpasswd.c,
src/su.c, src/useradd.c, src/groupmod.c, src/passwd.c, src/pwck.c,
src/groupadd.c, src/chage.c, src/login.c, src/suauth.c,
src/faillog.c, src/groups.c, src/chsh.c, src/id.c: Review all the
usage of one of the getpwnam(), getpwuid(), getgrnam(),
getgrgid(), and getspnam() functions. It was noticed on
http://bugs.debian.org/341230 that chfn and chsh use a passwd
structure after calling a pam function, which result in using
information from the passwd structure requested by pam, not the
original one. It is much easier to use the new xget... functions
to avoid these issues. I've checked which call to the original
get... functions could be left (reducing the scope of the
structure if possible), and I've left comments to ease future
reviews (e.g. /* local, no need for xgetpwnam */).
Note: the getpwent/getgrent calls should probably be checked also.
* src/groupdel.c, src/expiry.c: Fix typos in comments.
* src/groupmod.c: Re-indent.
* libmisc/Makefile.am, lib/groupmem.c, lib/groupio.c, lib/pwmem.c,
lib/pwio.c, lib/shadowmem.c, lib/shadowio.c: Move the __<xx>_dup
functions (used by the xget... functions) from the <xx>io.c files
to the new <xx>mem.c files. This avoid linking some utils against
the SELinux library.
2007-11-19 04:45:26 +05:30
|
|
|
struct passwd *pwent;
|
2007-10-07 17:15:58 +05:30
|
|
|
|
2009-03-14 04:19:20 +05:30
|
|
|
uflg = true;
|
* lib/prototypes.h, configure.in, libmisc/Makefile.am,
libmisc/xgetXXbyYY.c, libmisc/xgetpwnam.c, libmisc/xgetpwuid.c,
libmisc/xgetgrnam.c, libmisc/xgetgrgid.c, libmisc/xgetspnam.c:
Added functions xgetpwnam(), xgetpwuid(), xgetgrnam(),
xgetgrgid(), and xgetspnam(). They allocate memory for the
returned structure and are more robust to successive calls. They
are implemented with the libc's getxxyyy_r() functions if
available.
* libmisc/limits.c, libmisc/entry.c, libmisc/chowntty.c,
libmisc/addgrps.c, libmisc/myname.c, libmisc/rlogin.c,
libmisc/pwdcheck.c, src/newgrp.c, src/login_nopam.c,
src/userdel.c, src/lastlog.c, src/grpck.c, src/gpasswd.c,
src/newusers.c, src/chpasswd.c, src/chfn.c, src/groupmems.c,
src/usermod.c, src/expiry.c, src/groupdel.c, src/chgpasswd.c,
src/su.c, src/useradd.c, src/groupmod.c, src/passwd.c, src/pwck.c,
src/groupadd.c, src/chage.c, src/login.c, src/suauth.c,
src/faillog.c, src/groups.c, src/chsh.c, src/id.c: Review all the
usage of one of the getpwnam(), getpwuid(), getgrnam(),
getgrgid(), and getspnam() functions. It was noticed on
http://bugs.debian.org/341230 that chfn and chsh use a passwd
structure after calling a pam function, which result in using
information from the passwd structure requested by pam, not the
original one. It is much easier to use the new xget... functions
to avoid these issues. I've checked which call to the original
get... functions could be left (reducing the scope of the
structure if possible), and I've left comments to ease future
reviews (e.g. /* local, no need for xgetpwnam */).
Note: the getpwent/getgrent calls should probably be checked also.
* src/groupdel.c, src/expiry.c: Fix typos in comments.
* src/groupmod.c: Re-indent.
* libmisc/Makefile.am, lib/groupmem.c, lib/groupio.c, lib/pwmem.c,
lib/pwio.c, lib/shadowmem.c, lib/shadowio.c: Move the __<xx>_dup
functions (used by the xget... functions) from the <xx>io.c files
to the new <xx>mem.c files. This avoid linking some utils against
the SELinux library.
2007-11-19 04:45:26 +05:30
|
|
|
/* local, no need for xgetpwnam */
|
2007-10-07 17:15:58 +05:30
|
|
|
pwent = getpwnam (optarg);
|
2009-03-14 04:19:20 +05:30
|
|
|
if (NULL != pwent) {
|
|
|
|
umin = (unsigned long) pwent->pw_uid;
|
|
|
|
has_umin = true;
|
|
|
|
umax = umin;
|
|
|
|
has_umax = true;
|
|
|
|
} else {
|
|
|
|
if (getrange (optarg,
|
|
|
|
&umin, &has_umin,
|
|
|
|
&umax, &has_umax) == 0) {
|
|
|
|
fprintf (stderr,
|
2011-11-07 00:09:03 +05:30
|
|
|
_("%s: Unknown user or range: %s\n"),
|
|
|
|
Prog, optarg);
|
* src/newgrp.c, src/chfn.c, src/groupmems.c, src/usermod.c,
src/userdel.c, src/chpasswd.c, src/grpck.c, src/gpasswd.c,
src/groupdel.c, src/chgpasswd.c, src/vipw.c, src/useradd.c,
src/su.c, src/groupmod.c, src/passwd.c, src/pwck.c,
src/groupadd.c, src/chage.c, src/login.c, src/faillog.c,
src/sulogin.c, src/chsh.c, src/pwconv.c: Added splint annotations.
* src/userdel.c, src/pwconv.c, src/lastlog.c, src/grpck.c,
src/vipw.c, src/groupmod.c, src/passwd.c, src/pwck.c, src/login.c,
src/sulogin.c, src/usermod.c: Use return instead of exit at the
end of main().
* src/gpasswd.c, src/passwd.c, src/faillog.c: Use the exitcodes.h
exit codes.
* src/chpasswd.c: Added missing ||.
* src/nologin.c: Do not include exitcodes.h.
* src/nologin.c: Added brackets.
* src/nologin.c: Avoid assignments in comparisons.
2009-05-01 03:09:38 +05:30
|
|
|
exit (E_BAD_ARG);
|
2009-03-14 04:19:20 +05:30
|
|
|
}
|
2007-10-07 17:15:58 +05:30
|
|
|
}
|
2009-03-14 04:19:20 +05:30
|
|
|
|
2007-10-07 17:15:58 +05:30
|
|
|
break;
|
* lib/prototypes.h, configure.in, libmisc/Makefile.am,
libmisc/xgetXXbyYY.c, libmisc/xgetpwnam.c, libmisc/xgetpwuid.c,
libmisc/xgetgrnam.c, libmisc/xgetgrgid.c, libmisc/xgetspnam.c:
Added functions xgetpwnam(), xgetpwuid(), xgetgrnam(),
xgetgrgid(), and xgetspnam(). They allocate memory for the
returned structure and are more robust to successive calls. They
are implemented with the libc's getxxyyy_r() functions if
available.
* libmisc/limits.c, libmisc/entry.c, libmisc/chowntty.c,
libmisc/addgrps.c, libmisc/myname.c, libmisc/rlogin.c,
libmisc/pwdcheck.c, src/newgrp.c, src/login_nopam.c,
src/userdel.c, src/lastlog.c, src/grpck.c, src/gpasswd.c,
src/newusers.c, src/chpasswd.c, src/chfn.c, src/groupmems.c,
src/usermod.c, src/expiry.c, src/groupdel.c, src/chgpasswd.c,
src/su.c, src/useradd.c, src/groupmod.c, src/passwd.c, src/pwck.c,
src/groupadd.c, src/chage.c, src/login.c, src/suauth.c,
src/faillog.c, src/groups.c, src/chsh.c, src/id.c: Review all the
usage of one of the getpwnam(), getpwuid(), getgrnam(),
getgrgid(), and getspnam() functions. It was noticed on
http://bugs.debian.org/341230 that chfn and chsh use a passwd
structure after calling a pam function, which result in using
information from the passwd structure requested by pam, not the
original one. It is much easier to use the new xget... functions
to avoid these issues. I've checked which call to the original
get... functions could be left (reducing the scope of the
structure if possible), and I've left comments to ease future
reviews (e.g. /* local, no need for xgetpwnam */).
Note: the getpwent/getgrent calls should probably be checked also.
* src/groupdel.c, src/expiry.c: Fix typos in comments.
* src/groupmod.c: Re-indent.
* libmisc/Makefile.am, lib/groupmem.c, lib/groupio.c, lib/pwmem.c,
lib/pwio.c, lib/shadowmem.c, lib/shadowio.c: Move the __<xx>_dup
functions (used by the xget... functions) from the <xx>io.c files
to the new <xx>mem.c files. This avoid linking some utils against
the SELinux library.
2007-11-19 04:45:26 +05:30
|
|
|
}
|
2007-10-07 17:15:58 +05:30
|
|
|
default:
|
* NEWS, src/userdel.c, src/lastlog.c, src/gpasswd.c,
src/newusers.c, src/chpasswd.c, src/groupmems.c, src/usermod.c,
src/chgpasswd.c, src/vipw.c, src/su.c, src/useradd.c,
src/groupmod.c, src/passwd.c, src/groupadd.c, src/chage.c,
src/faillog.c, src/chsh.c: If someone uses the -h/--help options,
the usage should not go to stderr nor should the utility exit with
non-zero status. All of the shadow utils do just this
unfortunately, so convert them over to sanity.
* man/groupmems.8.xml, man/gpasswd.1.xml: Added option -h/--help.
2009-09-05 04:32:33 +05:30
|
|
|
usage (E_USAGE);
|
2007-10-07 17:15:58 +05:30
|
|
|
}
|
|
|
|
}
|
2011-07-23 05:29:57 +05:30
|
|
|
if (argc > optind) {
|
|
|
|
fprintf (stderr,
|
2011-11-07 00:09:03 +05:30
|
|
|
_("%s: unexpected argument: %s\n"),
|
|
|
|
Prog, argv[optind]);
|
2011-07-23 05:29:57 +05:30
|
|
|
usage (EXIT_FAILURE);
|
|
|
|
}
|
2007-10-07 17:15:58 +05:30
|
|
|
}
|
|
|
|
|
2009-03-14 04:19:20 +05:30
|
|
|
if (tflg && (lflg || mflg || rflg)) {
|
* NEWS, src/userdel.c, src/lastlog.c, src/gpasswd.c,
src/newusers.c, src/chpasswd.c, src/groupmems.c, src/usermod.c,
src/chgpasswd.c, src/vipw.c, src/su.c, src/useradd.c,
src/groupmod.c, src/passwd.c, src/groupadd.c, src/chage.c,
src/faillog.c, src/chsh.c: If someone uses the -h/--help options,
the usage should not go to stderr nor should the utility exit with
non-zero status. All of the shadow utils do just this
unfortunately, so convert them over to sanity.
* man/groupmems.8.xml, man/gpasswd.1.xml: Added option -h/--help.
2009-09-05 04:32:33 +05:30
|
|
|
usage (E_USAGE);
|
2009-03-14 04:19:20 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
/* Open the faillog database */
|
|
|
|
if (lflg || mflg || rflg) {
|
|
|
|
fail = fopen (FAILLOG_FILE, "r+");
|
|
|
|
} else {
|
|
|
|
fail = fopen (FAILLOG_FILE, "r");
|
|
|
|
}
|
|
|
|
if (NULL == fail) {
|
|
|
|
fprintf (stderr,
|
2011-11-07 00:09:03 +05:30
|
|
|
_("%s: Cannot open %s: %s\n"),
|
|
|
|
Prog, FAILLOG_FILE, strerror (errno));
|
* src/newgrp.c, src/chfn.c, src/groupmems.c, src/usermod.c,
src/userdel.c, src/chpasswd.c, src/grpck.c, src/gpasswd.c,
src/groupdel.c, src/chgpasswd.c, src/vipw.c, src/useradd.c,
src/su.c, src/groupmod.c, src/passwd.c, src/pwck.c,
src/groupadd.c, src/chage.c, src/login.c, src/faillog.c,
src/sulogin.c, src/chsh.c, src/pwconv.c: Added splint annotations.
* src/userdel.c, src/pwconv.c, src/lastlog.c, src/grpck.c,
src/vipw.c, src/groupmod.c, src/passwd.c, src/pwck.c, src/login.c,
src/sulogin.c, src/usermod.c: Use return instead of exit at the
end of main().
* src/gpasswd.c, src/passwd.c, src/faillog.c: Use the exitcodes.h
exit codes.
* src/chpasswd.c: Added missing ||.
* src/nologin.c: Do not include exitcodes.h.
* src/nologin.c: Added brackets.
* src/nologin.c: Avoid assignments in comparisons.
2009-05-01 03:09:38 +05:30
|
|
|
exit (E_NOPERM);
|
2009-03-14 04:19:20 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
/* Get the size of the faillog */
|
|
|
|
if (fstat (fileno (fail), &statbuf) != 0) {
|
|
|
|
fprintf (stderr,
|
2011-11-07 00:09:03 +05:30
|
|
|
_("%s: Cannot get the size of %s: %s\n"),
|
|
|
|
Prog, FAILLOG_FILE, strerror (errno));
|
* src/newgrp.c, src/chfn.c, src/groupmems.c, src/usermod.c,
src/userdel.c, src/chpasswd.c, src/grpck.c, src/gpasswd.c,
src/groupdel.c, src/chgpasswd.c, src/vipw.c, src/useradd.c,
src/su.c, src/groupmod.c, src/passwd.c, src/pwck.c,
src/groupadd.c, src/chage.c, src/login.c, src/faillog.c,
src/sulogin.c, src/chsh.c, src/pwconv.c: Added splint annotations.
* src/userdel.c, src/pwconv.c, src/lastlog.c, src/grpck.c,
src/vipw.c, src/groupmod.c, src/passwd.c, src/pwck.c, src/login.c,
src/sulogin.c, src/usermod.c: Use return instead of exit at the
end of main().
* src/gpasswd.c, src/passwd.c, src/faillog.c: Use the exitcodes.h
exit codes.
* src/chpasswd.c: Added missing ||.
* src/nologin.c: Do not include exitcodes.h.
* src/nologin.c: Added brackets.
* src/nologin.c: Avoid assignments in comparisons.
2009-05-01 03:09:38 +05:30
|
|
|
exit (E_NOPERM);
|
2009-03-14 04:19:20 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
if (lflg) {
|
|
|
|
set_locktime (fail_locktime);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mflg) {
|
|
|
|
setmax (fail_max);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rflg) {
|
|
|
|
reset ();
|
2008-06-11 00:46:02 +05:30
|
|
|
}
|
2009-03-14 04:19:20 +05:30
|
|
|
|
|
|
|
if (!(lflg || mflg || rflg)) {
|
2007-10-07 17:15:58 +05:30
|
|
|
print ();
|
2008-06-11 00:46:02 +05:30
|
|
|
}
|
2009-03-14 04:19:20 +05:30
|
|
|
|
2011-11-20 03:14:34 +05:30
|
|
|
if (lflg || mflg || rflg) {
|
|
|
|
if ( (ferror (fail) != 0)
|
|
|
|
|| (fflush (fail) != 0)
|
|
|
|
|| (fsync (fileno (fail)) != 0)
|
|
|
|
|| (fclose (fail) != 0)) {
|
|
|
|
fprintf (stderr,
|
|
|
|
_("%s: Failed to write %s: %s\n"),
|
|
|
|
Prog, FAILLOG_FILE, strerror (errno));
|
|
|
|
(void) fclose (fail);
|
|
|
|
errors = true;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
(void) fclose (fail);
|
|
|
|
}
|
2007-10-07 17:16:52 +05:30
|
|
|
|
* src/newgrp.c, src/chfn.c, src/groupmems.c, src/usermod.c,
src/userdel.c, src/chpasswd.c, src/grpck.c, src/gpasswd.c,
src/groupdel.c, src/chgpasswd.c, src/vipw.c, src/useradd.c,
src/su.c, src/groupmod.c, src/passwd.c, src/pwck.c,
src/groupadd.c, src/chage.c, src/login.c, src/faillog.c,
src/sulogin.c, src/chsh.c, src/pwconv.c: Added splint annotations.
* src/userdel.c, src/pwconv.c, src/lastlog.c, src/grpck.c,
src/vipw.c, src/groupmod.c, src/passwd.c, src/pwck.c, src/login.c,
src/sulogin.c, src/usermod.c: Use return instead of exit at the
end of main().
* src/gpasswd.c, src/passwd.c, src/faillog.c: Use the exitcodes.h
exit codes.
* src/chpasswd.c: Added missing ||.
* src/nologin.c: Do not include exitcodes.h.
* src/nologin.c: Added brackets.
* src/nologin.c: Avoid assignments in comparisons.
2009-05-01 03:09:38 +05:30
|
|
|
exit (errors ? E_NOPERM : E_SUCCESS);
|
2007-10-07 17:15:58 +05:30
|
|
|
}
|
2008-06-11 00:46:02 +05:30
|
|
|
|