diff options
| author | Mark Murray <markm@FreeBSD.org> | 2001-05-29 18:32:17 +0000 | 
|---|---|---|
| committer | Mark Murray <markm@FreeBSD.org> | 2001-05-29 18:32:17 +0000 | 
| commit | 13b65deafa70c2bfa71ce45d2904bae0dc4c098d (patch) | |
| tree | fa2eea2cc3a2eddfb6e7e99207a4149ca9b9100a | |
| parent | 83f1488d6e39ad3f0f3d9da96c1052c205965e38 (diff) | |
Notes
| -rw-r--r-- | contrib/libpam/modules/pam_ftp/Makefile | 16 | ||||
| -rw-r--r-- | contrib/libpam/modules/pam_ftp/README | 19 | ||||
| -rw-r--r-- | contrib/libpam/modules/pam_ftp/pam_ftp.c | 298 | ||||
| -rw-r--r-- | contrib/libpam/modules/pam_rhosts/Makefile | 16 | ||||
| -rw-r--r-- | contrib/libpam/modules/pam_rhosts/README | 58 | ||||
| -rw-r--r-- | contrib/libpam/modules/pam_rhosts/pam_rhosts_auth.c | 787 | ||||
| -rw-r--r-- | contrib/libpam/modules/pam_securetty/Makefile | 16 | ||||
| -rw-r--r-- | contrib/libpam/modules/pam_securetty/README | 10 | ||||
| -rw-r--r-- | contrib/libpam/modules/pam_securetty/pam_securetty.c | 192 | ||||
| -rw-r--r-- | contrib/libpam/modules/pam_shells/Makefile | 16 | ||||
| -rw-r--r-- | contrib/libpam/modules/pam_shells/README | 11 | ||||
| -rw-r--r-- | contrib/libpam/modules/pam_shells/pam_shells.c | 134 | ||||
| -rw-r--r-- | contrib/libpam/modules/pam_warn/Makefile | 16 | ||||
| -rw-r--r-- | contrib/libpam/modules/pam_warn/README | 26 | ||||
| -rw-r--r-- | contrib/libpam/modules/pam_warn/pam_warn.c | 133 | 
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 0000000000000..4ea360d13f78e --- /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 0000000000000..0e9315ec2f7a5 --- /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 0000000000000..df10a03479a4f --- /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 0000000000000..0108969fc5d68 --- /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 0000000000000..8bd01aa3e7f2d --- /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 0000000000000..f520fda08ba70 --- /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 **)¤t); +    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 **)¤t); +    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 0000000000000..fb3bb56f4ca0f --- /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 0000000000000..fe17ce5c2f6cb --- /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 0000000000000..b99a2f07194b6 --- /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 0000000000000..f60780452dbea --- /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 0000000000000..7e358fe0995b2 --- /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 0000000000000..d83e0f2ee8702 --- /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 0000000000000..46201d0a99f2f --- /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 0000000000000..cd8158bfaa7b0 --- /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 0000000000000..ac627fb363c85 --- /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 */  | 
