summaryrefslogtreecommitdiffstats
path: root/contrib
diff options
context:
space:
mode:
authormarkm <markm@FreeBSD.org>2001-05-29 18:32:17 +0000
committermarkm <markm@FreeBSD.org>2001-05-29 18:32:17 +0000
commit8d833bf6a1dc67213e8fe8c5774ae6a413dd2deb (patch)
treeeedffe7280d5301f52da4b686f561d61acd4d735 /contrib
parentfdb8cf17739d4a5c562ccce5e7c635e0a9ce985d (diff)
downloadFreeBSD-src-8d833bf6a1dc67213e8fe8c5774ae6a413dd2deb.zip
FreeBSD-src-8d833bf6a1dc67213e8fe8c5774ae6a413dd2deb.tar.gz
Bring back from the er, dead some useful PAM modules.
Diffstat (limited to 'contrib')
-rw-r--r--contrib/libpam/modules/pam_ftp/Makefile16
-rw-r--r--contrib/libpam/modules/pam_ftp/README19
-rw-r--r--contrib/libpam/modules/pam_ftp/pam_ftp.c298
-rw-r--r--contrib/libpam/modules/pam_rhosts/Makefile16
-rw-r--r--contrib/libpam/modules/pam_rhosts/README58
-rw-r--r--contrib/libpam/modules/pam_rhosts/pam_rhosts_auth.c787
-rw-r--r--contrib/libpam/modules/pam_securetty/Makefile16
-rw-r--r--contrib/libpam/modules/pam_securetty/README10
-rw-r--r--contrib/libpam/modules/pam_securetty/pam_securetty.c192
-rw-r--r--contrib/libpam/modules/pam_shells/Makefile16
-rw-r--r--contrib/libpam/modules/pam_shells/README11
-rw-r--r--contrib/libpam/modules/pam_shells/pam_shells.c134
-rw-r--r--contrib/libpam/modules/pam_warn/Makefile16
-rw-r--r--contrib/libpam/modules/pam_warn/README26
-rw-r--r--contrib/libpam/modules/pam_warn/pam_warn.c133
15 files changed, 1748 insertions, 0 deletions
diff --git a/contrib/libpam/modules/pam_ftp/Makefile b/contrib/libpam/modules/pam_ftp/Makefile
new file mode 100644
index 0000000..4ea360d
--- /dev/null
+++ b/contrib/libpam/modules/pam_ftp/Makefile
@@ -0,0 +1,16 @@
+#
+# $Id: Makefile,v 1.2 2000/11/19 23:54:03 agmorgan Exp $
+# $FreeBSD$
+#
+# This Makefile controls a build process of $(TITLE) module for
+# Linux-PAM. You should not modify this Makefile (unless you know
+# what you are doing!).
+#
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
+#
+
+include ../../Make.Rules
+
+TITLE=pam_ftp
+
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_ftp/README b/contrib/libpam/modules/pam_ftp/README
new file mode 100644
index 0000000..0e9315e
--- /dev/null
+++ b/contrib/libpam/modules/pam_ftp/README
@@ -0,0 +1,19 @@
+$FreeBSD$
+This is the README for pam_ftp
+------------------------------
+
+This module is an authentication module that does simple ftp
+authentication.
+
+Recognized arguments:
+
+ "debug" print debug messages
+ "users=" comma separated list of users which
+ could login only with email adress
+ "ignore" allow invalid email adresses
+
+Options for:
+auth: for authentication it provides pam_authenticate() and
+ pam_setcred() hooks.
+
+Thorsten Kukuk <kukuk@suse.de>, 17. June 1999
diff --git a/contrib/libpam/modules/pam_ftp/pam_ftp.c b/contrib/libpam/modules/pam_ftp/pam_ftp.c
new file mode 100644
index 0000000..df10a03
--- /dev/null
+++ b/contrib/libpam/modules/pam_ftp/pam_ftp.c
@@ -0,0 +1,298 @@
+/* pam_ftp module */
+
+/*
+ * $Id: pam_ftp.c,v 1.2 2000/11/19 23:54:03 agmorgan Exp $
+ * $FreeBSD$
+ *
+ * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11
+ *
+ */
+
+#define PLEASE_ENTER_PASSWORD "Password required for %s."
+#define GUEST_LOGIN_PROMPT "Guest login ok, " \
+"send your complete e-mail address as password."
+
+/* the following is a password that "can't be correct" */
+#define BLOCK_PASSWORD "\177BAD PASSWPRD\177"
+
+#include <security/_pam_aconf.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <stdarg.h>
+#include <string.h>
+
+/*
+ * here, we make a definition for the externally accessible function
+ * in this file (this definition is required for static a module
+ * but strongly encouraged generally) it is used to instruct the
+ * modules include file to define the function prototypes.
+ */
+
+#define PAM_SM_AUTH
+
+#include <security/pam_modules.h>
+#include <security/_pam_macros.h>
+
+/* some syslogging */
+
+static void _pam_log(int err, const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ openlog("PAM-ftp", LOG_CONS|LOG_PID, LOG_AUTH);
+ vsyslog(err, format, args);
+ va_end(args);
+ closelog();
+}
+
+static int converse(pam_handle_t *pamh, int nargs
+ , struct pam_message **message
+ , struct pam_response **response)
+{
+ int retval;
+ struct pam_conv *conv;
+
+ D(("begin to converse\n"));
+
+ retval = pam_get_item( pamh, PAM_CONV, (const void **) &conv ) ;
+ if ( retval == PAM_SUCCESS ) {
+
+ retval = conv->conv(nargs, ( const struct pam_message ** ) message
+ , response, conv->appdata_ptr);
+
+ D(("returned from application's conversation function\n"));
+
+ if ((retval != PAM_SUCCESS) && (retval != PAM_CONV_AGAIN)) {
+ _pam_log(LOG_DEBUG, "conversation failure [%s]"
+ , pam_strerror(pamh, retval));
+ }
+
+ } else {
+ _pam_log(LOG_ERR, "couldn't obtain coversation function [%s]"
+ , pam_strerror(pamh, retval));
+ }
+
+ D(("ready to return from module conversation\n"));
+
+ return retval; /* propagate error status */
+}
+
+/* argument parsing */
+
+#define PAM_DEBUG_ARG 01
+#define PAM_IGNORE_EMAIL 02
+#define PAM_NO_ANON 04
+
+static int _pam_parse(int argc, const char **argv, char **users)
+{
+ int ctrl=0;
+
+ /* step through arguments */
+ for (ctrl=0; argc-- > 0; ++argv) {
+
+ /* generic options */
+
+ if (!strcmp(*argv,"debug"))
+ ctrl |= PAM_DEBUG_ARG;
+ else if (!strncmp(*argv,"users=",6)) {
+ *users = x_strdup(6+*argv);
+ if (*users == NULL) {
+ ctrl |= PAM_NO_ANON;
+ _pam_log(LOG_CRIT, "failed to duplicate user list - anon off");
+ }
+ } else if (!strcmp(*argv,"ignore")) {
+ ctrl |= PAM_IGNORE_EMAIL;
+ } else {
+ _pam_log(LOG_ERR,"pam_parse: unknown option; %s",*argv);
+ }
+ }
+
+ return ctrl;
+}
+
+/*
+ * check if name is in list or default list. place users name in *_user
+ * return 1 if listed 0 if not.
+ */
+
+static int lookup(const char *name, char *list, const char **_user)
+{
+ int anon = 0;
+
+ *_user = name; /* this is the default */
+ if (list) {
+ const char *l;
+ char *x;
+
+ x = list;
+ while ((l = strtok(x, ","))) {
+ x = NULL;
+ if (!strcmp(name, l)) {
+ *_user = list;
+ anon = 1;
+ }
+ }
+ } else {
+#define MAX_L 2
+ static const char *l[MAX_L] = { "ftp", "anonymous" };
+ int i;
+
+ for (i=0; i<MAX_L; ++i) {
+ if (!strcmp(l[i], name)) {
+ *_user = l[0];
+ anon = 1;
+ break;
+ }
+ }
+ }
+
+ return anon;
+}
+
+/* --- authentication management functions (only) --- */
+
+PAM_EXTERN
+int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc
+ ,const char **argv)
+{
+ int retval, anon=0, ctrl;
+ const char *user;
+ char *users=NULL;
+
+ /*
+ * this module checks if the user name is ftp or annonymous. If
+ * this is the case, it can set the PAM_RUSER to the entered email
+ * address and SUCCEEDS, otherwise it FAILS.
+ */
+
+ ctrl = _pam_parse(argc, argv, &users);
+
+ retval = pam_get_user(pamh, &user, NULL);
+ if (retval != PAM_SUCCESS || user == NULL) {
+ _pam_log(LOG_ERR, "no user specified");
+ return PAM_USER_UNKNOWN;
+ }
+
+ if (!(ctrl & PAM_NO_ANON)) {
+ anon = lookup(user, users, &user);
+ }
+
+ if (anon) {
+ retval = pam_set_item(pamh, PAM_USER, (const void *)user);
+ if (retval != PAM_SUCCESS || user == NULL) {
+ _pam_log(LOG_ERR, "user resetting failed");
+ return PAM_USER_UNKNOWN;
+ }
+ }
+
+ /*
+ * OK. we require an email address for user or the user's password.
+ * - build conversation and get their input.
+ */
+
+ {
+ struct pam_message msg[1], *mesg[1];
+ struct pam_response *resp=NULL;
+ const char *token;
+ char *prompt=NULL;
+ int i=0;
+
+ if (!anon) {
+ prompt = malloc(strlen(PLEASE_ENTER_PASSWORD) + strlen(user));
+ if (prompt == NULL) {
+ D(("out of memory!?"));
+ return PAM_BUF_ERR;
+ } else {
+ sprintf(prompt, PLEASE_ENTER_PASSWORD, user);
+ msg[i].msg = prompt;
+ }
+ } else {
+ msg[i].msg = GUEST_LOGIN_PROMPT;
+ }
+
+ msg[i].msg_style = PAM_PROMPT_ECHO_OFF;
+ mesg[i] = &msg[i];
+
+ retval = converse(pamh, ++i, mesg, &resp);
+ if (prompt) {
+ _pam_overwrite(prompt);
+ _pam_drop(prompt);
+ }
+
+ if (retval != PAM_SUCCESS) {
+ if (resp != NULL)
+ _pam_drop_reply(resp,i);
+ return ((retval == PAM_CONV_AGAIN)
+ ? PAM_INCOMPLETE:PAM_AUTHINFO_UNAVAIL);
+ }
+
+ if (anon) {
+ /* XXX: Some effort should be made to verify this email address! */
+
+ if (!(ctrl & PAM_IGNORE_EMAIL)) {
+ token = strtok(resp->resp, "@");
+ retval = pam_set_item(pamh, PAM_RUSER, token);
+
+ if ((token) && (retval == PAM_SUCCESS)) {
+ token = strtok(NULL, "@");
+ retval = pam_set_item(pamh, PAM_RHOST, token);
+ }
+ }
+
+ /* we are happy to grant annonymous access to the user */
+ retval = PAM_SUCCESS;
+
+ } else {
+ /*
+ * we have a password so set AUTHTOK
+ */
+
+ (void) pam_set_item(pamh, PAM_AUTHTOK, resp->resp);
+
+ /*
+ * this module failed, but the next one might succeed with
+ * this password.
+ */
+
+ retval = PAM_AUTH_ERR;
+ }
+
+ if (resp) { /* clean up */
+ _pam_drop_reply(resp, i);
+ }
+
+ /* success or failure */
+
+ return retval;
+ }
+}
+
+PAM_EXTERN
+int pam_sm_setcred(pam_handle_t *pamh,int flags,int argc
+ ,const char **argv)
+{
+ return PAM_IGNORE;
+}
+
+
+#ifdef PAM_STATIC
+
+/* static module data */
+
+struct pam_module _pam_ftp_modstruct = {
+ "pam_ftp",
+ pam_sm_authenticate,
+ pam_sm_setcred,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+};
+
+#endif
+
+/* end of module definition */
diff --git a/contrib/libpam/modules/pam_rhosts/Makefile b/contrib/libpam/modules/pam_rhosts/Makefile
new file mode 100644
index 0000000..0108969
--- /dev/null
+++ b/contrib/libpam/modules/pam_rhosts/Makefile
@@ -0,0 +1,16 @@
+#
+# $Id: Makefile,v 1.2 2000/11/19 23:54:05 agmorgan Exp $
+# $FreeBSD$
+#
+# This Makefile controls a build process of $(TITLE) module for
+# Linux-PAM. You should not modify this Makefile (unless you know
+# what you are doing!).
+#
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
+#
+
+include ../../Make.Rules
+
+TITLE=pam_rhosts_auth
+
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_rhosts/README b/contrib/libpam/modules/pam_rhosts/README
new file mode 100644
index 0000000..8bd01aa
--- /dev/null
+++ b/contrib/libpam/modules/pam_rhosts/README
@@ -0,0 +1,58 @@
+$FreeBSD$
+arguments recognized:
+
+"no_hosts_equiv"
+"no_rhosts"
+"debug"
+"nowarn"
+"suppress"
+"promiscuous"
+
+.rhosts/hosts.equiv format:
+
+There are positive entries, when one is matched authentication
+succeeds and terminates. There are negative entries, when one is
+matched authentication fails and terminates. Thus order is
+significant.
+
+Entry hosts.equiv .rhosts
+<host> All users on <host> are ok Same username from <host> is ok
+<host> <user> <user> from <host> is ok ditto
+-<host> No users from <host> are ok ditto
+<host> -<user> <user> from <host> is not ok ditto
+
+<host> can be ip (IPv4) numbers.
+
+Netgroups may be used in either host or user fields, and then applies
+to all hosts, or users, in the netgroup. The syntax is
+
+ +@<ng>
+
+The entries
+
+ <host> +@<ng>
+ +@<ng> +@<ng>
+ +@<ng> <user>
+
+means exactly what you think it does. Negative entries are of the
+form
+
+ -@<ng>
+
+When the "promiscuous" option is given the special character + may be
+used as a wildcard in any field.
+
+ + Allow anyone from any host to connect. DANGEROUS.
+ + + Ditto.
+ + <user> Allow the user to connect from anywhere. DANGEROUS.
+ <host> + Allow any user from the host. Dangerous.
+
+These, perhaps more usefull, forms of the + form is also disallowed
+unless "promiscuous" is specified:
+
+ + -<user> Disallow the user from any host
+ + -@<ng> Disallow all members of the netgroup from any host
+
+When "promiscuous" is not specified a '+' is handled as a negative
+match.
+
diff --git a/contrib/libpam/modules/pam_rhosts/pam_rhosts_auth.c b/contrib/libpam/modules/pam_rhosts/pam_rhosts_auth.c
new file mode 100644
index 0000000..f520fda
--- /dev/null
+++ b/contrib/libpam/modules/pam_rhosts/pam_rhosts_auth.c
@@ -0,0 +1,787 @@
+/*----------------------------------------------------------------------
+ * Modified for Linux-PAM by Al Longyear <longyear@netcom.com> 96/5/5
+ * Modifications, Cristian Gafton 97/2/8
+ * Modifications, Peter Allgeyer 97/3
+ * Modifications (netgroups and fixes), Nicolai Langfeldt 97/3/21
+ * Security fix: 97/10/2 - gethostbyname called repeatedly without care
+ * Modification (added privategroup option) Andrew <morgan@transmeta.com>
+ *----------------------------------------------------------------------
+ * Copyright (c) 1983, 1993, 1994
+ * The Regents of the University of California. 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * $FreeBSD$
+ */
+
+#define _BSD_SOURCE
+
+#define USER_RHOSTS_FILE "/.rhosts" /* prefixed by user's home dir */
+
+#ifdef linux
+#include <endian.h>
+#endif
+
+#ifdef NEED_FSUID_H
+#include <sys/fsuid.h>
+#endif /* NEED_FSUID_H */
+
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h> /* This is supposed(?) to contain the following */
+int innetgr(const char *, const char *, const char *,const char *);
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <arpa/inet.h>
+
+#ifndef MAXDNAME
+#define MAXDNAME 256
+#endif
+
+#include <stdarg.h>
+#include <ctype.h>
+
+#include <net/if.h>
+#ifdef linux
+# include <linux/sockios.h>
+# ifndef __USE_MISC
+# define __USE_MISC
+# include <sys/fsuid.h>
+# endif /* __USE_MISC */
+#endif
+
+#include <pwd.h>
+#include <grp.h>
+#include <sys/file.h>
+#include <sys/signal.h>
+#include <sys/stat.h>
+#include <syslog.h>
+#ifndef _PATH_HEQUIV
+#define _PATH_HEQUIV "/etc/hosts.equiv"
+#endif /* _PATH_HEQUIV */
+
+#define PAM_SM_AUTH /* only defines this management group */
+
+#include <security/pam_modules.h>
+#include <security/_pam_macros.h>
+
+/* to the best of my knowledge, all modern UNIX boxes have 32 bit integers */
+#define U32 unsigned int
+
+
+/*
+ * Options for this module
+ */
+
+struct _options {
+ int opt_no_hosts_equiv;
+ int opt_hosts_equiv_rootok;
+ int opt_no_rhosts;
+ int opt_debug;
+ int opt_nowarn;
+ int opt_disallow_null_authtok;
+ int opt_silent;
+ int opt_promiscuous;
+ int opt_suppress;
+ int opt_private_group;
+ int opt_no_uid_check;
+ const char *superuser;
+ const char *last_error;
+};
+
+/* logging */
+static void _pam_log(int err, const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ openlog("pam_rhosts_auth", LOG_CONS|LOG_PID, LOG_AUTH);
+ vsyslog(err, format, args);
+ va_end(args);
+ closelog();
+}
+
+static void set_option (struct _options *opts, const char *arg)
+{
+ if (strcmp(arg, "no_hosts_equiv") == 0) {
+ opts->opt_no_hosts_equiv = 1;
+ return;
+ }
+
+ if (strcmp(arg, "hosts_equiv_rootok") == 0) {
+ opts->opt_hosts_equiv_rootok = 1;
+ return;
+ }
+
+ if (strcmp(arg, "no_rhosts") == 0) {
+ opts->opt_no_rhosts = 1;
+ return;
+ }
+
+ if (strcmp(arg, "debug") == 0) {
+ D(("debugging enabled"));
+ opts->opt_debug = 1;
+ return;
+ }
+
+ if (strcmp(arg, "no_warn") == 0) {
+ opts->opt_nowarn = 1;
+ return;
+ }
+
+ if (strcmp(arg, "promiscuous") == 0) {
+ opts->opt_promiscuous = 1; /* used to permit '+' in ...hosts file */
+ return;
+ }
+
+ if (strcmp(arg, "suppress") == 0) {
+ opts->opt_suppress = 1; /* used to suppress failure warning message */
+ return;
+ }
+
+ if (strcmp(arg, "privategroup") == 0) {
+ opts->opt_private_group = 1; /* used to permit group write on .rhosts
+ file if group has same name as owner */
+ return;
+ }
+
+ if (strcmp(arg, "no_uid_check") == 0) {
+ opts->opt_no_uid_check = 1; /* NIS optimization */
+ return;
+ }
+
+ if (strcmp(arg, "superuser=") == 0) {
+ opts->superuser = arg+sizeof("superuser=")-1;
+ return;
+ }
+ /*
+ * All other options are ignored at the present time.
+ */
+ _pam_log(LOG_WARNING, "unrecognized option '%s'", arg);
+}
+
+static void set_parameters (struct _options *opts, int flags,
+ int argc, const char **argv)
+{
+ opts->opt_silent = flags & PAM_SILENT;
+ opts->opt_disallow_null_authtok = flags & PAM_DISALLOW_NULL_AUTHTOK;
+
+ while (argc-- > 0) {
+ set_option (opts, *argv);
+ ++argv;
+ }
+}
+
+/*
+ * Obtain the name of the remote host. Currently, this is simply by
+ * requesting the contents of the PAM_RHOST item.
+ */
+
+static int pam_get_rhost(pam_handle_t *pamh, const char **rhost
+ , const char *prompt)
+{
+ int retval;
+ const char *current;
+
+ retval = pam_get_item (pamh, PAM_RHOST, (const void **)&current);
+ if (retval != PAM_SUCCESS)
+ return retval;
+
+ if (current == NULL) {
+ return PAM_AUTH_ERR;
+ }
+ *rhost = current;
+
+ return retval; /* pass on any error from conversation */
+}
+
+/*
+ * Obtain the name of the remote user. Currently, this is simply by
+ * requesting the contents of the PAM_RUSER item.
+ */
+
+static int pam_get_ruser(pam_handle_t *pamh, const char **ruser
+ , const char *prompt)
+{
+ int retval;
+ const char *current;
+
+ retval = pam_get_item (pamh, PAM_RUSER, (const void **)&current);
+ if (retval != PAM_SUCCESS)
+ return retval;
+
+ if (current == NULL) {
+ return PAM_AUTH_ERR;
+ }
+ *ruser = current;
+
+ return retval; /* pass on any error from conversation */
+}
+
+/*
+ * Returns 1 if positive match, 0 if no match, -1 if negative match.
+ */
+
+static int
+__icheckhost (pam_handle_t *pamh, struct _options *opts, U32 raddr
+ , register char *lhost, const char *rhost)
+{
+ struct hostent *hp;
+ U32 laddr;
+ int negate=1; /* Multiply return with this to get -1 instead of 1 */
+ char **pp, *user;
+
+ /* Check nis netgroup. We assume that pam has done all needed
+ paranoia checking before we are handed the rhost */
+ if (strncmp("+@",lhost,2) == 0)
+ return(innetgr(&lhost[2],rhost,NULL,NULL));
+
+ if (strncmp("-@",lhost,2) == 0)
+ return(-innetgr(&lhost[2],rhost,NULL,NULL));
+
+ /* -host */
+ if (strncmp("-",lhost,1) == 0) {
+ negate=-1;
+ lhost++;
+ } else if (strcmp("+",lhost) == 0) {
+ (void) pam_get_item(pamh, PAM_USER, (const void **)&user);
+ D(("user %s has a `+' host entry", user));
+ if (opts->opt_promiscuous)
+ return (1); /* asking for trouble, but ok.. */
+ /* If not promiscuous: handle as negative */
+ return (-1);
+ }
+
+ /* Try for raw ip address first. */
+ if (isdigit(*lhost) && (long)(laddr = inet_addr(lhost)) != -1)
+ return (negate*(! (raddr ^ laddr)));
+
+ /* Better be a hostname. */
+ hp = gethostbyname(lhost);
+ if (hp == NULL)
+ return (0);
+
+ /* Spin through ip addresses. */
+ for (pp = hp->h_addr_list; *pp; ++pp)
+ if (!memcmp (&raddr, *pp, sizeof (U32)))
+ return (negate);
+
+ /* No match. */
+ return (0);
+}
+
+/* Returns 1 on positive match, 0 on no match, -1 on negative match */
+
+static int __icheckuser(pam_handle_t *pamh, struct _options *opts
+ , const char *luser, const char *ruser
+ , const char *rhost)
+{
+ /*
+ luser is user entry from .rhosts/hosts.equiv file
+ ruser is user id on remote host
+ rhost is the remote host name
+ */
+ char *user;
+
+ /* [-+]@netgroup */
+ if (strncmp("+@",luser,2) == 0)
+ return (innetgr(&luser[2],NULL,ruser,NULL));
+
+ if (strncmp("-@",luser,2) == 0)
+ return (-innetgr(&luser[2],NULL,ruser,NULL));
+
+ /* -user */
+ if (strncmp("-",luser,1) == 0)
+ return(-(strcmp(&luser[1],ruser) == 0));
+
+ /* + */
+ if (strcmp("+",luser) == 0) {
+ (void) pam_get_item(pamh, PAM_USER, (const void **)&user);
+ _pam_log(LOG_WARNING, "user %s has a `+' user entry", user);
+ if (opts->opt_promiscuous)
+ return(1);
+ /* If not promiscuous we handle it as a negative match */
+ return(-1);
+ }
+
+ /* simple string match */
+ return (strcmp(ruser, luser) == 0);
+}
+
+/*
+ * Returns 1 for blank lines (or only comment lines) and 0 otherwise
+ */
+
+static int __isempty(char *p)
+{
+ while (*p && isspace(*p)) {
+ ++p;
+ }
+
+ return (*p == '\0' || *p == '#') ? 1:0 ;
+}
+
+/*
+ * Returns 0 if positive match, 1 if _not_ ok.
+ */
+
+static int
+__ivaliduser (pam_handle_t *pamh, struct _options *opts,
+ FILE *hostf, U32 raddr,
+ const char *luser, const char *ruser, const char *rhost)
+{
+ register const char *user;
+ register char *p;
+ int hcheck, ucheck;
+ char buf[MAXHOSTNAMELEN + 128]; /* host + login */
+
+ buf[sizeof (buf)-1] = '\0'; /* terminate line */
+
+ while (fgets(buf, sizeof(buf), hostf) != NULL) { /* hostf file line */
+ p = buf; /* from beginning of file.. */
+
+ /* Skip empty or comment lines */
+ if (__isempty(p)) {
+ continue;
+ }
+
+ /* Skip lines that are too long. */
+ if (strchr(p, '\n') == NULL) {
+ int ch = getc(hostf);
+
+ while (ch != '\n' && ch != EOF)
+ ch = getc(hostf);
+ continue;
+ }
+
+ /*
+ * If there is a hostname at the start of the line. Set it to
+ * lower case. A leading ' ' or '\t' indicates no hostname
+ */
+
+ for (;*p && !isspace(*p); ++p) {
+ *p = tolower(*p);
+ }
+
+ /*
+ * next we want to find the permitted name for the remote user
+ */
+
+ if (*p == ' ' || *p == '\t') {
+
+ /* <nul> terminate hostname and skip spaces */
+ for (*p++='\0'; *p && isspace(*p); ++p);
+
+ user = p; /* this is the user's name */
+ while (*p && !isspace(*p))
+ ++p; /* find end of user's name */
+ } else
+ user = p;
+
+ *p = '\0'; /* <nul> terminate username (+host?) */
+
+ /* buf -> host(?) ; user -> username(?) */
+
+ /* First check host part */
+ hcheck=__icheckhost(pamh, opts, raddr, buf, rhost);
+
+ if (hcheck<0)
+ return(1);
+
+ if (hcheck) {
+ /* Then check user part */
+ if (! (*user))
+ user = luser;
+
+ ucheck=__icheckuser(pamh, opts, user, ruser, rhost);
+
+ /* Positive 'host user' match? */
+ if (ucheck>0)
+ return(0);
+
+ /* Negative 'host -user' match? */
+ if (ucheck<0)
+ return(1);
+
+ /* Neither, go on looking for match */
+ }
+ }
+
+ return (1);
+}
+
+/*
+ * New .rhosts strategy: We are passed an ip address. We spin through
+ * hosts.equiv and .rhosts looking for a match. When the .rhosts only
+ * has ip addresses, we don't have to trust a nameserver. When it
+ * contains hostnames, we spin through the list of addresses the nameserver
+ * gives us and look for a match.
+ *
+ * Returns 0 if ok, -1 if not ok.
+ */
+
+static int
+pam_iruserok(pam_handle_t *pamh,
+ struct _options *opts, U32 raddr, int superuser,
+ const char *ruser, const char *luser, const char *rhost)
+{
+ const char *cp;
+ struct stat sbuf;
+ struct passwd *pwd;
+ FILE *hostf;
+ uid_t uid;
+ int answer;
+ char pbuf[MAXPATHLEN]; /* potential buffer overrun */
+
+ if ((!superuser||opts->opt_hosts_equiv_rootok) && !opts->opt_no_hosts_equiv ) {
+
+ /* try to open system hosts.equiv file */
+ hostf = fopen (_PATH_HEQUIV, "r");
+ if (hostf) {
+ answer = __ivaliduser(pamh, opts, hostf, raddr, luser
+ , ruser, rhost);
+ (void) fclose(hostf);
+ if (answer == 0)
+ return 0; /* remote host is equivalent to localhost */
+ } /* else {
+ No hosts.equiv file on system.
+ } */
+ }
+
+ if ( opts->opt_no_rhosts )
+ return 1;
+
+ /*
+ * Identify user's local .rhosts file
+ */
+
+ pwd = getpwnam(luser);
+ if (pwd == NULL) {
+ /*
+ * luser is assumed to be valid because of an earlier check for uid = 0
+ * we don't log this error twice. However, this shouldn't happen !
+ * --cristiang
+ */
+ return(1);
+ }
+
+ /* check for buffer overrun */
+ if (strlen(pwd->pw_dir) + sizeof(USER_RHOSTS_FILE) + 2 >= MAXPATHLEN) {
+ if (opts->opt_debug)
+ _pam_log(LOG_DEBUG,"home directory for `%s' is too long", luser);
+ return 1; /* to dangerous to try */
+ }
+
+ (void) strcpy(pbuf, pwd->pw_dir);
+ (void) strcat(pbuf, USER_RHOSTS_FILE);
+
+ /*
+ * Change effective uid while _reading_ .rhosts. (not just
+ * opening). If root and reading an NFS mounted file system,
+ * can't read files that are 0600 as .rhosts files should be.
+ */
+
+ /* We are root, this will not fail */
+#ifdef linux
+ /* If we are on linux the better way is setfsuid */
+ uid = setfsuid(pwd->pw_uid);
+ hostf = fopen(pbuf, "r");
+#else
+ uid = geteuid();
+ (void) seteuid(pwd->pw_uid);
+ hostf = fopen(pbuf, "r");
+#endif
+
+ if (hostf == NULL) {
+ if (opts->opt_debug)
+ _pam_log(LOG_DEBUG,"Could not open %s file",pbuf);
+ answer = 1;
+ goto exit_function;
+ }
+
+ /*
+ * If not a regular file, or is owned by someone other than
+ * user or root or if writeable by anyone but the owner, quit.
+ */
+
+ cp = NULL;
+ if (lstat(pbuf, &sbuf) < 0 || !S_ISREG(sbuf.st_mode))
+ cp = ".rhosts not regular file";
+ else if (fstat(fileno(hostf), &sbuf) < 0)
+ cp = ".rhosts fstat failed";
+ else if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid)
+ cp = "bad .rhosts owner";
+ else if (sbuf.st_mode & S_IWOTH)
+ cp = ".rhosts writable by other!";
+ else if (sbuf.st_mode & S_IWGRP) {
+
+ /* private group caveat */
+ if (opts->opt_private_group) {
+ struct group *grp = getgrgid(sbuf.st_gid);
+
+ if (NULL == grp || NULL == grp->gr_name
+ || strcmp(luser,grp->gr_name)) {
+ cp = ".rhosts writable by public group";
+ } else if (grp->gr_mem) {
+ int gcount;
+
+ /* require at most one member (luser) of this group */
+ for (gcount=0; grp->gr_mem[gcount]; ++gcount) {
+ if (strcmp(grp->gr_mem[gcount], luser)) {
+ gcount = -1;
+ break;
+ }
+ }
+ if (gcount < 0) {
+ cp = ".rhosts writable by other members of group";
+ }
+ }
+ } else {
+ cp = ".rhosts writable by group";
+ }
+
+ } /* It is _NOT_ safe to append an else here... Do so prior to
+ * S_IWGRP check */
+
+ /* If there were any problems, quit. */
+ if (cp) {
+ opts->last_error = cp;
+ answer = 1;
+ goto exit_function;
+ }
+
+ answer = __ivaliduser (pamh, opts, hostf, raddr, luser, ruser, rhost);
+
+exit_function:
+ /*
+ * Go here to exit after the fsuid/euid has been adjusted so that
+ * they are reset before we exit.
+ */
+
+#ifdef linux
+ setfsuid(uid);
+#else
+ (void)seteuid(uid);
+#endif
+
+ if (hostf != NULL)
+ (void) fclose(hostf);
+
+ return answer;
+}
+
+static int
+pam_ruserok (pam_handle_t *pamh,
+ struct _options *opts, const char *rhost, int superuser,
+ const char *ruser, const char *luser)
+{
+ struct hostent *hp;
+ int answer = 1; /* default to failure */
+ U32 *addrs;
+ int n, i;
+
+ opts->last_error = (char *) 0;
+ hp = gethostbyname(rhost); /* identify host */
+
+ if (hp != NULL) {
+ /* First of all check the address length */
+ if (hp->h_length != 4) {
+ _pam_log(LOG_ALERT, "pam_rhosts module can't work with not IPv4 "
+ "addresses");
+ return 1; /* not allowed */
+ }
+
+ /* loop though address list */
+ for (n = 0; hp->h_addr_list[n]; n++);
+ D(("rhosts: %d addresses", n));
+
+ if (n) {
+ addrs = calloc (n, hp->h_length);
+ for (i = 0; i < n; i++)
+ memcpy (addrs+i, hp->h_addr_list[i], hp->h_length);
+
+ for (i = 0; i < n && answer; i++) {
+ D(("rhosts: address %d is %04x", i, addrs[i]));
+ answer = pam_iruserok(pamh, opts, addrs[i], superuser,
+ ruser, luser, rhost);
+ /* answer == 0 means success */
+ }
+
+ free (addrs);
+ }
+ }
+
+ return answer;
+}
+
+/*
+ * Internal function to do authentication
+ */
+
+static int _pam_auth_rhosts (pam_handle_t *pamh,
+ int flags,
+ int argc,
+ const char **argv)
+{
+ int retval;
+ const char *luser;
+ const char *ruser,*rhost;
+ struct _options opts;
+ int as_root = 0;
+ /*
+ * Look at the options and set the flags accordingly.
+ */
+ memset (&opts, 0, sizeof (opts));
+ set_parameters (&opts, flags, argc, argv);
+ /*
+ * Obtain the parameters for the various items
+ */
+ for (;;) { /* abuse loop to avoid goto */
+
+ /* get the remotehost */
+ retval = pam_get_rhost(pamh, &rhost, NULL);
+ (void) pam_set_item(pamh, PAM_RHOST, rhost);
+ if (retval != PAM_SUCCESS) {
+ if (opts.opt_debug) {
+ _pam_log(LOG_DEBUG, "could not get the remote host name");
+ }
+ break;
+ }
+
+ /* get the remote user */
+ retval = pam_get_ruser(pamh, &ruser, NULL);
+ (void) pam_set_item(pamh, PAM_RUSER, ruser);
+ if (retval != PAM_SUCCESS) {
+ if (opts.opt_debug)
+ _pam_log(LOG_DEBUG, "could not get the remote username");
+ break;
+ }
+
+ /* get the local user */
+ retval = pam_get_user(pamh, &luser, NULL);
+
+ if (retval != PAM_SUCCESS) {
+ if (opts.opt_debug)
+ _pam_log(LOG_DEBUG, "could not determine name of local user");
+ break;
+ }
+
+ if (opts.superuser && !strcmp(opts.superuser, luser)) {
+ as_root = 1;
+ }
+
+ /* check if the luser uid == 0... --cristiang */
+ if (! opts.opt_no_uid_check) {
+ struct passwd *luser_pwd;
+
+ luser_pwd = getpwnam(luser);
+ if (luser_pwd == NULL) {
+ if (opts.opt_debug)
+ _pam_log(LOG_DEBUG, "user '%s' unknown to this system",
+ luser);
+ retval = PAM_AUTH_ERR;
+ break;
+ }
+ if (luser_pwd->pw_uid == 0)
+ as_root = 1;
+ luser_pwd = NULL; /* forget */
+ }
+/*
+ * Validate the account information.
+ */
+ if (pam_ruserok (pamh, &opts, rhost, as_root, ruser, luser) != 0) {
+ if ( !opts.opt_suppress ) {
+ _pam_log(LOG_WARNING, "denied to %s@%s as %s: %s",
+ ruser, rhost, luser, (opts.last_error==NULL) ?
+ "access not allowed":opts.last_error);
+ }
+ retval = PAM_AUTH_ERR;
+ } else {
+ _pam_log(LOG_NOTICE, "allowed to %s@%s as %s",
+ ruser, rhost, luser);
+ }
+ break;
+ }
+
+ return retval;
+}
+
+/* --- authentication management functions --- */
+
+PAM_EXTERN
+int pam_sm_authenticate (pam_handle_t *pamh,
+ int flags,
+ int argc,
+ const char **argv)
+{
+ int retval;
+
+ if (sizeof(U32) != 4) {
+ _pam_log (LOG_ALERT, "pam_rhosts module can\'t work on this hardware "
+ "(yet)");
+ return PAM_AUTH_ERR;
+ }
+ sethostent(1);
+ retval = _pam_auth_rhosts (pamh, flags, argc, argv);
+ endhostent();
+ return retval;
+}
+
+PAM_EXTERN
+int pam_sm_setcred(pam_handle_t *pamh,int flags,int argc,
+ const char **argv)
+{
+ return PAM_SUCCESS;
+}
+
+/* end of module definition */
+
+
+#ifdef PAM_STATIC
+
+/* static module data */
+
+struct pam_module _pam_rhosts_auth_modstruct = {
+ "pam_rhosts_auth",
+ pam_sm_authenticate,
+ pam_sm_setcred,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+};
+
+#endif
diff --git a/contrib/libpam/modules/pam_securetty/Makefile b/contrib/libpam/modules/pam_securetty/Makefile
new file mode 100644
index 0000000..fb3bb56
--- /dev/null
+++ b/contrib/libpam/modules/pam_securetty/Makefile
@@ -0,0 +1,16 @@
+#
+# $Id: Makefile,v 1.2 2000/11/19 23:54:05 agmorgan Exp $
+# $FreeBSD$
+#
+# This Makefile controls a build process of $(TITLE) module for
+# Linux-PAM. You should not modify this Makefile (unless you know
+# what you are doing!).
+#
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
+#
+
+include ../../Make.Rules
+
+TITLE=pam_securetty
+
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_securetty/README b/contrib/libpam/modules/pam_securetty/README
new file mode 100644
index 0000000..fe17ce5
--- /dev/null
+++ b/contrib/libpam/modules/pam_securetty/README
@@ -0,0 +1,10 @@
+$FreeBSD$
+pam_securetty:
+ Allows root logins only if the user is logging in on a
+ "secure" tty, as defined by the listing in /etc/securetty
+
+ Also checks to make sure that /etc/securetty is a plain
+ file and not world writable.
+
+ - Elliot Lee <sopwith@redhat.com>, Red Hat Software.
+ July 25, 1996.
diff --git a/contrib/libpam/modules/pam_securetty/pam_securetty.c b/contrib/libpam/modules/pam_securetty/pam_securetty.c
new file mode 100644
index 0000000..b99a2f0
--- /dev/null
+++ b/contrib/libpam/modules/pam_securetty/pam_securetty.c
@@ -0,0 +1,192 @@
+/* pam_securetty module */
+
+#define SECURETTY_FILE "/etc/securetty"
+#define TTY_PREFIX "/dev/"
+
+/*
+ * by Elliot Lee <sopwith@redhat.com>, Red Hat Software.
+ * July 25, 1996.
+ * This code shamelessly ripped from the pam_rootok module.
+ * Slight modifications AGM. 1996/12/3
+ * $FreeBSD$
+ */
+
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <stdarg.h>
+#include <pwd.h>
+#include <string.h>
+
+#define PAM_SM_AUTH
+
+/*
+ * here, we make a definition for the externally accessible function
+ * in this file (this definition is required for static a module
+ * but strongly encouraged generally) it is used to instruct the
+ * modules include file to define the function prototypes.
+ */
+
+#define PAM_SM_AUTH
+
+#include <security/pam_modules.h>
+
+/* some syslogging */
+
+static void _pam_log(int err, const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ openlog("PAM-securetty", LOG_CONS|LOG_PID, LOG_AUTH);
+ vsyslog(err, format, args);
+ va_end(args);
+ closelog();
+}
+
+/* argument parsing */
+
+#define PAM_DEBUG_ARG 0x0001
+
+static int _pam_parse(int argc, const char **argv)
+{
+ int ctrl=0;
+
+ /* step through arguments */
+ for (ctrl=0; argc-- > 0; ++argv) {
+
+ /* generic options */
+
+ if (!strcmp(*argv,"debug"))
+ ctrl |= PAM_DEBUG_ARG;
+ else {
+ _pam_log(LOG_ERR,"pam_parse: unknown option; %s",*argv);
+ }
+ }
+
+ return ctrl;
+}
+
+/* --- authentication management functions (only) --- */
+
+PAM_EXTERN
+int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc
+ ,const char **argv)
+{
+ int retval = PAM_AUTH_ERR;
+ const char *username;
+ char *uttyname;
+ char ttyfileline[256];
+ struct stat ttyfileinfo;
+ struct passwd *user_pwd;
+ FILE *ttyfile;
+ int ctrl;
+
+ /* parse the arguments */
+ ctrl = _pam_parse(argc, argv);
+
+ retval = pam_get_user(pamh, &username, NULL);
+ if (retval != PAM_SUCCESS || username == NULL) {
+ if (ctrl & PAM_DEBUG_ARG) {
+ _pam_log(LOG_WARNING, "cannot determine username");
+ }
+ return (retval == PAM_CONV_AGAIN
+ ? PAM_INCOMPLETE:PAM_SERVICE_ERR);
+ }
+
+ retval = pam_get_item(pamh, PAM_TTY, (const void **)&uttyname);
+ if (retval != PAM_SUCCESS || uttyname == NULL) {
+ if (ctrl & PAM_DEBUG_ARG) {
+ _pam_log(LOG_WARNING, "cannot determine user's tty");
+ }
+ return PAM_SERVICE_ERR;
+ }
+
+ /* The PAM_TTY item may be prefixed with "/dev/" - skip that */
+ if (strncmp(TTY_PREFIX, uttyname, sizeof(TTY_PREFIX)-1) == 0)
+ uttyname += sizeof(TTY_PREFIX)-1;
+
+ user_pwd = getpwnam(username);
+ if (user_pwd == NULL) {
+ return PAM_IGNORE;
+ } else if (user_pwd->pw_uid != 0) { /* If the user is not root,
+ securetty's does not apply
+ to them */
+ return PAM_SUCCESS;
+ }
+
+ if (stat(SECURETTY_FILE, &ttyfileinfo)) {
+ _pam_log(LOG_NOTICE, "Couldn't open " SECURETTY_FILE);
+ return PAM_SUCCESS; /* for compatibility with old securetty handling,
+ this needs to succeed. But we still log the
+ error. */
+ }
+
+ if ((ttyfileinfo.st_mode & S_IWOTH)
+ || !S_ISREG(ttyfileinfo.st_mode)) {
+ /* If the file is world writable or is not a
+ normal file, return error */
+ _pam_log(LOG_ERR, SECURETTY_FILE
+ " is either world writable or not a normal file");
+ return PAM_AUTH_ERR;
+ }
+
+ ttyfile = fopen(SECURETTY_FILE,"r");
+ if(ttyfile == NULL) { /* Check that we opened it successfully */
+ _pam_log(LOG_ERR,
+ "Error opening " SECURETTY_FILE);
+ return PAM_SERVICE_ERR;
+ }
+ /* There should be no more errors from here on */
+ retval=PAM_AUTH_ERR;
+ /* This loop assumes that PAM_SUCCESS == 0
+ and PAM_AUTH_ERR != 0 */
+ while((fgets(ttyfileline,sizeof(ttyfileline)-1, ttyfile) != NULL)
+ && retval) {
+ if(ttyfileline[strlen(ttyfileline) - 1] == '\n')
+ ttyfileline[strlen(ttyfileline) - 1] = '\0';
+ retval = strcmp(ttyfileline,uttyname);
+ }
+ fclose(ttyfile);
+ if(retval) {
+ if (ctrl & PAM_DEBUG_ARG)
+ _pam_log(LOG_WARNING, "access denied: tty '%s' is not secure !",
+ uttyname);
+ retval = PAM_AUTH_ERR;
+ }
+ if ((retval == PAM_SUCCESS) && (ctrl & PAM_DEBUG_ARG))
+ _pam_log(LOG_DEBUG, "access allowed for '%s' on '%s'",
+ username, uttyname);
+ return retval;
+}
+
+PAM_EXTERN
+int pam_sm_setcred(pam_handle_t *pamh,int flags,int argc
+ ,const char **argv)
+{
+ return PAM_SUCCESS;
+}
+
+
+#ifdef PAM_STATIC
+
+/* static module data */
+
+struct pam_module _pam_securetty_modstruct = {
+ "pam_securetty",
+ pam_sm_authenticate,
+ pam_sm_setcred,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+};
+
+#endif
+
+/* end of module definition */
diff --git a/contrib/libpam/modules/pam_shells/Makefile b/contrib/libpam/modules/pam_shells/Makefile
new file mode 100644
index 0000000..f607804
--- /dev/null
+++ b/contrib/libpam/modules/pam_shells/Makefile
@@ -0,0 +1,16 @@
+#
+# $Id: Makefile,v 1.2 2000/11/19 23:54:05 agmorgan Exp $
+# $FreeBSD$
+#
+# This Makefile controls a build process of $(TITLE) module for
+# Linux-PAM. You should not modify this Makefile (unless you know
+# what you are doing!).
+#
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
+#
+
+include ../../Make.Rules
+
+TITLE=pam_shells
+
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_shells/README b/contrib/libpam/modules/pam_shells/README
new file mode 100644
index 0000000..7e358fe
--- /dev/null
+++ b/contrib/libpam/modules/pam_shells/README
@@ -0,0 +1,11 @@
+$FreeBSD$
+pam_shells:
+ Authentication is granted if the users shell is listed in
+ /etc/shells. If no shell is in /etc/passwd (empty), the
+ /bin/sh is used (following ftpd's convention).
+
+ Also checks to make sure that /etc/shells is a plain
+ file and not world writable.
+
+ - Erik Troan <ewt@redhat.com>, Red Hat Software.
+ August 5, 1996.
diff --git a/contrib/libpam/modules/pam_shells/pam_shells.c b/contrib/libpam/modules/pam_shells/pam_shells.c
new file mode 100644
index 0000000..d83e0f2
--- /dev/null
+++ b/contrib/libpam/modules/pam_shells/pam_shells.c
@@ -0,0 +1,134 @@
+/* pam_shells module */
+
+#define SHELL_FILE "/etc/shells"
+
+/*
+ * by Erik Troan <ewt@redhat.com>, Red Hat Software.
+ * August 5, 1996.
+ * This code shamelessly ripped from the pam_securetty module.
+ * $FreeBSD$
+ */
+
+#define _BSD_SOURCE
+
+#include <pwd.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <syslog.h>
+#include <unistd.h>
+
+/*
+ * here, we make a definition for the externally accessible function
+ * in this file (this definition is required for static a module
+ * but strongly encouraged generally) it is used to instruct the
+ * modules include file to define the function prototypes.
+ */
+
+#define PAM_SM_AUTH
+
+#include <security/pam_modules.h>
+
+/* some syslogging */
+
+static void _pam_log(int err, const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ openlog("PAM-shells", LOG_CONS|LOG_PID, LOG_AUTH);
+ vsyslog(err, format, args);
+ va_end(args);
+ closelog();
+}
+
+/* --- authentication management functions (only) --- */
+
+PAM_EXTERN
+int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc
+ ,const char **argv)
+{
+ int retval = PAM_AUTH_ERR;
+ const char *userName;
+ char *userShell;
+ char shellFileLine[256];
+ struct stat sb;
+ struct passwd * pw;
+ FILE * shellFile;
+
+ retval = pam_get_user(pamh,&userName,NULL);
+ if(retval != PAM_SUCCESS)
+ return PAM_SERVICE_ERR;
+
+ if(!userName || (strlen(userName) <= 0)) {
+ /* Don't let them use a NULL username... */
+ pam_get_user(pamh,&userName,NULL);
+ if (retval != PAM_SUCCESS)
+ return PAM_SERVICE_ERR;
+ }
+
+ pw = getpwnam(userName);
+ if (!pw)
+ return PAM_AUTH_ERR; /* user doesn't exist */
+ userShell = pw->pw_shell;
+
+ if(stat(SHELL_FILE,&sb)) {
+ _pam_log(LOG_ERR,
+ "%s cannot be stat'd (it probably does not exist)", SHELL_FILE);
+ return PAM_AUTH_ERR; /* must have /etc/shells */
+ }
+
+ if((sb.st_mode & S_IWOTH) || !S_ISREG(sb.st_mode)) {
+ _pam_log(LOG_ERR,
+ "%s is either world writable or not a normal file", SHELL_FILE);
+ return PAM_AUTH_ERR;
+ }
+
+ shellFile = fopen(SHELL_FILE,"r");
+ if(shellFile == NULL) { /* Check that we opened it successfully */
+ _pam_log(LOG_ERR,
+ "Error opening %s", SHELL_FILE);
+ return PAM_SERVICE_ERR;
+ }
+ /* There should be no more errors from here on */
+ retval=PAM_AUTH_ERR;
+ /* This loop assumes that PAM_SUCCESS == 0
+ and PAM_AUTH_ERR != 0 */
+ while((fgets(shellFileLine,255,shellFile) != NULL)
+ && retval) {
+ if (shellFileLine[strlen(shellFileLine) - 1] == '\n')
+ shellFileLine[strlen(shellFileLine) - 1] = '\0';
+ retval = strcmp(shellFileLine, userShell);
+ }
+ fclose(shellFile);
+ if(retval)
+ retval = PAM_AUTH_ERR;
+ return retval;
+}
+
+PAM_EXTERN
+int pam_sm_setcred(pam_handle_t *pamh,int flags,int argc
+ ,const char **argv)
+{
+ return PAM_SUCCESS;
+}
+
+
+#ifdef PAM_STATIC
+
+/* static module data */
+
+struct pam_module _pam_shells_modstruct = {
+ "pam_shells",
+ pam_sm_authenticate,
+ pam_sm_setcred,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+};
+
+#endif
+
+/* end of module definition */
diff --git a/contrib/libpam/modules/pam_warn/Makefile b/contrib/libpam/modules/pam_warn/Makefile
new file mode 100644
index 0000000..46201d0
--- /dev/null
+++ b/contrib/libpam/modules/pam_warn/Makefile
@@ -0,0 +1,16 @@
+#
+# $Id: Makefile,v 1.2 2000/11/19 23:54:06 agmorgan Exp $
+# $FreeBSD$
+#
+# This Makefile controls a build process of $(TITLE) module for
+# Linux-PAM. You should not modify this Makefile (unless you know
+# what you are doing!).
+#
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
+#
+
+include ../../Make.Rules
+
+TITLE=pam_warn
+
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_warn/README b/contrib/libpam/modules/pam_warn/README
new file mode 100644
index 0000000..cd8158b
--- /dev/null
+++ b/contrib/libpam/modules/pam_warn/README
@@ -0,0 +1,26 @@
+# $Id: README,v 1.1.1.1 2000/06/20 22:12:10 agmorgan Exp $
+# $FreeBSD$
+
+This module is an authentication module that does not authenticate.
+Instead it always returns PAM_IGNORE, indicating that it does not want
+to affect the authentication process.
+
+Its purpose is to log a message to the syslog indicating the
+pam_item's available at the time it was invoked. It is a diagnostic
+tool.
+
+Recognized arguments:
+
+ <none>
+
+module services provided:
+
+ auth _authenticate and _setcred (blank)
+ acct _acct_mgmt [mapped to _authenticate]
+ session _open_session and
+ _close_session [mapped to _authenticate ]
+ password _chauthtok [mapped to _authenticate]
+
+
+Andrew Morgan
+1996/11/14
diff --git a/contrib/libpam/modules/pam_warn/pam_warn.c b/contrib/libpam/modules/pam_warn/pam_warn.c
new file mode 100644
index 0000000..ac627fb
--- /dev/null
+++ b/contrib/libpam/modules/pam_warn/pam_warn.c
@@ -0,0 +1,133 @@
+/* pam_warn module */
+
+/*
+ * $Id: pam_warn.c,v 1.1.1.1 2000/06/20 22:12:10 agmorgan Exp $
+ * $FreeBSD$
+ *
+ * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11
+ */
+
+#define _BSD_SOURCE
+
+#include <stdio.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <stdarg.h>
+
+/*
+ * here, we make a definition for the externally accessible function
+ * in this file (this definition is required for static a module
+ * but strongly encouraged generally) it is used to instruct the
+ * modules include file to define the function prototypes.
+ */
+
+#define PAM_SM_AUTH
+#define PAM_SM_PASSWORD
+
+#include <security/pam_modules.h>
+
+/* some syslogging */
+
+static void _pam_log(int err, const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ openlog("PAM-warn", LOG_CONS|LOG_PID, LOG_AUTH);
+ vsyslog(err, format, args);
+ va_end(args);
+ closelog();
+}
+
+/* --- authentication management functions (only) --- */
+
+PAM_EXTERN
+int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc
+ , const char **argv)
+{
+ const char *service=NULL, *user=NULL, *terminal=NULL
+ , *rhost=NULL, *ruser=NULL;
+
+ (void) pam_get_item(pamh, PAM_SERVICE, (const void **)&service);
+ (void) pam_get_item(pamh, PAM_TTY, (const void **)&terminal);
+ _pam_log(LOG_NOTICE, "service: %s [on terminal: %s]"
+ , service ? service : "<unknown>"
+ , terminal ? terminal : "<unknown>"
+ );
+ (void) pam_get_user(pamh, &user, "Who are you? ");
+ (void) pam_get_item(pamh, PAM_RUSER, (const void **)&ruser);
+ (void) pam_get_item(pamh, PAM_RHOST, (const void **)&rhost);
+ _pam_log(LOG_NOTICE, "user: (uid=%d) -> %s [remote: %s@%s]"
+ , getuid()
+ , user ? user : "<unknown>"
+ , ruser ? ruser : "?nobody"
+ , rhost ? rhost : "?nowhere"
+ );
+
+ /* we are just a fly on the wall */
+
+ return PAM_IGNORE;
+}
+
+PAM_EXTERN
+int pam_sm_setcred(pam_handle_t *pamh,int flags,int argc
+ , const char **argv)
+{
+ return PAM_IGNORE;
+}
+
+/* password updating functions */
+
+PAM_EXTERN
+int pam_sm_chauthtok(pam_handle_t *pamh,int flags,int argc
+ , const char **argv)
+{
+ /* map to the authentication function... */
+
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
+
+PAM_EXTERN int
+pam_sm_acct_mgmt (pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ /* map to the authentication function... */
+
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
+
+PAM_EXTERN int
+pam_sm_open_session (pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ /* map to the authentication function... */
+
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
+
+PAM_EXTERN int
+pam_sm_close_session (pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ /* map to the authentication function... */
+
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
+
+#ifdef PAM_STATIC
+
+/* static module data */
+
+struct pam_module _pam_warn_modstruct = {
+ "pam_warn",
+ pam_sm_authenticate,
+ pam_sm_setcred,
+ pam_sm_acct_mgmt,
+ pam_sm_open_session,
+ pam_sm_close_session,
+ pam_sm_chauthtok,
+};
+
+#endif
+
+/* end of module definition */
OpenPOWER on IntegriCloud