From: jan@unixpapa.com Date: Fri, 3 Apr 2009 19:36:15 +0000 (+0000) Subject: Initial Import X-Git-Tag: pwauth-2.3.10~7 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9a3b28defc8f9ea6ee52522d87f575d4620deeeb;p=pwauth Initial Import --- 9a3b28defc8f9ea6ee52522d87f575d4620deeeb diff --git a/pwauth/CHANGES b/pwauth/CHANGES new file mode 100644 index 0000000..933022c --- /dev/null +++ b/pwauth/CHANGES @@ -0,0 +1,76 @@ +Pwauth Change Log +================= + +VERSION 2.3.8 - + - 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. diff --git a/pwauth/FORM_AUTH b/pwauth/FORM_AUTH new file mode 100644 index 0000000..7892cc7 --- /dev/null +++ b/pwauth/FORM_AUTH @@ -0,0 +1,60 @@ + 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://www.wwnet.net/~janc/auth.html for more information +about this, including explainations 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. diff --git a/pwauth/INSTALL b/pwauth/INSTALL new file mode 100644 index 0000000..1036089 --- /dev/null +++ b/pwauth/INSTALL @@ -0,0 +1,174 @@ +Installation Notes for pwauth.c +------------------------------- + +This program is designed to be used with Apache to authenticate users out +of the password file. To use it for basic authentication, follow the +instructions below. See the FORM_AUTH instructions for notes on using it +with other forms of authentication. + + (1) Install mod_auth_external or mod_authnz_external in Apache. This + version of pwauth requires mod_auth_external version 2.1.1 or later. + You can either recompile Apache with the new modules, or install them + as dynamically loaded modules. See the module installation instructions + for detail. + + (2) Edit the config.h file in this directory to set the configuration + appropriate for your system. There are lots of comments in the file. + + (3) If you are using PAM on Linux, you could be missing the header files + you need to compile the auth_pam.c file. You may need to load some + sort of PAM development module this isn't part of the standard install + to get these headers. + + (4) Edit the Makefile in this directory, setting appropriate CC, LIB and + LOCALFLAGS variables. + + (5) Do "make" to compile the program. + + (6) If you are using PAM, you need to do some work on the configuration + files. Depending on your operating system, you'll either need to + create a /etc/pam.d/pwauth file or edit the /etc/pam.conf file. + + If you have a /etc/pam.d directory, you need to create a file named + "pwauth" inside it. To authenticate out of the Unix Shadow file + under Redhat 6.x, the /etc/pam.d/pwauth file should look something like + this: + + auth required /lib/security/pam_pwdb.so shadow nullok + auth required /lib/security/pam_nologin.so + account required /lib/security/pam_pwdb.so + + Under OS X 10.4.11, something like the following works (possibly the + pam_securityserver line should be removed): + + auth required pam_nologin.so + auth sufficient pam_securityserver.so + auth sufficient pam_unix.so + auth required pam_deny.so + account required pam_permit.so + + If you have a /etc/pam.conf file instead of a /etc/pam.d directory, + then you need to add appropriate lines to that instead. For + Solaris 2.6, you need to add lines like this to authenticate out + of the shadow file: + + pwauth auth required /lib/security/pam_unix.so + pwauth account required /lib/security/pam_unix.so + + You can authenticate from a SMB server if you have installed the pam_smb + package (available from http://samba.org/samba). On Solaris 2.6, the + /etc/pam.conf lines to do this would be something like: + + pwauth auth required /lib/security/pam_smb_auth.so.1 + + You may want a "nolocal" flag on that line if you are authenticating from + a remote server, or you may not. Note that if you configure pam_smb so + that root access isn't required, you should be able to use mod_auth_pam + instead of mod_auth_external and pwauth and get faster authentications. + + (6) Test the pwauth program. As root, you can just run the thing, type + in a login (hit return) and a password (hit return), and then check + the exit code (in csh: "echo $status" in sh: "echo $?"). It should + be 0 for correct login/password pairs and 1 otherwise. + + (7) Install it in some sensible place (say, /usr/local/libexec/pwauth). + Unless you are doing SHADOW_NONE, it should be suid-root, so that + it has the necessary access to read the shadow file. That is, the + file should be owned by root, and you should do "chmod o+s pwauth" on + it. After you've installed it, it is worth su-ing to whatever account + your httpd runs under and testing pwauth again from that account. This + should confirm that all the uid's and suid-bits are configured correctly. + + On OpenBSD the master password database is readable (but not writable) + to group _shadow, so you should be able to install it sgid to group + "_shadow" instead of suid root. However, I've not been able to make + this work. + + (8) If you are using pwauth with mod_auth_external, add to the Apache + server configuration file directives that give the full path to + wherever you installed this program and designate the pipe method + for communicating with the authenticator. For example: + + AddExternalAuth pwauth /usr/local/libexec/pwauth + SetExternalAuthMethod pwauth pipe + + It is possible to use this module with the "environment" method + instead of the "pipe" method by compiling it with the ENV_METHOD + flag defined, however this has security problems on some Unixes. + + (9) Put an .htaccess file in whatever directory you want to protect. + (For .htaccess files to work, you may need to change some + "AllowOverride None" directives in your httpd.conf file into + "AllowOverride AuthConfig" directives). + + A typical .htaccess file using mod_auth_external would look like: + + AuthType Basic + AuthName Your-Site-Name + AuthExternal pwauth + require valid-user + + A typical .htaccess file using mod_authnz_external would look like: + + AuthType Basic + AuthName Your-Site-Name + AuthBasicProvider external + AuthExternal pwauth + require valid-user + + Alternately, you can put a block with the same directives + in your httpd.conf file. + +(10) Test it by trying to access a file in the protected directory with your + web browser. + + If it fails to accept correct logins, then check Apache's error log file. + This should give some messages explaining why authentication failed. + + If it was unable to execute pwauth, check that the pathnames and + permissions are all correct. + + If it says that pwauth failed, it will give the numeric return code. + The numeric return codes returned by pwauth are as follows: + + 0 - Login OK. + + 1 - Nonexistant login or (for some configurations) incorrect + password. + + 2 - Incorrect password (for some configurations). + + 3 - Uid number is below MIN_UNIX_UID value configured in config.h. + + 4 - Login ID has expired. + + 5 - Login's password has expired. + + 6 - Logins to system have been turned off (usually by /etc/nologin + file). + + 7 - Limit on number of bad logins exceeded. + + 50 - pwauth was not run with real uid SERVER_UID. If you get this + error code, you probably have SERVER_UID set incorrectly in + pwauth's config.h file. + + 51 - pwauth was not given a login & password to check. The means + the passing of data from mod_auth_external to pwauth is messed + up. Most likely one is trying to pass data via environment + variables, while the other is trying to pass data via a pipe. + + 52 - one of several possible internal errors occured. You'll have + to read the source code to figure these out. + + 53 - pwauth was not able to read the password database. Usually + this means it is not running as root. (PAM and login.conf + configurations will return 1 in this case.) + +If you want to allow users of only certain groups to login, the perl +"unixgroup" command included in this directory will do the job, though not +very efficiently. If you are using mod_authnz_external, a better approach +is to use mod_authz_unixgroup. This will not only allow you to restrict +logins to users in particular groups, but restrict access to individual +files based on group ownership of the files, if used with the standard Apache +module mod_authz_owner. diff --git a/pwauth/Makefile b/pwauth/Makefile new file mode 100644 index 0000000..da50906 --- /dev/null +++ b/pwauth/Makefile @@ -0,0 +1,52 @@ +# The following three lines should be modified to appropriate values for your +# system. Most of the configurable stuff is in config.h +# +# CC= an ansi-C compiler. If "cc" doesn't work, try "gcc". +# LIB= libraries to link in. -lcrypt, -lshadow, -lpam sometimes needed. +# LOCALFLAGS= compiler flags. Usually -g, -O, and stuff like that. + +# Settings for author's system (Redhat 6.1) +CC=gcc +LIB= -lcrypt +LOCALFLAGS= -g + +# For PAM on Redhat Linux +# LIB=-lpam -ldl + +# For PAM on Solaris or OS X +# LIB=-lpam + +# -------------------- No User Servicable Parts Below ----------------------- + +CFLAGS= $(LOCALFLAGS) + +pwauth: main.o auth_aix.o auth_bsd.o auth_hpux.o auth_mdw.o auth_openbsd.o \ + auth_pam.o auth_sun.o fail_log.o lastlog.o nologin.o snooze.o + $(CC) -o pwauth $(CFLAGS) main.o auth_aix.o auth_bsd.o auth_hpux.o \ + auth_mdw.o auth_openbsd.o auth_pam.o auth_sun.o fail_log.o \ + lastlog.o nologin.o snooze.o $(LIB) + +checkfaillog: checkfaillog.o fail_check.o + $(CC) -o checkfaillog $(CFLAGS) checkfaillog.o fail_check.o $(LIB) + +main.o: main.c config.h pwauth.h fail_log.h +auth_aix.o: auth_aix.c config.h pwauth.h +auth_bsd.o: auth_bsd.c config.h pwauth.h +auth_hpux.o: auth_hpux.c config.h pwauth.h +auth_mdw.o: auth_mdw.c config.h pwauth.h +auth_openbsd.o: auth_openbsd.c config.h +auth_pam.o: auth_pam.c config.h pwauth.h +auth_sun.o: auth_sun.c config.h pwauth.h +checkfaillog.o: checkfaillog.c config.h fail_log.h +fail_check.o: fail_check.c config.h fail_log.h +fail_log.o: fail_log.c config.h pwauth.h fail_log.h +lastlog.o: lastlog.c config.h pwauth.h +nologin.o: nologin.c config.h pwauth.h +snooze.o: snooze.c config.h pwauth.h + + +clean: + rm -f *.o + +distclean: + rm -f *.o pwauth checkfaillog diff --git a/pwauth/README b/pwauth/README new file mode 100644 index 0000000..e708a13 --- /dev/null +++ b/pwauth/README @@ -0,0 +1,58 @@ + pwauth 2.3.8 + + 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/ diff --git a/pwauth/auth_aix.c b/pwauth/auth_aix.c new file mode 100644 index 0000000..e0ded2a --- /dev/null +++ b/pwauth/auth_aix.c @@ -0,0 +1,70 @@ +/* ======================================================================= + * 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_AIX +#ifdef NEED_UID +#include +#include +#endif +#include + +/* ===================== AIX Authentication ===================== */ + + +/* CHECK_AUTH - Check a login and return a status code. + * (This version for systems with a getuserpw() call.) + */ + +int check_auth(char *login, char *passwd) +{ + char *cpass; + struct userpw *upwd= getuserpw(login); +#ifdef NEED_UID + struct passwd *pwd; +#endif + if (upwd == 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 + cpass= crypt(passwd, upwd->upw_passwd); + return(strcmp(cpass, upwd->upw_passwd) ? STATUS_INVALID : STATUS_OK); +} +#endif /* SHADOW_AIX */ diff --git a/pwauth/auth_bsd.c b/pwauth/auth_bsd.c new file mode 100644 index 0000000..b5e9004 --- /dev/null +++ b/pwauth/auth_bsd.c @@ -0,0 +1,82 @@ +/* ======================================================================= + * 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 */ diff --git a/pwauth/auth_hpux.c b/pwauth/auth_hpux.c new file mode 100644 index 0000000..c19ce54 --- /dev/null +++ b/pwauth/auth_hpux.c @@ -0,0 +1,65 @@ +/* ======================================================================= + * 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_HPUX +#include +#include +#include + +/* ===================== HPUX Authentication ===================== */ + + +/* CHECK_AUTH - Check a login and return a status code. + * (This version for systems with a getprpwnam() call.) + */ + +int check_auth(char *login, char *passwd) +{ + char *cpass; + struct pr_passwd *pwd= getprpwnam(login); + if (pwd == NULL) return(STATUS_UNKNOWN); +#ifdef NEED_UID + hisuid= pwd->ufld.fd_uid; + haveuid= 1; +#endif +#ifdef MIN_UNIX_UID + if (hisuid < MIN_UNIX_UID) return(STATUS_BLOCKED); +#endif + /* Should this be a call to bigcrypt() instead? */ + cpass= crypt(passwd, pwd->ufld.fd_encrypt); + return(strcmp(cpass, pwd->ufld.fd_encrypt) ? + STATUS_INVALID : STATUS_OK); +} +#endif /* SHADOW_HPUX */ diff --git a/pwauth/auth_mdw.c b/pwauth/auth_mdw.c new file mode 100644 index 0000000..b0a4f7b --- /dev/null +++ b/pwauth/auth_mdw.c @@ -0,0 +1,95 @@ +/* ======================================================================= + * 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 */ diff --git a/pwauth/auth_openbsd.c b/pwauth/auth_openbsd.c new file mode 100644 index 0000000..d0571ec --- /dev/null +++ b/pwauth/auth_openbsd.c @@ -0,0 +1,160 @@ +/* ======================================================================= + * 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 */ diff --git a/pwauth/auth_pam.c b/pwauth/auth_pam.c new file mode 100644 index 0000000..25f37eb --- /dev/null +++ b/pwauth/auth_pam.c @@ -0,0 +1,196 @@ +/* ======================================================================= + * 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_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 */ diff --git a/pwauth/auth_sun.c b/pwauth/auth_sun.c new file mode 100644 index 0000000..fc3c3e8 --- /dev/null +++ b/pwauth/auth_sun.c @@ -0,0 +1,109 @@ +/* ======================================================================= + * 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 */ diff --git a/pwauth/checkfaillog.c b/pwauth/checkfaillog.c new file mode 100644 index 0000000..c282a86 --- /dev/null +++ b/pwauth/checkfaillog.c @@ -0,0 +1,107 @@ +/* ======================================================================= + * 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); +} diff --git a/pwauth/config.h b/pwauth/config.h new file mode 100644 index 0000000..9a86203 --- /dev/null +++ b/pwauth/config.h @@ -0,0 +1,324 @@ +/* ======================================================================= + * 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. + * + * - 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 you 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. + */ + +/* #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 */ +/* #define SHADOW_HPUX /* HPUX ? */ + +/* #define PAM /* Linux PAM or OpenPAM*/ +/* #define PAM_OS_X /* PAM on OS X */ +/* #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 */ + + +/* There is also limited support for two 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 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. This kind of logging is handled + * at a lower level with PAM. + * + * - 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 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 do 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. 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 72 /* user "nobody" */ + + +/* 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. + */ + +/* #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 /**/ diff --git a/pwauth/fail_check.c b/pwauth/fail_check.c new file mode 100644 index 0000000..7006fbb --- /dev/null +++ b/pwauth/fail_check.c @@ -0,0 +1,182 @@ +/* ======================================================================= + * 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