pwauth-2.3.11/0000755000175000001440000000000012252365042011576 5ustar januserspwauth-2.3.11/FORM_AUTH0000644000175000001440000000475111165563124013117 0ustar janusers Using PWAUTH with Form Authentication Although 'pwauth' was designed for use with the mod_auth_external Apache module to do "Basic Authentication", it can also be "Form Authentication". In "Form Authentication" you display a login form in HTML, like
Login:
Password:
When a person submits this form, the "login.cgi" program gets run. It checks the login and password, and if they are correct, initiates a session for the user. See http://unixpapa.com/auth/ for more information about this, including explanations about why it is important for good security to use "METHOD=post", and to turn off caching both on the login form page and on the first page transmitted after a successful login. It is possible to use 'pwauth' (or any other authenticator written for mod_auth_external) with this kind of authentication system. All you have to do is have your CGI program run 'pwauth' when it wants to check the password. Here's a sample function in Perl that does exactly this. It assumes that the 'pwauth' program has been compiled with ENV_METHOD *NOT* defined (which is generally more secure). $pwauth_path= "/usr/local/libexec/pwauth"; sub trypass { my $userid= $_[0]; my $passwd= $_[1]; open PWAUTH, "|$pwauth_path" or die("Could not run $pwauth_path"); print PWAUTH "$userid\n$passwd\n"; close PWAUTH; return !$?; } Obviously the $pwauth_path should be defined to wherever you install pwauth, and the die() call should be replaced with whatever is an appropriate way to handle a fatal error in your CGI program. Note that pwauth must be configured so that SERVER_UIDS includes whatever uid your CGI program runs as. Normally this is the same user ID that httpd runs as, but if your CGIs are running under suExec, then you may need to include other uid numbers. You may want to examine the return code from pwauth more carefully than is done in this example, so that you can tell the user if his login was rejected due to logins being turned off, his account being expired, or his password being expired. Though in some configurations pwauth will return different return codes for bad password and bad login name, it is generally considered good practice NOT to tell the user which of these two occured. With reasonable caution, this is as secure as using 'pwauth' with mod_auth_external or mod_authnz_external. pwauth-2.3.11/config.h0000644000175000001440000003661412223544654013234 0ustar janusers/* ======================================================================= * Copyright 1996, Jan D. Wolter and Steven R. Weiss, 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. * * 3. The names of the authors must not be used to endorse or * promote products derived from this software without prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY * EXPRESSED 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 AUTHORS * 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. * ======================================================================= */ /* PWAUTH configuration file * * Note - the default settings in this file are the way I use it. I * guarantee you, they won't work for you. You must change them. * */ /* There are lots of different kinds of password databases. Define one of * the following: * * - SHADOW_NONE: old fashioned Unix systems which have the encrypted * passwords in the passwd file. Actually, since you don't need to be * root to access these, you might do better using Lou Langholtz's * mod_auth_system.c, which is available from the contributed modules * directory at apache.org. * * - SHADOW_BSD: This is the shadow password system in BSDI, NetBSD, OpenBSD, * and FreeBSD. It uses exactly the same calls as SHADOW_NONE, but * getpwnam() only returns the encrypted password if you are root. This * would only work with OS X if the accounts being authenticated are * configured with legacy crypt style passwords. In general, the PAM * option is more likely to be usuable in OS X. * * - SHADOW_SUN: This is the shadow password system in Solaris, Linux and * IRIX 5.3 systems. It uses getspnam() to fetch passwords and crypt() to * encrypt them. * * - SHADOW_JFH: This the old version of Julianne F. Haugh's public-domain * shadow package. It uses getspnam() to fetch passwords and pw_encrpyt() * to encrypt them. The JFH shadow code is available at * ftp://gumby.dsd.trw.com/pub/security/shadow-3.2.2.tar.Z * Newer versions seem to be compatible with SHADOW_SUN. * * - SHADOW_MDW: This is Grex's variation on the JFH shadow file system, * which uses Marcus D. Watt's interface to the password encryption. If you * ain't Grex, you ain't got it. * * - SHADOW_AIX: This is the AIX shadow password system. It uses getuserpw() * to fetch passwords and (apparantly) crypt() to encrypt them. This has * not been tested. Shadow BSD is also likely to work with AIX. The * AUTHENTICATE_AIX option is probably a better option for AIX users. * * - SHADOW_HPUX: This is the HP-UX shadow password system. It uses * getprpwnam() to fetch passwords and either crypt() or bigcrypt() to * encrypt them (I'm not sure which is right). This has not been tested * and probably doesn't work. * * - PAM: Talk to the authentication system through PAM - the plug-in * authentication module interface. This exists on Solaris 7, FreeBSD, * most versions of Linux and OS X. You'll need to create * /etc/pam.d/pwauth or edit /etc/pam.config to include entries for * pwauth. If you are using PAM to authenticate out of something you * don't need to be root to access, then you might use instead Ingo * Lutkebohle's mod_auth_pam.c module. You probably want to comment * out the UNIX_LASTLOG, MIN_UNIX_UID, and NOLOGIN_FILE options below. * * - PAM_SOLARIS: Solaris versions of PAM have some incompatibilities with * Linux/FreeBSD versions. I think HP-UX needs this too, but don't really * know. * * - PAM_SOLARIS_26: Solaris 2.6 PAM has some header file declarations and * function behaviors that don't agree with either their own documentation * or with any other implementation. Bugs, in short. This option uses * PAM with work-arounds for the Solaris 2.6 bugs. * * - PAM_OS_X: OS X keeps it's header files in a different place, so use * this option instead of the PAM option. * * - LOGIN_CONF_OPENBSD: Many BSD derived systems use a login.conf file to * configure authentication instead of (or in addition to) PAM. We * currently support authentication through this mechanism only for * OpenBSD. Of course, if your login.conf configuration is standard, you * can just use SHADOW_BSD, but if you want pwauth to respect settings * in login.conf this option can be used instead. The API used here, is * however, pretty much unique to OpenBSD and will not work on NetBSD or * FreeBSD. * * - AUTHENTICATE_AIX: AIX has it's own system for configuring authentication * via various files in the /etc/security directory. This can be used to * configure special authentication parameters on a per-user basis including * things like authenticating via kerberos and ldap and such like. We can * tie into this interface via the authenticate() system call. The module * to support this was contributed by a user and has not been tested by * the author. */ /* LOW-LEVEL OPTIONS */ /* #define SHADOW_NONE /**/ /* #define SHADOW_BSD /* FreeBSD, NetBSD, OpenBSD, BSDI, OS X */ #define SHADOW_SUN /* Linux, Solaris, IRIX */ /* #define SHADOW_JFH /**/ /* #define SHADOW_MDW /**/ /* #define SHADOW_AIX /* AIX (see also AUTHENTICATE_AIX) */ /* #define SHADOW_HPUX /* HPUX ? */ /* HIGH-LEVEL OPTIONS */ /* #define PAM /* Linux PAM or OpenPAM */ /* #define PAM_OLD_OS_X /* PAM on OS X version 10.5 or older */ /* #define PAM_SOLARIS /* PAM on Solaris other than 2.6 */ /* #define PAM_SOLARIS_26 /* PAM on Solaris 2.6 */ /* #define LOGIN_CONF_OPENBSD /* login.conf on OpenBSD */ /* #define AUTHENTICATE_AIX /* AIX authenticate() function */ /* There is also limited support for three failure logging systems (the * database that informs you that "there have been 3426 unsuccessful attempts * to log into your account since your last login" and which may disable * accounts with too many failed logins). * * If a FAILLOG option is enabled, pwauth will increment the failure count * each time there is a failed attempt to login. Depending on the * configuration, it may also deny logins to users who have had too many * bad login attempts. * * Very few Unix systems seem to have faillog files installed, so most * installations will not want this option. * * No faillog option should be used with PAM or AUTHENTICATE_AIX. This kind * of logging is handled at a lower level within those systems. * * - FAILLOG_JFH: This is associated with the JFH shadow system. Some Linux * systems may have this, but most don't seem to. Failures are logged in * the /var/adm/faillog file, and if any user accumulates too many failed * logins, future logins are denied. The faillog.h header file is part of * the JFH shadow file package. If you define PATH_FAILLOG, then this * will be used as the path of the faillog file instead of the one defined * in faillog.h. * * - FAILLOG_OPENBSD: OpenBSD has a faillog, although it does not disable * logins if any maximum is exceeded. Failure counts are kept in * /var/log/failedlogin. There is no system header file that defines the * format of this file, however. Instead the definition for the file * format is embedded in the "login" source code. Bad things will happen * if the definition there does not the match the definition in pwauth. * * Though OpenBSD's login program does not refuse further logins if the * number of failed logins has gotten too large, pwauth will do so if you * define MAX_FAIL_COUNT. If you want to use a file different than the * default, you can define this in PATH_FAILLOG. * * - FAILLOG_PWAUTH: This is meant to be used by systems that lack any * native faillog. This will keep a faillog for pwauth only. For the * moment, this is identical to FAILLOG_OPENBSD, except that the default * path of the log file is different. In future releases this may * diverge from FAILLOG_OPENBSD. Defining MAX_FAIL_COUNT and PATH_FAILLOG * has the same effect as above. * * RESET_FAIL_COUNT controls whether or not the failure count is reset to * zero when a successful login occurs. The advantages of this are obvious. * The problem with it is that it obliterates all record of how many failures * there were. Login utilities normally print out the failure count before * resetting it, so that users are notified if their account is under attack, * but pwauth cannot print messages that the user will see. The optimum * strategy would probably be to have your CGI run a separate program, such * as the 'checkfaillog' program included in this distribution, that * reports and resets the failure count. */ /* #define FAILLOG_JFH /**/ /* #define FAILLOG_OPENBSD /**/ /* #define FAILLOG_PWAUTH /**/ /* #define PATH_FAILLOG "/var/log/faillog" /**/ /* #define MAX_FAIL_COUNT 40 /**/ /* #define RESET_FAIL_COUNT /**/ /* If UNIX_LASTLOG is defined, the program will update the lastlog entry so * that there is a record of the user having logged in. This is important on * systems where you expire unused accounts and some users may only log in * via the web. If you have the lastlog.h header file, define HAVE_LASTLOG_H. * * If you are using PAM to authentication out of something other than the * unix user database, then you should disable this. The lastlog file is * index by the user's uid number, and users from other databases don't have * uid numbers. */ #define UNIX_LASTLOG /**/ #define HAVE_LASTLOG_H /**/ /* If NOLOGIN_FILE is defined to the full path name of a file, then the * existance of that file is checked on every login attempt. If it exists * all logins to accounts with uid's of MIN_NOLOGIN_UID or more will be * rejected. * * If you are using PAM, then you should disable this. In that case, this * check is better done through PAM, and the maximum uid check won't work * right with PAM. */ #define NOLOGIN_FILE "/etc/nologin" /**/ #define MIN_NOLOGIN_UID 1 /**/ /* Defining CHECK_LOGIN_EXPIRATION and CHECK_PASSWORD_EXPIRATION causes * pwauth to check if the given login has expired, or it's password has * expired. Most modern versions of Unix support these options. * * These checks have not been implemented for the SHADOW_AIX and SHADOW_HPUX * options. It's probably possible to do so for SHADOW_HPUX, but lacking a * system to test on, I haven't bothered. */ #define CHECK_LOGIN_EXPIRATION /**/ #define CHECK_PASSWORD_EXPIRATION /**/ /* It is generally sensible to restrict what users can run pwauth. Though * there are other programs that users can use to test if password guesses * are correct, like "su" and "passwd", pwauth is much easier to interface * a password guessing program to, so why not be paranoid and restrict it * as much as possible? * * If you are using pwauth with mod_auth_external, you will want to restrict * it to be runnable from whatever uid your httpd runs as. (For apache, this * is determined by the "User" directive in your httpd.conf file. It may be * called something like "nobody" or "httpd" or "apache". Usually the easiest * way to figure it out is just to do a "ps" and see what most apache processes * are running as.) * * There are two ways to configure this. First, you can compile in the uid * numbers that are allowed to run this program, by listing them on the * SERVER_UID variable below. At runtime, pwauth will check that the uid * of the user that invoked it is on this list. So if you have just one * uid that should be able to run pwauth, you can say something like: * #define SERVER_UIDS 72 * If you have several, separate them by commas, like this: * #define SERVER_UIDS 12,343,93 * The root account can always run this program, so you don't have to * to list that. If you do list it, it must be given last. * * The second option is to create a special group, called something like * "pwauth" for user id's that are allowed to run pwauth. To do this, you * should compile pwauth with the SERVER_UIDS variable UNDEFINED (that is * the definition should be removed or commented out). This will disable the * runtime uid check. Then, when you install the pwauth program, set it's * group ownership to the "pwauth" group, and permit it so that only the * owner and the group can run it. Do not permit it to be executable to * others. This has the advantage of not requiring a recompile if you want * to change the uid list. */ #define SERVER_UIDS 30 /* user "wwwrun" on the author's system */ /* If MIN_UNIX_UID is defined to an integer, logins with uid numbers less than * that value will be rejected, even if the password is correct. * * If you are using PAM to authenticate against anything other than the local * unix password file, then leave this undefined (if you define it, only login * names which are in the local unix passwd file and have uid's greater the * given value will be accepted). */ #define MIN_UNIX_UID 500 /**/ /* If IGNORE_CASE is defined, the login given is checked in two different * ways. First without any changes and then with all letters converted to * lower case. This is useful for users accustomed to the Windows environment. * This ignores the case of the login name only, not the password. */ /* #define IGNORE_CASE /**/ /* If DOMAIN_AWARE is enabled, then we we check login names to see if they * contain a backslash, and discard anything up to and including the backslash. * This is for use in environments where there are Windows users accustomed * to login names formed like "domain\username". */ /* #define DOMAIN_AWARE /**/ /* On failed authentications, pwauth will sleep for SLEEP_TIME seconds, using * a lock on the file whose full path is given by SLEEP_LOCK to prevent any * other instances of pwauth from running during that time. This is meant * to slow down password guessing programs, but could be a performance * problem on extremely heavily used systems. To disable this, don't define * SLEEP_LOCK. SLEEP_TIME defaults to 2 seconds if not defined. */ #define SLEEP_LOCK "/var/run/pwauth.lock" /* If ENV_METHOD is defined, pwauth expects mod_auth_external to be configured * SetAuthExternalMethod environment * instead of * SetAuthExternalMethod pipe * This is insecure on some versions of Unixes, but might be a bit faster. */ /* #define ENV_METHOD /**/ /* If /usr/include/paths.h exists define this. Obviously I need to autoconfig * this. */ #define PATHS_H /**/ pwauth-2.3.11/auth_mdw.c0000644000175000001440000000646011165563004013560 0ustar janusers/* ======================================================================= * Copyright 1996, Jan D. Wolter and Steven R. Weiss, 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. * * 3. The names of the authors must not be used to endorse or * promote products derived from this software without prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY * EXPRESSED 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 AUTHORS * 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. * ======================================================================= */ #include "pwauth.h" #ifdef SHADOW_MDW #ifdef NEED_UID #include #endif #include /* is -I/usr/local/include on gcc command? */ char *kg_pwhash(char *clear, char *user, char *result, int resultlen); char *pw_encrypt(); #endif /* SHADOW_MDW */ #ifdef SHADOW_MDW /* ===================== MDW Authentication ===================== */ /* CHECK_AUTH - Check a login and return a status code. * (This version for systems with kg_pwhash() call.) */ int check_auth(char *login, char *passwd) { char *cpass; char bf[40]; struct spwd *spwd= getspnam(login); #ifdef NEED_UID struct passwd *pwd; #endif #if defined(CHECK_LOGIN_EXPIRATION) || defined(CHECK_PASSWORD_EXPIRATION) int today= time(NULL)/(24*60*60); #endif if (spwd == NULL) return(errno == EACCES ? STATUS_INT_NOROOT : STATUS_UNKNOWN); #ifdef NEED_UID if ((pwd= getpwnam(login)) == NULL) return(STATUS_UNKNOWN); hisuid= pwd->pw_uid; haveuid= 1; #endif #ifdef MIN_UNIX_UID if (hisuid < MIN_UNIX_UID) return(STATUS_BLOCKED); #endif if (spwd->sp_pwdp[0] != '%') cpass= pw_encrypt(passwd, spwd->sp_pwdp); else if ((cpass= kg_pwhash(passwd, login, bf, 40)) == NULL) return(STATUS_INT_ERR); if (strcmp(cpass, spwd->sp_pwdp)) return STATUS_INVALID; #ifdef CHECK_LOGIN_EXPIRATION if (spwd->sp_expire >= 0 && spwd->sp_expire < today) return STATUS_EXPIRED; #endif #ifdef CHECK_PASSWORD_EXPIRATION /* Root forced password expiration */ if (spwd->sp_lstchg == 0) return STATUS_PW_EXPIRED; /* Normal password expiration */ if (spwd->sp_max >= 0 && spwd->sp_lstchg + spwd->sp_max < today) return STATUS_PW_EXPIRED; #endif return STATUS_OK; } #endif /* SHADOW_MDW */ pwauth-2.3.11/README0000644000175000001440000000611212252363622012460 0ustar janusers pwauth 2.3.11 Author: Jan Wolter http://www.unixpapa.com/pwauth/ Pwauth is a conceptually a simple program. You run it, giving it a login and a password, and it returns a status code telling whether or not that login/password is valid. It is designed to be combined with mod_auth_external (or mod_authnz_external) and Apache to give reasonably secure HTTP authentication from a Unix password file, though it can be used in other ways too. Mod_auth_external and mod_authnz_external are available from http://www.unixpapa.com/mod_auth_external/ Pwauth ends up being slightly more complex because of the lack of consistancy in the way different versions of Unix do authentication. It includes code for doing low-level authentication in most different versions of Unix. It also can be configured to use one higher-level interface to authentication, PAM. All configuration is compiled in, because in typical applications this program runs very frequently (on every web hit on a protected page), so the cumulative overhead of reading a config file on every run would be substantial. I believe that mod_auth_external, with the included pwauth program, is the most secure method for doing web authentication out of unix shadow password systems. Mod_auth_pam or mod_auth_system can also do this, but since they are internal authenticators, they will only work if you make the shadow password file readable to the http server. This means that if there are any exploitable vulnerabilities in the http server, then it may be possible for people to grab a copy of your shadow password file. Worse, any CGI program on your system which is not run under suExec or cgiwrap also has read access to your shadow password database, and any bugs in these might also expose your entire password database. When mod_auth_external and pwauth are used, neither the http server nor any CGI programs are given access to the shadow database. Only the "pwauth" program does. Since it is a small and simple program, it is much easier to assure that it does not have security weaknesses. Having said that, authenticating from a Unix password file is an idea that many sensible people find seriously questionable. See Apache's FAQ (http://httpd.apache.org/docs/misc/FAQ-G.html#passwdauth) for a overview of some of the issues. Pwauth has features that can address most of the arguments made here, if correctly configured, but you need to be aware of the issues and extremely careful. I've used it for many years without problems on systems that are under almost continuous assault by hackers, but none of those systems are at all typical in their security requirements. You should think hard about using this software and proceed with caution. Installation instructions are in the INSTALL file. The FORM-AUTH file discusses using this in form-based authentication applications. Configuration information is in the comments in the "pwauth.h" file. Versions of pwauth before version 2.2.8 were distributed as part of the mod_auth_external distribution. Author and Maintainer: Jan Wolter http://www.unixpapa.com/ pwauth-2.3.11/lastlog.c0000644000175000001440000000444511165563004013416 0ustar janusers/* ======================================================================= * Copyright 1996, Jan D. Wolter and Steven R. Weiss, 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. * * 3. The names of the authors must not be used to endorse or * promote products derived from this software without prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY * EXPRESSED 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 AUTHORS * 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. * ======================================================================= */ #include "pwauth.h" /* LASTLOG - update the system's lastlog */ #ifdef UNIX_LASTLOG void lastlog() { struct lastlog ll; int fd; char *hostname= getenv("HOST"); char *hostaddr= getenv("IP"); ll.ll_time= time(0L); strncpy(ll.ll_line,"http",UT_LINESIZE); if (hostname != NULL && strlen(hostname) <= UT_HOSTSIZE) strncpy(ll.ll_host,hostname,UT_HOSTSIZE); else if (hostaddr != NULL) strncpy(ll.ll_host,hostaddr,UT_HOSTSIZE); else ll.ll_host[0]= '\0'; if ((fd= open(LASTLOG,O_WRONLY)) < 0) return; lseek(fd, (long)(hisuid * sizeof(struct lastlog)), 0); write(fd, &ll, sizeof(struct lastlog)); close(fd); } #endif /*UNIX_LASTLOG*/ pwauth-2.3.11/checkfaillog.c0000644000175000001440000000565711165563004014372 0ustar janusers/* ======================================================================= * Copyright 1996, Jan D. Wolter and Steven R. Weiss, 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. * * 3. The names of the authors must not be used to endorse or * promote products derived from this software without prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY * EXPRESSED 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 AUTHORS * 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. * ======================================================================= */ #include #include #include #include #include "config.h" #include "fail_log.h" int main(int argc, char **argv) { int i, j; int reset= 0, verbose= 1; char *user= NULL, *msg= NULL; uid_t uid= getuid(); /* Parse command line */ for (i= 1; i < argc; i++) { if (argv[i][0] == '-') { for (j= 1; argv[i][j] != '\0'; j++) { switch (argv[i][j]) { case 'z': reset= 1; break; case 's': verbose= 0; break; default: goto usage; } } } else if (user == NULL) user= argv[i]; else goto usage; } /* Root can run this on other user's accounts */ if (user != NULL) { struct passwd *pw; if ((pw= getpwnam(user)) == NULL) { fprintf(stderr,"%s: User %s does not exist.\n", argv[0], user); exit(2); } if (uid != 0 && pw->pw_uid != uid) { fprintf(stderr,"%s: Only root can access other user's accounts.\n", argv[0]); exit(3); } uid= pw->pw_uid; } /* Do the thing */ #if defined(FAILLOG_JFH) || defined(FAILLOG_OPENBSD) msg= check_fails(uid, reset, verbose); #endif /* Output the result */ if (msg != NULL) puts(msg); else if (!verbose) puts("0:::"); exit(0); usage: fprintf(stderr,"usage: %s [-z] [-s] [user]\n", argv[0]); exit(1); } pwauth-2.3.11/snooze.c0000644000175000001440000000457711643054464013302 0ustar janusers/* ======================================================================= * Copyright 1996, Jan D. Wolter and Steven R. Weiss, 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. * * 3. The names of the authors must not be used to endorse or * promote products derived from this software without prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY * EXPRESSED 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 AUTHORS * 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. * ======================================================================= */ #include "pwauth.h" #ifdef SLEEP_LOCK /* SNOOZE - Do a serialized sleep of the given number of seconds. This means, * wait till no other pwauth processes are in their sleeps, and then sleep * for the number of seconds given. Note that a snooze(0) may lead to some * sleep time, if other pwauth processes are in sleeps. */ snooze(int seconds) { int slfd; struct flock lock; lock.l_type= F_WRLCK; lock.l_whence= SEEK_SET; lock.l_start= 0; lock.l_len= 0; /* Lock the sleep-lock file to serialize our sleeps */ if ((slfd= open(SLEEP_LOCK,O_CREAT|O_RDWR,0644)) >= 0) fcntl(slfd,F_SETLKW,&lock); sleep(seconds); /* Release sleep-lock file */ /*lock.l_type= F_UNLCK; fcntl(slfd,F_SETLK,&lock);*/ close(slfd); } #endif pwauth-2.3.11/fail_log.h0000644000175000001440000000227611165563004013532 0ustar janusers/* For now, FAILLOG_PWAUTH is just FAILLOG_OPENBSD */ #ifdef FAILLOG_PWAUTH # define FAILLOG_OPENBSD # ifndef PATH_FAILLOG # define PATH_FAILLOG "/var/log/pwauth.faillog" # endif #endif #ifdef FAILLOG_JFH # define KEEP_FAILLOG # include "faillog.h" # ifndef NEED_UID # define NEED_UID # endif # ifndef PATH_FAILLOG # define PATH_FAILLOG FAILFILE # endif #endif #ifdef FAILLOG_OPENBSD # define KEEP_FAILLOG /* The following is clipped from OpenBSD 3.5 src/usr.bin/login/failedlogin.c * If you are actually using this on OpenBSD to update the same faillog file * that is used by the login program, then it is important that this * definition match the definition there. */ struct badlogin { char bl_line[UT_LINESIZE]; /* tty used */ char bl_name[UT_NAMESIZE]; /* remote username */ char bl_host[UT_HOSTSIZE]; /* remote host */ time_t bl_time; /* time of the login attempt */ size_t count; /* number of bad logins */ }; # ifndef NEED_UID # define NEED_UID # endif # ifndef PATH_FAILLOG # ifdef _PATH_FAILEDLOGIN # define PATH_FAILLOG _PATH_FAILEDLOGIN # else # define PATH_FAILLOG "/var/log/failedlogin" # endif # endif #endif pwauth-2.3.11/auth_pam.c0000644000175000001440000001333011551567770013555 0ustar janusers/* ======================================================================= * Copyright 1996, Jan D. Wolter and Steven R. Weiss, 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. * * 3. The names of the authors must not be used to endorse or * promote products derived from this software without prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY * EXPRESSED 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 AUTHORS * 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. * ======================================================================= */ #include "pwauth.h" #if defined(PAM_SOLARIS_26) || defined(PAM_SOLARIS) || defined(PAM_OS_X) #define PAM #endif /* PAM_SOLARIS_26 or PAM_SOLARIS */ #ifdef PAM #ifdef NEED_UID #include #endif #ifdef PAM_OLD_OS_X #include #else #include #endif #endif #ifdef PAM /* ========================= PAM Authentication ======================== */ /* Based on version by Karyl Stein (xenon313@arbornet.org) */ /* and on parts of mod_auth_pam.c by Ingo Lutkebohnle */ /* Application data structure passed to PAM_conv: */ struct ad_user { char *login; char *passwd; }; /* The pam_unix.so library in Solaris 2.6 fails to pass along appdata_ptr * when it calls the conversation function. So we use a global variable. */ #ifdef PAM_SOLARIS_26 struct ad_user user_info; #define PAM_SOLARIS #endif /* PAM_SOLARIS_26 */ /* PAM_CONF - PAM Conversation Function. Called by PAM to get login/password. * Note that "appdata_ptr" is really a "struct ad_user *" structure. */ #ifdef PAM_SOLARIS /* In Solaris PAM, msg is a pointer to a pointer to a size num_msg array of * pam_message structures. */ # define msgi(i) ((*msg)[i]) #else /* In Linux PAM and OpenPAM, msg is a pointer to a size num_msg array of * pointers to pam_message structures. */ # define msgi(i) (*(msg[i])) #endif #ifdef PAM_SOLARIS_26 int PAM_conv (int num_msg, struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { struct ad_user *user= &user_info; #else int PAM_conv (int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { struct ad_user *user= (struct ad_user *)appdata_ptr; #endif /* PAM_SOLARIS_26 */ struct pam_response *response; int i; /* Sanity checking */ if (msg == NULL || resp == NULL || user == NULL) return PAM_CONV_ERR; #ifdef PAM_SOLARIS if (*msg == NULL) return PAM_CONV_ERR; #endif response= (struct pam_response *) malloc(num_msg * sizeof(struct pam_response)); for (i= 0; i < num_msg; i++) { response[i].resp_retcode= 0; response[i].resp= NULL; switch (msgi(i).msg_style) { case PAM_PROMPT_ECHO_ON: /* Store the login as the response */ /* This likely never gets called, since login was on pam_start() */ response[i].resp= appdata_ptr ? (char *)strdup(user->login) : NULL; break; case PAM_PROMPT_ECHO_OFF: /* Store the password as the response */ response[i].resp= appdata_ptr ? (char *)strdup(user->passwd) : NULL; break; case PAM_TEXT_INFO: case PAM_ERROR_MSG: /* Shouldn't happen since we have PAM_SILENT set. If it happens * anyway, ignore it. */ break; default: /* Something strange... */ if (response != NULL) free(response); return PAM_CONV_ERR; } } /* On success, return the response structure */ *resp= response; return PAM_SUCCESS; } /* CHECK_AUTH - Check a login and return a status code. * (This version for systems using PAM.) */ int check_auth(char *login, char *passwd) { #ifndef PAM_SOLARIS_26 struct ad_user user_info= {login, passwd}; #endif /* PAM_SOLARIS_26 */ struct pam_conv conv= { PAM_conv, (void *)&user_info }; pam_handle_t *pamh= NULL; int retval; #ifdef NEED_UID struct passwd *pwd; if ((pwd= getpwnam(login)) == NULL) return STATUS_UNKNOWN; hisuid= pwd->pw_uid; haveuid= 1; #endif #ifdef MIN_UNIX_UID if (hisuid < MIN_UNIX_UID) return STATUS_BLOCKED; #endif #ifdef PAM_SOLARIS_26 user_info.login= login; user_info.passwd= passwd; #endif /* PAM_SOLARIS_26 */ retval= pam_start("pwauth", login, &conv, &pamh); if (retval == PAM_SUCCESS) retval= pam_authenticate(pamh, PAM_SILENT); if (retval == PAM_SUCCESS) retval= pam_acct_mgmt(pamh, 0); /* permitted access? */ if (pam_end(pamh,retval) != PAM_SUCCESS) /* close PAM */ { pamh= NULL; return STATUS_INT_ERR; } /* On failure we always return STATUS_UNKNOWN although we can't tell * if the failure was because of a bad login or a bad password */ return (retval == PAM_SUCCESS ? STATUS_OK : STATUS_UNKNOWN); } #endif /* PAM */ pwauth-2.3.11/auth_sun.c0000644000175000001440000000723011165563004013572 0ustar janusers/* ======================================================================= * Copyright 1996, Jan D. Wolter and Steven R. Weiss, 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. * * 3. The names of the authors must not be used to endorse or * promote products derived from this software without prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY * EXPRESSED 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 AUTHORS * 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. * ======================================================================= */ #include "pwauth.h" #ifdef SHADOW_SUN #ifdef NEED_UID #include #endif #include struct spwd *getspnam(); char *crypt(); #endif /* SHADOW_SUN */ #ifdef SHADOW_JFH #ifdef NEED_UID #include #endif #include /* this may be hidden in /usr/local/include */ struct spwd *getspnam(); char *pw_encrypt(); #endif /* SHADOW_JFH */ #if defined(SHADOW_JFH) || defined(SHADOW_SUN) /* ===================== JFH and SUN Authentication ===================== */ /* CHECK_AUTH - Check a login and return a status code. * (This version for systems with getspnam() call.) */ int check_auth(char *login, char *passwd) { char *cpass; struct spwd *spwd= getspnam(login); #ifdef NEED_UID struct passwd *pwd; #endif #if defined(CHECK_LOGIN_EXPIRATION) || defined(CHECK_PASSWORD_EXPIRATION) int today= time(NULL)/(24*60*60); #endif if (spwd == NULL) return(errno == EACCES ? STATUS_INT_NOROOT : STATUS_UNKNOWN); #ifdef NEED_UID if ((pwd= getpwnam(login)) == NULL) return(STATUS_UNKNOWN); hisuid= pwd->pw_uid; haveuid= 1; #endif #ifdef MIN_UNIX_UID if (hisuid < MIN_UNIX_UID) return(STATUS_BLOCKED); #endif #ifdef SHADOW_JFH cpass= pw_encrypt(passwd, spwd->sp_pwdp); #else cpass= crypt(passwd, spwd->sp_pwdp); #endif if (strcmp(cpass, spwd->sp_pwdp)) return STATUS_INVALID; #ifdef CHECK_LOGIN_EXPIRATION if (spwd->sp_expire >= 0 && spwd->sp_expire < today) return STATUS_EXPIRED; #endif #ifdef CHECK_PASSWORD_EXPIRATION /* Root forced password expiration */ if (spwd->sp_lstchg == 0) return STATUS_PW_EXPIRED; /* Normal password expiration */ /* We used to have sp_lstchg + sp_max + sp_inact < today * here, apparantly during the inact period you are only supposed to be able * to get on to change your password, not anything else, show we shouldn't * allow access during that period. */ if (spwd->sp_max >= 0 && spwd->sp_lstchg + spwd->sp_max < today) return STATUS_PW_EXPIRED; #endif return STATUS_OK; } #endif /* SHADOW_JFH || SHADOW_SUN */ pwauth-2.3.11/pwauth.h0000644000175000001440000000771711165563004013273 0ustar janusers/* ======================================================================= * Copyright 1996, Jan D. Wolter and Steven R. Weiss, 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. * * 3. The names of the authors must not be used to endorse or * promote products derived from this software without prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY * EXPRESSED 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 AUTHORS * 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. * ======================================================================= */ #include #include #include #include #include #include #include #include #include #include #include /* Configuration is meant to be done in config.h */ #include "config.h" /* Status codes returned from pwauth - note normally we return STATUS_UNKNOWN * if the login name does not exist and STATUS_INVALID if the login exists * but the password is incorrect. However, in some configurations it is not * possible to distinguish between these two cases, so STATUS_UNKNOWN is * returned for both. */ #define STATUS_OK 0 /* Valid Login */ #define STATUS_UNKNOWN 1 /* Login doesn't exist or password incorrect */ #define STATUS_INVALID 2 /* Password was incorrect */ #define STATUS_BLOCKED 3 /* UID is below minimum allowed to use this */ #define STATUS_EXPIRED 4 /* Login ID has passed it's expiration date */ #define STATUS_PW_EXPIRED 5 /* Password has expired and must be changed */ #define STATUS_NOLOGIN 6 /* Logins have been turned off */ #define STATUS_MANYFAILS 7 /* Bad login limit exceeded */ #define STATUS_INT_USER 50 /* pwauth was run by wrong uid */ #define STATUS_INT_ARGS 51 /* login/password not passed in correctly */ #define STATUS_INT_ERR 52 /* Miscellaneous internal errors */ #define STATUS_INT_NOROOT 53 /* pwauth cannot read password database */ #ifdef IGNORE_CASE # include #endif #ifdef UNIX_LASTLOG # define NEED_UID # include # ifdef HAVE_LASTLOG_H # include # endif # ifndef UT_LINESIZE # define UT_LINESIZE 8 # endif # ifndef UT_HOSTSIZE # define UT_HOSTSIZE 16 # endif # if !defined(LASTLOG) && defined(PATHS_H) # include # ifdef _PATH_LASTLOG # define LASTLOG _PATH_LASTLOG # endif # endif # ifndef LASTLOG # define LASTLOG "/usr/adm/lastlog" # endif #endif /*UNIX_LASTLONG*/ #ifdef NOLOGIN_FILE # ifndef MIN_NOLOGIN_UID # define MIN_NOLOGIN_UID 0 # endif # if MIN_NOLOGIN_UID > 0 # define NEED_UID # endif #endif #include "fail_log.h" #ifdef MIN_UNIX_UID # if MIN_UNIX_UID <= 0 # undef MIN_UNIX_UID # else # ifndef NEED_UID # define NEED_UID # endif # endif #endif #ifdef NEED_UID extern int hisuid; extern int haveuid; #endif #ifndef SLEEP_TIME # define SLEEP_TIME 2 #endif #ifndef BFSZ # define BFSZ 1024 #endif pwauth-2.3.11/auth_openbsd.c0000644000175000001440000001124611165563004014421 0ustar janusers/* ======================================================================= * Copyright 1996, Jan D. Wolter and Steven R. Weiss, 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. * * 3. The names of the authors must not be used to endorse or * promote products derived from this software without prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY * EXPRESSED 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 AUTHORS * 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. * ======================================================================= */ #include "pwauth.h" #ifdef LOGIN_CONF_OPENBSD #include #include #include /* =================== OpenBSD LOGIN.CONF Authentication =================== */ /* CHECK_AUTH - Check a login and return a status code. * (This version for systems with auth_usercheck() call.) */ int check_auth(char *login, char *passwd) { auth_session_t *as; login_cap_t *lc; struct passwd *pwd; char *style; int state, exists; /* The following would work, but it doesn't return the logincap to us, * and we will need it below to check for nologin files. * * as= auth_usercheck(login, NULL, NULL, passwd); */ /* Get the login cap for this user from the database */ pwd= getpwnam(login); exists= (pwd != NULL); #ifdef NEED_UID if (exists) {hisuid= pwd->pw_uid; haveuid= 1;} #endif if ((lc = login_getclass(pwd ? pwd->pw_class : NULL)) == NULL) return STATUS_INT_ERR; /* Get the login style to use */ if ((style= login_getstyle(lc, NULL, NULL)) == NULL) { login_close(lc); return STATUS_INT_ERR+1; } /* Start a BSD authentication session and set it up */ if ((as= auth_open()) == NULL) { login_close(lc); return STATUS_INT_ERR+2; } auth_setitem(as, AUTHV_SERVICE, "response"); auth_setdata(as, "", 1); auth_setdata(as, passwd, strlen(passwd)+1); /* Run the authenticator */ as= auth_verify(as, style, login, lc->lc_class, (char *)NULL); /* Check if login is expired */ #ifdef CHECK_LOGIN_EXPIRATION if (auth_check_expire(as) < 0) { login_close(lc); auth_close(as); return STATUS_EXPIRED; } #endif /* Check if password has expired */ #ifdef CHECK_PASSWORD_EXPIRATION if (auth_check_change(as) < 0) { login_close(lc); auth_close(as); return STATUS_PW_EXPIRED; } #endif /* Get the results */ pwd= auth_getpwd(as); exists= exists || (pwd != NULL); state= auth_getstate(as); auth_close(as); #ifdef NEED_UID /* prefer this uid number to any one we got before - probably the same */ if (pwd != NULL) {hisuid= pwd->pw_uid; haveuid= 1;} #endif if (!(state & AUTH_OKAY)) { login_close(lc); return (exists ? STATUS_INVALID : STATUS_UNKNOWN); } /* Check for nologin file */ if (!login_getcapbool(lc, "ignorenologin", 0)) { /* If ignorelogin is not define, nologin should be defined */ char *nologin= login_getcapstr(lc, "nologin", "", NULL); login_close(lc); if (nologin == NULL) return STATUS_INT_ERR+4; /* check existance of nologin file defined for class in login.conf */ if (*nologin != '\0') { int rc= access(nologin,F_OK); free(nologin); if (rc == 0) return STATUS_NOLOGIN; } /* Check existance of stock nologin file */ #ifdef _PATH_NOLOGIN if (access(_PATH_NOLOGIN,F_OK) == 0) return STATUS_NOLOGIN; #endif } else login_close(lc); /* Check if uid is above minimum */ #ifdef MIN_UNIX_UID if (haveuid && hisuid < MIN_UNIX_UID) return(STATUS_BLOCKED); #endif return STATUS_OK; } #endif /* LOGIN_CONF_OPENBSD */ pwauth-2.3.11/auth_bsd.c0000644000175000001440000000560011165563004013534 0ustar janusers/* ======================================================================= * Copyright 1996, Jan D. Wolter and Steven R. Weiss, 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. * * 3. The names of the authors must not be used to endorse or * promote products derived from this software without prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY * EXPRESSED 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 AUTHORS * 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. * ======================================================================= */ #include "pwauth.h" #ifdef SHADOW_BSD /* BSD shadow password system requires no special coding - good job */ #define SHADOW_NONE #endif /* SHADOW_BSD */ #ifdef SHADOW_NONE #include #include /* ===================== NONE Authentication ===================== */ /* CHECK_AUTH - Check a login and return a status code. * (This version for systems with only a getpwnam() call.) */ int check_auth(char *login, char *passwd) { char *cpass; struct passwd *pwd= getpwnam(login); #if defined(CHECK_LOGIN_EXPIRATION) || defined(CHECK_PASSWORD_EXPIRATION) time_t now= time(NULL); #endif if (pwd == NULL) return(STATUS_UNKNOWN); #ifdef NEED_UID if (pwd->pw_passwd[0] == '*' && pwd->pw_passwd[1] == '\0') return STATUS_INT_NOROOT; hisuid= pwd->pw_uid; haveuid= 1; #endif #ifdef MIN_UNIX_UID if (hisuid < MIN_UNIX_UID) return(STATUS_BLOCKED); #endif cpass= crypt(passwd, pwd->pw_passwd); if (strcmp(cpass, pwd->pw_passwd)) return STATUS_INVALID; #ifdef CHECK_LOGIN_EXPIRATION if (pwd->pw_expire > 0 && pwd->pw_expire <= now) return STATUS_EXPIRED; #endif #ifdef CHECK_PASSWORD_EXPIRATION if (pwd->pw_change > 0 && pwd->pw_change <= now) return STATUS_PW_EXPIRED; #endif return STATUS_OK; } #endif /* SHADOW_NONE */ pwauth-2.3.11/main.c0000644000175000001440000000751312252363312012672 0ustar janusers/* ======================================================================= * Copyright 1996, Jan D. Wolter and Steven R. Weiss, 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. * * 3. The names of the authors must not be used to endorse or * promote products derived from this software without prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY * EXPRESSED 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 AUTHORS * 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. * ======================================================================= */ #include "pwauth.h" #ifdef NEED_UID int hisuid; int haveuid= 0; #endif #ifdef SERVER_UIDS /* Array of uid numbers that may run this program */ int server_uids[]= {SERVER_UIDS, 0}; #endif main(int argc, char **argv) { #ifdef ENV_METHOD char *login, *passwd; #else char login[BFSZ+1], passwd[BFSZ+1]; char *c; #endif #ifdef SERVER_UIDS int uid; #endif int i; int status; struct rlimit rlim; /* Don't dump core (could contain part of shadow file) */ rlim.rlim_cur = rlim.rlim_max = 0; (void)setrlimit(RLIMIT_CORE, &rlim); #ifdef SERVER_UIDS /* Check that we were invoked by one of the listed uids or by root */ uid= getuid(); for (i= 0; server_uids[i] != 0 && server_uids[i] != uid; i++) ; if (uid != server_uids[i]) exit(STATUS_INT_USER); #endif /* Get the arguments (login and password) */ #ifdef ENV_METHOD if ((login= getenv("USER")) == NULL || (passwd= getenv("PASS")) == NULL) exit(STATUS_INT_ARGS); #else if (fgets(login, BFSZ, stdin) == NULL || fgets(passwd, BFSZ, stdin) == NULL) exit(STATUS_INT_ARGS); if ((c= strchr(login,'\n')) != NULL) *c= '\0'; if ((c= strchr(passwd,'\n')) != NULL) *c= '\0'; #endif #ifdef DOMAIN_AWARE if ((c= strchr(login,'\\')) != NULL) strcpy (login,++c); #endif /* Check validity of login/passwd */ status= check_auth(login,passwd); #ifdef IGNORE_CASE if (status == STATUS_UNKNOWN) { int uc= 0; for (c= login; *c != '\0'; c++) if (isascii(*c) && isupper(*c)) { uc= 1; *c= tolower(*c); } if (uc) status= check_auth(login,passwd); } #endif bzero(passwd,strlen(passwd)); /* Erase plain-text from our memory */ #if defined(FAILLOG_JFH) || defined(FAILLOG_OPENBSD) || defined(FAILLOG_PWAUTH) if (status == STATUS_OK && !check_fails()) status= STATUS_MANYFAILS; #endif #ifdef NOLOGIN_FILE if (status == STATUS_OK && !check_nologin()) status= STATUS_NOLOGIN; #endif if (status == STATUS_OK) { /* Good login */ #ifdef UNIX_LASTLOG lastlog(); #endif #ifdef SLEEP_LOCK snooze(0); #endif exit(STATUS_OK); } else { /* Bad login */ #ifdef KEEP_FAILLOG log_failure(); #endif #ifdef SLEEP_LOCK snooze(SLEEP_TIME); #endif exit(status); } } pwauth-2.3.11/unixgroup0000755000175000001440000000422111165563004013563 0ustar janusers#!/usr/bin/perl # # This is a group authenticator for use with mod_auth_external using the # "environment" argument passing method. If you are using mod_authnz_external, # then a much better choice is to use mod_authz_unixgroup for group checking. # It checks if the Unix user ID passed in the USER environment variable is in # any of Unix groups (names or numbers) listed in the GROUP environment # variable. It returns # 0 - if the user is in one of the groups # 1 - if the user is not in any of the groups # 2 - if the user does not exist. # # This isn't a very efficient way to do group checking. I hope to find time # to do something better someday. # # Typical Usage: # In httpd.conf declare an pwauth authenticator and a unixgroup authenticator: # # AddExternalAuth pwauth /path/to/pwauth # SetExternalAuthMethod pwauth pipe # AddExternalGroup unixgroup /path/to/unixgroup # SetExternalGroupMethod unixgroup environment # # In .htaccess file do something like # # AuthType Basic # AuthName SystemName # AuthExternal pwauth # GroupExternal unixgroup # require group customers admins staff # # Here "SystemName" is a string that will be included in the pop-up login # box, all Unix groupnames which are to be allowed to login are listed on the # "require group" command. If you are using this with mod_authnz_external, # you'll need to add the directive "AuthBasicProvider external", but if you are # using mod_authnz_external, you should be using mod_authz_unixgroup instead # of this. # Get primary GID number for the user $user= $ENV{USER}; $gid= (getpwnam($user))[3]; exit 2 if !defined $gid; # user does not exist - Reject # Loop through groups foreach $group (split ' ', $ENV{GROUP}) { if ($group =~ /^\d+$/) { # Group given as GID number exit 0 if ($group == $gid); # Get list of members $members= (getgrgid($group))[3]; } else { # Group given by name ($gname, $x, $ggid, $members)= getgrnam($group); next if !$gname; # skip non-existant group exit 0 if ($ggid == $gid); } # Check if user is in member list foreach $mem (split ' ',$members) { exit 0 if ($user eq $mem); } } exit 1; pwauth-2.3.11/CHANGES0000644000175000001440000001102212252363607012572 0ustar janusersPwauth Change Log ================= VERSION 2.3.11 - Dec 12, 2013 - Fix fail logging code, which was badly broken. Thanks to lsmarandir for this. - Don't define "uid" variable if SERVER_UID is not defined. - Removed old-style strchr prototype. - Clarified some instructions in config.h. VERSION 2.3.10 - Oct 5, 2011 - Changed the serialized sleep code in snooze.c to use fcntl() locking instead of flock() locking. Fcntl() locking is a POSIX standard and is likely to work better on more systems, notably including Solaris which doesn't seem to support flock() at all any more. - Minor fixes to typos in various documentation. VERSION 2.3.9 - May 2, 2011 - Add AUTHENTICATE_AIX option for authenticating via AIX's authentication configuration system. Thanks to Hans Dieter Petersen of the University of Bonn for this implementation. - Renamed PAM_OS_X configuration setting to PAM_OLD_OS_X since it only is needed for OS X 10.5 and older. - Rearranged ifdef's so that undefining SLEEP_LOCK actually completely disables the sleep-on-failure behavior. - Minor documentation fixes VERSION 2.3.8 - Apr 3, 2009 - Undefining SERVER_UIDS now disables the runtime uid check. Documentation added to suggest using this, together with group execution permissions on the binary, to create a group for users who can run pwauth. Thanks to Adi Kriegisch for suggesting this. - Return a distinct status code if authentication fails because we are not running as root. This is currently only done for SHADOW_SUN, SHADOW_BSD, SHADOW_AIX, and SHADOW_MDW. It's just to help confused installers figure out why things aren't working. - Warn installers that they may need to install PAM development packages. VERSION 2.3.7 - Jan 9, 2009 - DOCUMENTATION FIX ONLY - Corrected erroneous AuthBasicProvider command in INSTALL file. VERSION 2.3.6 - May 19, 2008 - Add PAM_OS_X option. - Clarified comments in config.h. - Replace wildly obsolete inclusion of strings.h with inclusion of string.h VERSION 2.3.5 - Dec 17, 2007 - Fixed return codes from AIX and HPUX versions (thanks to Paul Marvin for finding this bug). VERSION 2.3.4 - Nov 11, 2007 - Fixed PAM_SOLARIS define. VERSION 2.3.3 - Sep 1, 2007 - Don't allow logins during inactive period after password expiration. VERSION 2.3.2 - Feb 19, 2006 - Update documentation to discuss usage with mod_authnz_external. - Update documentation to discuss use of mod_authz_unixgroup instead of the unixgroup script. - Drop "development release" notation. VERSION 2.3.1 - Jan 10, 2005 - Fix the checks for expired passwords and expired accounts for LOGIN_CONF_OPENBSD configurations. - Fix the handling of the pam_message argument to the conversation function for Solaris. The old handling was right for Linux PAM and OpenPAM, but not for Solaris. However, the bug occurs only when the PAM modules passes more than one prompt to the conversation function, which should probably never happen. VERSION 2.3.0 - Sep 28, 2004 - Status code values returned by pwauth have changed. 0 is still success, of course, but there is a much wider range of non-zero error codes returned to indicate different causes of login failure. - Pwauth now checks for /etc/nologin file by default. Undefine NOLOGIN_FILE in config.h if you don't want this behavior. - Pwauth now checks if an account is expired and refuses logins if it is. Undefine CHECK_LOGIN_EXPIRATION in config.h if you don't want this behavior. - Pwauth now checks if an account's password has expired and refuses logins if it is and if logins are supposed to be disabled when the password has expired. Undefine CHECK_PASSWORD_EXPIRATION if you don't want this behavior. - Added support for authenticating through login.conf interface on OpenBSD. Support for login.conf systems on other versions of Unix is not yet here. - Added support for OpenBSD failure logs. - Source code split into multiple files. - Added 'checkfaillog' program which CGIs can run to report/reset failures and admins can run to reset failure counts. VERSION 2.2.8 - Sep 25, 2004 - First separate distribution of pwauth. This version is identical to the version in the mod_auth_external version 2.2.8 package, except for repackaging and slight modifications to the documentation. Versions of pwauth previous to version 2.2.8 were distributed as part of the mod_auth_external package, and change-log information is included in pwauth change log. pwauth-2.3.11/fail_log.c0000644000175000001440000001312512252363454013525 0ustar janusers/* ======================================================================= * Copyright 1996, Jan D. Wolter and Steven R. Weiss, 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. * * 3. The names of the authors must not be used to endorse or * promote products derived from this software without prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY * EXPRESSED 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 AUTHORS * 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. * ======================================================================= */ #include "pwauth.h" #ifdef RESET_FAIL_COUNT #define MODE_FAILLOG O_RDWR #else #define MODE_FAILLOG O_RDONLY #endif #ifdef FAILLOG_JFH /* CHECK_FAILS - Check if the account is disable dued to the maximum number of * failed logins being exceeded. Returns true if the account is OK to log * into or if the faillog information doesn't exist. This never resets the * bad login count to zero. It should, but I don't really believe anyone * uses this anymore, so I'm not going to bother implementing that. */ int check_fails() { int result= 1; struct faillog flog; int flfd; if (!haveuid) return 1; if ((flfd= open(PATH_FAILLOG,MODE_FAILLOG)) >= 0) { lseek(flfd, hisuid * sizeof(struct faillog), 0); result= (read(flfd, &flog, sizeof(struct faillog)) != sizeof(struct faillog)) || flog.fail_max == 0 || flog.fail_cur < flog.fail_max; close(flfd); } return result; } /* LOG_FAILURE - Do whatever we need to do to log a failed login attempt. */ void log_failure() { int flfd; struct faillog flog; if (!haveuid) return; /* Log the failure in /var/adm/faillog - JFH style */ if ((flfd= open(PATH_FAILLOG,O_RDWR)) > 0) { /* Read the user's record (indexed by uid) */ lseek(flfd, hisuid * sizeof(struct faillog), 0); if (read(flfd,&flog,sizeof(struct faillog)) != sizeof(struct faillog)) { flog.fail_cnt= 0; flog.fail_max= 0; flog.fail_time= 0L; flog.failline[0]= '\0'; } /* Increment the count (checking for overflow) */ if (flog.fail_cnt + 1 > 0) flog.fail_cnt++; flog.fail_time= time(0L); strcpy(flog.fail_line,"http"); /* Write it back out */ lseek(flfd, hisuid * sizeof(struct faillog), 0); write(flfd, &flog, sizeof(struct faillog)); close(flfd); } } #endif /* FAILLOG_JFH */ #ifdef FAILLOG_OPENBSD /* CHECK_FAILS - Check if the account is disabled due to the maximum number of * failed logins being exceeded. Returns true if the account is OK to log * into or if the faillog information doesn't exist. If the count has not * been exceeded, then the count is reset to zero. */ int check_fails() { int result= 1; #if defined(MAX_FAIL_COUNT) || defined(RESET_FAIL_COUNT) struct badlogin flog; int flfd; if (!haveuid) return 1; if ((flfd= open(PATH_FAILLOG,MODE_FAILLOG)) >= 0) { /* Read user's record (indexed by uid) */ lseek(flfd, hisuid * sizeof(struct badlogin), 0); if (read(flfd, &flog, sizeof(struct badlogin)) != sizeof(struct badlogin) || flog.bl_time == 0) memset(&flog, 0, sizeof(struct badlogin)); #ifdef MAX_FAIL_COUNT result= (flog.count < MAX_FAIL_COUNT); #endif #ifdef RESET_FAIL_COUNT if (result && flog.count > 0) { flog.count= 0; lseek(flfd, hisuid * sizeof(struct badlogin), 0); write(flfd, &flog, sizeof(struct badlogin)); } #endif close(flfd); } #endif /* MAX_FAIL_COUNT || RESET_FAIL_COUNT */ return result; } /* LOG_FAILURE - Do whatever we need to do to log a failed login attempt. */ log_failure() { int flfd; struct badlogin flog; char *host; if (!haveuid) return; /* Log the failure in /var/log/failedlogin - OpenBSD style */ if ((flfd= open(PATH_FAILLOG,O_RDWR)) > 0) { /* Read user's record (indexed by uid) */ lseek(flfd, hisuid * sizeof(struct badlogin), 0); if (read(flfd, &flog, sizeof(struct badlogin)) != sizeof(struct badlogin) || flog.bl_time == 0) memset(&flog, 0, sizeof(struct badlogin)); /* Increment the count (checking for overflow) */ if (flog.count + 1 > 0) flog.count++; /* Set time and remote host names */ time(&flog.bl_time); strncpy(flog.bl_line, "http", sizeof(flog.bl_line)); if ((host= getenv("HOST")) == NULL) host= getenv("IP"); if (host != NULL) strncpy(flog.bl_host, host, sizeof(flog.bl_host)); else flog.bl_host[0]= '\0'; flog.bl_name[0]= '\0'; /* Remote name always unknown */ /* Write it back out */ lseek(flfd, hisuid * sizeof(struct badlogin), 0); write(flfd, &flog, sizeof(struct badlogin)); close(flfd); } } #endif pwauth-2.3.11/fail_check.c0000644000175000001440000001300611165563004014012 0ustar janusers/* ======================================================================= * Copyright 1996, Jan D. Wolter and Steven R. Weiss, 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. * * 3. The names of the authors must not be used to endorse or * promote products derived from this software without prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY * EXPRESSED 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 AUTHORS * 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. * ======================================================================= */ #include #include #include #include #include #include "config.h" #include "fail_log.h" #ifdef FAILLOG_JFH /* CHECK_FAILS - Read the faillog file entry for the given uid. Return NULL * if there have been no failures. If there have been failures, reset the * count to zero if "reset" is true, and Return a string describing the state. * The format of the string depends on the versbose flag. * verbose=0 * :::\n * verbose=1 * failures since last login. Last was