Bring back from the er, dead some useful PAM modules.
This commit is contained in:
parent
83f1488d6e
commit
13b65deafa
16
contrib/libpam/modules/pam_ftp/Makefile
Normal file
16
contrib/libpam/modules/pam_ftp/Makefile
Normal file
@ -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
|
19
contrib/libpam/modules/pam_ftp/README
Normal file
19
contrib/libpam/modules/pam_ftp/README
Normal file
@ -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
|
298
contrib/libpam/modules/pam_ftp/pam_ftp.c
Normal file
298
contrib/libpam/modules/pam_ftp/pam_ftp.c
Normal file
@ -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 */
|
16
contrib/libpam/modules/pam_rhosts/Makefile
Normal file
16
contrib/libpam/modules/pam_rhosts/Makefile
Normal file
@ -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
|
58
contrib/libpam/modules/pam_rhosts/README
Normal file
58
contrib/libpam/modules/pam_rhosts/README
Normal file
@ -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.
|
||||
|
787
contrib/libpam/modules/pam_rhosts/pam_rhosts_auth.c
Normal file
787
contrib/libpam/modules/pam_rhosts/pam_rhosts_auth.c
Normal file
@ -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
|
16
contrib/libpam/modules/pam_securetty/Makefile
Normal file
16
contrib/libpam/modules/pam_securetty/Makefile
Normal file
@ -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
|
10
contrib/libpam/modules/pam_securetty/README
Normal file
10
contrib/libpam/modules/pam_securetty/README
Normal file
@ -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.
|
192
contrib/libpam/modules/pam_securetty/pam_securetty.c
Normal file
192
contrib/libpam/modules/pam_securetty/pam_securetty.c
Normal file
@ -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 */
|
16
contrib/libpam/modules/pam_shells/Makefile
Normal file
16
contrib/libpam/modules/pam_shells/Makefile
Normal file
@ -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
|
11
contrib/libpam/modules/pam_shells/README
Normal file
11
contrib/libpam/modules/pam_shells/README
Normal file
@ -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.
|
134
contrib/libpam/modules/pam_shells/pam_shells.c
Normal file
134
contrib/libpam/modules/pam_shells/pam_shells.c
Normal file
@ -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 */
|
16
contrib/libpam/modules/pam_warn/Makefile
Normal file
16
contrib/libpam/modules/pam_warn/Makefile
Normal file
@ -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
|
26
contrib/libpam/modules/pam_warn/README
Normal file
26
contrib/libpam/modules/pam_warn/README
Normal file
@ -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
|
133
contrib/libpam/modules/pam_warn/pam_warn.c
Normal file
133
contrib/libpam/modules/pam_warn/pam_warn.c
Normal file
@ -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 */
|
Loading…
x
Reference in New Issue
Block a user