--- /dev/null
+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 <adi@kriegisch.at> 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.
--- /dev/null
+ 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
+
+ <FORM ACTION=login.cgi METHOD=post>
+ Login: <INPUT TYPE=text NAME=login><BR>
+ Password: <INPUT TYPE=password NAME=passwd><BR>
+ <INPUT TYPE=submit VALUE="Login Now">
+ </FORM>
+
+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.
--- /dev/null
+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 <Directory> 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.
--- /dev/null
+# 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
--- /dev/null
+ 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/
--- /dev/null
+/* =======================================================================
+ * 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 <sys/types.h>
+#include <pwd.h>
+#endif
+#include <userpw.h>
+
+/* ===================== 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 */
--- /dev/null
+/* =======================================================================
+ * 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 <unistd.h>
+#include <pwd.h>
+
+/* ===================== 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 */
--- /dev/null
+/* =======================================================================
+ * 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 <sys/types.h>
+#include <hpsecurity.h>
+#include <prot.h>
+
+/* ===================== 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 */
--- /dev/null
+/* =======================================================================
+ * 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 <pwd.h>
+#endif
+#include <shadow.h> /* 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 */
--- /dev/null
+/* =======================================================================
+ * 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 <pwd.h>
+#include <login_cap.h>
+#include <bsd_auth.h>
+
+/* =================== 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 */
--- /dev/null
+/* =======================================================================
+ * 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 <pwd.h>
+#endif
+#ifdef PAM_OS_X
+#include <pam/pam_appl.h>
+#else
+#include <security/pam_appl.h>
+#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 */
--- /dev/null
+/* =======================================================================
+ * 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 <pwd.h>
+#endif
+#include <shadow.h>
+struct spwd *getspnam();
+char *crypt();
+#endif /* SHADOW_SUN */
+
+#ifdef SHADOW_JFH
+#ifdef NEED_UID
+#include <pwd.h>
+#endif
+#include <shadow.h> /* 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 */
--- /dev/null
+/* =======================================================================
+ * 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 <stdio.h>
+#include <sys/types.h>
+#include <utmp.h>
+#include <pwd.h>
+
+#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);
+}
--- /dev/null
+/* =======================================================================
+ * 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 /**/
--- /dev/null
+/* =======================================================================
+ * 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 <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <utmp.h>
+
+#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
+ * <count>:<unixtime>::<tty>\n
+ * verbose=1
+ * <count> failures since last login. Last was <time> on <tty>.\n
+ */
+
+char *check_fails(uid_t uid, int reset, int verbose)
+{
+ struct faillog flog;
+ int flfd;
+ static char buf[1024];
+ char *ct;
+ time_t now;
+
+ /* Return null if we can't open the file */
+ if ((flfd= open(PATH_FAILLOG, reset ? O_RDWR : O_RDONLY)) < 0)
+ return NULL;
+
+ /* Read the log file entry for this user - if none then there have
+ * been no failures */
+ lseek(flfd, uid * sizeof(struct faillog), 0);
+ if (read(flfd, &flog, sizeof(struct faillog)) != sizeof(struct faillog))
+ {
+ close(flfd);
+ return NULL;
+ }
+
+ /* Check if there have been any failures */
+ if (flog.fail_cur <= 0)
+ {
+ close(flfd);
+ return NULL;
+ }
+
+ /* Generate the result message */
+ if (verbose)
+ {
+ time(&now);
+ ct= ctime(&flog.fail_time);
+ ct[24]= '\0';
+ if (now - flog.fail_time < (365*24*3600))
+ ct[19]= '\0';
+ if (now - flog.fail_time < (24*3600))
+ ct+= 11;
+ sprintf(buf,"%d %s since last login. Last was %s on %s.",
+ flog.fail_cnt, flog.fail_cnt == 1 ? "failure" : "failures",
+ ct, flog.fail_line);
+ }
+ else
+ sprintf(buf,"%d:%ld::%s",
+ flog.fail_cnt, flog.fail_time, flog.fail_line);
+
+ /* Reset the count, if that was desired */
+ flog.fail_cnt= 0;
+ lseek(flfd, uid * sizeof(struct faillog), 0);
+ write(flfd, &flog, sizeof(struct faillog));
+ close(flfd);
+
+ return buf;
+}
+#endif /* FAILLOG_JFH */
+
+
+#ifdef FAILLOG_OPENBSD
+/* 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
+ * <count>:<unixtime>:<host>:<tty>\n
+ * verbose=1
+ * <count> failures since last login. Last was <time> from <host> on <tty>.\n
+ */
+
+char *check_fails(uid_t uid, int reset, int verbose)
+{
+ struct badlogin flog;
+ int flfd;
+ static char buf[1024];
+ char *ct;
+ time_t now;
+
+ /* Return null if we can't open the file */
+ if ((flfd= open(PATH_FAILLOG, reset ? O_RDWR : O_RDONLY)) < 0)
+ return NULL;
+
+ /* Read the log file entry for this user - if none then there have
+ * been no failures */
+ lseek(flfd, uid * sizeof(struct badlogin), 0);
+ if (read(flfd, &flog, sizeof(struct badlogin)) != sizeof(struct badlogin))
+ {
+ close(flfd);
+ return NULL;
+ }
+
+ /* Check if there have been any failures */
+ if (flog.count <= 0)
+ {
+ close(flfd);
+ return NULL;
+ }
+
+ /* Generate the result message */
+ if (verbose)
+ {
+ time(&now);
+ ct= ctime(&flog.bl_time);
+ ct[24]= '\0';
+ if (now - flog.bl_time < (365*24*3600))
+ ct[19]= '\0';
+ if (now - flog.bl_time < (24*3600))
+ ct+= 11;
+ if (flog.bl_host[0] != '\0')
+ sprintf(buf,"%d %s since last login. Last was %s from %s on %s.",
+ flog.count, flog.count == 1 ? "failure" : "failures",
+ ct, flog.bl_host, flog.bl_line);
+ else
+ sprintf(buf,"%d %s since last login. Last was %s on %s.",
+ flog.count, flog.count == 1 ? "failure" : "failures",
+ ct, flog.bl_line);
+ }
+ else
+ sprintf(buf,"%d:%ld:%s:%s",
+ flog.count, flog.bl_time, flog.bl_host, flog.bl_line);
+
+ /* Reset the count, if that was desired */
+ flog.count= 0;
+ lseek(flfd, uid * sizeof(struct badlogin), 0);
+ write(flfd, &flog, sizeof(struct badlogin));
+ close(flfd);
+
+ return buf;
+}
+#endif
--- /dev/null
+/* =======================================================================
+ * 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 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. 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
--- /dev/null
+/* 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
+
--- /dev/null
+/* =======================================================================
+ * 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*/
--- /dev/null
+/* =======================================================================
+ * 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, *strchr();
+#endif
+ int uid,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 */
+
+#ifdef FAILLOG_JFH
+ 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
+ snooze(0);
+ exit(STATUS_OK);
+ }
+ else
+ {
+ /* Bad login */
+#ifdef KEEP_FAILLOG
+ log_failure();
+#endif
+ snooze(SLEEP_TIME);
+ exit(status);
+ }
+}
--- /dev/null
+/* =======================================================================
+ * 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 NOLOGIN_FILE
+/* CHECK_NOLOGIN - return true if the nologin file does not exist or our
+ * uid is below MIN_NOLOGIN_UID.
+ */
+
+check_nologin()
+{
+ /* Return true if the file does not exist (the access() function returns
+ * true if the file doesn't exist - pretty dumb, eh?) */
+ if (access(NOLOGIN_FILE, F_OK))
+ return 1;
+#if MIN_NOLOGIN_UID > 0
+ if (hisuid < MIN_NOLOGIN_UID)
+ return 1;
+#endif
+ return 0;
+}
+#endif
--- /dev/null
+/* =======================================================================
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/file.h>
+#include <sys/resource.h>
+/* 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 <ctype.h>
+#endif
+
+#ifdef UNIX_LASTLOG
+# define NEED_UID
+# include <utmp.h>
+# ifdef HAVE_LASTLOG_H
+# include <lastlog.h>
+# endif
+# ifndef UT_LINESIZE
+# define UT_LINESIZE 8
+# endif
+# ifndef UT_HOSTSIZE
+# define UT_HOSTSIZE 16
+# endif
+# if !defined(LASTLOG) && defined(PATHS_H)
+# include <paths.h>
+# 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
--- /dev/null
+/* =======================================================================
+ * 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"
+
+/* 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)
+{
+#ifdef SLEEP_LOCK
+ int slfd;
+#endif
+
+ /* Lock the sleep-lock file to serialize our sleeps */
+#ifdef SLEEP_LOCK
+ if ((slfd= open(SLEEP_LOCK,O_CREAT|O_RDONLY,0644)) >= 0)
+ flock(slfd,LOCK_EX);
+#endif
+
+ sleep(seconds);
+
+ /* Release sleep-lock file */
+#ifdef SLEEP_LOCK
+ /*flock(slfd,LOCK_UN);*/
+ close(slfd);
+#endif
+}
--- /dev/null
+#!/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;