diff options
Diffstat (limited to 'lib/libpam/modules')
62 files changed, 8725 insertions, 0 deletions
diff --git a/lib/libpam/modules/Makefile b/lib/libpam/modules/Makefile new file mode 100644 index 0000000..9e7b91b --- /dev/null +++ b/lib/libpam/modules/Makefile @@ -0,0 +1,30 @@ +# Copyright 1998 Juniper Networks, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ + +.include "modules.inc" +SUBDIR = ${MODULES} + +.include <bsd.subdir.mk> diff --git a/lib/libpam/modules/Makefile.inc b/lib/libpam/modules/Makefile.inc new file mode 100644 index 0000000..70f85db --- /dev/null +++ b/lib/libpam/modules/Makefile.inc @@ -0,0 +1,19 @@ +# $FreeBSD$ + +PAMDIR= ${.CURDIR}/../../../../contrib/openpam + +INTERNALLIB= yes +INTERNALSTATICLIB=yes + +CFLAGS+= -I${PAMDIR}/include +CFLAGS+= -I${.CURDIR}/../../libpam +WARNS?= 4 + +# This is nasty. +# For the static case, libpam.a depends on the modules. +# For the dynamic case, the modules depend on libpam.so.N +# Punt for the time being until I can figure out how to do it. +#DPADD+= ${LIBPAM} +#LDADD+= -lpam + +.include "../Makefile.inc" diff --git a/lib/libpam/modules/modules.inc b/lib/libpam/modules/modules.inc new file mode 100644 index 0000000..d7b08aa --- /dev/null +++ b/lib/libpam/modules/modules.inc @@ -0,0 +1,28 @@ +# $FreeBSD$ + +MODULES = +MODULES += pam_deny +MODULES += pam_ftp +.if defined(MAKE_KERBEROS4) && !defined(NOCRYPT) && !defined(NO_OPENSSL) +MODULES += pam_kerberosIV +.endif +.if defined(MAKE_KERBEROS5) && !defined(NOCRYPT) && !defined(NO_OPENSSL) +MODULES += pam_krb5 +.endif +MODULES += pam_lastlog +MODULES += pam_login_access +MODULES += pam_nologin +MODULES += pam_opie +MODULES += pam_opieaccess +MODULES += pam_passwdqc +MODULES += pam_permit +MODULES += pam_radius +MODULES += pam_rootok +MODULES += pam_securetty +MODULES += pam_self +.if !defined(NOCRYPT) && !defined(NO_OPENSSL) && !defined(NO_OPENSSH) +MODULES += pam_ssh +.endif +MODULES += pam_tacplus +MODULES += pam_unix +MODULES += pam_wheel diff --git a/lib/libpam/modules/pam_deny/Makefile b/lib/libpam/modules/pam_deny/Makefile new file mode 100644 index 0000000..adbda34 --- /dev/null +++ b/lib/libpam/modules/pam_deny/Makefile @@ -0,0 +1,32 @@ +# Copyright 1999 Max Khon. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ + +LIB= pam_deny +SHLIB_NAME= ${LIB}.so.${SHLIB_MAJOR} +SRCS= pam_deny.c +MAN= pam_deny.8 + +.include <bsd.lib.mk> diff --git a/lib/libpam/modules/pam_deny/pam_deny.8 b/lib/libpam/modules/pam_deny/pam_deny.8 new file mode 100644 index 0000000..d9544be --- /dev/null +++ b/lib/libpam/modules/pam_deny/pam_deny.8 @@ -0,0 +1,80 @@ +.\" Copyright (c) 2001 Mark R V Murray +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ +.\" +.Dd July 7, 2001 +.Dt PAM_DENY 8 +.Os +.Sh NAME +.Nm pam_deny +.Nd Deny PAM module +.Sh SYNOPSIS +.Op Ar service-name +.Ar module-type +.Ar control-flag +.Pa pam_deny +.Op Ar options +.Sh DESCRIPTION +The Deny authentication service module for PAM, +.Nm +provides functionality for all the PAM categories: +authentication, +account management, +session management and +password management. +In terms of the +.Ar module-type +parameter, these are the +.Dq Li auth , +.Dq Li account , +.Dq Li session , +and +.Dq Li password +features. +.Pp +The Deny module +will universally deny all requests. +It is primarily of use during testing, +and to +.Dq null-out +unwanted functionality. +.Pp +The following options may be passed to the module: +.Bl -tag -width ".Cm no_warn" +.It Cm debug +.Xr syslog 3 +debugging information at +.Dv LOG_DEBUG +level. +.It Cm no_warn +suppress warning messages to the user. +These messages include +reasons why the user's +authentication attempt was declined. +.El +.Sh SEE ALSO +.Xr syslog 3 , +.Xr pam.conf 5 , +.Xr pam 8 diff --git a/lib/libpam/modules/pam_deny/pam_deny.c b/lib/libpam/modules/pam_deny/pam_deny.c new file mode 100644 index 0000000..02dc8a5 --- /dev/null +++ b/lib/libpam/modules/pam_deny/pam_deny.c @@ -0,0 +1,125 @@ +/*- + * Copyright 2001 Mark R V Murray + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stddef.h> + +#define PAM_SM_AUTH +#define PAM_SM_ACCOUNT +#define PAM_SM_SESSION +#define PAM_SM_PASSWORD + +#include <security/pam_appl.h> +#include <security/pam_modules.h> +#include <security/pam_mod_misc.h> + +PAM_EXTERN int +pam_sm_authenticate(pam_handle_t *pamh, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_VERBOSE_ERROR("Unconditional deny"); + + PAM_RETURN(PAM_AUTH_ERR); +} + +PAM_EXTERN int +pam_sm_setcred(pam_handle_t *pamh, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_VERBOSE_ERROR("Unconditional deny"); + + PAM_RETURN(PAM_CRED_UNAVAIL); +} + +PAM_EXTERN int +pam_sm_acct_mgmt(pam_handle_t *pamh, int flags __unused, int argc ,const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_VERBOSE_ERROR("Unconditional deny"); + + PAM_RETURN(PAM_ACCT_EXPIRED); +} + +PAM_EXTERN int +pam_sm_chauthtok(pam_handle_t *pamh, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_VERBOSE_ERROR("Unconditional deny"); + + PAM_RETURN(PAM_PERM_DENIED); +} + +PAM_EXTERN int +pam_sm_open_session(pam_handle_t *pamh, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_VERBOSE_ERROR("Unconditional deny"); + + PAM_RETURN(PAM_SESSION_ERR); +} + +PAM_EXTERN int +pam_sm_close_session(pam_handle_t *pamh, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_VERBOSE_ERROR("Unconditional deny"); + + PAM_RETURN(PAM_SESSION_ERR); +} + +PAM_MODULE_ENTRY("pam_deny"); diff --git a/lib/libpam/modules/pam_ftp/Makefile b/lib/libpam/modules/pam_ftp/Makefile new file mode 100644 index 0000000..414325e --- /dev/null +++ b/lib/libpam/modules/pam_ftp/Makefile @@ -0,0 +1,32 @@ +# Copyright 2001 Mark R V Murray +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ + +LIB= pam_ftp +SHLIB_NAME= ${LIB}.so.${SHLIB_MAJOR} +SRCS= pam_ftp.c +MAN= pam_ftp.8 + +.include <bsd.lib.mk> diff --git a/lib/libpam/modules/pam_ftp/pam_ftp.8 b/lib/libpam/modules/pam_ftp/pam_ftp.8 new file mode 100644 index 0000000..5be1070 --- /dev/null +++ b/lib/libpam/modules/pam_ftp/pam_ftp.8 @@ -0,0 +1,100 @@ +.\" Copyright (c) 2001 Mark R V Murray +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ +.\" +.Dd July 8, 2001 +.Dt PAM_FTP 8 +.Os +.Sh NAME +.Nm pam_ftp +.Nd FTP PAM module +.Sh SYNOPSIS +.Op Ar service-name +.Ar module-type +.Ar control-flag +.Pa pam_ftp +.Op Ar options +.Sh DESCRIPTION +The FTP authentication service module for PAM, +.Nm +provides functionality for only one PAM category: +authentication. +In terms of the +.Ar module-type +parameter, this is the +.Dq Li auth +feature. +It also provides a null function for session management. +.Ss FTP Authentication Module +The FTP authentication component +.Pq Fn pam_sm_authenticate , +authenticates the anonymous user +(usually +.Dq anonymous +or +.Dq ftp ) +usually by simply requesting an email address as a password. +The supplied email address is broken up +into its username and host parts, +and these are assigned to the +.Dv PAM_RUSER +and +.Dv PAM_RHOST +facilities respectively. +.Pp +This module is intended for the +.Xr ftpd 8 +service. +.Pp +The following options may be passed to the authentication module: +.Bl -tag -width ".Cm no_warn" +.It Cm debug +.Xr syslog 3 +debugging information at +.Dv LOG_DEBUG +level. +.It Cm no_warn +suppress warning messages to the user. +These messages include +reasons why the user's +authentication attempt was declined. +.It Cm no_anon +Disallow anonymous access. +.It Cm ignore +Ingnore the password supplied, +and do not use its constituent parts +(username and hostname) +as +.Dv PAM_RUSER +and +.Dv PAM_RHOST +respectively. +.El +.Sh SEE ALSO +.Xr ftp 1 , +.Xr syslog 3 , +.Xr pam.conf 5 , +.Xr ftpd 8 , +.Xr pam 8 diff --git a/lib/libpam/modules/pam_ftp/pam_ftp.c b/lib/libpam/modules/pam_ftp/pam_ftp.c new file mode 100644 index 0000000..e99fbd8 --- /dev/null +++ b/lib/libpam/modules/pam_ftp/pam_ftp.c @@ -0,0 +1,258 @@ +/*- + * Copyright (c) 2001 Mark R V Murray + * All rights reserved. + * Copyright (c) 2001 Networks Associates Technology, Inc. + * All rights reserved. + * + * Portions of this software were developed for the FreeBSD Project by + * ThinkSec AS and NAI Labs, the Security Research Division of Network + * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 + * ("CBOSS"), as part of the DARPA CHATS research program. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#define PROMPT "Password required for %s." +#define GUEST_PROMPT "Guest login ok, send your e-mail address as password." + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <syslog.h> +#include <stdarg.h> +#include <string.h> + +#define PAM_SM_AUTH +#define PAM_SM_ACCOUNT +#define PAM_SM_SESSION +#define PAM_SM_PASSWORD + +#include <security/pam_appl.h> +#include <security/pam_modules.h> +#include <security/pam_mod_misc.h> + +enum { + PAM_OPT_NO_ANON = PAM_OPT_STD_MAX, + PAM_OPT_IGNORE, + PAM_OPT_USERS +}; + +static struct opttab other_options[] = { + { "no_anon", PAM_OPT_NO_ANON }, + { "ignore", PAM_OPT_IGNORE }, + { "users", PAM_OPT_USERS }, + { NULL, 0 } +}; + +static const char *anonusers[] = {"ftp", "anonymous", NULL}; + +/* Check if *user is in supplied *list or *anonusers[] list. + * Place username in *userret + * Return 1 if listed 0 otherwise + */ +static int +lookup(const char *user, char *list, const char **userret) +{ + int anon, i; + char *item, *context, *locallist; + + anon = 0; + *userret = user; /* this is the default */ + if (list) { + *userret = NULL; + locallist = list; + while ((item = strtok_r(locallist, ",", &context))) { + if (*userret == NULL) + *userret = item; + if (strcmp(user, item) == 0) { + anon = 1; + break; + } + locallist = NULL; + } + } + else { + for (i = 0; anonusers[i] != NULL; i++) { + if (strcmp(anonusers[i], user) == 0) { + *userret = anonusers[0]; + anon = 1; + break; + } + } + } + return anon; +} + +/* Check if the user name is 'ftp' or 'anonymous'. + * If this is the case, set the PAM_RUSER to the entered email address + * and succeed, otherwise fail. + */ +PAM_EXTERN int +pam_sm_authenticate(pam_handle_t * pamh, int flags __unused, int argc, const char **argv) +{ + struct options options; + int retval, anon; + char *users, *context, *token, *p; + const char *user, *prompt; + + pam_std_option(&options, other_options, argc, argv); + + PAM_LOG("Options processed"); + + retval = pam_get_user(pamh, &user, NULL); + if (retval != PAM_SUCCESS || user == NULL) + PAM_RETURN(PAM_USER_UNKNOWN); + + PAM_LOG("Got user: %s", user); + + users = NULL; + if (pam_test_option(&options, PAM_OPT_USERS, &users)) + PAM_LOG("Got extra anonymous users: %s", users); + + anon = 0; + if (!pam_test_option(&options, PAM_OPT_NO_ANON, NULL)) + anon = lookup(user, users, &user); + + PAM_LOG("Done user: %s", user); + + if (anon) { + retval = pam_set_item(pamh, PAM_USER, (const void *)user); + if (retval != PAM_SUCCESS) + PAM_RETURN(retval); + prompt = GUEST_PROMPT; + PAM_LOG("Doing anonymous"); + } + else { + prompt = PROMPT; + PAM_LOG("Doing non-anonymous"); + } + + retval = pam_prompt(pamh, PAM_PROMPT_ECHO_OFF, &token, "%s", prompt); + if (retval != PAM_SUCCESS) + PAM_RETURN(PAM_AUTHINFO_UNAVAIL); + + PAM_LOG("Got password"); + + if (anon) { + if (!pam_test_option(&options, PAM_OPT_IGNORE, NULL)) { + p = strtok_r(token, "@", &context); + if (p != NULL) { + pam_set_item(pamh, PAM_RUSER, p); + PAM_LOG("Got ruser: %s", p); + if (retval == PAM_SUCCESS) { + /* XXX XXX XXX */ + p = strtok_r(NULL, "@", &context); + if (p != NULL) { + pam_set_item(pamh, PAM_RHOST, p); + PAM_LOG("Got rhost: %s", p); + } + } + } + } + else { + PAM_LOG("Ignoring supplied password structure"); + } + + PAM_LOG("Done anonymous"); + + retval = PAM_SUCCESS; + } + else { + pam_set_item(pamh, PAM_AUTHTOK, token); + + PAM_VERBOSE_ERROR("Anonymous module reject"); + + PAM_LOG("Done non-anonymous"); + + retval = PAM_AUTH_ERR; + } + + PAM_RETURN(retval); +} + +PAM_EXTERN int +pam_sm_setcred(pam_handle_t * pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, other_options, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_SUCCESS); +} + +PAM_EXTERN int +pam_sm_acct_mgmt(pam_handle_t *pamh __unused, int flags __unused, int argc ,const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_chauthtok(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_open_session(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_close_session(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_MODULE_ENTRY("pam_ftp"); diff --git a/lib/libpam/modules/pam_kerberosIV/Makefile b/lib/libpam/modules/pam_kerberosIV/Makefile new file mode 100644 index 0000000..f6b288e --- /dev/null +++ b/lib/libpam/modules/pam_kerberosIV/Makefile @@ -0,0 +1,34 @@ +# Copyright 1998 Juniper Networks, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ + +LIB= pam_kerberosIV +SHLIB_NAME= ${LIB}.so.${SHLIB_MAJOR} +SRCS= pam_kerberosIV.c klogin.c +CFLAGS+= -DKERBEROS +DPADD= ${LIBKRB} ${LIBCRYPTO} ${LIBCOM_ERR} +LDADD= -lkrb -lcrypto -lcom_err + +.include <bsd.lib.mk> diff --git a/lib/libpam/modules/pam_kerberosIV/klogin.c b/lib/libpam/modules/pam_kerberosIV/klogin.c new file mode 100644 index 0000000..ae51f74 --- /dev/null +++ b/lib/libpam/modules/pam_kerberosIV/klogin.c @@ -0,0 +1,207 @@ +/*- + * Copyright (c) 1990, 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#ifndef lint +static const char sccsid[] = "@(#)klogin.c 8.3 (Berkeley) 4/2/94"; +#endif /* not lint */ + +#ifdef KERBEROS +#include <sys/param.h> +#include <sys/syslog.h> +#include <openssl/des.h> +#include <krb.h> + +#include <err.h> +#include <netdb.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define INITIAL_TICKET "krbtgt" +#define VERIFY_SERVICE "rcmd" + +extern int notickets; +extern char *krbtkfile_env; + +/* + * Attempt to log the user in using Kerberos authentication + * + * return 0 on success (will be logged in) + * 1 if Kerberos failed (try local password in login) + */ +int +klogin(pw, instance, localhost, password) + struct passwd *pw; + char *instance, *localhost, *password; +{ + int kerror; + char realm[REALM_SZ], savehost[MAXHOSTNAMELEN]; + char tkt_location[MAXPATHLEN]; + char *krb_get_phost(); + extern int noticketsdontcomplain; + +#ifdef KLOGIN_PARANOID + AUTH_DAT authdata; + KTEXT_ST ticket; + struct hostent *hp; + unsigned long faddr; + + noticketsdontcomplain = 0; /* enable warning message */ +#endif + + /* + * Root logins don't use Kerberos. + * If we have a realm, try getting a ticket-granting ticket + * and using it to authenticate. Otherwise, return + * failure so that we can try the normal passwd file + * for a password. If that's ok, log the user in + * without issuing any tickets. + */ + if (strcmp(pw->pw_name, "root") == 0 || + krb_get_lrealm(realm, 0) != KSUCCESS) + return (1); + + noticketsdontcomplain = 0; /* enable warning message */ + + /* + * get TGT for local realm + * tickets are stored in a file named TKT_ROOT plus uid + * except for user.root tickets. + */ + + if (strcmp(instance, "root") != 0) + (void)sprintf(tkt_location, "%s%d", TKT_ROOT, pw->pw_uid); + else { + (void)sprintf(tkt_location, "%s_root_%d", TKT_ROOT, pw->pw_uid); + krbtkfile_env = tkt_location; + } + (void)krb_set_tkt_string(tkt_location); + + /* + * Set real as well as effective ID to 0 for the moment, + * to make the kerberos library do the right thing. + */ + if (setuid(0) < 0) { + warnx("setuid"); + return (1); + } + kerror = krb_get_pw_in_tkt(pw->pw_name, instance, + realm, INITIAL_TICKET, realm, DEFAULT_TKT_LIFE, password); + + /* + * If we got a TGT, get a local "rcmd" ticket and check it so as to + * ensure that we are not talking to a bogus Kerberos server. + * + * There are 2 cases where we still allow a login: + * 1: the VERIFY_SERVICE doesn't exist in the KDC + * 2: local host has no srvtab, as (hopefully) indicated by a + * return value of RD_AP_UNDEC from krb_rd_req(). + */ + if (kerror != INTK_OK) { + if (kerror != INTK_BADPW && kerror != KDC_PR_UNKNOWN) { + syslog(LOG_ERR, "Kerberos intkt error: %s", + krb_err_txt[kerror]); + dest_tkt(); + } + return (1); + } + + if (chown(TKT_FILE, pw->pw_uid, pw->pw_gid) < 0) + syslog(LOG_ERR, "chown tkfile (%s): %m", TKT_FILE); + + (void)strncpy(savehost, krb_get_phost(localhost), sizeof(savehost)); + savehost[sizeof(savehost)-1] = NULL; + +#ifdef KLOGIN_PARANOID + /* + * if the "VERIFY_SERVICE" doesn't exist in the KDC for this host, + * still allow login with tickets, but log the error condition. + */ + + kerror = krb_mk_req(&ticket, VERIFY_SERVICE, savehost, realm, 33); + if (kerror == KDC_PR_UNKNOWN) { + syslog(LOG_NOTICE, + "warning: TGT not verified (%s); %s.%s not registered, or srvtab is wrong?", + krb_err_txt[kerror], VERIFY_SERVICE, savehost); + notickets = 0; + return (0); + } + + if (kerror != KSUCCESS) { + warnx("unable to use TGT: (%s)", krb_err_txt[kerror]); + syslog(LOG_NOTICE, "unable to use TGT: (%s)", + krb_err_txt[kerror]); + dest_tkt(); + return (1); + } + + if (!(hp = gethostbyname(localhost))) { + syslog(LOG_ERR, "couldn't get local host address"); + dest_tkt(); + return (1); + } + + memmove((void *)&faddr, (void *)hp->h_addr, sizeof(faddr)); + + kerror = krb_rd_req(&ticket, VERIFY_SERVICE, savehost, faddr, + &authdata, ""); + + if (kerror == KSUCCESS) { + notickets = 0; + return (0); + } + + /* undecipherable: probably didn't have a srvtab on the local host */ + if (kerror == RD_AP_UNDEC) { + syslog(LOG_NOTICE, "krb_rd_req: (%s)\n", krb_err_txt[kerror]); + dest_tkt(); + return (1); + } + /* failed for some other reason */ + warnx("unable to verify %s ticket: (%s)", VERIFY_SERVICE, + krb_err_txt[kerror]); + syslog(LOG_NOTICE, "couldn't verify %s ticket: %s", VERIFY_SERVICE, + krb_err_txt[kerror]); + dest_tkt(); + return (1); +#else + notickets = 0; + return (0); +#endif +} +#endif diff --git a/lib/libpam/modules/pam_kerberosIV/pam_kerberosIV.c b/lib/libpam/modules/pam_kerberosIV/pam_kerberosIV.c new file mode 100644 index 0000000..71e22c3 --- /dev/null +++ b/lib/libpam/modules/pam_kerberosIV/pam_kerberosIV.c @@ -0,0 +1,139 @@ +/*- + * Copyright 1998 Juniper Networks, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <pwd.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define PAM_SM_AUTH +#include <security/pam_appl.h> +#include <security/pam_modules.h> +#include <security/pam_mod_misc.h> + +#define PASSWORD_PROMPT "Password:" + +extern int klogin(struct passwd *, char *, char *, char *); + +/* Globals used by klogin.c */ +int notickets = 1; +int noticketsdontcomplain = 1; +char *krbtkfile_env; + +PAM_EXTERN int +pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) +{ + struct options options; + int retval; + const char *user; + char *principal; + char *instance; + const char *password; + char localhost[MAXHOSTNAMELEN + 1]; + struct passwd *pwd; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + retval = pam_get_user(pamh, &user, NULL); + if (retval != PAM_SUCCESS) + PAM_RETURN(retval); + + PAM_LOG("Got user: %s", user); + + retval = pam_get_pass(pamh, &password, PASSWORD_PROMPT, &options); + if (retval != PAM_SUCCESS) + PAM_RETURN(retval); + + PAM_LOG("Got password"); + + if (gethostname(localhost, sizeof localhost - 1) == -1) + PAM_RETURN(PAM_SYSTEM_ERR); + + PAM_LOG("Got localhost: %s", localhost); + + principal = strdup(user); + if (principal == NULL) + PAM_RETURN(PAM_BUF_ERR); + + instance = strchr(principal, '.'); + if (instance != NULL) + *instance++ = '\0'; + else + instance = ""; + + PAM_LOG("Got principal.instance: %s.%s", principal, instance); + + retval = PAM_AUTH_ERR; + pwd = getpwnam(user); + if (pwd != NULL) { + if (klogin(pwd, instance, localhost, (char *)password) == 0) { + if (!(flags & PAM_SILENT) && notickets && !noticketsdontcomplain) + pam_prompt(pamh, PAM_ERROR_MSG, + "Warning: no Kerberos tickets issued", + NULL); + /* + * XXX - I think the ticket file isn't supposed to + * be created until pam_sm_setcred() is called. + */ + if (krbtkfile_env != NULL) + setenv("KRBTKFILE", krbtkfile_env, 1); + retval = PAM_SUCCESS; + } + + PAM_LOG("Done klogin()"); + + } + /* + * The PAM infrastructure will obliterate the cleartext + * password before returning to the application. + */ + free(principal); + + if (retval != PAM_SUCCESS) + PAM_VERBOSE_ERROR("Kerberos IV refuses you"); + + PAM_RETURN(retval); +} + +PAM_EXTERN int +pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_SUCCESS); +} + +PAM_MODULE_ENTRY("pam_kerberosIV"); diff --git a/lib/libpam/modules/pam_krb5/Makefile b/lib/libpam/modules/pam_krb5/Makefile new file mode 100644 index 0000000..525358a --- /dev/null +++ b/lib/libpam/modules/pam_krb5/Makefile @@ -0,0 +1,36 @@ +# Copyright 2001 FreeBSD, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ + +LIB= pam_krb5 +SHLIB_NAME= ${LIB}.so.${SHLIB_MAJOR} +SRCS= pam_krb5.c +DPADD= ${LIBKRB5} ${LIBGSSAPI} ${LIBASN1} ${LIBCRYPTO} ${LIBCRYPT} \ + ${LIBCOM_ERR} ${LIBROKEN} +LDADD= -lkrb5 -lgssapi -lasn1 -lcrypto -lcrypt -lcom_err \ + -L${.OBJDIR}/../../../../kerberos5/lib/libroken -lroken +MAN= pam_krb5.8 + +.include <bsd.lib.mk> diff --git a/lib/libpam/modules/pam_krb5/pam_krb5.8 b/lib/libpam/modules/pam_krb5/pam_krb5.8 new file mode 100644 index 0000000..3e0db91 --- /dev/null +++ b/lib/libpam/modules/pam_krb5/pam_krb5.8 @@ -0,0 +1,217 @@ +.\" +.\" $Id: pam_krb5.5,v 1.5 2000/01/05 00:59:56 fcusack Exp $ +.\" $FreeBSD$ +.Dd January 15, 1999 +.Dt PAM_KRB5 8 +.Os +.Sh NAME +.Nm pam_krb5 +.Nd Kerberos 5 PAM module +.Sh SYNOPSIS +.Pa /usr/lib/pam_krb5.so +.Sh DESCRIPTION +The Kerberos 5 service module for PAM, typically +.Pa /usr/lib/pam_krb5.so , +provides functionality for three PAM categories: +authentication, +account management, +and password management. +It also provides null functions for session management. +The +.Pa pam_krb5.so +module is a shared object +that can be dynamically loaded to provide +the necessary functionality upon demand. +Its path is specified in the +PAM configuration file. +.Ss Kerberos 5 Authentication Module +The Kerberos 5 authentication component +provides functions to verify the identity of a user +.Pq Fn pam_sm_authenticate +and to set user specific credentials +.Pq Fn pam_sm_setcred . +.Fn pam_sm_authenticate +converts the supplied username into a Kerberos principal, +by appending the default local realm name. +It also supports usernames with explicit realm names. +If a realm name is supplied, then upon a successful return, it +changes the username by mapping the principal name into a local username +(calling +.Fn krb5_aname_to_localname ) . +This typically just means +the realm name is stripped. +.Pp +It prompts the user for a password and obtains a new Kerberos TGT for +the principal. +The TGT is verified by obtaining a service +ticket for the local host. +.Pp +When prompting for the current password, the authentication +module will use the prompt +.Dq Li "Password for <principal>:" . +.Pp +The +.Fn pam_sm_setcred +function stores the newly acquired credentials in a credentials cache, +and sets the environment variable +.Ev KRB5CCNAME +appropriately. +The credentials cache should be destroyed by the user at logout with +.Xr kdestroy 1 . +.Pp +The following options may be passed to the authentication module: +.Bl -tag -width ".Cm use_first_pass" +.It Cm debug +.Xr syslog 3 +debugging information at +.Dv LOG_DEBUG +level. +.It Cm no_warn +suppress warning messages to the user. +These messages include +reasons why the user's +authentication attempt was declined. +.It Cm use_first_pass +If the authentication module is not the first in the stack, +and a previous module obtained the user's password, that password is +used to authenticate the user. +If this fails, the authentication +module returns failure without prompting the user for a password. +This option has no effect if the authentication module is +the first in the stack, or if no previous modules obtained the +user's password. +.It Cm try_first_pass +This option is similar to the +.Cm use_first_pass +option, except that if the previously obtained password fails, the +user is prompted for another password. +.It Cm forwardable +Obtain forwardable Kerberos credentials for the user. +.It Cm no_ccache +Do not save the obtained credentials in a credentials cache. +This is a +useful option if the authentication module is used for services such +as ftp or pop, where the user would not be able to destroy them. +[This +is not a recommendation to use the module for those services.] +.It Cm ccache Ns = Ns Ar name +Use +.Ar name +as the credentials cache. +.Ar name +must be in the form +.Ar type : Ns Ar residual . +The special tokens +.Ql %u , +to designate the decimal UID of the user; +and +.Ql %p , +to designate the current process ID; can be used in +.Ar name . +.El +.Ss Kerberos 5 Account Management Module +The Kerberos 5 account management component +provides a function to perform account management, +.Fn pam_sm_acct_mgmt . +The function verifies that the authenticated principal is allowed +to login to the local user account by calling +.Fn krb5_kuserok +(which checks the user's +.Pa .k5login +file). +.Ss Kerberos 5 Password Management Module +The Kerberos 5 password management component +provides a function to change passwords +.Pq Fn pam_sm_chauthtok . +The username supplied (the +user running the +.Xr passwd 1 +command, or the username given as an argument) is mapped into +a Kerberos principal name, using the same technique as in +the authentication module. +Note that if a realm name was +explicitly supplied during authentication, but not during +a password change, the mapping +done by the password management module may not result in the +same principal as was used for authentication. +.Pp +Unlike when +changing a +.Ux +password, the password management module will +allow any user to change any principal's password (if the user knows +the principal's old password, of course). +Also unlike +.Ux , +root +is always prompted for the principal's old password. +.Pp +The password management module uses the same heuristics as +.Xr kpasswd 1 +to determine how to contact the Kerberos password server. +.Pp +The following options may be passed to the password management +module: +.Bl -tag -width ".Cm use_first_pass" +.It Cm debug +.Xr syslog 3 +debugging information at +.Dv LOG_DEBUG +level. +.It Cm use_first_pass +If the password management module is not the first in the stack, +and a previous module obtained the user's old password, that password is +used to authenticate the user. +If this fails, the password +management +module returns failure without prompting the user for the old password. +If successful, the new password entered to the previous module is also +used as the new Kerberos password. +If the new password fails, +the password management module returns failure without +prompting the user for a new password. +.It Cm try_first_pass +This option is similar to the +.Cm use_first_pass +option, except that if the previously obtained old or new passwords fail, +the user is prompted for them. +.El +.Ss Kerberos 5 Session Management Module +The Kerberos 5 session management component +provides functions to initiate +.Pq Fn pam_sm_open_session +and terminate +.Pq Fn pam_sm_close_session +sessions. +Since session management is not defined under Kerberos 5, +both of these functions simply return success. +They are provided +only because of the naming conventions for PAM modules. +.Sh ENVIRONMENT +.Bl -tag -width "KRB5CCNAME" +.It Ev KRB5CCNAME +Location of the credentials cache. +.El +.Sh FILES +.Bl -tag -width ".Pa /tmp/krb5cc_ Ns Ar uid" -compact +.It Pa /tmp/krb5cc_ Ns Ar uid +default credentials cache +.Ar ( uid +is the decimal UID of the user). +.It Pa $HOME/.k5login +file containing Kerberos principals that are allowed access. +.El +.Sh SEE ALSO +.Xr kdestroy 1 , +.Xr passwd 1 , +.Xr syslog 3 , +.Xr pam.conf 5 , +.Xr pam 8 +.Sh NOTES +Applications should not call +.Fn pam_authenticate +more than once between calls to +.Fn pam_start +and +.Fn pam_end +when using the Kerberos 5 PAM module. diff --git a/lib/libpam/modules/pam_krb5/pam_krb5.c b/lib/libpam/modules/pam_krb5/pam_krb5.c new file mode 100644 index 0000000..2c54448 --- /dev/null +++ b/lib/libpam/modules/pam_krb5/pam_krb5.c @@ -0,0 +1,1101 @@ +/*- + * Copyright 2001 Mark R V Murray + * Copyright Frank Cusack fcusack@fcusack.com 1999-2000 + * 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, and the entire permission notice in its entirety, + * including the disclaimer of warranties. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * ALTERNATIVELY, this product may be distributed under the terms of + * the GNU Public License, in which case the provisions of the GPL are + * required INSTEAD OF the above restrictions. (This clause is + * necessary due to a potential bad interaction between the GPL and + * the restrictions contained in a BSD-style copyright.) + * + * THIS SOFTWARE IS PROVIDED ``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 AUTHOR 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. + * --------------------------------------------------------------------------- + * + * This software may contain code from Naomaru Itoi: + * + * PAM-kerberos5 module Copyright notice. + * Naomaru Itoi <itoi@eecs.umich.edu>, June 24, 1997. + * + * ---------------------------------------------------------------------------- + * COPYRIGHT (c) 1997 + * THE REGENTS OF THE UNIVERSITY OF MICHIGAN + * ALL RIGHTS RESERVED + * + * PERMISSION IS GRANTED TO USE, COPY, CREATE DERIVATIVE WORKS AND REDISTRIBUTE + * THIS SOFTWARE AND SUCH DERIVATIVE WORKS FOR ANY PURPOSE, SO LONG AS THE NAME + * OF THE UNIVERSITY OF MICHIGAN IS NOT USED IN ANY ADVERTISING OR PUBLICITY + * PERTAINING TO THE USE OR DISTRIBUTION OF THIS SOFTWARE WITHOUT SPECIFIC, + * WRITTEN PRIOR AUTHORIZATION. IF THE ABOVE COPYRIGHT NOTICE OR ANY OTHER + * IDENTIFICATION OF THE UNIVERSITY OF MICHIGAN IS INCLUDED IN ANY COPY OF ANY + * PORTION OF THIS SOFTWARE, THEN THE DISCLAIMER BELOW MUST ALSO BE INCLUDED. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE UNIVERSITY OF + * MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND WITHOUT WARRANTY BY THE + * UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING + * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABITILY AND FITNESS FOR A + * PARTICULAR PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE + * LIABLE FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING OUT OF OR IN + * CONNECTION WITH THE USE OF THE SOFTWARE, EVEN IF IT HAS BEEN OR IS HEREAFTER + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * PAM-kerberos5 module is written based on PAM-kerberos4 module + * by Derrick J. Brashear and kerberos5-1.0pl1 by M.I.T. kerberos team. + * Permission to use, copy, modify, distribute this software is hereby + * granted, as long as it is granted by Derrick J. Brashear and + * M.I.T. kerberos team. Followings are their copyright information. + * ---------------------------------------------------------------------------- + * + * This software may contain code from Derrick J. Brashear: + * + * + * Copyright (c) Derrick J. Brashear, 1996. 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, and the entire permission notice in its entirety, + * including the disclaimer of warranties. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * ALTERNATIVELY, this product may be distributed under the terms of + * the GNU Public License, in which case the provisions of the GPL are + * required INSTEAD OF the above restrictions. (This clause is + * necessary due to a potential bad interaction between the GPL and + * the restrictions contained in a BSD-style copyright.) + * + * THIS SOFTWARE IS PROVIDED ``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 AUTHOR 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. + * + * ---------------------------------------------------------------------------- + * + * This software may contain code from MIT Kerberos 5: + * + * Copyright Notice and Legal Administrivia + * ---------------------------------------- + * + * Copyright (C) 1996 by the Massachusetts Institute of Technology. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Individual source code files are copyright MIT, Cygnus Support, + * OpenVision, Oracle, Sun Soft, and others. + * + * Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira, + * and Zephyr are trademarks of the Massachusetts Institute of Technology + * (MIT). No commercial use of these trademarks may be made without + * prior written permission of MIT. + * + * "Commercial use" means use of a name in a product or other for-profit + * manner. It does NOT prevent a commercial firm from referring to the + * MIT trademarks in order to convey information (although in doing so, + * recognition of their trademark status should be given). + * + * The following copyright and permission notice applies to the + * OpenVision Kerberos Administration system located in kadmin/create, + * kadmin/dbutil, kadmin/passwd, kadmin/server, lib/kadm5, and portions + * of lib/rpc: + * + * Copyright, OpenVision Technologies, Inc., 1996, All Rights Reserved + * + * WARNING: Retrieving the OpenVision Kerberos Administration system + * source code, as described below, indicates your acceptance of the + * following terms. If you do not agree to the following terms, do not + * retrieve the OpenVision Kerberos administration system. + * + * You may freely use and distribute the Source Code and Object Code + * compiled from it, with or without modification, but this Source + * Code is provided to you "AS IS" EXCLUSIVE OF ANY WARRANTY, + * INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE, OR ANY OTHER WARRANTY, WHETHER + * EXPRESS OR IMPLIED. IN NO EVENT WILL OPENVISION HAVE ANY LIABILITY + * FOR ANY LOST PROFITS, LOSS OF DATA OR COSTS OF PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES, OR FOR ANY SPECIAL, INDIRECT, OR + * CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, INCLUDING, + * WITHOUT LIMITATION, THOSE RESULTING FROM THE USE OF THE SOURCE + * CODE, OR THE FAILURE OF THE SOURCE CODE TO PERFORM, OR FOR ANY + * OTHER REASON. + * + * OpenVision retains all copyrights in the donated Source Code. OpenVision + * also retains copyright to derivative works of the Source Code, whether + * created by OpenVision or by a third party. The OpenVision copyright + * notice must be preserved if derivative works are made based on the + * donated Source Code. + * + * OpenVision Technologies, Inc. has donated this Kerberos + * Administration system to MIT for inclusion in the standard + * Kerberos 5 distribution. This donation underscores our + * commitment to continuing Kerberos technology development + * and our gratitude for the valuable work which has been + * performed by MIT and the Kerberos community. + * + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> +#include <limits.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <syslog.h> +#include <unistd.h> + +#include <krb5.h> +#include <com_err.h> + +#define PAM_SM_AUTH +#define PAM_SM_ACCOUNT +#define PAM_SM_SESSION +#define PAM_SM_PASSWORD + +#include <security/pam_appl.h> +#include <security/pam_modules.h> +#include <security/pam_mod_misc.h> + +#define COMPAT_HEIMDAL +/* #define COMPAT_MIT */ + +extern krb5_cc_ops krb5_mcc_ops; + +static int verify_krb_v5_tgt(krb5_context, krb5_ccache, char *, int); +static void cleanup_cache(pam_handle_t *, void *, int); +static const char *compat_princ_component(krb5_context, krb5_principal, int); +static void compat_free_data_contents(krb5_context, krb5_data *); + +#define USER_PROMPT "Username: " +#define PASSWORD_PROMPT "Password:" +#define NEW_PASSWORD_PROMPT "New Password:" +#define NEW_PASSWORD_PROMPT_2 "New Password (again):" + +enum { PAM_OPT_AUTH_AS_SELF=PAM_OPT_STD_MAX, PAM_OPT_CCACHE, PAM_OPT_FORWARDABLE, PAM_OPT_NO_CCACHE, PAM_OPT_REUSE_CCACHE }; + +static struct opttab other_options[] = { + { "auth_as_self", PAM_OPT_AUTH_AS_SELF }, + { "ccache", PAM_OPT_CCACHE }, + { "forwardable", PAM_OPT_FORWARDABLE }, + { "no_ccache", PAM_OPT_NO_CCACHE }, + { "reuse_ccache", PAM_OPT_REUSE_CCACHE }, + { NULL, 0 } +}; + +/* + * authentication management + */ +PAM_EXTERN int +pam_sm_authenticate(pam_handle_t *pamh, int flags __unused, int argc, const char **argv) +{ + krb5_error_code krbret; + krb5_context pam_context; + krb5_creds creds; + krb5_principal princ; + krb5_ccache ccache, ccache_check; + krb5_get_init_creds_opt opts; + struct options options; + struct passwd *pwd; + int retval; + const char *sourceuser, *user, *pass, *service; + char *principal, *princ_name, *cache_name, luser[32]; + + pam_std_option(&options, other_options, argc, argv); + + PAM_LOG("Options processed"); + + retval = pam_get_user(pamh, &user, USER_PROMPT); + if (retval != PAM_SUCCESS) + PAM_RETURN(retval); + + PAM_LOG("Got user: %s", user); + + retval = pam_get_item(pamh, PAM_RUSER, (const void **)&sourceuser); + if (retval != PAM_SUCCESS) + PAM_RETURN(retval); + + PAM_LOG("Got ruser: %s", sourceuser); + + service = NULL; + pam_get_item(pamh, PAM_SERVICE, (const void **)&service); + if (service == NULL) + service = "unknown"; + + PAM_LOG("Got service: %s", service); + + krbret = krb5_init_context(&pam_context); + if (krbret != 0) { + PAM_VERBOSE_ERROR("Kerberos 5 error"); + PAM_RETURN(PAM_SERVICE_ERR); + } + + PAM_LOG("Context initialised"); + + krb5_get_init_creds_opt_init(&opts); + + if (pam_test_option(&options, PAM_OPT_FORWARDABLE, NULL)) + krb5_get_init_creds_opt_set_forwardable(&opts, 1); + + PAM_LOG("Credentials initialised"); + + krbret = krb5_cc_register(pam_context, &krb5_mcc_ops, FALSE); + if (krbret != 0 && krbret != KRB5_CC_TYPE_EXISTS) { + PAM_VERBOSE_ERROR("Kerberos 5 error"); + retval = PAM_SERVICE_ERR; + goto cleanup3; + } + + PAM_LOG("Done krb5_cc_register()"); + + /* Get principal name */ + if (pam_test_option(&options, PAM_OPT_AUTH_AS_SELF, NULL)) + asprintf(&principal, "%s/%s", sourceuser, user); + else + principal = strdup(user); + + PAM_LOG("Created principal: %s", principal); + + krbret = krb5_parse_name(pam_context, principal, &princ); + free(principal); + if (krbret != 0) { + PAM_LOG("Error krb5_parse_name(): %s", error_message(krbret)); + PAM_VERBOSE_ERROR("Kerberos 5 error"); + retval = PAM_SERVICE_ERR; + goto cleanup3; + } + + PAM_LOG("Done krb5_parse_name()"); + + /* Now convert the principal name into something human readable */ + princ_name = NULL; + krbret = krb5_unparse_name(pam_context, princ, &princ_name); + if (krbret != 0) { + PAM_LOG("Error krb5_unparse_name(): %s", error_message(krbret)); + PAM_VERBOSE_ERROR("Kerberos 5 error"); + retval = PAM_SERVICE_ERR; + goto cleanup2; + } + + PAM_LOG("Got principal: %s", princ_name); + + /* Get password */ + retval = pam_get_pass(pamh, &pass, PASSWORD_PROMPT, &options); + if (retval != PAM_SUCCESS) + goto cleanup2; + + PAM_LOG("Got password"); + + /* Verify the local user exists (AFTER getting the password) */ + if (strchr(user, '@')) { + /* get a local account name for this principal */ + krbret = krb5_aname_to_localname(pam_context, princ, + sizeof(luser), luser); + if (krbret != 0) { + PAM_VERBOSE_ERROR("Kerberos 5 error"); + PAM_LOG("Error krb5_aname_to_localname(): %s", + error_message(krbret)); + retval = PAM_USER_UNKNOWN; + goto cleanup2; + } + + retval = pam_set_item(pamh, PAM_USER, luser); + if (retval != PAM_SUCCESS) + goto cleanup2; + + retval = pam_get_item(pamh, PAM_USER, (const void **)&user); + if (retval != PAM_SUCCESS) + goto cleanup2; + + PAM_LOG("PAM_USER Redone"); + } + + pwd = getpwnam(user); + if (pwd == NULL) { + retval = PAM_USER_UNKNOWN; + goto cleanup2; + } + + PAM_LOG("Done getpwnam()"); + + /* Get a TGT */ + memset(&creds, 0, sizeof(krb5_creds)); + krbret = krb5_get_init_creds_password(pam_context, &creds, princ, + pass, NULL, pamh, 0, NULL, &opts); + if (krbret != 0) { + PAM_VERBOSE_ERROR("Kerberos 5 error"); + PAM_LOG("Error krb5_get_init_creds_password(): %s", + error_message(krbret)); + retval = PAM_AUTH_ERR; + goto cleanup2; + } + + PAM_LOG("Got TGT"); + + /* Generate a unique cache_name */ + asprintf(&cache_name, "MEMORY:/tmp/%s.%d", service, getpid()); + krbret = krb5_cc_resolve(pam_context, cache_name, &ccache); + free(cache_name); + if (krbret != 0) { + PAM_VERBOSE_ERROR("Kerberos 5 error"); + PAM_LOG("Error krb5_cc_resolve(): %s", error_message(krbret)); + retval = PAM_SERVICE_ERR; + goto cleanup; + } + krbret = krb5_cc_initialize(pam_context, ccache, princ); + if (krbret != 0) { + PAM_VERBOSE_ERROR("Kerberos 5 error"); + PAM_LOG("Error krb5_cc_initialize(): %s", error_message(krbret)); + retval = PAM_SERVICE_ERR; + goto cleanup; + } + krbret = krb5_cc_store_cred(pam_context, ccache, &creds); + if (krbret != 0) { + PAM_VERBOSE_ERROR("Kerberos 5 error"); + PAM_LOG("Error krb5_cc_store_cred(): %s", error_message(krbret)); + krb5_cc_destroy(pam_context, ccache); + retval = PAM_SERVICE_ERR; + goto cleanup; + } + + PAM_LOG("Credentials stashed"); + + /* Verify them */ + if (verify_krb_v5_tgt(pam_context, ccache, (char *)service, + pam_test_option(&options, PAM_OPT_FORWARDABLE, NULL)) == -1) { + PAM_VERBOSE_ERROR("Kerberos 5 error"); + krb5_cc_destroy(pam_context, ccache); + retval = PAM_AUTH_ERR; + goto cleanup; + } + + PAM_LOG("Credentials stash verified"); + + retval = pam_get_data(pamh, "ccache", (const void **)&ccache_check); + if (retval == PAM_SUCCESS) { + krb5_cc_destroy(pam_context, ccache); + PAM_VERBOSE_ERROR("Kerberos 5 error"); + retval = PAM_AUTH_ERR; + goto cleanup; + } + + PAM_LOG("Credentials stash not pre-existing"); + + retval = pam_set_data(pamh, "ccache", ccache, cleanup_cache); + if (retval != 0) { + krb5_cc_destroy(pam_context, ccache); + PAM_VERBOSE_ERROR("Kerberos 5 error"); + retval = PAM_SERVICE_ERR; + goto cleanup; + } + + PAM_LOG("Credentials stash saved"); + +cleanup: + krb5_free_cred_contents(pam_context, &creds); + PAM_LOG("Done cleanup"); +cleanup2: + krb5_free_principal(pam_context, princ); + PAM_LOG("Done cleanup2"); +cleanup3: + if (princ_name) + free(princ_name); + + krb5_free_context(pam_context); + + PAM_LOG("Done cleanup3"); + + if (retval != PAM_SUCCESS) + PAM_VERBOSE_ERROR("Kerberos 5 refuses you"); + + PAM_RETURN(retval); +} + +PAM_EXTERN int +pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) +{ + + krb5_error_code krbret; + krb5_context pam_context; + krb5_principal princ; + krb5_creds creds; + krb5_ccache ccache_temp, ccache_perm; + krb5_cc_cursor cursor; + struct options options; + struct passwd *pwd = NULL; + int retval; + char *user; + char *cache_name, *cache_env_name, *p, *q; + + uid_t euid; + gid_t egid; + + pam_std_option(&options, other_options, argc, argv); + + PAM_LOG("Options processed"); + + if (flags & PAM_DELETE_CRED) + PAM_RETURN(PAM_SUCCESS); + + if (flags & PAM_REFRESH_CRED) + PAM_RETURN(PAM_SUCCESS); + + if (flags & PAM_REINITIALIZE_CRED) + PAM_RETURN(PAM_SUCCESS); + + if (!(flags & PAM_ESTABLISH_CRED)) + PAM_RETURN(PAM_SERVICE_ERR); + + PAM_LOG("Establishing credentials"); + + /* Get username */ + retval = pam_get_item(pamh, PAM_USER, (const void **)&user); + if (retval != PAM_SUCCESS) + PAM_RETURN(retval); + + PAM_LOG("Got user: %s", user); + + krbret = krb5_init_context(&pam_context); + if (krbret != 0) { + PAM_LOG("Error krb5_init_context(): %s", error_message(krbret)); + PAM_RETURN(PAM_SERVICE_ERR); + } + + PAM_LOG("Context initialised"); + + euid = geteuid(); /* Usually 0 */ + egid = getegid(); + + PAM_LOG("Got euid, egid: %d %d", euid, egid); + + /* Retrieve the cache name */ + retval = pam_get_data(pamh, "ccache", (const void **)&ccache_temp); + if (retval != PAM_SUCCESS) + goto cleanup3; + + /* Get the uid. This should exist. */ + pwd = getpwnam(user); + if (pwd == NULL) { + retval = PAM_USER_UNKNOWN; + goto cleanup3; + } + + PAM_LOG("Done getpwnam()"); + + /* Avoid following a symlink as root */ + if (setegid(pwd->pw_gid)) { + retval = PAM_SERVICE_ERR; + goto cleanup3; + } + if (seteuid(pwd->pw_uid)) { + retval = PAM_SERVICE_ERR; + goto cleanup3; + } + + PAM_LOG("Done setegid() & seteuid()"); + + /* Get the cache name */ + cache_name = NULL; + pam_test_option(&options, PAM_OPT_CCACHE, &cache_name); + if (cache_name == NULL) + asprintf(&cache_name, "FILE:/tmp/krb5cc_%d", pwd->pw_uid); + + p = calloc(PATH_MAX + 16, sizeof(char)); + q = cache_name; + + if (p == NULL) { + PAM_LOG("Error malloc(): failure"); + retval = PAM_BUF_ERR; + goto cleanup3; + } + cache_name = p; + + /* convert %u and %p */ + while (*q) { + if (*q == '%') { + q++; + if (*q == 'u') { + sprintf(p, "%d", pwd->pw_uid); + p += strlen(p); + } + else if (*q == 'p') { + sprintf(p, "%d", getpid()); + p += strlen(p); + } + else { + /* Not a special token */ + *p++ = '%'; + q--; + } + q++; + } + else { + *p++ = *q++; + } + } + + PAM_LOG("Got cache_name: %s", cache_name); + + /* Initialize the new ccache */ + krbret = krb5_cc_get_principal(pam_context, ccache_temp, &princ); + if (krbret != 0) { + PAM_LOG("Error krb5_cc_get_principal(): %s", + error_message(krbret)); + retval = PAM_SERVICE_ERR; + goto cleanup3; + } + krbret = krb5_cc_resolve(pam_context, cache_name, &ccache_perm); + if (krbret != 0) { + PAM_LOG("Error krb5_cc_resolve(): %s", error_message(krbret)); + retval = PAM_SERVICE_ERR; + goto cleanup2; + } + krbret = krb5_cc_initialize(pam_context, ccache_perm, princ); + if (krbret != 0) { + PAM_LOG("Error krb5_cc_initialize(): %s", error_message(krbret)); + retval = PAM_SERVICE_ERR; + goto cleanup2; + } + + PAM_LOG("Cache initialised"); + + /* Prepare for iteration over creds */ + krbret = krb5_cc_start_seq_get(pam_context, ccache_temp, &cursor); + if (krbret != 0) { + PAM_LOG("Error krb5_cc_start_seq_get(): %s", error_message(krbret)); + krb5_cc_destroy(pam_context, ccache_perm); + retval = PAM_SERVICE_ERR; + goto cleanup2; + } + + PAM_LOG("Prepared for iteration"); + + /* Copy the creds (should be two of them) */ + while ((krbret = krb5_cc_next_cred(pam_context, ccache_temp, + &cursor, &creds) == 0)) { + krbret = krb5_cc_store_cred(pam_context, ccache_perm, &creds); + if (krbret != 0) { + PAM_LOG("Error krb5_cc_store_cred(): %s", + error_message(krbret)); + krb5_cc_destroy(pam_context, ccache_perm); + krb5_free_cred_contents(pam_context, &creds); + retval = PAM_SERVICE_ERR; + goto cleanup2; + } + krb5_free_cred_contents(pam_context, &creds); + PAM_LOG("Iteration"); + } + krb5_cc_end_seq_get(pam_context, ccache_temp, &cursor); + + PAM_LOG("Done iterating"); + + if (strstr(cache_name, "FILE:") == cache_name) { + if (chown(&cache_name[5], pwd->pw_uid, pwd->pw_gid) == -1) { + PAM_LOG("Error chown(): %s", strerror(errno)); + krb5_cc_destroy(pam_context, ccache_perm); + retval = PAM_SERVICE_ERR; + goto cleanup2; + } + PAM_LOG("Done chown()"); + + if (chmod(&cache_name[5], (S_IRUSR | S_IWUSR)) == -1) { + PAM_LOG("Error chmod(): %s", strerror(errno)); + krb5_cc_destroy(pam_context, ccache_perm); + retval = PAM_SERVICE_ERR; + goto cleanup2; + } + PAM_LOG("Done chmod()"); + } + + krb5_cc_close(pam_context, ccache_perm); + + PAM_LOG("Cache closed"); + + cache_env_name = malloc(strlen(cache_name) + 12); + if (!cache_env_name) { + PAM_LOG("Error malloc(): failure"); + krb5_cc_destroy(pam_context, ccache_perm); + retval = PAM_BUF_ERR; + goto cleanup2; + } + + sprintf(cache_env_name, "KRB5CCNAME=%s", cache_name); + if ((retval = pam_putenv(pamh, cache_env_name)) != 0) { + PAM_LOG("Error pam_putenv(): %s", pam_strerror(pamh, retval)); + krb5_cc_destroy(pam_context, ccache_perm); + retval = PAM_SERVICE_ERR; + goto cleanup2; + } + + PAM_LOG("Environment done: KRB5CCNAME=%s", cache_name); + +cleanup2: + krb5_free_principal(pam_context, princ); + PAM_LOG("Done cleanup2"); +cleanup3: + krb5_free_context(pam_context); + PAM_LOG("Done cleanup3"); + + seteuid(euid); + setegid(egid); + + PAM_LOG("Done seteuid() & setegid()"); + + PAM_RETURN(retval); +} + +/* + * account management + */ +PAM_EXTERN int +pam_sm_acct_mgmt(pam_handle_t *pamh, int flags __unused, int argc, const char **argv) +{ + krb5_error_code krbret; + krb5_context pam_context; + krb5_ccache ccache; + krb5_principal princ; + struct options options; + int retval; + const char *user; + + pam_std_option(&options, other_options, argc, argv); + + PAM_LOG("Options processed"); + + retval = pam_get_item(pamh, PAM_USER, (const void **)&user); + if (retval != PAM_SUCCESS) + PAM_RETURN(retval); + + PAM_LOG("Got user: %s", user); + + retval = pam_get_data(pamh, "ccache", (const void **)&ccache); + if (retval != PAM_SUCCESS) + PAM_RETURN(PAM_SUCCESS); + + PAM_LOG("Got ccache"); + + krbret = krb5_init_context(&pam_context); + if (krbret != 0) { + PAM_LOG("Error krb5_init_context(): %s", error_message(krbret)); + PAM_RETURN(PAM_PERM_DENIED); + } + + PAM_LOG("Context initialised"); + + krbret = krb5_cc_get_principal(pam_context, ccache, &princ); + if (krbret != 0) { + PAM_LOG("Error krb5_cc_get_principal(): %s", error_message(krbret)); + retval = PAM_PERM_DENIED;; + goto cleanup; + } + + PAM_LOG("Got principal"); + + if (krb5_kuserok(pam_context, princ, user)) + retval = PAM_SUCCESS; + else + retval = PAM_PERM_DENIED; + krb5_free_principal(pam_context, princ); + + PAM_LOG("Done kuserok()"); + +cleanup: + krb5_free_context(pam_context); + PAM_LOG("Done cleanup"); + + PAM_RETURN(retval); + +} + +/* + * session management + * + * logging only + */ +PAM_EXTERN int +pam_sm_open_session(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_SUCCESS); +} + +PAM_EXTERN int +pam_sm_close_session(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_SUCCESS); +} + +/* + * password management + */ +PAM_EXTERN int +pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) +{ + krb5_error_code krbret; + krb5_context pam_context; + krb5_creds creds; + krb5_principal princ; + krb5_get_init_creds_opt opts; + krb5_data result_code_string, result_string; + struct options options; + int result_code, retval; + const char *user, *pass, *pass2; + char *princ_name; + + pam_std_option(&options, other_options, argc, argv); + + PAM_LOG("Options processed"); + + if (!(flags & PAM_UPDATE_AUTHTOK)) + PAM_RETURN(PAM_AUTHTOK_ERR); + + retval = pam_get_item(pamh, PAM_USER, (const void **)&user); + if (retval != PAM_SUCCESS) + PAM_RETURN(retval); + + PAM_LOG("Got user: %s", user); + + krbret = krb5_init_context(&pam_context); + if (krbret != 0) { + PAM_LOG("Error krb5_init_context(): %s", error_message(krbret)); + PAM_RETURN(PAM_SERVICE_ERR); + } + + PAM_LOG("Context initialised"); + + krb5_get_init_creds_opt_init(&opts); + + PAM_LOG("Credentials options initialised"); + + /* Get principal name */ + krbret = krb5_parse_name(pam_context, user, &princ); + if (krbret != 0) { + PAM_LOG("Error krb5_parse_name(): %s", error_message(krbret)); + retval = PAM_USER_UNKNOWN; + goto cleanup3; + } + + /* Now convert the principal name into something human readable */ + princ_name = NULL; + krbret = krb5_unparse_name(pam_context, princ, &princ_name); + if (krbret != 0) { + PAM_LOG("Error krb5_unparse_name(): %s", error_message(krbret)); + retval = PAM_SERVICE_ERR; + goto cleanup2; + } + + PAM_LOG("Got principal: %s", princ_name); + + /* Get password */ + retval = pam_get_pass(pamh, &pass, PASSWORD_PROMPT, &options); + if (retval != PAM_SUCCESS) + goto cleanup2; + + PAM_LOG("Got password"); + + memset(&creds, 0, sizeof(krb5_creds)); + krbret = krb5_get_init_creds_password(pam_context, &creds, princ, + pass, NULL, pamh, 0, "kadmin/changepw", &opts); + if (krbret != 0) { + PAM_LOG("Error krb5_get_init_creds_password()", + error_message(krbret)); + retval = PAM_AUTH_ERR; + goto cleanup2; + } + + PAM_LOG("Credentials established"); + + /* Now get the new password */ + retval = pam_get_pass(pamh, &pass, NEW_PASSWORD_PROMPT, &options); + if (retval != PAM_SUCCESS) + goto cleanup; + + retval = pam_get_pass(pamh, &pass2, NEW_PASSWORD_PROMPT_2, &options); + if (retval != PAM_SUCCESS) + goto cleanup; + + PAM_LOG("Got new password twice"); + + if (strcmp(pass, pass2) != 0) { + PAM_LOG("Error strcmp(): passwords are different"); + retval = PAM_AUTHTOK_ERR; + goto cleanup; + } + + PAM_LOG("New passwords are the same"); + + /* Change it */ + krbret = krb5_change_password(pam_context, &creds, (char *)pass, + &result_code, &result_code_string, &result_string); + if (krbret != 0) { + PAM_LOG("Error krb5_change_password(): %s", + error_message(krbret)); + retval = PAM_AUTHTOK_ERR; + goto cleanup; + } + if (result_code) { + PAM_LOG("Error krb5_change_password(): (result_code)"); + retval = PAM_AUTHTOK_ERR; + goto cleanup; + } + + PAM_LOG("Password changed"); + + if (result_string.data) + free(result_string.data); + if (result_code_string.data) + free(result_code_string.data); + +cleanup: + krb5_free_cred_contents(pam_context, &creds); + PAM_LOG("Done cleanup"); +cleanup2: + krb5_free_principal(pam_context, princ); + PAM_LOG("Done cleanup2"); +cleanup3: + if (princ_name) + free(princ_name); + + krb5_free_context(pam_context); + + PAM_LOG("Done cleanup3"); + + PAM_RETURN(retval); +} + +PAM_MODULE_ENTRY("pam_krb5"); + +/* + * This routine with some modification is from the MIT V5B6 appl/bsd/login.c + * Modified by Sam Hartman <hartmans@mit.edu> to support PAM services + * for Debian. + * + * Verify the Kerberos ticket-granting ticket just retrieved for the + * user. If the Kerberos server doesn't respond, assume the user is + * trying to fake us out (since we DID just get a TGT from what is + * supposedly our KDC). If the host/<host> service is unknown (i.e., + * the local keytab doesn't have it), and we cannot find another + * service we do have, let her in. + * + * Returns 1 for confirmation, -1 for failure, 0 for uncertainty. + */ +static int +verify_krb_v5_tgt(krb5_context context, krb5_ccache ccache, + char *pam_service, int debug) +{ + krb5_error_code retval; + krb5_principal princ; + krb5_keyblock *keyblock; + krb5_data packet; + krb5_auth_context auth_context; + char phost[BUFSIZ]; + const char *services[3], **service; + + packet.data = 0; + + /* If possible we want to try and verify the ticket we have + * received against a keytab. We will try multiple service + * principals, including at least the host principal and the PAM + * service principal. The host principal is preferred because access + * to that key is generally sufficient to compromise root, while the + * service key for this PAM service may be less carefully guarded. + * It is important to check the keytab first before the KDC so we do + * not get spoofed by a fake KDC. + */ + services[0] = "host"; + services[1] = pam_service; + services[2] = NULL; + keyblock = 0; + retval = -1; + for (service = &services[0]; *service != NULL; service++) { + retval = krb5_sname_to_principal(context, NULL, *service, + KRB5_NT_SRV_HST, &princ); + if (retval != 0) { + if (debug) + syslog(LOG_DEBUG, "pam_krb5: verify_krb_v5_tgt(): %s: %s", "krb5_sname_to_principal()", error_message(retval)); + return -1; + } + + /* Extract the name directly. */ + strncpy(phost, compat_princ_component(context, princ, 1), + BUFSIZ); + phost[BUFSIZ - 1] = '\0'; + + /* + * Do we have service/<host> keys? + * (use default/configured keytab, kvno IGNORE_VNO to get the + * first match, and ignore enctype.) + */ + retval = krb5_kt_read_service_key(context, NULL, princ, 0, 0, + &keyblock); + if (retval != 0) + continue; + break; + } + if (retval != 0) { /* failed to find key */ + /* Keytab or service key does not exist */ + if (debug) + syslog(LOG_DEBUG, "pam_krb5: verify_krb_v5_tgt(): %s: %s", "krb5_kt_read_service_key()", error_message(retval)); + retval = 0; + goto cleanup; + } + if (keyblock) + krb5_free_keyblock(context, keyblock); + + /* Talk to the kdc and construct the ticket. */ + auth_context = NULL; + retval = krb5_mk_req(context, &auth_context, 0, *service, phost, + NULL, ccache, &packet); + if (auth_context) { + krb5_auth_con_free(context, auth_context); + auth_context = NULL; /* setup for rd_req */ + } + if (retval) { + if (debug) + syslog(LOG_DEBUG, "pam_krb5: verify_krb_v5_tgt(): %s: %s", "krb5_mk_req()", error_message(retval)); + retval = -1; + goto cleanup; + } + + /* Try to use the ticket. */ + retval = krb5_rd_req(context, &auth_context, &packet, princ, NULL, + NULL, NULL); + if (retval) { + if (debug) + syslog(LOG_DEBUG, "pam_krb5: verify_krb_v5_tgt(): %s: %s", "krb5_rd_req()", error_message(retval)); + retval = -1; + } + else + retval = 1; + +cleanup: + if (packet.data) + compat_free_data_contents(context, &packet); + krb5_free_principal(context, princ); + return retval; +} + +/* Free the memory for cache_name. Called by pam_end() */ +static void +cleanup_cache(pam_handle_t *pamh __unused, void *data, int pam_end_status __unused) +{ + krb5_context pam_context; + krb5_ccache ccache; + + if (krb5_init_context(&pam_context)) + return; + + ccache = (krb5_ccache)data; + krb5_cc_destroy(pam_context, ccache); + krb5_free_context(pam_context); +} + +#ifdef COMPAT_HEIMDAL +#ifdef COMPAT_MIT +#error This cannot be MIT and Heimdal compatible! +#endif +#endif + +#ifndef COMPAT_HEIMDAL +#ifndef COMPAT_MIT +#error One of COMPAT_MIT and COMPAT_HEIMDAL must be specified! +#endif +#endif + +#ifdef COMPAT_HEIMDAL +static const char * +compat_princ_component(krb5_context context __unused, krb5_principal princ, int n) +{ + return princ->name.name_string.val[n]; +} + +static void +compat_free_data_contents(krb5_context context __unused, krb5_data * data) +{ + krb5_xfree(data->data); +} +#endif + +#ifdef COMPAT_MIT +static const char * +compat_princ_component(krb5_context context, krb5_principal princ, int n) +{ + return krb5_princ_component(context, princ, n)->data; +} + +static void +compat_free_data_contents(krb5_context context, krb5_data * data) +{ + krb5_free_data_contents(context, data); +} +#endif diff --git a/lib/libpam/modules/pam_lastlog/Makefile b/lib/libpam/modules/pam_lastlog/Makefile new file mode 100644 index 0000000..8a516ed --- /dev/null +++ b/lib/libpam/modules/pam_lastlog/Makefile @@ -0,0 +1,35 @@ +# Copyright 2001 Mark R V Murray +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ + +LIB= pam_lastlog +SHLIB_NAME= ${LIB}.so.${SHLIB_MAJOR} +SRCS= pam_lastlog.c +DPADD= ${LIBUTIL} +LDADD= -lutil + +MAN= pam_lastlog.8 + +.include <bsd.lib.mk> diff --git a/lib/libpam/modules/pam_lastlog/pam_lastlog.8 b/lib/libpam/modules/pam_lastlog/pam_lastlog.8 new file mode 100644 index 0000000..953c584 --- /dev/null +++ b/lib/libpam/modules/pam_lastlog/pam_lastlog.8 @@ -0,0 +1,93 @@ +.\" Copyright (c) 2001 Mark R V Murray +.\" All rights reserved. +.\" Copyright (c) 2001 Networks Associates Technology, Inc. +.\" All rights reserved. +.\" +.\" Portions of this software were developed for the FreeBSD Project by +.\" ThinkSec AS and NAI Labs, the Security Research Division of Network +.\" Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 +.\" ("CBOSS"), as part of the DARPA CHATS research program. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. The name of the author may not be used to endorse or promote +.\" products derived from this software without specific prior written +.\" permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ +.\" +.Dd January 24, 2002 +.Dt PAM_LASTLOG 8 +.Os +.Sh NAME +.Nm pam_lastlog +.Nd login accounting PAM module +.Sh SYNOPSIS +.Op Ar service-name +.Ar module-type +.Ar control-flag +.Pa pam_lastlog +.Op Ar options +.Sh DESCRIPTION +The login accounting service module for PAM, +.Nm +provides functionality for only one PAM category: +session management. +In terms of the +.Ar module-type +parameter, this is the +.Dq Li session +feature. +.Ss Login Accounting Session Management Module +The login accounting session management component provides functions +to initiate +.Pq Fn pam_sm_open_session +and terminate +.Pq Fn pam_sm_close_session +sessions. +The +.Fn pam_sm_open_session +function records the session in the +.Xr utmp 5 , +.Xr wtmp 5 +and +.Xr lastlog 5 +databases. +The +.Fn pam_sm_close_session +function does nothing. +.Sh SEE ALSO +.Xr last 1 , +.Xr lastlogin 1 , +.Xr w 1 , +.Xr login 3 , +.Xr logout 3 , +.Xr pam.conf 5 , +.Xr utmp 5 , +.Xr pam 8 +.Sh AUTHORS +The +.Nm +module and this manual page were developed for the FreeBSD Project by +ThinkSec AS and NAI Labs, the Security Research Division of Network +Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 +.Pq Dq CBOSS , +as part of the DARPA CHATS research program. diff --git a/lib/libpam/modules/pam_lastlog/pam_lastlog.c b/lib/libpam/modules/pam_lastlog/pam_lastlog.c new file mode 100644 index 0000000..81f94ff --- /dev/null +++ b/lib/libpam/modules/pam_lastlog/pam_lastlog.c @@ -0,0 +1,225 @@ +/*- + * Copyright (c) 1980, 1987, 1988, 1991, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * Copyright (c) 2001 Mark R V Murray + * All rights reserved. + * Copyright (c) 2001 Networks Associates Technology, Inc. + * All rights reserved. + * + * Portions of this software were developed for the FreeBSD Project by + * ThinkSec AS and NAI Labs, the Security Research Division of Network + * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 + * ("CBOSS"), as part of the DARPA CHATS research program. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#define _BSD_SOURCE + +#include <sys/param.h> + +#include <fcntl.h> +#include <libutil.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <syslog.h> +#include <time.h> +#include <unistd.h> +#include <utmp.h> + +#define PAM_SM_AUTH +#define PAM_SM_ACCOUNT +#define PAM_SM_SESSION +#define PAM_SM_PASSWORD + +#include <security/pam_appl.h> +#include <security/pam_modules.h> +#include <security/pam_mod_misc.h> + +extern int login_access(const char *, const char *); + +PAM_EXTERN int +pam_sm_authenticate(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_setcred(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_acct_mgmt(pam_handle_t *pamh __unused, int flags __unused, int argc ,const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_chauthtok(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) +{ + struct options options; + struct passwd *pwd; + struct utmp utmp; + struct lastlog ll; + const char *rhost, *user, *tty; + off_t llpos; + int fd, pam_err; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + pam_err = pam_get_item(pamh, PAM_USER, (const void **)&user); + if (pam_err != PAM_SUCCESS) + PAM_RETURN(pam_err); + if (user == NULL || (pwd = getpwnam(user)) == NULL) + PAM_RETURN(PAM_SERVICE_ERR); + PAM_LOG("Got user: %s", user); + + pam_err = pam_get_item(pamh, PAM_RHOST, (const void **)&rhost); + if (pam_err != PAM_SUCCESS) + PAM_RETURN(pam_err); + + pam_err = pam_get_item(pamh, PAM_TTY, (const void **)&tty); + if (pam_err != PAM_SUCCESS) + PAM_RETURN(pam_err); + if (tty == NULL) + PAM_RETURN(PAM_SERVICE_ERR); + + fd = open(_PATH_LASTLOG, O_RDWR|O_CREAT, 0644); + if (fd == -1) { + syslog(LOG_ERR, "cannot open %s: %m", _PATH_LASTLOG); + PAM_RETURN(PAM_SERVICE_ERR); + } + + /* + * Record session in lastlog(5). + */ + llpos = (off_t)(pwd->pw_uid * sizeof(ll)); + if (lseek(fd, llpos, L_SET) != llpos) + goto file_err; + if ((flags & PAM_SILENT) == 0) { + if (read(fd, &ll, sizeof(ll)) == sizeof(ll) && + ll.ll_time != 0) { + pam_info(pamh, "Last login: %.*s ", 24 - 5, + ctime(&ll.ll_time)); + if (*ll.ll_host != '\0') + pam_info(pamh, "from %.*s\n", + (int)sizeof(ll.ll_host), ll.ll_host); + else + pam_info(pamh, "on %.*s\n", + (int)sizeof(ll.ll_line), ll.ll_line); + } + if (lseek(fd, llpos, L_SET) != llpos) + goto file_err; + } + + bzero(&ll, sizeof(ll)); + time(&ll.ll_time); + + /* note: does not need to be NUL-terminated */ + strncpy(ll.ll_line, tty, sizeof(ll.ll_line)); + if (rhost != NULL) + /* note: does not need to be NUL-terminated */ + strncpy(ll.ll_host, rhost, sizeof(ll.ll_host)); + + if (write(fd, (char *)&ll, sizeof(ll)) != sizeof(ll) || close(fd) != 0) + goto file_err; + + PAM_LOG("Login recorded in %s", _PATH_LASTLOG); + + /* + * Record session in utmp(5) and wtmp(5). + */ + bzero(&utmp, sizeof(utmp)); + time(&utmp.ut_time); + /* note: does not need to be NUL-terminated */ + strncpy(utmp.ut_name, user, sizeof(utmp.ut_name)); + if (rhost != NULL) + strncpy(utmp.ut_host, rhost, sizeof(utmp.ut_host)); + (void)strncpy(utmp.ut_line, tty, sizeof(utmp.ut_line)); + login(&utmp); + + PAM_RETURN(PAM_IGNORE); + + file_err: + syslog(LOG_ERR, "%s: %m", _PATH_LASTLOG); + close(fd); + PAM_RETURN(PAM_SERVICE_ERR); +} + +PAM_EXTERN int +pam_sm_close_session(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_SUCCESS); +} + +PAM_MODULE_ENTRY("pam_lastlog"); diff --git a/lib/libpam/modules/pam_login_access/Makefile b/lib/libpam/modules/pam_login_access/Makefile new file mode 100644 index 0000000..2235292 --- /dev/null +++ b/lib/libpam/modules/pam_login_access/Makefile @@ -0,0 +1,32 @@ +# Copyright 2001 Mark R V Murray +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ + +LIB= pam_login_access +SHLIB_NAME= ${LIB}.so.${SHLIB_MAJOR} +SRCS= pam_login_access.c login_access.c +MAN= pam_login_access.8 + +.include <bsd.lib.mk> diff --git a/lib/libpam/modules/pam_login_access/login.access.5 b/lib/libpam/modules/pam_login_access/login.access.5 new file mode 100644 index 0000000..d5af0ee --- /dev/null +++ b/lib/libpam/modules/pam_login_access/login.access.5 @@ -0,0 +1,56 @@ +.\" +.\" $FreeBSD$ +.\" +.\" this is comment +.Dd April 30, 1994 +.Dt LOGIN.ACCESS 5 +.Os +.Sh NAME +.Nm login.access +.Nd login access control table +.Sh DESCRIPTION +The +.Nm +file specifies (user, host) combinations and/or (user, tty) +combinations for which a login will be either accepted or refused. +.Pp +When someone logs in, the +.Nm +is scanned for the first entry that +matches the (user, host) combination, or, in case of non-networked +logins, the first entry that matches the (user, tty) combination. The +permissions field of that table entry determines whether the login will +be accepted or refused. +.Pp +Each line of the login access control table has three fields separated by a +":" character: permission : users : origins +.Pp +The first field should be a "+" (access granted) or "-" (access denied) +character. +The second field should be a list of one or more login names, +group names, or ALL (always matches). The third field should be a list +of one or more tty names (for non-networked logins), host names, domain +names (begin with "."), host addresses, internet network numbers (end +with "."), ALL (always matches) or LOCAL (matches any string that does +not contain a "." character). If you run NIS you can use @netgroupname +in host or user patterns. +.Pp +The EXCEPT operator makes it possible to write very compact rules. +.Pp +The group file is searched only when a name does not match that of the +logged-in user. +Only groups are matched in which users are explicitly +listed: the program does not look at a user's primary group id value. +.Sh FILES +.Bl -tag -width /etc/login.access -compact +.It Pa /etc/login.access +The +.Nm +file resides in +.Pa /etc . +.El +.Sh SEE ALSO +.Xr login 1 , +.Xr pam 8 +.Sh AUTHORS +.An Guido van Rooij diff --git a/lib/libpam/modules/pam_login_access/login_access.c b/lib/libpam/modules/pam_login_access/login_access.c new file mode 100644 index 0000000..90089d8 --- /dev/null +++ b/lib/libpam/modules/pam_login_access/login_access.c @@ -0,0 +1,231 @@ + /* + * This module implements a simple but effective form of login access + * control based on login names and on host (or domain) names, internet + * addresses (or network numbers), or on terminal line names in case of + * non-networked logins. Diagnostics are reported through syslog(3). + * + * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands. + */ + +#if 0 +#ifndef lint +static char sccsid[] = "%Z% %M% %I% %E% %U%"; +#endif +#endif + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <ctype.h> +#include <errno.h> +#include <grp.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <syslog.h> +#include <unistd.h> + +#include "pam_login_access.h" + +#define _PATH_LOGACCESS "/etc/login.access" + + /* Delimiters for fields and for lists of users, ttys or hosts. */ + +static char fs[] = ":"; /* field separator */ +static char sep[] = ", \t"; /* list-element separator */ + + /* Constants to be used in assignments only, not in comparisons... */ + +#define YES 1 +#define NO 0 + +static int from_match(const char *, const char *); +static int list_match(char *, const char *, + int (*)(const char *, const char *)); +static int netgroup_match(const char *, const char *, const char *); +static int string_match(const char *, const char *); +static int user_match(const char *, const char *); + +/* login_access - match username/group and host/tty with access control file */ + +int +login_access(const char *user, const char *from) +{ + FILE *fp; + char line[BUFSIZ]; + char *perm; /* becomes permission field */ + char *users; /* becomes list of login names */ + char *froms; /* becomes list of terminals or hosts */ + int match = NO; + int end; + int lineno = 0; /* for diagnostics */ + + /* + * Process the table one line at a time and stop at the first match. + * Blank lines and lines that begin with a '#' character are ignored. + * Non-comment lines are broken at the ':' character. All fields are + * mandatory. The first field should be a "+" or "-" character. A + * non-existing table means no access control. + */ + + if ((fp = fopen(_PATH_LOGACCESS, "r")) != NULL) { + while (!match && fgets(line, sizeof(line), fp)) { + lineno++; + if (line[end = strlen(line) - 1] != '\n') { + syslog(LOG_ERR, "%s: line %d: missing newline or line too long", + _PATH_LOGACCESS, lineno); + continue; + } + if (line[0] == '#') + continue; /* comment line */ + while (end > 0 && isspace(line[end - 1])) + end--; + line[end] = 0; /* strip trailing whitespace */ + if (line[0] == 0) /* skip blank lines */ + continue; + if (!(perm = strtok(line, fs)) + || !(users = strtok((char *) 0, fs)) + || !(froms = strtok((char *) 0, fs)) + || strtok((char *) 0, fs)) { + syslog(LOG_ERR, "%s: line %d: bad field count", _PATH_LOGACCESS, + lineno); + continue; + } + if (perm[0] != '+' && perm[0] != '-') { + syslog(LOG_ERR, "%s: line %d: bad first field", _PATH_LOGACCESS, + lineno); + continue; + } + match = (list_match(froms, from, from_match) + && list_match(users, user, user_match)); + } + (void) fclose(fp); + } else if (errno != ENOENT) { + syslog(LOG_ERR, "cannot open %s: %m", _PATH_LOGACCESS); + } + return (match == 0 || (line[0] == '+')); +} + +/* list_match - match an item against a list of tokens with exceptions */ + +static int +list_match(char *list, const char *item, + int (*match_fn)(const char *, const char *)) +{ + char *tok; + int match = NO; + + /* + * Process tokens one at a time. We have exhausted all possible matches + * when we reach an "EXCEPT" token or the end of the list. If we do find + * a match, look for an "EXCEPT" list and recurse to determine whether + * the match is affected by any exceptions. + */ + + for (tok = strtok(list, sep); tok != 0; tok = strtok((char *) 0, sep)) { + if (strcasecmp(tok, "EXCEPT") == 0) /* EXCEPT: give up */ + break; + if ((match = (*match_fn)(tok, item)) != NULL) /* YES */ + break; + } + /* Process exceptions to matches. */ + + if (match != NO) { + while ((tok = strtok((char *) 0, sep)) && strcasecmp(tok, "EXCEPT")) + /* VOID */ ; + if (tok == 0 || list_match((char *) 0, item, match_fn) == NO) + return (match); + } + return (NO); +} + +/* netgroup_match - match group against machine or user */ + +static int +netgroup_match(const char *group __unused, + const char *machine __unused, const char *user __unused) +{ + syslog(LOG_ERR, "NIS netgroup support not configured"); + return 0; +} + +/* user_match - match a username against one token */ + +static int +user_match(const char *tok, const char *string) +{ + struct group *group; + int i; + + /* + * If a token has the magic value "ALL" the match always succeeds. + * Otherwise, return YES if the token fully matches the username, or if + * the token is a group that contains the username. + */ + + if (tok[0] == '@') { /* netgroup */ + return (netgroup_match(tok + 1, (char *) 0, string)); + } else if (string_match(tok, string)) { /* ALL or exact match */ + return (YES); + } else if ((group = getgrnam(tok)) != NULL) {/* try group membership */ + for (i = 0; group->gr_mem[i]; i++) + if (strcasecmp(string, group->gr_mem[i]) == 0) + return (YES); + } + return (NO); +} + +/* from_match - match a host or tty against a list of tokens */ + +static int +from_match(const char *tok, const char *string) +{ + int tok_len; + int str_len; + + /* + * If a token has the magic value "ALL" the match always succeeds. Return + * YES if the token fully matches the string. If the token is a domain + * name, return YES if it matches the last fields of the string. If the + * token has the magic value "LOCAL", return YES if the string does not + * contain a "." character. If the token is a network number, return YES + * if it matches the head of the string. + */ + + if (tok[0] == '@') { /* netgroup */ + return (netgroup_match(tok + 1, string, (char *) 0)); + } else if (string_match(tok, string)) { /* ALL or exact match */ + return (YES); + } else if (tok[0] == '.') { /* domain: match last fields */ + if ((str_len = strlen(string)) > (tok_len = strlen(tok)) + && strcasecmp(tok, string + str_len - tok_len) == 0) + return (YES); + } else if (strcasecmp(tok, "LOCAL") == 0) { /* local: no dots */ + if (strchr(string, '.') == 0) + return (YES); + } else if (tok[(tok_len = strlen(tok)) - 1] == '.' /* network */ + && strncmp(tok, string, tok_len) == 0) { + return (YES); + } + return (NO); +} + +/* string_match - match a string against one token */ + +static int +string_match(const char *tok, const char *string) +{ + + /* + * If the token has the magic value "ALL" the match always succeeds. + * Otherwise, return YES if the token fully matches the string. + */ + + if (strcasecmp(tok, "ALL") == 0) { /* all: always matches */ + return (YES); + } else if (strcasecmp(tok, string) == 0) { /* try exact match */ + return (YES); + } + return (NO); +} diff --git a/lib/libpam/modules/pam_login_access/pam_login_access.8 b/lib/libpam/modules/pam_login_access/pam_login_access.8 new file mode 100644 index 0000000..9e808ae --- /dev/null +++ b/lib/libpam/modules/pam_login_access/pam_login_access.8 @@ -0,0 +1,89 @@ +.\" Copyright (c) 2001 Mark R V Murray +.\" All rights reserved. +.\" Copyright (c) 2001 Networks Associates Technology, Inc. +.\" All rights reserved. +.\" +.\" Portions of this software were developed for the FreeBSD Project by +.\" ThinkSec AS and NAI Labs, the Security Research Division of Network +.\" Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 +.\" ("CBOSS"), as part of the DARPA CHATS research program. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. The name of the author may not be used to endorse or promote +.\" products derived from this software without specific prior written +.\" permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ +.\" +.Dd January 24, 2002 +.Dt PAM_LOGIN_ACCESS 8 +.Os +.Sh NAME +.Nm pam_login_access +.Nd login.access PAM module +.Sh SYNOPSIS +.Op Ar service-name +.Ar module-type +.Ar control-flag +.Pa pam_login_access +.Op Ar options +.Sh DESCRIPTION +The +.Pa login.access +service module for PAM, +.Nm +provides functionality for only one PAM category: +account management. +In terms of the +.Ar module-type +parameter, this is the +.Dq Li account +feature. +.Ss Login.access Account Management Module +The +.Pa login.access +account management component +.Pq Fn pam_sm_acct_mgmt , +returns success if and only the user is allowed to log in on the +specified tty (in the case of a local login) or from the specified +remote host (in the case of a remote login), according to the +restrictions listed in +.Pa /etc/login.access . +.Sh SEE ALSO +.Xr login.access 5 , +.Xr pam.conf 5 , +.Xr pam 8 +.Sh AUTHORS +The +.Xr login.access 5 +access control scheme was designed and implemented by +.An Wietse Venema . +.Pp +The +.Nm +module and this manual page were developed for the +.Fx +Project by +ThinkSec AS and NAI Labs, the Security Research Division of Network +Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 +.Pq Dq CBOSS , +as part of the DARPA CHATS research program. diff --git a/lib/libpam/modules/pam_login_access/pam_login_access.c b/lib/libpam/modules/pam_login_access/pam_login_access.c new file mode 100644 index 0000000..87cf450 --- /dev/null +++ b/lib/libpam/modules/pam_login_access/pam_login_access.c @@ -0,0 +1,168 @@ +/*- + * Copyright (c) 2001 Mark R V Murray + * All rights reserved. + * Copyright (c) 2001 Networks Associates Technology, Inc. + * All rights reserved. + * + * Portions of this software were developed for the FreeBSD Project by + * ThinkSec AS and NAI Labs, the Security Research Division of Network + * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 + * ("CBOSS"), as part of the DARPA CHATS research program. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#define _BSD_SOURCE + +#include <sys/param.h> + +#include <syslog.h> +#include <unistd.h> + +#define PAM_SM_AUTH +#define PAM_SM_ACCOUNT +#define PAM_SM_SESSION +#define PAM_SM_PASSWORD + +#include <security/pam_appl.h> +#include <security/pam_modules.h> +#include <security/pam_mod_misc.h> + +#include "pam_login_access.h" + +PAM_EXTERN int +pam_sm_authenticate(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_setcred(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_acct_mgmt(pam_handle_t *pamh, int flags __unused, int argc ,const char **argv) +{ + struct options options; + const char *rhost, *tty, *user; + char hostname[MAXHOSTNAMELEN]; + int pam_err; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + pam_err = pam_get_item(pamh, PAM_USER, (const void **)&user); + if (pam_err != PAM_SUCCESS) + PAM_RETURN(pam_err); + + if (user == NULL) + PAM_RETURN(PAM_SERVICE_ERR); + + PAM_LOG("Got user: %s", user); + + pam_err = pam_get_item(pamh, PAM_RHOST, (const void **)&rhost); + if (pam_err != PAM_SUCCESS) + PAM_RETURN(pam_err); + + pam_err = pam_get_item(pamh, PAM_TTY, (const void **)&tty); + if (pam_err != PAM_SUCCESS) + PAM_RETURN(pam_err); + + gethostname(hostname, sizeof hostname); + + if (rhost == NULL) { + PAM_LOG("Checking login.access for user %s on tty %s", + user, tty); + if (login_access(user, tty) != 0) + PAM_RETURN(PAM_SUCCESS); + PAM_VERBOSE_ERROR("%s is not allowed to log in on %s", + user, tty); + } else { + PAM_LOG("Checking login.access for user %s from host %s", + user, rhost); + if (login_access(user, rhost) != 0) + PAM_RETURN(PAM_SUCCESS); + PAM_VERBOSE_ERROR("%s is not allowed to log in from %s", + user, rhost); + } + + PAM_RETURN(PAM_AUTH_ERR); +} + +PAM_EXTERN int +pam_sm_chauthtok(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_open_session(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_close_session(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_MODULE_ENTRY("pam_login_access"); diff --git a/lib/libpam/modules/pam_login_access/pam_login_access.h b/lib/libpam/modules/pam_login_access/pam_login_access.h new file mode 100644 index 0000000..38c3049 --- /dev/null +++ b/lib/libpam/modules/pam_login_access/pam_login_access.h @@ -0,0 +1,39 @@ +/*- + * Copyright (c) 2001 Mark R V Murray + * All rights reserved. + * Copyright (c) 2001 Networks Associates Technology, Inc. + * All rights reserved. + * + * Portions of this software were developed for the FreeBSD Project by + * ThinkSec AS and NAI Labs, the Security Research Division of Network + * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 + * ("CBOSS"), as part of the DARPA CHATS research program. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ + */ + +extern int login_access(const char *, const char *); diff --git a/lib/libpam/modules/pam_nologin/Makefile b/lib/libpam/modules/pam_nologin/Makefile new file mode 100644 index 0000000..d907dae --- /dev/null +++ b/lib/libpam/modules/pam_nologin/Makefile @@ -0,0 +1,34 @@ +# Copyright 2001 Mark R V Murray +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ + +LIB= pam_nologin +SHLIB_NAME= ${LIB}.so.${SHLIB_MAJOR} +SRCS= pam_nologin.c +DPADD= ${LIBUTIL} +LDADD= -lutil +MAN= pam_nologin.8 + +.include <bsd.lib.mk> diff --git a/lib/libpam/modules/pam_nologin/pam_nologin.8 b/lib/libpam/modules/pam_nologin/pam_nologin.8 new file mode 100644 index 0000000..a2c5990 --- /dev/null +++ b/lib/libpam/modules/pam_nologin/pam_nologin.8 @@ -0,0 +1,90 @@ +.\" Copyright (c) 2001 Mark R V Murray +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ +.\" +.Dd July 8, 2001 +.Dt PAM_NOLOGIN 8 +.Os +.Sh NAME +.Nm pam_nologin +.Nd NoLogin PAM module +.Sh SYNOPSIS +.Op Ar service-name +.Ar module-type +.Ar control-flag +.Pa pam_nologin +.Op Ar options +.Sh DESCRIPTION +The NoLogin authentication service module for PAM, +.Nm +provides functionality for only one PAM category: +authentication. +In terms of the +.Ar module-type +parameter, this is the +.Dq Li auth +feature. +It also provides a null function for session management. +.Ss NoLogin Authentication Module +The NoLogin authentication component +.Pq Fn pam_sm_authenticate , +always returns success for the superuser, +and returns success for all other users +if the file +.Pa /var/run/nologin +does not exist. +If +.Pa /var/run/nologin +does exist, +then its contents are echoed +to non-superusers +before failure is returned. +If a "nologin" capability +is specified in +.Xr login.conf 5 , +then the file thus specified +is used instead. +This usually defaults to +.Pa /var/run/nologin . +.Pp +The following options may be passed to the authentication module: +.Bl -tag -width ".Cm no_warn" +.It Cm debug +.Xr syslog 3 +debugging information at +.Dv LOG_DEBUG +level. +.It Cm no_warn +suppress warning messages to the user. +These messages include +reasons why the user's +authentication attempt was declined. +.El +.Sh SEE ALSO +.Xr syslog 3 , +.Xr login.conf 5 , +.Xr nologin 5 , +.Xr pam.conf 5 , +.Xr pam 8 diff --git a/lib/libpam/modules/pam_nologin/pam_nologin.c b/lib/libpam/modules/pam_nologin/pam_nologin.c new file mode 100644 index 0000000..4becc6e --- /dev/null +++ b/lib/libpam/modules/pam_nologin/pam_nologin.c @@ -0,0 +1,181 @@ +/*- + * Copyright 2001 Mark R V Murray + * All rights reserved. + * Copyright (c) 2001 Networks Associates Technology, Inc. + * All rights reserved. + * + * Portions of this software were developed for the FreeBSD Project by + * ThinkSec AS and NAI Labs, the Security Research Division of Network + * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 + * ("CBOSS"), as part of the DARPA CHATS research program. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <login_cap.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#define PAM_SM_AUTH +#define PAM_SM_ACCOUNT +#define PAM_SM_SESSION +#define PAM_SM_PASSWORD + +#include <security/pam_appl.h> +#include <security/pam_modules.h> +#include <security/pam_mod_misc.h> + +#define NOLOGIN "/var/run/nologin" + +static char nologin_def[] = NOLOGIN; + +PAM_EXTERN int +pam_sm_authenticate(pam_handle_t *pamh, int flags __unused, int argc, const char **argv) +{ + login_cap_t *lc; + struct options options; + struct passwd *pwd; + struct stat st; + int retval, fd; + const char *user, *nologin; + char *mtmp; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + retval = pam_get_user(pamh, &user, NULL); + if (retval != PAM_SUCCESS) + PAM_RETURN(retval); + + PAM_LOG("Got user: %s", user); + + lc = login_getclass(NULL); + nologin = login_getcapstr(lc, "nologin", nologin_def, nologin_def); + login_close(lc); + lc = NULL; + + fd = open(nologin, O_RDONLY, 0); + if (fd < 0) + PAM_RETURN(PAM_SUCCESS); + + PAM_LOG("Opened %s file", NOLOGIN); + + pwd = getpwnam(user); + if (pwd && pwd->pw_uid == 0) + retval = PAM_SUCCESS; + else { + if (!pwd) + retval = PAM_USER_UNKNOWN; + else + retval = PAM_AUTH_ERR; + } + + if (fstat(fd, &st) < 0) + PAM_RETURN(retval); + + mtmp = malloc(st.st_size + 1); + if (mtmp != NULL) { + read(fd, mtmp, st.st_size); + mtmp[st.st_size] = '\0'; + pam_error(pamh, "%s", mtmp, NULL); + free(mtmp); + } + + if (retval != PAM_SUCCESS) + PAM_VERBOSE_ERROR("Administrator refusing you: %s", NOLOGIN); + + PAM_RETURN(retval); +} + +PAM_EXTERN int +pam_sm_setcred(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_SUCCESS); +} + +PAM_EXTERN int +pam_sm_acct_mgmt(pam_handle_t *pamh __unused, int flags __unused, int argc ,const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_chauthtok(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_open_session(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_close_session(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_MODULE_ENTRY("pam_nologin"); diff --git a/lib/libpam/modules/pam_opie/Makefile b/lib/libpam/modules/pam_opie/Makefile new file mode 100644 index 0000000..330b4cc --- /dev/null +++ b/lib/libpam/modules/pam_opie/Makefile @@ -0,0 +1,35 @@ +# Copyright 2000 James Bloom +# All rights reserved. +# Based upon code Copyright 1998 Juniper Networks, Inc. +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ + +LIB= pam_opie +SHLIB_NAME= ${LIB}.so.${SHLIB_MAJOR} +SRCS= pam_opie.c +DPADD= ${LIBOPIE} +LDADD= -lopie +MAN= pam_opie.8 + +.include <bsd.lib.mk> diff --git a/lib/libpam/modules/pam_opie/pam_opie.8 b/lib/libpam/modules/pam_opie/pam_opie.8 new file mode 100644 index 0000000..bae696d --- /dev/null +++ b/lib/libpam/modules/pam_opie/pam_opie.8 @@ -0,0 +1,123 @@ +.\" Copyright (c) 2001 Mark R V Murray +.\" All rights reserved. +.\" Copyright (c) 2002 Networks Associates Technology, Inc. +.\" All rights reserved. +.\" +.\" Portions of this software were developed for the FreeBSD Project by +.\" ThinkSec AS and NAI Labs, the Security Research Division of Network +.\" Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 +.\" ("CBOSS"), as part of the DARPA CHATS research program. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. The name of the author may not be used to endorse or promote +.\" products derived from this software without specific prior written +.\" permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ +.\" +.Dd July 7, 2001 +.Dt PAM_OPIE 8 +.Os +.Sh NAME +.Nm pam_opie +.Nd OPIE PAM module +.Sh SYNOPSIS +.Op Ar service-name +.Ar module-type +.Ar control-flag +.Pa pam_opie +.Op Ar options +.Sh DESCRIPTION +The OPIE authentication service module for PAM, +.Nm +provides functionality for only one PAM category: +that of authentication. +In terms of the +.Ar module-type +parameter, this is the +.Dq Li auth +feature. +It also provides a null function for session management. +.Pp +Note that this module does not enforce +.Xr opieaccess 5 +checks. +There is a separate module, +.Xr pam_opieaccess 8 , +for this purpose. +.Ss OPIE Authentication Module +The OPIE authentication component +provides functions to verify the identity of a user +.Pq Fn pam_sm_authenticate , +which obtains the relevant +.Xr opie 4 +credentials. +It provides the user with an OPIE challenge, +and verifies that this is correct with +.Xr opiechallenge 3 . +.Pp +The following options may be passed to the authentication module: +.Bl -tag -width ".Cm auth_as_self" +.It Cm debug +.Xr syslog 3 +debugging information at +.Dv LOG_DEBUG +level. +.It Cm auth_as_self +This option will require the user +to authenticate themself as the user +given by +.Xr getlogin 2 , +not as the account they are attempting to access. +This is primarily for services like +.Xr su 1 , +where the user's ability to retype +their own password +might be deemed sufficient. +.It Cm no_fake_prompts +Do not generate fake challenges for users who do not have an OPIE key. +Note that this can leak information to a hypothetical attacker about +who uses OPIE and who does not, but it can be useful on systems where +some users want to use OPIE but most do not. +.El +.Pp +Note that +.Nm +ignores the standard options +.Cm try_first_pass +and +.Cm use_first_pass , +since a challenge must be generated before the user can submit a valid +response. +.Sh FILES +.Bl -tag -width ".Pa /etc/opiekeys" -compact +.It Pa /etc/opiekeys +default OPIE password database. +.El +.Sh SEE ALSO +.Xr passwd 1 , +.Xr getlogin 2 , +.Xr opiechallenge 3 , +.Xr syslog 3 , +.Xr opie 4 , +.Xr pam.conf 5 , +.Xr pam 8 diff --git a/lib/libpam/modules/pam_opie/pam_opie.c b/lib/libpam/modules/pam_opie/pam_opie.c new file mode 100644 index 0000000..521fbb4 --- /dev/null +++ b/lib/libpam/modules/pam_opie/pam_opie.c @@ -0,0 +1,215 @@ +/*- + * Copyright 2000 James Bloom + * All rights reserved. + * Based upon code Copyright 1998 Juniper Networks, Inc. + * Copyright (c) 2001 Networks Associates Technology, Inc. + * All rights reserved. + * Copyright (c) 2002 Networks Associates Technology, Inc. + * All rights reserved. + * + * Portions of this software were developed for the FreeBSD Project by + * ThinkSec AS and NAI Labs, the Security Research Division of Network + * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 + * ("CBOSS"), as part of the DARPA CHATS research program. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <opie.h> +#include <pwd.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +#define PAM_SM_AUTH +#define PAM_SM_ACCOUNT +#define PAM_SM_SESSION +#define PAM_SM_PASSWORD + +#include <security/pam_appl.h> +#include <security/pam_modules.h> +#include <security/pam_mod_misc.h> + +enum { + PAM_OPT_AUTH_AS_SELF = PAM_OPT_STD_MAX, + PAM_OPT_NO_FAKE_PROMPTS +}; + +static struct opttab other_options[] = { + { "auth_as_self", PAM_OPT_AUTH_AS_SELF }, + { "no_fake_prompts", PAM_OPT_NO_FAKE_PROMPTS }, + { NULL, 0 } +}; + +PAM_EXTERN int +pam_sm_authenticate(pam_handle_t *pamh, int flags __unused, int argc, const char **argv) +{ + struct opie opie; + struct options options; + struct passwd *pwd; + int retval, i; + const char *(promptstr[]) = { "%s\nPassword: ", "%s\nPassword [echo on]: "}; + char challenge[OPIE_CHALLENGE_MAX]; + char prompt[OPIE_CHALLENGE_MAX+22]; + char resp[OPIE_SECRET_MAX]; + char *user; + const char *response; + + pam_std_option(&options, other_options, argc, argv); + + PAM_LOG("Options processed"); + + user = NULL; + if (pam_test_option(&options, PAM_OPT_AUTH_AS_SELF, NULL)) { + if ((pwd = getpwnam(getlogin())) == NULL) + PAM_RETURN(PAM_AUTH_ERR); + user = pwd->pw_name; + } + else { + retval = pam_get_user(pamh, (const char **)&user, NULL); + if (retval != PAM_SUCCESS) + PAM_RETURN(retval); + } + + PAM_LOG("Got user: %s", user); + + /* + * Don't call the OPIE atexit() handler when our program exits, + * since the module has been unloaded and we will SEGV. + */ + opiedisableaeh(); + + /* + * If the no_fake_prompts option was given, and the user + * doesn't have an OPIE key, just fail rather than present the + * user with a bogus OPIE challenge. + */ + /* XXX generates a const warning because of incorrect prototype */ + if (opiechallenge(&opie, (char *)user, challenge) != 0 && + pam_test_option(&options, PAM_OPT_NO_FAKE_PROMPTS, NULL)) + PAM_RETURN(PAM_AUTH_ERR); + + /* + * It doesn't make sense to use a password that has already been + * typed in, since we haven't presented the challenge to the user + * yet, so clear the stored password. + */ + pam_set_item(pamh, PAM_AUTHTOK, NULL); + + for (i = 0; i < 2; i++) { + snprintf(prompt, sizeof prompt, promptstr[i], challenge); + retval = pam_get_authtok(pamh, &response, prompt); + if (retval != PAM_SUCCESS) { + opieunlock(); + PAM_RETURN(retval); + } + + PAM_LOG("Completed challenge %d: %s", i, response); + + if (response[0] != '\0') + break; + + /* Second time round, echo the password */ + pam_set_option(&options, PAM_OPT_ECHO_PASS); + } + + /* We have to copy the response, because opieverify mucks with it. */ + strlcpy(resp, response, sizeof (resp)); + + /* + * Opieverify is supposed to return -1 only if an error occurs. + * But it returns -1 even if the response string isn't in the form + * it expects. Thus we can't log an error and can only check for + * success or lack thereof. + */ + retval = opieverify(&opie, resp) == 0 ? PAM_SUCCESS : PAM_AUTH_ERR; + PAM_RETURN(retval); +} + +PAM_EXTERN int +pam_sm_setcred(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, other_options, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_SUCCESS); +} + +PAM_EXTERN int +pam_sm_acct_mgmt(pam_handle_t *pamh __unused, int flags __unused, int argc ,const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_chauthtok(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_open_session(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_close_session(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_MODULE_ENTRY("pam_opie"); diff --git a/lib/libpam/modules/pam_opieaccess/Makefile b/lib/libpam/modules/pam_opieaccess/Makefile new file mode 100644 index 0000000..2be222c --- /dev/null +++ b/lib/libpam/modules/pam_opieaccess/Makefile @@ -0,0 +1,10 @@ +# $FreeBSD$ + +LIB= pam_opieaccess +SHLIB_NAME= ${LIB}.so.${SHLIB_MAJOR} +SRCS= ${LIB}.c +DPADD= ${LIBOPIE} +LDADD= -lopie +MAN= pam_opieaccess.8 + +.include <bsd.lib.mk> diff --git a/lib/libpam/modules/pam_opieaccess/pam_opieaccess.8 b/lib/libpam/modules/pam_opieaccess/pam_opieaccess.8 new file mode 100644 index 0000000..fac671e --- /dev/null +++ b/lib/libpam/modules/pam_opieaccess/pam_opieaccess.8 @@ -0,0 +1,125 @@ +.\" Copyright (c) 2001 Mark R V Murray +.\" All rights reserved. +.\" Copyright (c) 2002 Networks Associates Technology, Inc. +.\" All rights reserved. +.\" +.\" Portions of this software were developed for the FreeBSD Project by +.\" ThinkSec AS and NAI Labs, the Security Research Division of Network +.\" Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 +.\" ("CBOSS"), as part of the DARPA CHATS research program. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. The name of the author may not be used to endorse or promote +.\" products derived from this software without specific prior written +.\" permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ +.\" +.Dd January 21, 2002 +.Dt PAM_OPIEACCESS 8 +.Os +.Sh NAME +.Nm pam_opieaccess +.Nd OPIEAccess PAM module +.Sh SYNOPSIS +.Op Ar service-name +.Ar module-type +.Ar control-flag +.Pa pam_opieaccess +.Op Ar options +.Sh DESCRIPTION +The +.Nm +module is used in conjunction with the +.Xr pam_opie 8 +PAM module to ascertain that authentication can proceed by other means +(such as the +.Xr pam_unix 8 +module) even if OPIE authentication failed. +To properly use this module, +.Xr pam_opie 8 +should be marked +.Dq Li sufficient , +and +.Nm +should be listed right below it and marked +.Dq Li requisite . +.Pp +The +.Nm +module provides functionality for only one PAM category: +authentication. +In terms of the +.Ar module-type +parameter, this is the +.Dq Li auth +feature. +It also provides null functions for the remaining module types. +.Ss OPIEAccess Authentication Module +The authentication component +.Pq Fn pam_sm_authenticate , +returns +.Dv PAM_IGNORE +in two cases: +.Bl -enum +.It +The user does not have OPIE enabled. +.It +The user has OPIE enabled, and the remote host is listed as a trusted +host in +.Pa /etc/opieaccess , +and the user does not have a file named +.Pa opiealways +in his home directory. +.El +.Pp +Otherwise, it returns +.Dv PAM_AUTH_ERR . +.Pp +The following options may be passed to the authentication module: +.Bl -tag -width ".Cm no_warn" +.It Cm debug +.Xr syslog 3 +debugging information at +.Dv LOG_DEBUG +level. +.It Cm no_warn +suppress warning messages to the user. +These messages include reasons why the user's authentication attempt +was declined. +.El +.Sh SEE ALSO +.Xr opie 4 , +.Xr opieaccess 5 , +.Xr pam.conf 5 , +.Xr pam 8 , +.Xr pam_opie 8 +.Sh AUTHORS +The +.Nm +module and this manual page were developed for the +.Fx +Project by +ThinkSec AS and NAI Labs, the Security Research Division of Network +Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 +.Pq Dq CBOSS , +as part of the DARPA CHATS research program. diff --git a/lib/libpam/modules/pam_opieaccess/pam_opieaccess.c b/lib/libpam/modules/pam_opieaccess/pam_opieaccess.c new file mode 100644 index 0000000..1d559d7 --- /dev/null +++ b/lib/libpam/modules/pam_opieaccess/pam_opieaccess.c @@ -0,0 +1,153 @@ +/*- + * Copyright (c) 2002 Networks Associates Technology, Inc. + * All rights reserved. + * + * This software was developed for the FreeBSD Project by ThinkSec AS and + * NAI Labs, the Security Research Division of Network Associates, Inc. + * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the + * DARPA CHATS research program. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#define _BSD_SOURCE + +#include <sys/types.h> +#include <opie.h> +#include <pwd.h> +#include <unistd.h> +#include <syslog.h> + +#define PAM_SM_AUTH +#define PAM_SM_ACCOUNT +#define PAM_SM_SESSION +#define PAM_SM_PASSWORD + +#include <security/pam_appl.h> +#include <security/pam_modules.h> +#include <security/pam_mod_misc.h> + +PAM_EXTERN int +pam_sm_authenticate(pam_handle_t *pamh, int flags __unused, int argc, const char **argv) +{ + struct options options; + struct opie opie; + struct passwd *pwent; + char *luser, *rhost; + int r; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + r = pam_get_item(pamh, PAM_USER, (const void **)&luser); + if (r != PAM_SUCCESS) + PAM_RETURN(r); + if (luser == NULL) + PAM_RETURN(PAM_SERVICE_ERR); + + pwent = getpwnam(luser); + if (pwent == NULL || opielookup(&opie, luser) != 0) + PAM_RETURN(PAM_IGNORE); + + r = pam_get_item(pamh, PAM_RHOST, (const void **)&rhost); + if (r != PAM_SUCCESS) + PAM_RETURN(r); + + if ((rhost == NULL || opieaccessfile(rhost)) && + opiealways(pwent->pw_dir) != 0) + PAM_RETURN(PAM_IGNORE); + + PAM_VERBOSE_ERROR("Refused; remote host is not in opieaccess"); + + PAM_RETURN(PAM_AUTH_ERR); +} + +PAM_EXTERN int +pam_sm_setcred(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_SUCCESS); +} + +PAM_EXTERN int +pam_sm_acct_mgmt(pam_handle_t *pamh __unused, int flags __unused, int argc ,const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_chauthtok(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_open_session(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_close_session(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_MODULE_ENTRY("pam_opieaccess"); diff --git a/lib/libpam/modules/pam_passwdqc/Makefile b/lib/libpam/modules/pam_passwdqc/Makefile new file mode 100644 index 0000000..ddb5cbd --- /dev/null +++ b/lib/libpam/modules/pam_passwdqc/Makefile @@ -0,0 +1,13 @@ +# $FreeBSD$ + +SRCDIR= ${.CURDIR}/../../../../contrib/pam_modules/pam_passwdqc + +LIB= pam_passwdqc +SHLIB_NAME= ${LIB}.so.${SHLIB_MAJOR} +SRCS= pam_passwdqc.c passwdqc_check.c passwdqc_random.c wordset_4k.c +CFLAGS+= -I${SRCDIR} -DPAM_AUTHTOK_RECOVER_ERR=PAM_AUTHTOK_RECOVERY_ERR +MAN= #pam_passwdqc.8 + +.include <bsd.lib.mk> + +.PATH: ${SRCDIR} diff --git a/lib/libpam/modules/pam_permit/Makefile b/lib/libpam/modules/pam_permit/Makefile new file mode 100644 index 0000000..e549b03 --- /dev/null +++ b/lib/libpam/modules/pam_permit/Makefile @@ -0,0 +1,32 @@ +# Copyright 1999 Max Khon. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ + +LIB= pam_permit +SHLIB_NAME= ${LIB}.so.${SHLIB_MAJOR} +SRCS= pam_permit.c +MAN= pam_permit.8 + +.include <bsd.lib.mk> diff --git a/lib/libpam/modules/pam_permit/pam_permit.8 b/lib/libpam/modules/pam_permit/pam_permit.8 new file mode 100644 index 0000000..c7d98ab --- /dev/null +++ b/lib/libpam/modules/pam_permit/pam_permit.8 @@ -0,0 +1,75 @@ +.\" Copyright (c) 2001 Mark R V Murray +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ +.\" +.Dd July 7, 2001 +.Dt PAM_PERMIT 8 +.Os +.Sh NAME +.Nm pam_permit +.Nd Promiscuous PAM module +.Sh SYNOPSIS +.Op Ar service-name +.Ar module-type +.Ar control-flag +.Pa pam_permit +.Op Ar options +.Sh DESCRIPTION +The Promiscuous authentication service module for PAM, +.Nm +provides functionality for all the PAM categories: +authentication, +account management, +session management and +password management. +In terms of the +.Ar module-type +parameter, these are the +.Dq Li auth , +.Dq Li account , +.Dq Li session , +and +.Dq Li password +features. +.Pp +The Promiscuous module +will universally allow all requests. +It is primarily of use during testing, +and to silence +.Dq noisy +PAM-enabled applications. +.Pp +The following options may be passed to the module: +.Bl -tag -width ".Cm debug" +.It Cm debug +.Xr syslog 3 +debugging information at +.Dv LOG_DEBUG +level. +.El +.Sh SEE ALSO +.Xr syslog 3 , +.Xr pam.conf 5 , +.Xr pam 8 diff --git a/lib/libpam/modules/pam_permit/pam_permit.c b/lib/libpam/modules/pam_permit/pam_permit.c new file mode 100644 index 0000000..632fbcb --- /dev/null +++ b/lib/libpam/modules/pam_permit/pam_permit.c @@ -0,0 +1,129 @@ +/*- + * Copyright 2001 Mark R V Murray + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stddef.h> + +#define PAM_SM_AUTH +#define PAM_SM_ACCOUNT +#define PAM_SM_SESSION +#define PAM_SM_PASSWORD + +#include <security/pam_appl.h> +#include <security/pam_modules.h> +#include <security/pam_mod_misc.h> + +#define NOBODY "nobody" + +PAM_EXTERN int +pam_sm_authenticate(pam_handle_t *pamh, int flags __unused, int argc, const char **argv) +{ + struct options options; + int retval; + const char *user; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + /* We always need to know who the user is */ + user = NULL; + retval = pam_get_user(pamh, &user, NULL); + if (retval != PAM_SUCCESS) + PAM_RETURN(retval); + + PAM_LOG("Got user: %s", user); + + if (user == NULL || *user == '\0') + pam_set_item(pamh, PAM_USER, (const void *)NOBODY); + user = NULL; + + PAM_RETURN(PAM_SUCCESS); +} + +PAM_EXTERN int +pam_sm_setcred(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_SUCCESS); +} + +PAM_EXTERN int +pam_sm_acct_mgmt(pam_handle_t *pamh __unused, int flags __unused, int argc ,const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_SUCCESS); +} + +PAM_EXTERN int +pam_sm_chauthtok(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_SUCCESS); +} + +PAM_EXTERN int +pam_sm_open_session(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_SUCCESS); +} + +PAM_EXTERN int +pam_sm_close_session(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_SUCCESS); +} + +PAM_MODULE_ENTRY("pam_permit"); diff --git a/lib/libpam/modules/pam_radius/Makefile b/lib/libpam/modules/pam_radius/Makefile new file mode 100644 index 0000000..be084b2 --- /dev/null +++ b/lib/libpam/modules/pam_radius/Makefile @@ -0,0 +1,35 @@ +# Copyright 1998 Juniper Networks, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ + +LIB= pam_radius +SHLIB_NAME= ${LIB}.so.${SHLIB_MAJOR} +SRCS= pam_radius.c +DPADD= ${LIBRADIUS} +LDADD= -lradius + +MAN= pam_radius.8 + +.include <bsd.lib.mk> diff --git a/lib/libpam/modules/pam_radius/pam_radius.8 b/lib/libpam/modules/pam_radius/pam_radius.8 new file mode 100644 index 0000000..240e122 --- /dev/null +++ b/lib/libpam/modules/pam_radius/pam_radius.8 @@ -0,0 +1,130 @@ +.\" Copyright (c) 1999 +.\" Andrzej Bialecki <abial@FreeBSD.org>. All rights reserved. +.\" +.\" Copyright (c) 1992, 1993, 1994 +.\" The Regents of the University of California. All rights reserved. +.\" All rights reserved. +.\" +.\" This code is derived from software donated to Berkeley by +.\" Jan-Simon Pendry. +.\" +.\" 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$ +.\" +.Dd August 2, 1999 +.Dt PAM_RADIUS 8 +.Os +.Sh NAME +.Nm pam_radius +.Nd RADIUS authentication PAM module +.Sh SYNOPSIS +.Op Ar service-name +.Ar module-type +.Ar control-flag +.Pa pam_radius +.Op Ar options +.Sh DESCRIPTION +The +.Nm +module provides authentication services based +upon the RADIUS (Remote Authentication Dial In User Service) protocol +for the PAM (Pluggable Authentication Module) framework. +.Pp +The +.Nm +module accepts these optional parameters: +.Bl -tag -width Fl +.It Cm use_first_pass +causes +.Nm +to use a previously entered password instead of prompting for a new one. +If no password has been entered then authentication fails. +.It Cm try_first_pass +causes +.Nm +to use a previously entered password, if one is available. If no +password has been entered, +.Nm +prompts for one as usual. +.It Cm echo_pass +causes echoing to be left on if +.Nm +prompts for a password. +.It Cm conf Ns No = Ns Ar pathname +specifies a non-standard location for the RADIUS client configuration file +(normally located in /etc/radius.conf). +.It Cm template_user Ns No = Ns Ar username +specifies a user whose +.Xr passwd 5 +entry will be used as a template to create the session environment +if the supplied username doesn't exist in local password database. +The user +will be authenticated with the supplied username and password, but his +credentials to the system will be presented as the ones for +.Ar username , +i.e., his login class, home directory, resource limits, etc. will be set to ones +defined for +.Ar username . +.Pp +If this option is omitted, and there is no username +in the system databases equal to the supplied one (as determined by call to +.Xr getpwnam 3 ) , +the authentication will fail. +.El +.Sh FILES +.Bl -tag -width /etc/radius.conf -compact +.It Pa /etc/radius.conf +The standard RADIUS client configuration file for +.Nm +.El +.Sh SEE ALSO +.Xr passwd 5 , +.Xr radius.conf 5 , +.Xr pam 8 +.Sh HISTORY +The +.Nm +module first appeared in +.Fx 3.1 . +The +.Nm +manual page first appeared in +.Fx 3.3 . +.Sh AUTHORS +.An -nosplit +The +.Nm +manual page was written by +.An Andrzej Bialecki Aq abial@FreeBSD.org . +.Pp +The +.Nm +module was written by +.An John D. Polstra Aq jdp@FreeBSD.org . diff --git a/lib/libpam/modules/pam_radius/pam_radius.c b/lib/libpam/modules/pam_radius/pam_radius.c new file mode 100644 index 0000000..4e19f82 --- /dev/null +++ b/lib/libpam/modules/pam_radius/pam_radius.c @@ -0,0 +1,391 @@ +/*- + * Copyright 1998 Juniper Networks, Inc. + * All rights reserved. + * Copyright (c) 2001 Networks Associates Technology, Inc. + * All rights reserved. + * + * Portions of this software were developed for the FreeBSD Project by + * ThinkSec AS and NAI Labs, the Security Research Division of Network + * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 + * ("CBOSS"), as part of the DARPA CHATS research program. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <pwd.h> +#include <radlib.h> +#include <stdlib.h> +#include <string.h> +#include <syslog.h> +#include <unistd.h> + +#define PAM_SM_AUTH +#define PAM_SM_ACCOUNT +#define PAM_SM_SESSION +#define PAM_SM_PASSWORD + +#include <security/pam_appl.h> +#include <security/pam_modules.h> +#include <security/pam_mod_misc.h> + +enum { PAM_OPT_CONF=PAM_OPT_STD_MAX, PAM_OPT_TEMPLATE_USER }; + +static struct opttab other_options[] = { + { "conf", PAM_OPT_CONF }, + { "template_user", PAM_OPT_TEMPLATE_USER }, + { NULL, 0 } +}; + +#define MAX_CHALLENGE_MSGS 10 +#define PASSWORD_PROMPT "RADIUS password:" + +static int build_access_request(struct rad_handle *, const char *, + const char *, const void *, size_t); +static int do_accept(pam_handle_t *, struct rad_handle *); +static int do_challenge(pam_handle_t *, struct rad_handle *, + const char *); + +/* + * Construct an access request, but don't send it. Returns 0 on success, + * -1 on failure. + */ +static int +build_access_request(struct rad_handle *radh, const char *user, + const char *pass, const void *state, size_t state_len) +{ + char host[MAXHOSTNAMELEN]; + + if (rad_create_request(radh, RAD_ACCESS_REQUEST) == -1) { + syslog(LOG_CRIT, "rad_create_request: %s", rad_strerror(radh)); + return -1; + } + if ((user != NULL && + rad_put_string(radh, RAD_USER_NAME, user) == -1) || + (pass != NULL && + rad_put_string(radh, RAD_USER_PASSWORD, pass) == -1) || + (gethostname(host, sizeof host) != -1 && + rad_put_string(radh, RAD_NAS_IDENTIFIER, host) == -1)) { + syslog(LOG_CRIT, "rad_put_string: %s", rad_strerror(radh)); + return -1; + } + if (state != NULL && rad_put_attr(radh, RAD_STATE, state, + state_len) == -1) { + syslog(LOG_CRIT, "rad_put_attr: %s", rad_strerror(radh)); + return -1; + } + if (rad_put_int(radh, RAD_SERVICE_TYPE, RAD_AUTHENTICATE_ONLY) == -1) { + syslog(LOG_CRIT, "rad_put_int: %s", rad_strerror(radh)); + return -1; + } + return 0; +} + +static int +do_accept(pam_handle_t *pamh, struct rad_handle *radh) +{ + int attrtype; + const void *attrval; + size_t attrlen; + char *s; + + while ((attrtype = rad_get_attr(radh, &attrval, &attrlen)) > 0) { + if (attrtype == RAD_USER_NAME) { + s = rad_cvt_string(attrval, attrlen); + if (s == NULL) { + syslog(LOG_CRIT, + "rad_cvt_string: out of memory"); + return -1; + } + pam_set_item(pamh, PAM_USER, s); + free(s); + } + } + if (attrtype == -1) { + syslog(LOG_CRIT, "rad_get_attr: %s", rad_strerror(radh)); + return -1; + } + return 0; +} + +static int +do_challenge(pam_handle_t *pamh, struct rad_handle *radh, const char *user) +{ + int retval; + int attrtype; + const void *attrval; + size_t attrlen; + const void *state; + size_t statelen; + struct pam_message msgs[MAX_CHALLENGE_MSGS]; + const struct pam_message *msg_ptrs[MAX_CHALLENGE_MSGS]; + struct pam_response *resp; + int num_msgs; + const void *item; + const struct pam_conv *conv; + + state = NULL; + statelen = 0; + num_msgs = 0; + while ((attrtype = rad_get_attr(radh, &attrval, &attrlen)) > 0) { + switch (attrtype) { + + case RAD_STATE: + state = attrval; + statelen = attrlen; + break; + + case RAD_REPLY_MESSAGE: + if (num_msgs >= MAX_CHALLENGE_MSGS) { + syslog(LOG_CRIT, + "Too many RADIUS challenge messages"); + return PAM_SERVICE_ERR; + } + msgs[num_msgs].msg = rad_cvt_string(attrval, attrlen); + if (msgs[num_msgs].msg == NULL) { + syslog(LOG_CRIT, + "rad_cvt_string: out of memory"); + return PAM_SERVICE_ERR; + } + msgs[num_msgs].msg_style = PAM_TEXT_INFO; + msg_ptrs[num_msgs] = &msgs[num_msgs]; + num_msgs++; + break; + } + } + if (attrtype == -1) { + syslog(LOG_CRIT, "rad_get_attr: %s", rad_strerror(radh)); + return PAM_SERVICE_ERR; + } + if (num_msgs == 0) { + msgs[num_msgs].msg = strdup("(null RADIUS challenge): "); + if (msgs[num_msgs].msg == NULL) { + syslog(LOG_CRIT, "Out of memory"); + return PAM_SERVICE_ERR; + } + msgs[num_msgs].msg_style = PAM_TEXT_INFO; + msg_ptrs[num_msgs] = &msgs[num_msgs]; + num_msgs++; + } + msgs[num_msgs-1].msg_style = PAM_PROMPT_ECHO_ON; + if ((retval = pam_get_item(pamh, PAM_CONV, &item)) != PAM_SUCCESS) { + syslog(LOG_CRIT, "do_challenge: cannot get PAM_CONV"); + return retval; + } + conv = (const struct pam_conv *)item; + if ((retval = conv->conv(num_msgs, msg_ptrs, &resp, + conv->appdata_ptr)) != PAM_SUCCESS) + return retval; + if (build_access_request(radh, user, resp[num_msgs-1].resp, state, + statelen) == -1) + return PAM_SERVICE_ERR; + memset(resp[num_msgs-1].resp, 0, strlen(resp[num_msgs-1].resp)); + free(resp[num_msgs-1].resp); + free(resp); + while (num_msgs > 0) + free(msgs[--num_msgs].msg); + return PAM_SUCCESS; +} + +PAM_EXTERN int +pam_sm_authenticate(pam_handle_t *pamh, int flags __unused, int argc, const char **argv) +{ + struct options options; + struct rad_handle *radh; + const char *user, *tmpuser, *pass; + char *conf_file, *template_user; + int retval; + int e; + + pam_std_option(&options, other_options, argc, argv); + + PAM_LOG("Options processed"); + + conf_file = NULL; + pam_test_option(&options, PAM_OPT_CONF, &conf_file); + template_user = NULL; + pam_test_option(&options, PAM_OPT_TEMPLATE_USER, &template_user); + + retval = pam_get_user(pamh, &user, NULL); + if (retval != PAM_SUCCESS) + PAM_RETURN(retval); + + PAM_LOG("Got user: %s", user); + + retval = pam_get_authtok(pamh, &pass, PASSWORD_PROMPT); + if (retval != PAM_SUCCESS) + PAM_RETURN(retval); + + PAM_LOG("Got password"); + + radh = rad_open(); + if (radh == NULL) { + syslog(LOG_CRIT, "rad_open failed"); + PAM_RETURN(PAM_SERVICE_ERR); + } + + PAM_LOG("Radius opened"); + + if (rad_config(radh, conf_file) == -1) { + syslog(LOG_ALERT, "rad_config: %s", rad_strerror(radh)); + rad_close(radh); + PAM_RETURN(PAM_SERVICE_ERR); + } + + PAM_LOG("Radius config file read"); + + if (build_access_request(radh, user, pass, NULL, 0) == -1) { + rad_close(radh); + PAM_RETURN(PAM_SERVICE_ERR); + } + + PAM_LOG("Radius build access done"); + + for (;;) { + switch (rad_send_request(radh)) { + + case RAD_ACCESS_ACCEPT: + e = do_accept(pamh, radh); + rad_close(radh); + if (e == -1) + PAM_RETURN(PAM_SERVICE_ERR); + if (template_user != NULL) { + + PAM_LOG("Trying template user: %s", + template_user); + + /* + * If the given user name doesn't exist in + * the local password database, change it + * to the value given in the "template_user" + * option. + */ + retval = pam_get_item(pamh, PAM_USER, + (const void **)&tmpuser); + if (retval != PAM_SUCCESS) + PAM_RETURN(retval); + if (getpwnam(tmpuser) == NULL) { + pam_set_item(pamh, PAM_USER, + template_user); + PAM_LOG("Using template user"); + } + + } + PAM_RETURN(PAM_SUCCESS); + + case RAD_ACCESS_REJECT: + rad_close(radh); + PAM_VERBOSE_ERROR("Radius rejection"); + PAM_RETURN(PAM_AUTH_ERR); + + case RAD_ACCESS_CHALLENGE: + retval = do_challenge(pamh, radh, user); + if (retval != PAM_SUCCESS) { + rad_close(radh); + PAM_RETURN(retval); + } + break; + + case -1: + syslog(LOG_CRIT, "rad_send_request: %s", + rad_strerror(radh)); + rad_close(radh); + PAM_VERBOSE_ERROR("Radius failure"); + PAM_RETURN(PAM_AUTHINFO_UNAVAIL); + + default: + syslog(LOG_CRIT, + "rad_send_request: unexpected return value"); + rad_close(radh); + PAM_VERBOSE_ERROR("Radius error"); + PAM_RETURN(PAM_SERVICE_ERR); + } + } +} + +PAM_EXTERN int +pam_sm_setcred(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_SUCCESS); +} + +PAM_EXTERN int +pam_sm_acct_mgmt(pam_handle_t *pamh __unused, int flags __unused, int argc ,const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_chauthtok(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_open_session(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_close_session(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_MODULE_ENTRY("pam_radius"); diff --git a/lib/libpam/modules/pam_rootok/Makefile b/lib/libpam/modules/pam_rootok/Makefile new file mode 100644 index 0000000..809bae1 --- /dev/null +++ b/lib/libpam/modules/pam_rootok/Makefile @@ -0,0 +1,32 @@ +# Copyright 2001 Mark R V Murray +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ + +LIB= pam_rootok +SHLIB_NAME= ${LIB}.so.${SHLIB_MAJOR} +SRCS= pam_rootok.c +MAN= pam_rootok.8 + +.include <bsd.lib.mk> diff --git a/lib/libpam/modules/pam_rootok/pam_rootok.8 b/lib/libpam/modules/pam_rootok/pam_rootok.8 new file mode 100644 index 0000000..4203fbd --- /dev/null +++ b/lib/libpam/modules/pam_rootok/pam_rootok.8 @@ -0,0 +1,75 @@ +.\" Copyright (c) 2001 Mark R V Murray +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ +.\" +.Dd July 8, 2001 +.Dt PAM_ROOTOK 8 +.Os +.Sh NAME +.Nm pam_rootok +.Nd RootOK PAM module +.Sh SYNOPSIS +.Op Ar service-name +.Ar module-type +.Ar control-flag +.Pa pam_rootok +.Op Ar options +.Sh DESCRIPTION +The RootOK authentication service module for PAM, +.Nm +provides functionality for only one PAM category: +authentication. +In terms of the +.Ar module-type +parameter, this is the +.Dq Li auth +feature. +It also provides a null function for session management. +.Ss RootOK Authentication Module +The RootOK authentication component +.Pq Fn pam_sm_authenticate , +always returns success for the superuser; +i.e., +if +.Xr getuid 2 +returns 0. +.Pp +The following options may be passed to the authentication module: +.Bl -tag -width ".Cm no_warn" +.It Cm debug +.Xr syslog 3 +debugging information at +.Dv LOG_DEBUG +level. +.It Cm no_warn +suppress warning messages to the user. +These messages include +reasons why the user's +authentication attempt was declined. +.El +.Sh SEE ALSO +.Xr getuid 2 , +.Xr pam.conf 5 , +.Xr pam 8 diff --git a/lib/libpam/modules/pam_rootok/pam_rootok.c b/lib/libpam/modules/pam_rootok/pam_rootok.c new file mode 100644 index 0000000..1134836 --- /dev/null +++ b/lib/libpam/modules/pam_rootok/pam_rootok.c @@ -0,0 +1,132 @@ +/*- + * Copyright (c) 2001 Mark R V Murray + * All rights reserved. + * Copyright (c) 2001 Networks Associates Technology, Inc. + * All rights reserved. + * + * Portions of this software were developed for the FreeBSD Project by + * ThinkSec AS and NAI Labs, the Security Research Division of Network + * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 + * ("CBOSS"), as part of the DARPA CHATS research program. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#define _BSD_SOURCE + +#include <unistd.h> +#include <syslog.h> + +#define PAM_SM_AUTH +#define PAM_SM_ACCOUNT +#define PAM_SM_SESSION +#define PAM_SM_PASSWORD + +#include <security/pam_appl.h> +#include <security/pam_modules.h> +#include <security/pam_mod_misc.h> + +PAM_EXTERN int +pam_sm_authenticate(pam_handle_t *pamh, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + if (getuid() == 0) + PAM_RETURN(PAM_SUCCESS); + + PAM_VERBOSE_ERROR("Refused; not superuser"); + PAM_LOG("User is not superuser"); + + PAM_RETURN(PAM_AUTH_ERR); +} + +PAM_EXTERN int +pam_sm_setcred(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_SUCCESS); +} + +PAM_EXTERN int +pam_sm_acct_mgmt(pam_handle_t *pamh __unused, int flags __unused, int argc ,const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_chauthtok(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_open_session(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_close_session(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_MODULE_ENTRY("pam_rootok"); diff --git a/lib/libpam/modules/pam_securetty/Makefile b/lib/libpam/modules/pam_securetty/Makefile new file mode 100644 index 0000000..bdecfde --- /dev/null +++ b/lib/libpam/modules/pam_securetty/Makefile @@ -0,0 +1,32 @@ +# Copyright 2001 Mark R V Murray +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ + +LIB= pam_securetty +SHLIB_NAME= ${LIB}.so.${SHLIB_MAJOR} +SRCS= pam_securetty.c +MAN= pam_securetty.8 + +.include <bsd.lib.mk> diff --git a/lib/libpam/modules/pam_securetty/pam_securetty.8 b/lib/libpam/modules/pam_securetty/pam_securetty.8 new file mode 100644 index 0000000..5825fb4 --- /dev/null +++ b/lib/libpam/modules/pam_securetty/pam_securetty.8 @@ -0,0 +1,92 @@ +.\" Copyright (c) 2001 Mark R V Murray +.\" All rights reserved. +.\" Copyright (c) 2002 Networks Associates Technology, Inc. +.\" All rights reserved. +.\" +.\" Portions of this software were developed for the FreeBSD Project by +.\" ThinkSec AS and NAI Labs, the Security Research Division of Network +.\" Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 +.\" ("CBOSS"), as part of the DARPA CHATS research program. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. The name of the author may not be used to endorse or promote +.\" products derived from this software without specific prior written +.\" permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ +.\" +.Dd July 8, 2001 +.Dt PAM_SECURETTY 8 +.Os +.Sh NAME +.Nm pam_securetty +.Nd SecureTTY PAM module +.Sh SYNOPSIS +.Op Ar service-name +.Ar module-type +.Ar control-flag +.Pa pam_securetty +.Op Ar options +.Sh DESCRIPTION +The SecureTTY service module for PAM, +.Nm +provides functionality for only one PAM category: +account management. +In terms of the +.Ar module-type +parameter, this is the +.Dq Li account +feature. +It also provides null functions for authentication and session +management. +.Ss SecureTTY Account Management Module +The SecureTTY account management component +.Pq Fn pam_sm_acct_mgmt , +returns failure if the user is attempting to authenticate as superuser, +and the process is attached to an insecure TTY. +In all other cases, the module returns success. +.Pp +A TTY is considered secure if it is listed in +.Pa /etc/ttys +and has the +.Dv TTY_SECURE +flag set. +.Pp +The following options may be passed to the authentication module: +.Bl -tag -width ".Cm no_warn" +.It Cm debug +.Xr syslog 3 +debugging information at +.Dv LOG_DEBUG +level. +.It Cm no_warn +suppress warning messages to the user. +These messages include +reasons why the user's +authentication attempt was declined. +.El +.Sh SEE ALSO +.Xr getttynam 3 , +.Xr syslog 3 , +.Xr pam.conf 5 , +.Xr ttys 5 , +.Xr pam 8 diff --git a/lib/libpam/modules/pam_securetty/pam_securetty.c b/lib/libpam/modules/pam_securetty/pam_securetty.c new file mode 100644 index 0000000..93db9c1 --- /dev/null +++ b/lib/libpam/modules/pam_securetty/pam_securetty.c @@ -0,0 +1,163 @@ +/*- + * Copyright (c) 2001 Mark R V Murray + * All rights reserved. + * Copyright (c) 2001 Networks Associates Technology, Inc. + * All rights reserved. + * + * Portions of this software were developed for the FreeBSD Project by + * ThinkSec AS and NAI Labs, the Security Research Division of Network + * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 + * ("CBOSS"), as part of the DARPA CHATS research program. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <sys/stat.h> +#include <pwd.h> +#include <ttyent.h> +#include <string.h> + +#define PAM_SM_AUTH +#define PAM_SM_ACCOUNT +#define PAM_SM_SESSION +#define PAM_SM_PASSWORD + +#include <security/pam_appl.h> +#include <security/pam_modules.h> +#include <security/pam_mod_misc.h> + +#define TTY_PREFIX "/dev/" + +PAM_EXTERN int +pam_sm_authenticate(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN +int +pam_sm_setcred(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_SUCCESS); +} + +PAM_EXTERN int +pam_sm_acct_mgmt(pam_handle_t *pamh __unused, int flags __unused, int argc ,const char **argv) +{ + struct options options; + struct passwd *pwd; + struct ttyent *ty; + const char *user, *tty; + int pam_err; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + pam_err = pam_get_user(pamh, &user, NULL); + if (pam_err != PAM_SUCCESS) + PAM_RETURN(pam_err); + if (user == NULL || (pwd = getpwnam(user)) == NULL) + PAM_RETURN(PAM_SERVICE_ERR); + + PAM_LOG("Got user: %s", user); + + /* If the user is not root, secure ttys do not apply */ + if (pwd->pw_uid != 0) + PAM_RETURN(PAM_SUCCESS); + + pam_err = pam_get_item(pamh, PAM_TTY, (const void **)&tty); + if (pam_err != PAM_SUCCESS) + PAM_RETURN(pam_err); + + PAM_LOG("Got TTY: %s", tty); + + /* Ignore any "/dev/" on the PAM_TTY item */ + if (tty != NULL && strncmp(TTY_PREFIX, tty, sizeof(TTY_PREFIX)) == 0) { + PAM_LOG("WARNING: PAM_TTY starts with " TTY_PREFIX); + tty += sizeof(TTY_PREFIX) - 1; + } + + if (tty != NULL && (ty = getttynam(tty)) != NULL && + (ty->ty_status & TTY_SECURE) != 0) + PAM_RETURN(PAM_SUCCESS); + + PAM_VERBOSE_ERROR("Not on secure TTY"); + PAM_RETURN(PAM_AUTH_ERR); +} + +PAM_EXTERN int +pam_sm_chauthtok(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_open_session(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_close_session(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_MODULE_ENTRY("pam_securetty"); diff --git a/lib/libpam/modules/pam_self/Makefile b/lib/libpam/modules/pam_self/Makefile new file mode 100644 index 0000000..985dd4e --- /dev/null +++ b/lib/libpam/modules/pam_self/Makefile @@ -0,0 +1,32 @@ +# Copyright 2001 Mark R V Murray +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ + +LIB= pam_self +SHLIB_NAME= ${LIB}.so.${SHLIB_MAJOR} +SRCS= pam_self.c +MAN= pam_self.8 + +.include <bsd.lib.mk> diff --git a/lib/libpam/modules/pam_self/pam_self.8 b/lib/libpam/modules/pam_self/pam_self.8 new file mode 100644 index 0000000..0317c23 --- /dev/null +++ b/lib/libpam/modules/pam_self/pam_self.8 @@ -0,0 +1,97 @@ +.\" Copyright (c) 2001 Mark R V Murray +.\" All rights reserved. +.\" Copyright (c) 2001 Networks Associates Technology, Inc. +.\" All rights reserved. +.\" +.\" Portions of this software were developed for the FreeBSD Project by +.\" ThinkSec AS and NAI Labs, the Security Research Division of Network +.\" Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 +.\" ("CBOSS"), as part of the DARPA CHATS research program. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. The name of the author may not be used to endorse or promote +.\" products derived from this software without specific prior written +.\" permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ +.\" +.Dd December 5, 2001 +.Dt PAM_SELF 8 +.Os +.Sh NAME +.Nm pam_self +.Nd Self PAM module +.Sh SYNOPSIS +.Op Ar service-name +.Ar module-type +.Ar control-flag +.Pa pam_self +.Op Ar options +.Sh DESCRIPTION +The Self authentication service module for PAM, +.Nm +provides functionality for only one PAM category: +authentication. +In terms of the +.Ar module-type +parameter, this is the +.Dq Li auth +feature. +It also provides a null function for session management. +.Ss Self Authentication Module +The Self authentication component +.Pq Fn pam_sm_authenticate , +returns success if and only if the target user's user ID is identical +with the current real user ID. +If the current real user ID is non-zero, authentication will fail, +unless the +.Cm even_root +option was specified. +.Pp +The following options may be passed to the authentication module: +.Bl -tag -width ".Cm even_root" +.It Cm debug +.Xr syslog 3 +debugging information at +.Dv LOG_DEBUG +level. +.It Cm no_warn +suppress warning messages to the user. +These messages include reasons why the user's authentication attempt +was declined. +.It Cm even_root +do not automatically fail if the current real user ID is 0. +.El +.Sh SEE ALSO +.Xr getuid 2 , +.Xr pam.conf 5 , +.Xr pam 8 +.Sh AUTHORS +The +.Nm +module and this manual page were developed for the +.Fx +Project by +ThinkSec AS and NAI Labs, the Security Research Division of Network +Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 +.Pq Dq CBOSS , +as part of the DARPA CHATS research program. diff --git a/lib/libpam/modules/pam_self/pam_self.c b/lib/libpam/modules/pam_self/pam_self.c new file mode 100644 index 0000000..ae42ba4 --- /dev/null +++ b/lib/libpam/modules/pam_self/pam_self.c @@ -0,0 +1,155 @@ +/*- + * Copyright (c) 2001 Mark R V Murray + * All rights reserved. + * Copyright (c) 2001 Networks Associates Technology, Inc. + * All rights reserved. + * + * Portions of this software were developed for the FreeBSD Project by + * ThinkSec AS and NAI Labs, the Security Research Division of Network + * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 + * ("CBOSS"), as part of the DARPA CHATS research program. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#define _BSD_SOURCE + +#include <pwd.h> +#include <unistd.h> +#include <syslog.h> + +#define PAM_SM_AUTH +#define PAM_SM_ACCOUNT +#define PAM_SM_SESSION +#define PAM_SM_PASSWORD + +#include <security/pam_appl.h> +#include <security/pam_modules.h> +#include <security/pam_mod_misc.h> + +enum { + PAM_OPT_EVEN_ROOT = PAM_OPT_STD_MAX, +}; + +static struct opttab other_options[] = { + { "even_root", PAM_OPT_EVEN_ROOT }, + { NULL, 0 } +}; + +PAM_EXTERN int +pam_sm_authenticate(pam_handle_t *pamh, int flags __unused, int argc, const char **argv) +{ + struct options options; + struct passwd *pwd; + const char *luser; + int pam_err; + uid_t uid; + + pam_std_option(&options, other_options, argc, argv); + + PAM_LOG("Options processed"); + + pam_err = pam_get_item(pamh, PAM_USER, (const void **)&luser); + if (pam_err != PAM_SUCCESS) + PAM_RETURN(pam_err); + if (luser == NULL || (pwd = getpwnam(luser)) == NULL) + PAM_RETURN(PAM_AUTH_ERR); + + uid = getuid(); + if (uid == 0 && !pam_test_option(&options, PAM_OPT_EVEN_ROOT, NULL)) + PAM_RETURN(PAM_AUTH_ERR); + + if (uid == (uid_t)pwd->pw_uid) + PAM_RETURN(PAM_SUCCESS); + + PAM_VERBOSE_ERROR("Refused; source and target users differ"); + + PAM_RETURN(PAM_AUTH_ERR); +} + +PAM_EXTERN int +pam_sm_setcred(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_SUCCESS); +} + +PAM_EXTERN int +pam_sm_acct_mgmt(pam_handle_t *pamh __unused, int flags __unused, int argc ,const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_chauthtok(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_open_session(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_close_session(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_MODULE_ENTRY("pam_self"); diff --git a/lib/libpam/modules/pam_ssh/Makefile b/lib/libpam/modules/pam_ssh/Makefile new file mode 100644 index 0000000..945bb4c --- /dev/null +++ b/lib/libpam/modules/pam_ssh/Makefile @@ -0,0 +1,14 @@ +# PAM module for SSH +# $FreeBSD$ + +SSHSRC= ${.CURDIR}/../../../../crypto/openssh + +LIB= pam_ssh +SHLIB_NAME= ${LIB}.so.${SHLIB_MAJOR} +SRCS= pam_ssh.c +CFLAGS+= -I${SSHSRC} +DPADD= ${LIBSSH} ${LIBCRYPTO} ${LIBCRYPT} ${LIBUTIL} +LDADD= -lssh -lcrypto -lcrypt -lutil +MAN= pam_ssh.8 + +.include <bsd.lib.mk> diff --git a/lib/libpam/modules/pam_ssh/pam_ssh.8 b/lib/libpam/modules/pam_ssh/pam_ssh.8 new file mode 100644 index 0000000..a932d02 --- /dev/null +++ b/lib/libpam/modules/pam_ssh/pam_ssh.8 @@ -0,0 +1,148 @@ +.\" Copyright (c) 2001 Mark R V Murray +.\" All rights reserved. +.\" Copyright (c) 2001 Networks Associates Technology, Inc. +.\" All rights reserved. +.\" +.\" This software was developed for the FreeBSD Project by ThinkSec AS and +.\" NAI Labs, the Security Research Division of Network Associates, Inc. +.\" under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the +.\" DARPA CHATS research program. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. The name of the author may not be used to endorse or promote +.\" products derived from this software without specific prior written +.\" permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ +.\" +.Dd November 26, 2001 +.Dt PAM_SSH 8 +.Os +.Sh NAME +.Nm pam_ssh +.Nd SSH PAM module +.Sh SYNOPSIS +.Op Ar service-name +.Ar module-type +.Ar control-flag +.Pa pam_ssh +.Op Ar options +.Sh DESCRIPTION +The +SSH +authentication service module for PAM, +.Nm +provides functionality for two PAM categories: +authentication +and session management. +In terms of the +.Ar module-type +parameter, they are the +.Dq Li auth +and +.Dq Li session +features. +It also provides null functions for the remaining categories. +.Ss SSH Authentication Module +The +SSH +authentication component +provides a function to verify the identity of a user +.Pq Fn pam_sm_authenticate , +by prompting the user for a passphrase and verifying that it can +decrypt the target user's SSH key using that passphrase. +.Pp +The following options may be passed to the authentication module: +.Bl -tag -width ".Cm use_first_pass" +.It Cm debug +.Xr syslog 3 +debugging information at +.Dv LOG_DEBUG +level. +.It Cm use_first_pass +If the authentication module +is not the first in the stack, +and a previous module +obtained the user's password, +that password is used +to authenticate the user. +If this fails, +the authentication module returns failure +without prompting the user for a password. +This option has no effect +if the authentication module +is the first in the stack, +or if no previous modules +obtained the user's password. +.It Cm try_first_pass +This option is similar to the +.Cm use_first_pass +option, +except that if the previously obtained password fails, +the user is prompted for another password. +.El +.Ss SSH Session Management Module +The +SSH +session management component +provides functions to initiate +.Pq Fn pam_sm_open_session +and terminate +.Pq Fn pam_sm_close_session +sessions. +The +.Fn pam_sm_open_session +function starts an SSH agent, +passing it any private keys it decrypted +during the authentication phase, +and sets the environment variables +the agent specifies. +The +.Fn pam_sm_close_session +function kills the previously started SSH agent +by sending it a +.Dv SIGTERM . +.Pp +The following options may be passed to the session management module: +.Bl -tag -width ".Cm use_first_pass" +.It Cm debug +.Xr syslog 3 +debugging information at +.Dv LOG_DEBUG +level. +.El +.Sh FILES +.Bl -tag -width ".Pa $HOME/.ssh2/id_dsa_*" -compact +.It Pa $HOME/.ssh/identity +SSH1/OpenSSH RSA key. +.It Pa $HOME/.ssh/id_dsa +OpenSSH DSA key. +.It Pa $HOME/.ssh2/id_rsa_* +SSH2 RSA keys. +.It Pa $HOME/.ssh2/id_dsa_* +SSH2 DSA keys. +.El +.Sh SEE ALSO +.Xr ssh-agent 1 , +.Xr syslog 3 , +.Xr pam.conf 5 , +.Xr pam 8 diff --git a/lib/libpam/modules/pam_ssh/pam_ssh.c b/lib/libpam/modules/pam_ssh/pam_ssh.c new file mode 100644 index 0000000..853bac7 --- /dev/null +++ b/lib/libpam/modules/pam_ssh/pam_ssh.c @@ -0,0 +1,628 @@ +/*- + * Copyright (c) 1999, 2000 Andrew J. Korty + * All rights reserved. + * Copyright (c) 2001 Networks Associates Technology, Inc. + * All rights reserved. + * + * Portions of this software were developed for the FreeBSD Project by + * ThinkSec AS and NAI Labs, the Security Research Division of Network + * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 + * ("CBOSS"), as part of the DARPA CHATS research program. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $Id: pam_ssh.c,v 1.23 2001/08/20 01:44:02 akorty Exp $ + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/stat.h> +#include <sys/wait.h> + +#include <fcntl.h> +#include <pwd.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define PAM_SM_AUTH +#define PAM_SM_ACCOUNT +#define PAM_SM_SESSION +#define PAM_SM_PASSWORD + +#include <security/pam_appl.h> +#include <security/pam_modules.h> +#include <security/pam_mod_misc.h> + +#include <openssl/dsa.h> +#include <openssl/evp.h> + +#include "key.h" +#include "authfd.h" +#include "authfile.h" +#include "log.h" +#include "pam_ssh.h" + +/* + * Generic cleanup function for OpenSSH "Key" type. + */ + +void +key_cleanup(pam_handle_t *pamh, void *data, int error_status) +{ + if (data) + key_free(data); +} + + +/* + * Generic PAM cleanup function for this module. + */ + +void +ssh_cleanup(pam_handle_t *pamh, void *data, int error_status) +{ + if (data) + free(data); +} + + +/* + * Authenticate a user's key by trying to decrypt it with the password + * provided. The key and its comment are then stored for later + * retrieval by the session phase. An increasing index is embedded in + * the PAM variable names so this function may be called multiple times + * for multiple keys. + */ + +static int +auth_via_key(pam_handle_t *pamh, const char *file, const char *dir, + const struct passwd *user, const char *pass) +{ + char *comment; /* private key comment */ + char *data_name; /* PAM state */ + static int index = 0; /* for saved keys */ + Key *key; /* user's key */ + char *path; /* to key files */ + int retval; /* from calls */ + uid_t saved_uid; /* caller's uid */ + + /* locate the user's private key file */ + + if (!asprintf(&path, "%s/%s", dir, file)) { + openpam_log(PAM_LOG_ERROR, "%s: %m", MODULE_NAME); + return PAM_SERVICE_ERR; + } + + saved_uid = getuid(); + + /* Try to decrypt the private key with the passphrase provided. If + success, the user is authenticated. */ + + comment = NULL; + (void) setreuid(user->pw_uid, saved_uid); + key = key_load_private(path, pass, &comment); + (void) setuid(saved_uid); + free(path); + if (!comment) + comment = strdup(file); + if (!key) { + free(comment); + return PAM_AUTH_ERR; + } + + /* save the key and comment to pass to ssh-agent in the session + phase */ + + if (!asprintf(&data_name, "ssh_private_key_%d", index)) { + openpam_log(PAM_LOG_ERROR, "%s: %m", MODULE_NAME); + free(comment); + return PAM_SERVICE_ERR; + } + retval = pam_set_data(pamh, data_name, key, key_cleanup); + free(data_name); + if (retval != PAM_SUCCESS) { + key_free(key); + free(comment); + return retval; + } + if (!asprintf(&data_name, "ssh_key_comment_%d", index)) { + openpam_log(PAM_LOG_ERROR, "%s: %m", MODULE_NAME); + free(comment); + return PAM_SERVICE_ERR; + } + retval = pam_set_data(pamh, data_name, comment, ssh_cleanup); + free(data_name); + if (retval != PAM_SUCCESS) { + free(comment); + return retval; + } + + ++index; + return PAM_SUCCESS; +} + + +/* + * Add the keys stored by auth_via_key() to the agent connected to the + * socket provided. + */ + +static int +add_keys(pam_handle_t *pamh, char *socket) +{ + AuthenticationConnection *ac; /* connection to ssh-agent */ + char *comment; /* private key comment */ + char *data_name; /* PAM state */ + int final; /* final return value */ + int index; /* for saved keys */ + Key *key; /* user's private key */ + int retval; /* from calls */ + + /* + * Connect to the agent. + * + * XXX Because ssh_get_authentication_connection() gets the + * XXX agent parameters from the environment, we have to + * XXX temporarily replace the environment with the PAM + * XXX environment list. This is a hack. + */ + { + extern char **environ; + char **saved, **evp; + + saved = environ; + if ((environ = pam_getenvlist(pamh)) == NULL) { + environ = saved; + openpam_log(PAM_LOG_ERROR, "%s: %m", MODULE_NAME); + return (PAM_BUF_ERR); + } + ac = ssh_get_authentication_connection(); + for (evp = environ; *evp; evp++) + free(*evp); + free(environ); + environ = saved; + } + if (!ac) { + openpam_log(PAM_LOG_ERROR, "%s: %s: %m", MODULE_NAME, socket); + return PAM_SESSION_ERR; + } + + /* hand off each private key to the agent */ + + final = 0; + for (index = 0; ; index++) { + if (!asprintf(&data_name, "ssh_private_key_%d", index)) { + openpam_log(PAM_LOG_ERROR, "%s: %m", MODULE_NAME); + ssh_close_authentication_connection(ac); + return PAM_SERVICE_ERR; + } + retval = pam_get_data(pamh, data_name, (const void **)&key); + free(data_name); + if (retval != PAM_SUCCESS) + break; + if (!asprintf(&data_name, "ssh_key_comment_%d", index)) { + openpam_log(PAM_LOG_ERROR, "%s: %m", MODULE_NAME); + ssh_close_authentication_connection(ac); + return PAM_SERVICE_ERR; + } + retval = pam_get_data(pamh, data_name, + (const void **)&comment); + free(data_name); + if (retval != PAM_SUCCESS) + break; + retval = ssh_add_identity(ac, key, comment); + if (!final) + final = retval; + } + ssh_close_authentication_connection(ac); + + return final ? PAM_SUCCESS : PAM_SESSION_ERR; +} + + +PAM_EXTERN int +pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, + const char **argv) +{ + int authenticated; /* user authenticated? */ + char *dotdir; /* .ssh dir name */ + char *file; /* current key file */ + char *keyfiles; /* list of key files to add */ + int options; /* options for pam_get_pass() */ + const char *pass; /* passphrase */ + const struct passwd *pwent; /* user's passwd entry */ + struct passwd *pwent_keep; /* our own copy */ + int retval; /* from calls */ + const char *user; /* username */ + + keyfiles = DEF_KEYFILES; + options = 0; + for (; argc; argc--, argv++) + if (strncmp(*argv, OPT_KEYFILES "=", sizeof OPT_KEYFILES) + == 0) { + if (!(keyfiles = strchr(*argv, '=') + 1)) + return PAM_AUTH_ERR; + } else if (strcmp(*argv, OPT_TRY_FIRST_PASS) == 0) + options |= PAM_OPT_TRY_FIRST_PASS; + else if (strcmp(*argv, OPT_USE_FIRST_PASS) == 0) + options |= PAM_OPT_USE_FIRST_PASS; + + + if ((retval = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS) + return retval; + if (!((pwent = getpwnam(user)) && pwent->pw_dir)) + return PAM_AUTH_ERR; + + /* pass prompt message to application and receive passphrase */ + + if ((retval = pam_get_authtok(pamh, &pass, NEED_PASSPHRASE)) + != PAM_SUCCESS) + return retval; + + OpenSSL_add_all_algorithms(); /* required for DSA */ + + /* any key will authenticate us, but if we can decrypt all of the + specified keys, we'll do so here so we can cache them in the + session phase */ + + if (!asprintf(&dotdir, "%s/%s", pwent->pw_dir, SSH_CLIENT_DIR)) { + openpam_log(PAM_LOG_ERROR, "%s: %m", MODULE_NAME); + return PAM_SERVICE_ERR; + } + authenticated = 0; + keyfiles = strdup(keyfiles); + for (file = strtok(keyfiles, SEP_KEYFILES); file; + file = strtok(NULL, SEP_KEYFILES)) + if (auth_via_key(pamh, file, dotdir, pwent, pass) == + PAM_SUCCESS) + authenticated++; + free(dotdir); + free(keyfiles); + if (!authenticated) + return PAM_AUTH_ERR; + + /* copy the passwd entry (in case successive calls are made) and + save it for the session phase */ + + if (!(pwent_keep = malloc(sizeof *pwent))) { + openpam_log(PAM_LOG_ERROR, "%m"); + return PAM_SERVICE_ERR; + } + (void) memcpy(pwent_keep, pwent, sizeof *pwent_keep); + if ((retval = pam_set_data(pamh, "ssh_passwd_entry", pwent_keep, + ssh_cleanup)) != PAM_SUCCESS) { + free(pwent_keep); + return retval; + } + + return PAM_SUCCESS; +} + + +PAM_EXTERN int +pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) +{ + return PAM_SUCCESS; +} + + +PAM_EXTERN int +pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, + const char **argv) +{ + char *agent_socket; /* agent socket */ + char *env_end; /* end of env */ + FILE *env_read; /* env data source */ + char env_string[BUFSIZ]; /* environment string */ + char *env_value; /* envariable value */ + int env_write; /* env file descriptor */ + char hname[MAXHOSTNAMELEN]; /* local hostname */ + int no_link; /* link per-agent file? */ + char *per_agent; /* to store env */ + char *per_session; /* per-session filename */ + char *agent_pid; /* agent pid */ + const struct passwd *pwent; /* user's passwd entry */ + int retval; /* from calls */ + uid_t saved_uid; /* caller's uid */ + int start_agent; /* start agent? */ + const char *tty; /* tty or display name */ + + /* dump output of ssh-agent in ~/.ssh */ + if ((retval = pam_get_data(pamh, "ssh_passwd_entry", + (const void **)&pwent)) != PAM_SUCCESS) + return retval; + + /* + * Use reference counts to limit agents to one per user per host. + * + * Technique: Create an environment file containing + * information about the agent. Only one file is created, but + * it may be given many names. One name is given for the + * agent itself, agent-<host>. Another name is given for each + * session, agent-<host>-<display> or agent-<host>-<tty>. We + * delete the per-session filename on session close, and when + * the link count goes to unity on the per-agent file, we + * delete the file and kill the agent. + */ + + /* the per-agent file contains just the hostname */ + + (void) gethostname(hname, sizeof hname); + if (asprintf(&per_agent, "%s/.ssh/agent-%s", pwent->pw_dir, hname) + == -1) { + openpam_log(PAM_LOG_ERROR, "%s: %m", MODULE_NAME); + return PAM_SERVICE_ERR; + } + + /* save the per-agent filename in case we want to delete it on + session close */ + + if ((retval = pam_set_data(pamh, "ssh_agent_env_agent", per_agent, + ssh_cleanup)) != PAM_SUCCESS) { + free(per_agent); + return retval; + } + + /* take on the user's privileges for writing files and starting the + agent */ + + saved_uid = geteuid(); + (void) seteuid(pwent->pw_uid); + + /* Try to create the per-agent file or open it for reading if it + exists. If we can't do either, we won't try to link a + per-session filename later. Start the agent if we can't open + the file for reading. */ + + env_write = no_link = 0; + env_read = NULL; + if ((env_write = open(per_agent, O_CREAT | O_EXCL | O_WRONLY, + S_IRUSR)) < 0 && !(env_read = fopen(per_agent, "r"))) + no_link = 1; + if (env_read) { + start_agent = 0; + (void) seteuid(saved_uid); + } else { + start_agent = 1; + env_read = popen(SSH_AGENT, "r"); + (void) seteuid(saved_uid); + if (!env_read) { + openpam_log(PAM_LOG_ERROR, "%s: %s: %m", MODULE_NAME, + SSH_AGENT); + if (env_write >= 0) + (void) close(env_write); + return PAM_SESSION_ERR; + } + } + + /* save environment for application with pam_putenv() */ + + agent_socket = NULL; + while (fgets(env_string, sizeof env_string, env_read)) { + + /* parse environment definitions */ + + if (env_write >= 0) + (void) write(env_write, env_string, + strlen(env_string)); + if (!(env_value = strchr(env_string, '=')) || + !(env_end = strchr(env_value, ';'))) + continue; + *env_end = '\0'; + + /* pass to the application */ + + if (!((retval = pam_putenv(pamh, env_string)) == + PAM_SUCCESS)) { + if (start_agent) + (void) pclose(env_read); + else + (void) fclose(env_read); + if (env_write >= 0) + (void) close(env_write); + if (agent_socket) + free(agent_socket); + return PAM_SERVICE_ERR; + } + + *env_value++ = '\0'; + + /* save the agent socket so we can connect to it and add + the keys as well as the PID so we can kill the agent on + session close. */ + + if (strcmp(&env_string[strlen(env_string) - + strlen(ENV_SOCKET_SUFFIX)], ENV_SOCKET_SUFFIX) == 0 && + !(agent_socket = strdup(env_value))) { + openpam_log(PAM_LOG_ERROR, "%s: %m", MODULE_NAME); + if (start_agent) + (void) pclose(env_read); + else + (void) fclose(env_read); + if (env_write >= 0) + (void) close(env_write); + if (agent_socket) + free(agent_socket); + return PAM_SERVICE_ERR; + } else if (strcmp(&env_string[strlen(env_string) - + strlen(ENV_PID_SUFFIX)], ENV_PID_SUFFIX) == 0 && + ((agent_pid = strdup(env_value)) == NULL || + (retval = pam_set_data(pamh, "ssh_agent_pid", + agent_pid, ssh_cleanup)) != PAM_SUCCESS)) { + if (start_agent) + (void) pclose(env_read); + else + (void) fclose(env_read); + if (env_write >= 0) + (void) close(env_write); + if (agent_socket) + free(agent_socket); + if (agent_pid) + free(agent_pid); + return retval; + } + + } + if (env_write >= 0) + (void) close(env_write); + + if (start_agent) { + switch (retval = pclose(env_read)) { + case -1: + openpam_log(PAM_LOG_ERROR, "%s: %s: %m", MODULE_NAME, + SSH_AGENT); + if (agent_socket) + free(agent_socket); + return PAM_SESSION_ERR; + case 0: + break; + case 127: + openpam_log(PAM_LOG_ERROR, "%s: cannot execute %s", + MODULE_NAME, SSH_AGENT); + if (agent_socket) + free(agent_socket); + return PAM_SESSION_ERR; + default: + openpam_log(PAM_LOG_ERROR, "%s: %s exited %s %d", + MODULE_NAME, + SSH_AGENT, WIFSIGNALED(retval) ? "on signal" : + "with status", WIFSIGNALED(retval) ? + WTERMSIG(retval) : WEXITSTATUS(retval)); + if (agent_socket) + free(agent_socket); + return PAM_SESSION_ERR; + } + } else + (void) fclose(env_read); + + if (!agent_socket) + return PAM_SESSION_ERR; + + if (start_agent && (retval = add_keys(pamh, agent_socket)) + != PAM_SUCCESS) + return retval; + free(agent_socket); + + /* if we couldn't access the per-agent file, don't link a + per-session filename to it */ + + if (no_link) + return PAM_SUCCESS; + + /* the per-session file contains the display name or tty name as + well as the hostname */ + + if ((retval = pam_get_item(pamh, PAM_TTY, (const void **)&tty)) + != PAM_SUCCESS) + return retval; + if (asprintf(&per_session, "%s/.ssh/agent-%s-%s", pwent->pw_dir, + hname, tty) == -1) { + openpam_log(PAM_LOG_ERROR, "%s: %m", MODULE_NAME); + return PAM_SERVICE_ERR; + } + + /* save the per-session filename so we can delete it on session + close */ + + if ((retval = pam_set_data(pamh, "ssh_agent_env_session", + per_session, ssh_cleanup)) != PAM_SUCCESS) { + free(per_session); + return retval; + } + + (void) unlink(per_session); /* remove cruft */ + (void) link(per_agent, per_session); + + return PAM_SUCCESS; +} + + +PAM_EXTERN int +pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, + const char **argv) +{ + const char *env_file; /* ssh-agent environment */ + pid_t pid; /* ssh-agent process id */ + int retval; /* from calls */ + const char *ssh_agent_pid; /* ssh-agent pid string */ + struct stat sb; /* to check st_nlink */ + + if ((retval = pam_get_data(pamh, "ssh_agent_env_session", + (const void **)&env_file)) == PAM_SUCCESS && env_file) + (void) unlink(env_file); + + /* Retrieve per-agent filename and check link count. If it's + greater than unity, other sessions are still using this + agent. */ + + if ((retval = pam_get_data(pamh, "ssh_agent_env_agent", + (const void **)&env_file)) == PAM_SUCCESS && env_file && + stat(env_file, &sb) == 0) { + if (sb.st_nlink > 1) + return PAM_SUCCESS; + (void) unlink(env_file); + } + + /* retrieve the agent's process id */ + + if ((retval = pam_get_data(pamh, "ssh_agent_pid", + (const void **)&ssh_agent_pid)) != PAM_SUCCESS) + return retval; + + /* Kill the agent. SSH's ssh-agent does not have a -k option, so + just call kill(). */ + + pid = atoi(ssh_agent_pid); + if (ssh_agent_pid <= 0) + return PAM_SESSION_ERR; + if (kill(pid, SIGTERM) != 0) { + openpam_log(PAM_LOG_ERROR, "%s: %s: %m", MODULE_NAME, + ssh_agent_pid); + return PAM_SESSION_ERR; + } + + return PAM_SUCCESS; +} + +PAM_EXTERN int +pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, + const char **argv) +{ + return (PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, + const char **argv) +{ + return (PAM_IGNORE); +} + +PAM_MODULE_ENTRY(MODULE_NAME); diff --git a/lib/libpam/modules/pam_ssh/pam_ssh.h b/lib/libpam/modules/pam_ssh/pam_ssh.h new file mode 100644 index 0000000..19a99ec --- /dev/null +++ b/lib/libpam/modules/pam_ssh/pam_ssh.h @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 1999, 2000 Andrew J. Korty + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 SSH_CLIENT_DIR ".ssh" + +#define MODULE_NAME "pam_ssh" +#define NEED_PASSPHRASE "SSH passphrase: " +#define SSH_AGENT "ssh-agent" + +#define ENV_PID_SUFFIX "_AGENT_PID" +#define ENV_SOCKET_SUFFIX "_AUTH_SOCK" + +#define DEF_KEYFILES "id_dsa,id_rsa,identity" + +#define OPT_KEYFILES "keyfiles" +#define OPT_TRY_FIRST_PASS "try_first_pass" +#define OPT_USE_FIRST_PASS "use_first_pass" + +#define SEP_KEYFILES "," diff --git a/lib/libpam/modules/pam_tacplus/Makefile b/lib/libpam/modules/pam_tacplus/Makefile new file mode 100644 index 0000000..5c5deb5 --- /dev/null +++ b/lib/libpam/modules/pam_tacplus/Makefile @@ -0,0 +1,34 @@ +# Copyright 1998 Juniper Networks, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ + +LIB= pam_tacplus +SHLIB_NAME= ${LIB}.so.${SHLIB_MAJOR} +SRCS= pam_tacplus.c +DPADD= ${LIBTACPLUS} +LDADD= -ltacplus +MAN= pam_tacplus.8 + +.include <bsd.lib.mk> diff --git a/lib/libpam/modules/pam_tacplus/pam_tacplus.8 b/lib/libpam/modules/pam_tacplus/pam_tacplus.8 new file mode 100644 index 0000000..5ad7f07 --- /dev/null +++ b/lib/libpam/modules/pam_tacplus/pam_tacplus.8 @@ -0,0 +1,130 @@ +.\" Copyright (c) 1999 +.\" Andrzej Bialecki <abial@FreeBSD.org>. All rights reserved. +.\" +.\" Copyright (c) 1992, 1993, 1994 +.\" The Regents of the University of California. All rights reserved. +.\" All rights reserved. +.\" +.\" This code is derived from software donated to Berkeley by +.\" Jan-Simon Pendry. +.\" +.\" 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$ +.\" +.Dd August 2, 1999 +.Dt PAM_TACPLUS 8 +.Os +.Sh NAME +.Nm pam_tacplus +.Nd TACACS+ authentication PAM module +.Sh SYNOPSIS +.Op Ar service-name +.Ar module-type +.Ar control-flag +.Pa pam_tacplus +.Op Ar options +.Sh DESCRIPTION +The +.Nm +module provides authentication services based +upon the TACACS+ protocol +for the PAM (Pluggable Authentication Module) framework. +.Pp +The +.Nm +module accepts these optional parameters: +.Bl -tag -width ".Cm use_first_pass" +.It Cm use_first_pass +causes +.Nm +to use a previously entered password instead of prompting for a new one. +If no password has been entered then authentication fails. +.It Cm try_first_pass +causes +.Nm +to use a previously entered password, if one is available. +If no +password has been entered, +.Nm +prompts for one as usual. +.It Cm echo_pass +causes echoing to be left on if +.Nm +prompts for a password. +.It Cm conf Ns = Ns Ar pathname +specifies a non-standard location for the TACACS+ client configuration file +(normally located in +.Pa /etc/tacplus.conf ) . +.It Cm template_user Ns = Ns Ar username +specifies a user whose +.Xr passwd 5 +entry will be used as a template to create the session environment +if the supplied username does not exist in local password database. +The user +will be authenticated with the supplied username and password, but his +credentials to the system will be presented as the ones for +.Ar username , +i.e., his login class, home directory, resource limits, etc. will be set to ones +defined for +.Ar username . +.Pp +If this option is omitted, and there is no username +in the system databases equal to the supplied one (as determined by call to +.Xr getpwnam 3 ) , +the authentication will fail. +.El +.Sh FILES +.Bl -tag -width /etc/tacplus.conf -compact +.It Pa /etc/tacplus.conf +The standard TACACS+ client configuration file for +.Nm +.El +.Sh SEE ALSO +.Xr passwd 5 , +.Xr tacplus.conf 5 , +.Xr pam 8 +.Sh HISTORY +The +.Nm +module first appeared in +.Fx 3.1 . +.Sh AUTHORS +.An -nosplit +The +.Nm +manual page was written by +.An Andrzej Bialecki Aq abial@FreeBSD.org +and adapted to TACACS+ from RADIUS by +.An Mark R V Murray Aq markm@FreeBSD.org . +.Pp +The +.Nm +module was written by +.An John D. Polstra Aq jdp@FreeBSD.org . diff --git a/lib/libpam/modules/pam_tacplus/pam_tacplus.c b/lib/libpam/modules/pam_tacplus/pam_tacplus.c new file mode 100644 index 0000000..05e98cc --- /dev/null +++ b/lib/libpam/modules/pam_tacplus/pam_tacplus.c @@ -0,0 +1,351 @@ +/*- + * Copyright 1998 Juniper Networks, Inc. + * All rights reserved. + * Copyright (c) 2001 Networks Associates Technology, Inc. + * All rights reserved. + * + * Portions of this software were developed for the FreeBSD Project by + * ThinkSec AS and NAI Labs, the Security Research Division of Network + * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 + * ("CBOSS"), as part of the DARPA CHATS research program. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> + +#include <pwd.h> +#include <stdlib.h> +#include <string.h> +#include <syslog.h> +#include <taclib.h> +#include <unistd.h> + +#define PAM_SM_AUTH +#define PAM_SM_ACCOUNT +#define PAM_SM_SESSION +#define PAM_SM_PASSWORD + +#include <security/pam_appl.h> +#include <security/pam_modules.h> +#include <security/pam_mod_misc.h> + +enum { PAM_OPT_CONF=PAM_OPT_STD_MAX, PAM_OPT_TEMPLATE_USER }; + +static struct opttab other_options[] = { + { "conf", PAM_OPT_CONF }, + { "template_user", PAM_OPT_TEMPLATE_USER }, + { NULL, 0 } +}; + +typedef int (*set_func)(struct tac_handle *, const char *); + +static int do_item(pam_handle_t *, struct tac_handle *, int, + set_func, const char *); +static char *get_msg(struct tac_handle *); +static int set_msg(struct tac_handle *, const char *); + +static int +do_item(pam_handle_t *pamh, struct tac_handle *tach, int item, + set_func func, const char *funcname) +{ + int retval; + const void *value; + + retval = pam_get_item(pamh, item, &value); + if (retval != PAM_SUCCESS) + return retval; + if (value != NULL && (*func)(tach, (const char *)value) == -1) { + syslog(LOG_CRIT, "%s: %s", funcname, tac_strerror(tach)); + tac_close(tach); + return PAM_SERVICE_ERR; + } + return PAM_SUCCESS; +} + +static char * +get_msg(struct tac_handle *tach) +{ + char *msg; + + msg = tac_get_msg(tach); + if (msg == NULL) { + syslog(LOG_CRIT, "tac_get_msg: %s", tac_strerror(tach)); + tac_close(tach); + return NULL; + } + return msg; +} + +static int +set_msg(struct tac_handle *tach, const char *msg) +{ + if (tac_set_msg(tach, msg) == -1) { + syslog(LOG_CRIT, "tac_set_msg: %s", tac_strerror(tach)); + tac_close(tach); + return -1; + } + return 0; +} + +PAM_EXTERN int +pam_sm_authenticate(pam_handle_t *pamh, int flags __unused, int argc, + const char **argv) +{ + struct options options; + int retval; + struct tac_handle *tach; + char *conf_file; + char *template_user; + + pam_std_option(&options, other_options, argc, argv); + + PAM_LOG("Options processed"); + + conf_file = NULL; + pam_test_option(&options, PAM_OPT_CONF, &conf_file); + template_user = NULL; + pam_test_option(&options, PAM_OPT_TEMPLATE_USER, &template_user); + + tach = tac_open(); + if (tach == NULL) { + syslog(LOG_CRIT, "tac_open failed"); + PAM_RETURN(PAM_SERVICE_ERR); + } + if (tac_config(tach, conf_file) == -1) { + syslog(LOG_ALERT, "tac_config: %s", tac_strerror(tach)); + tac_close(tach); + PAM_RETURN(PAM_SERVICE_ERR); + } + if (tac_create_authen(tach, TAC_AUTHEN_LOGIN, TAC_AUTHEN_TYPE_ASCII, + TAC_AUTHEN_SVC_LOGIN) == -1) { + syslog(LOG_CRIT, "tac_create_authen: %s", tac_strerror(tach)); + tac_close(tach); + PAM_RETURN(PAM_SERVICE_ERR); + } + + PAM_LOG("Done tac_open() ... tac_close()"); + + retval = do_item(pamh, tach, PAM_USER, tac_set_user, "tac_set_user"); + if (retval != PAM_SUCCESS) + PAM_RETURN(retval); + + PAM_LOG("Done user"); + + retval = do_item(pamh, tach, PAM_TTY, tac_set_port, "tac_set_port"); + if (retval != PAM_SUCCESS) + PAM_RETURN(retval); + + PAM_LOG("Done tty"); + + retval = do_item(pamh, tach, PAM_RHOST, tac_set_rem_addr, + "tac_set_rem_addr"); + if (retval != PAM_SUCCESS) + PAM_RETURN(retval); + + for ( ; ; ) { + char *srvr_msg; + size_t msg_len; + const char *user_msg; + char *data_msg; + int sflags; + int status; + + sflags = tac_send_authen(tach); + if (sflags == -1) { + syslog(LOG_CRIT, "tac_send_authen: %s", + tac_strerror(tach)); + tac_close(tach); + PAM_RETURN(PAM_AUTHINFO_UNAVAIL); + } + status = TAC_AUTHEN_STATUS(sflags); + if (!TAC_AUTHEN_NOECHO(sflags)) + pam_set_option(&options, PAM_OPT_ECHO_PASS); + switch (status) { + + case TAC_AUTHEN_STATUS_PASS: + tac_close(tach); + if (template_user != NULL) { + const void *item; + const char *user; + + PAM_LOG("Trying template user: %s", + template_user); + + /* + * If the given user name doesn't exist in + * the local password database, change it + * to the value given in the "template_user" + * option. + */ + retval = pam_get_item(pamh, PAM_USER, &item); + if (retval != PAM_SUCCESS) + PAM_RETURN(retval); + user = (const char *)item; + if (getpwnam(user) == NULL) { + pam_set_item(pamh, PAM_USER, + template_user); + PAM_LOG("Using template user"); + } + } + PAM_RETURN(PAM_SUCCESS); + + case TAC_AUTHEN_STATUS_FAIL: + tac_close(tach); + PAM_VERBOSE_ERROR("TACACS+ authentication failed"); + PAM_RETURN(PAM_AUTH_ERR); + + case TAC_AUTHEN_STATUS_GETUSER: + case TAC_AUTHEN_STATUS_GETPASS: + if ((srvr_msg = get_msg(tach)) == NULL) + PAM_RETURN(PAM_SERVICE_ERR); + if (status == TAC_AUTHEN_STATUS_GETUSER) + retval = pam_get_user(pamh, &user_msg, + srvr_msg[0] != '\0' ? srvr_msg : NULL); + else if (status == TAC_AUTHEN_STATUS_GETPASS) + retval = pam_get_authtok(pamh, &user_msg, + srvr_msg[0] != '\0' ? srvr_msg : + "Password:"); + free(srvr_msg); + if (retval != PAM_SUCCESS) { + /* XXX - send a TACACS+ abort packet */ + tac_close(tach); + PAM_RETURN(retval); + } + if (set_msg(tach, user_msg) == -1) + PAM_RETURN(PAM_SERVICE_ERR); + break; + + case TAC_AUTHEN_STATUS_GETDATA: + if ((srvr_msg = get_msg(tach)) == NULL) + PAM_RETURN(PAM_SERVICE_ERR); + retval = pam_prompt(pamh, + pam_test_option(&options, PAM_OPT_ECHO_PASS, NULL) + ? PAM_PROMPT_ECHO_ON : PAM_PROMPT_ECHO_OFF, + &data_msg, + "%s", + srvr_msg[0] != '\0' ? srvr_msg : "Data:"); + free(srvr_msg); + if (retval != PAM_SUCCESS) { + /* XXX - send a TACACS+ abort packet */ + tac_close(tach); + PAM_RETURN(retval); + } + retval = set_msg(tach, data_msg); + memset(data_msg, 0, strlen(data_msg)); + free(data_msg); + if (retval == -1) + PAM_RETURN(PAM_SERVICE_ERR); + break; + + case TAC_AUTHEN_STATUS_ERROR: + srvr_msg = (char *)tac_get_data(tach, &msg_len); + if (srvr_msg != NULL && msg_len != 0) { + syslog(LOG_CRIT, "tac_send_authen:" + " server detected error: %s", srvr_msg); + free(srvr_msg); + } + else + syslog(LOG_CRIT, + "tac_send_authen: server detected error"); + tac_close(tach); + PAM_RETURN(PAM_AUTHINFO_UNAVAIL); + break; + + case TAC_AUTHEN_STATUS_RESTART: + case TAC_AUTHEN_STATUS_FOLLOW: + default: + syslog(LOG_CRIT, + "tac_send_authen: unexpected status %#x", status); + tac_close(tach); + PAM_RETURN(PAM_AUTHINFO_UNAVAIL); + } + } +} + +PAM_EXTERN int +pam_sm_setcred(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_acct_mgmt(pam_handle_t *pamh __unused, int flags __unused, int argc ,const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_chauthtok(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_open_session(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_close_session(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_MODULE_ENTRY("pam_tacplus"); diff --git a/lib/libpam/modules/pam_unix/Makefile b/lib/libpam/modules/pam_unix/Makefile new file mode 100644 index 0000000..d4a14c9 --- /dev/null +++ b/lib/libpam/modules/pam_unix/Makefile @@ -0,0 +1,79 @@ +# Copyright 1998 Juniper Networks, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ + +LIB= pam_unix +SHLIB_NAME= ${LIB}.so.${SHLIB_MAJOR} +SRCS= pam_unix.c pw_copy.c pw_yp.c pw_util.c ypxfr_misc.c ${GENSRCS} +CFLAGS+= -DYP -Dyp_error=warnx \ + -I${.OBJDIR} \ + -I${.CURDIR}/../../../../libexec/ypxfr \ + -I${.CURDIR}/../../../../usr.sbin/vipw \ + -I${.CURDIR}/../../../../usr.bin/chpass \ + -I${.CURDIR}/../../../../lib/libc/gen +DPADD= ${LIBUTIL} ${LIBCRYPT} ${LIBRPCSVC} +LDADD= -lutil -lcrypt -lrpcsvc +MAN= pam_unix.8 + +GENSRCS=yp.h yp_clnt.c yppasswd.h yppasswd_clnt.c \ + yppasswd_private.h yppasswd_private_clnt.c yppasswd_private_xdr.c + +RPCGEN= rpcgen -C +RPCSRC= ${DESTDIR}/usr/include/rpcsvc/yp.x +RPCSRC_PW= ${DESTDIR}/usr/include/rpcsvc/yppasswd.x +RPCSRC_PRIV= ${.CURDIR}/../../../../usr.sbin/rpc.yppasswdd/yppasswd_private.x + +yp.h: ${RPCSRC} + ${RPCGEN} -h -o ${.TARGET} ${RPCSRC} + +yp_clnt.c: ${RPCSRC} yp.h + ${RPCGEN} -l -o ${.TARGET} ${RPCSRC} + +yppasswd.h: ${RPCSRC_PW} + ${RPCGEN} -h -o ${.TARGET} ${RPCSRC_PW} + +yppasswd_clnt.c: ${RPCSRC_PW} + ${RPCGEN} -l -o ${.TARGET} ${RPCSRC_PW} + +yppasswd_private.h: ${RPCSRC_PRIV} + ${RPCGEN} -h -o ${.TARGET} ${RPCSRC_PRIV} + +yppasswd_private_xdr.c: ${RPCSRC_PRIV} + ${RPCGEN} -c -o ${.TARGET} ${RPCSRC_PRIV} + +yppasswd_private_clnt.c: ${RPCSRC_PRIV} + ${RPCGEN} -l -o ${.TARGET} ${RPCSRC_PRIV} + + +yppasswd_private.h: ${RPCSRC_PRIV} + ${RPCGEN} -h -o ${.TARGET} ${RPCSRC_PRIV} + +CLEANFILES= ${GENSRCS} + +.include <bsd.lib.mk> + +.PATH: ${.CURDIR}/../../../../usr.bin/chpass +.PATH: ${.CURDIR}/../../../../usr.sbin/vipw +.PATH: ${.CURDIR}/../../../../libexec/ypxfr diff --git a/lib/libpam/modules/pam_unix/pam_unix.8 b/lib/libpam/modules/pam_unix/pam_unix.8 new file mode 100644 index 0000000..f8e5e0e --- /dev/null +++ b/lib/libpam/modules/pam_unix/pam_unix.8 @@ -0,0 +1,202 @@ +.\" Copyright (c) 2001 Mark R V Murray +.\" All rights reserved. +.\" Copyright (c) 2001 Networks Associates Technology, Inc. +.\" All rights reserved. +.\" +.\" This software was developed for the FreeBSD Project by ThinkSec AS and +.\" NAI Labs, the Security Research Division of Network Associates, Inc. +.\" under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the +.\" DARPA CHATS research program. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. The name of the author may not be used to endorse or promote +.\" products derived from this software without specific prior written +.\" permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ +.\" +.Dd November 26, 2001 +.Dt PAM_UNIX 8 +.Os +.Sh NAME +.Nm pam_unix +.Nd UNIX PAM module +.Sh SYNOPSIS +.Op Ar service-name +.Ar module-type +.Ar control-flag +.Pa pam_unix +.Op Ar options +.Sh DESCRIPTION +The +.Ux +authentication service module for PAM, +.Nm +provides functionality for two PAM categories: +authentication +and account management. +In terms of the +.Ar module-type +parameter, they are the +.Dq Li auth +and +.Dq Li account +features. +It also provides a null function for session management. +.Ss Ux Ss Authentication Module +The +.Ux +authentication component +provides functions to verify the identity of a user +.Pq Fn pam_sm_authenticate , +which obtains the relevant +.Xr passwd 5 +entry. +It prompts the user for a password +and verifies that this is correct with +.Xr crypt 3 . +.Pp +The following options may be passed to the authentication module: +.Bl -tag -width ".Cm use_first_pass" +.It Cm debug +.Xr syslog 3 +debugging information at +.Dv LOG_DEBUG +level. +.It Cm use_first_pass +If the authentication module +is not the first in the stack, +and a previous module +obtained the user's password, +that password is used +to authenticate the user. +If this fails, +the authentication module returns failure +without prompting the user for a password. +This option has no effect +if the authentication module +is the first in the stack, +or if no previous modules +obtained the user's password. +.It Cm try_first_pass +This option is similar to the +.Cm use_first_pass +option, +except that if the previously obtained password fails, +the user is prompted for another password. +.It Cm auth_as_self +This option will require the user +to authenticate themself as the user +given by +.Xr getlogin 2 , +not as the account they are attempting to access. +This is primarily for services like +.Xr su 1 , +where the user's ability to retype +their own password +might be deemed sufficient. +.It Cm nullok +If the password database +has no password +for the entity being authenticated, +then this option +will forgo password prompting, +and silently allow authentication to succeed. +.It Cm local_pass +Use only the local password database, +even if NIS is in use. +This will cause an authentication failure +if the system is configured +to only use NIS. +.It Cm nis_pass +Use only the NIS password database. +This will cause an authentication failure +if the system is not configured +to use NIS. +.El +.Ss Ux Ss Account Management Module +The +.Ux +account management component +provides a function to perform account management, +.Fn pam_sm_acct_mgmt . +The function verifies +that the authenticated user +is allowed to login to the local user account +by checking the password expiry date. +.Pp +The following options may be passed to the management module: +.Bl -tag -width ".Cm use_first_pass" +.It Cm debug +.Xr syslog 3 +debugging information at +.Dv LOG_DEBUG +level. +.El +.Ss Ux Ss Password Management Module +The +.Ux +password management component +provides a function to perform account management, +.Fn pam_sm_chauthtok . +The function changes +the user's password. +.Pp +The following options may be passed to the password module: +.Bl -tag -width ".Cm use_first_pass" +.It Cm debug +.Xr syslog 3 +debugging information at +.Dv LOG_DEBUG +level. +.It Cm no_warn +suppress warning messages to the user. +These messages include +reasons why the user's +authentication attempt was declined. +.It Cm local_pass +forces the password module +to change a local password +in favour of a NIS one. +.It Cm nis_pass +forces the password module +to change a NIS password +in favour of a local one. +.El +.Sh FILES +.Bl -tag -width ".Pa /etc/master.passwd" -compact +.It Pa /etc/master.passwd +default +.Ux +password database. +.El +.Sh SEE ALSO +.Xr passwd 1 , +.Xr getlogin 2 , +.Xr crypt 3 , +.Xr getpwent 3 , +.Xr syslog 3 , +.Xr nis 4 , +.Xr nsswitch.conf 5 , +.Xr pam.conf 5 , +.Xr passwd 5 , +.Xr pam 8 diff --git a/lib/libpam/modules/pam_unix/pam_unix.c b/lib/libpam/modules/pam_unix/pam_unix.c new file mode 100644 index 0000000..09910a6 --- /dev/null +++ b/lib/libpam/modules/pam_unix/pam_unix.c @@ -0,0 +1,731 @@ +/*- + * Copyright 1998 Juniper Networks, Inc. + * All rights reserved. + * Copyright (c) 2002 Networks Associates Technology, Inc. + * All rights reserved. + * + * Portions of this software was developed for the FreeBSD Project by + * ThinkSec AS and NAI Labs, the Security Research Division of Network + * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 + * ("CBOSS"), as part of the DARPA CHATS research program. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/socket.h> +#include <sys/time.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#ifdef YP +#include <rpc/rpc.h> +#include <rpcsvc/yp_prot.h> +#include <rpcsvc/ypclnt.h> +#include <rpcsvc/yppasswd.h> +#endif + +#include <login_cap.h> +#include <netdb.h> +#include <pwd.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <syslog.h> +#include <unistd.h> + +#include <pw_copy.h> +#include <pw_util.h> + +#ifdef YP +#include <pw_yp.h> +#include "yppasswd_private.h" +#endif + +#define PAM_SM_AUTH +#define PAM_SM_ACCOUNT +#define PAM_SM_SESSION +#define PAM_SM_PASSWORD + +#include <security/pam_appl.h> +#include <security/pam_modules.h> +#include <security/pam_mod_misc.h> + +#define USER_PROMPT "Username: " +#define PASSWORD_PROMPT "Password:" +#define PASSWORD_PROMPT_EXPIRED "\nPassword expired\nOld Password:" +#define NEW_PASSWORD_PROMPT_1 "New Password:" +#define NEW_PASSWORD_PROMPT_2 "New Password (again):" +#define PASSWORD_HASH "md5" +#define DEFAULT_WARN (2L * 7L * 86400L) /* Two weeks */ +#define MAX_TRIES 3 +#define SALTSIZE 32 + +static void makesalt(char []); + +static char password_prompt_def[] = PASSWORD_PROMPT; +static char password_hash[] = PASSWORD_HASH; +static char blank[] = ""; +static char colon[] = ":"; + +enum { + PAM_OPT_AUTH_AS_SELF = PAM_OPT_STD_MAX, + PAM_OPT_NULLOK, + PAM_OPT_LOCAL_PASS, + PAM_OPT_NIS_PASS +}; + +static struct opttab other_options[] = { + { "auth_as_self", PAM_OPT_AUTH_AS_SELF }, + { "nullok", PAM_OPT_NULLOK }, + { "local_pass", PAM_OPT_LOCAL_PASS }, + { "nis_pass", PAM_OPT_NIS_PASS }, + { NULL, 0 } +}; + +#ifdef YP +int pam_use_yp = 0; +int yp_errno = YP_TRUE; +#endif + +char *tempname = NULL; +static int local_passwd(const char *user, const char *pass); +#ifdef YP +static int yp_passwd(const char *user, const char *pass); +#endif + +/* + * authentication management + */ +PAM_EXTERN int +pam_sm_authenticate(pam_handle_t *pamh, int flags __unused, int argc, const char **argv) +{ + login_cap_t *lc; + struct options options; + struct passwd *pwd; + int retval; + const char *pass, *user; + char *encrypted, *password_prompt; + + pam_std_option(&options, other_options, argc, argv); + + PAM_LOG("Options processed"); + + if (pam_test_option(&options, PAM_OPT_AUTH_AS_SELF, NULL)) + pwd = getpwnam(getlogin()); + else { + retval = pam_get_user(pamh, &user, NULL); + if (retval != PAM_SUCCESS) + PAM_RETURN(retval); + pwd = getpwnam(user); + } + + PAM_LOG("Got user: %s", user); + + lc = login_getclass(NULL); + password_prompt = login_getcapstr(lc, "passwd_prompt", + password_prompt_def, password_prompt_def); + login_close(lc); + lc = NULL; + + if (pwd != NULL) { + + PAM_LOG("Doing real authentication"); + + if (pwd->pw_passwd[0] == '\0' + && pam_test_option(&options, PAM_OPT_NULLOK, NULL)) { + /* + * No password case. XXX Are we giving too much away + * by not prompting for a password? + */ + PAM_LOG("No password, and null password OK"); + PAM_RETURN(PAM_SUCCESS); + } + else { + retval = pam_get_authtok(pamh, &pass, password_prompt); + if (retval != PAM_SUCCESS) + PAM_RETURN(retval); + PAM_LOG("Got password"); + } + encrypted = crypt(pass, pwd->pw_passwd); + if (pass[0] == '\0' && pwd->pw_passwd[0] != '\0') + encrypted = colon; + + PAM_LOG("Encrypted password 1 is: %s", encrypted); + PAM_LOG("Encrypted password 2 is: %s", pwd->pw_passwd); + + retval = strcmp(encrypted, pwd->pw_passwd) == 0 ? + PAM_SUCCESS : PAM_AUTH_ERR; + } + else { + + PAM_LOG("Doing dummy authentication"); + + /* + * User unknown. + * Encrypt a dummy password so as to not give away too much. + */ + retval = pam_get_authtok(pamh, &pass, password_prompt); + if (retval != PAM_SUCCESS) + PAM_RETURN(retval); + PAM_LOG("Got password"); + crypt(pass, "xx"); + retval = PAM_AUTH_ERR; + } + + /* + * The PAM infrastructure will obliterate the cleartext + * password before returning to the application. + */ + if (retval != PAM_SUCCESS) + PAM_VERBOSE_ERROR("UNIX authentication refused"); + + PAM_RETURN(retval); +} + +PAM_EXTERN int +pam_sm_setcred(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, other_options, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_SUCCESS); +} + +/* + * account management + */ +PAM_EXTERN int +pam_sm_acct_mgmt(pam_handle_t *pamh, int flags __unused, int argc, const char **argv) +{ + struct addrinfo hints, *res; + struct options options; + struct passwd *pwd; + struct timeval tp; + login_cap_t *lc; + time_t warntime; + int retval; + const char *rhost, *tty, *user; + char rhostip[MAXHOSTNAMELEN]; + + pam_std_option(&options, other_options, argc, argv); + + PAM_LOG("Options processed"); + + retval = pam_get_item(pamh, PAM_USER, (const void **)&user); + if (retval != PAM_SUCCESS) + PAM_RETURN(retval); + + if (user == NULL || (pwd = getpwnam(user)) == NULL) + PAM_RETURN(PAM_SERVICE_ERR); + + PAM_LOG("Got user: %s", user); + + retval = pam_get_item(pamh, PAM_RHOST, (const void **)&rhost); + if (retval != PAM_SUCCESS) + PAM_RETURN(retval); + + retval = pam_get_item(pamh, PAM_TTY, (const void **)&tty); + if (retval != PAM_SUCCESS) + PAM_RETURN(retval); + + if (*pwd->pw_passwd == '\0' && + (flags & PAM_DISALLOW_NULL_AUTHTOK) != 0) + return (PAM_NEW_AUTHTOK_REQD); + + lc = login_getpwclass(pwd); + if (lc == NULL) { + PAM_LOG("Unable to get login class for user %s", user); + return (PAM_SERVICE_ERR); + } + + PAM_LOG("Got login_cap"); + + if (pwd->pw_change || pwd->pw_expire) + gettimeofday(&tp, NULL); + + /* + * Check pw_expire before pw_change - no point in letting the + * user change the password on an expired account. + */ + + if (pwd->pw_expire) { + warntime = login_getcaptime(lc, "warnexpire", + DEFAULT_WARN, DEFAULT_WARN); + if (tp.tv_sec >= pwd->pw_expire) { + login_close(lc); + PAM_RETURN(PAM_ACCT_EXPIRED); + } else if (pwd->pw_expire - tp.tv_sec < warntime && + (flags & PAM_SILENT) == 0) { + pam_error(pamh, "Warning: your account expires on %s", + ctime(&pwd->pw_expire)); + } + } + + retval = PAM_SUCCESS; + if (pwd->pw_change) { + warntime = login_getcaptime(lc, "warnpassword", + DEFAULT_WARN, DEFAULT_WARN); + if (tp.tv_sec >= pwd->pw_change) { + retval = PAM_NEW_AUTHTOK_REQD; + } else if (pwd->pw_change - tp.tv_sec < warntime && + (flags & PAM_SILENT) == 0) { + pam_error(pamh, "Warning: your password expires on %s", + ctime(&pwd->pw_change)); + } + } + + /* + * From here on, we must leave retval untouched (unless we + * know we're going to fail), because we need to remember + * whether we're supposed to return PAM_SUCCESS or + * PAM_NEW_AUTHTOK_REQD. + */ + + if (rhost) { + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + if (getaddrinfo(rhost, NULL, &hints, &res) == 0) { + getnameinfo(res->ai_addr, res->ai_addrlen, + rhostip, sizeof(rhostip), NULL, 0, + NI_NUMERICHOST|NI_WITHSCOPEID); + } + if (res != NULL) + freeaddrinfo(res); + } + + /* + * Check host / tty / time-of-day restrictions + */ + + if (!auth_hostok(lc, rhost, rhostip) || + !auth_ttyok(lc, tty) || + !auth_timeok(lc, time(NULL))) + retval = PAM_AUTH_ERR; + + login_close(lc); + + PAM_RETURN(retval); +} + +/* + * session management + * + * logging only + */ +PAM_EXTERN int +pam_sm_open_session(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, other_options, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_SUCCESS); +} + +PAM_EXTERN int +pam_sm_close_session(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, other_options, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_SUCCESS); +} + +/* + * password management + * + * standard Unix and NIS password changing + */ +PAM_EXTERN int +pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) +{ + struct options options; + struct passwd *pwd; + int retval, retry, res, got; + const char *user, *pass; + char *new_pass, *new_pass_, *encrypted, *usrdup; + + pam_std_option(&options, other_options, argc, argv); + + PAM_LOG("Options processed"); + + if (pam_test_option(&options, PAM_OPT_AUTH_AS_SELF, NULL)) + pwd = getpwnam(getlogin()); + else { + retval = pam_get_user(pamh, &user, NULL); + if (retval != PAM_SUCCESS) + PAM_RETURN(retval); + pwd = getpwnam(user); + } + + PAM_LOG("Got user: %s", user); + + if (flags & PAM_PRELIM_CHECK) { + + PAM_LOG("PRELIM round; checking user password"); + + if (pwd->pw_passwd[0] == '\0' + && pam_test_option(&options, PAM_OPT_NULLOK, NULL)) { + /* + * No password case. XXX Are we giving too much away + * by not prompting for a password? + */ + PAM_LOG("No password, and null password OK"); + PAM_RETURN(PAM_SUCCESS); + } + else { + retval = pam_get_authtok(pamh, &pass, + PASSWORD_PROMPT_EXPIRED); + if (retval != PAM_SUCCESS) + PAM_RETURN(retval); + PAM_LOG("Got password: %s", pass); + } + encrypted = crypt(pass, pwd->pw_passwd); + if (pass[0] == '\0' && pwd->pw_passwd[0] != '\0') + encrypted = colon; + + PAM_LOG("Encrypted password 1 is: %s", encrypted); + PAM_LOG("Encrypted password 2 is: %s", pwd->pw_passwd); + + if (strcmp(encrypted, pwd->pw_passwd) != 0) + PAM_RETURN(PAM_AUTH_ERR); + + retval = pam_set_item(pamh, PAM_OLDAUTHTOK, (const void *)pass); + pass = NULL; + if (retval != PAM_SUCCESS) + PAM_RETURN(retval); + + PAM_LOG("Stashed old password"); + + retval = pam_set_item(pamh, PAM_AUTHTOK, (const void *)pass); + if (retval != PAM_SUCCESS) + PAM_RETURN(retval); + + PAM_LOG("Voided old password"); + + PAM_RETURN(PAM_SUCCESS); + } + else if (flags & PAM_UPDATE_AUTHTOK) { + PAM_LOG("UPDATE round; checking user password"); + + retval = pam_get_item(pamh, PAM_OLDAUTHTOK, + (const void **)&pass); + if (retval != PAM_SUCCESS) + PAM_RETURN(retval); + + PAM_LOG("Got old password: %s", pass); + + got = 0; + retry = 0; + while (retry++ < MAX_TRIES) { + new_pass = NULL; + retval = pam_prompt(pamh, PAM_PROMPT_ECHO_OFF, + &new_pass, "%s", NEW_PASSWORD_PROMPT_1); + + if (new_pass == NULL) + new_pass = blank; + + if (retval == PAM_SUCCESS) { + new_pass_ = NULL; + retval = pam_prompt(pamh, PAM_PROMPT_ECHO_OFF, + &new_pass_, "%s", NEW_PASSWORD_PROMPT_2); + + if (new_pass_ == NULL) + new_pass_ = blank; + + if (retval == PAM_SUCCESS) { + if (strcmp(new_pass, new_pass_) == 0) { + got = 1; + break; + } + else + PAM_VERBOSE_ERROR("Password mismatch"); + } + } + } + + if (!got) { + PAM_VERBOSE_ERROR("Unable to get valid password"); + PAM_RETURN(PAM_PERM_DENIED); + } + + PAM_LOG("Got new password: %s", new_pass); + +#ifdef YP + /* If NIS is set in the passwd database, use it */ + if ((usrdup = strdup(user)) == NULL) + PAM_RETURN(PAM_BUF_ERR); + res = use_yp(usrdup, 0, 0); + free(usrdup); + if (res == USER_YP_ONLY) { + if (!pam_test_option(&options, PAM_OPT_LOCAL_PASS, + NULL)) + retval = yp_passwd(user, new_pass); + else { + /* Reject 'local' flag if NIS is on and the user + * is not local + */ + retval = PAM_PERM_DENIED; + PAM_LOG("Unknown local user: %s", user); + } + } + else if (res == USER_LOCAL_ONLY) { + if (!pam_test_option(&options, PAM_OPT_NIS_PASS, NULL)) + retval = local_passwd(user, new_pass); + else { + /* Reject 'nis' flag if user is only local */ + retval = PAM_PERM_DENIED; + PAM_LOG("Unknown NIS user: %s", user); + } + } + else if (res == USER_YP_AND_LOCAL) { + if (pam_test_option(&options, PAM_OPT_NIS_PASS, NULL)) + retval = yp_passwd(user, new_pass); + else + retval = local_passwd(user, new_pass); + } + else + retval = PAM_SERVICE_ERR; /* Bad juju */ +#else + retval = local_passwd(user, new_pass); +#endif + + /* XXX wipe the mem as well */ + pass = NULL; + new_pass = NULL; + } + else { + /* Very bad juju */ + retval = PAM_ABORT; + PAM_LOG("Illegal 'flags'"); + } + + PAM_RETURN(retval); +} + +/* Mostly stolen from passwd(1)'s local_passwd.c - markm */ + +static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */ + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +static void +to64(char *s, long v, int n) +{ + while (--n >= 0) { + *s++ = itoa64[v&0x3f]; + v >>= 6; + } +} + +static int +local_passwd(const char *user, const char *pass) +{ + login_cap_t * lc; + struct passwd *pwd; + struct timeval tv; + int pfd, tfd; + char *crypt_type, salt[SALTSIZE + 1]; + + pwd = getpwnam(user); + if (pwd == NULL) + return(PAM_SERVICE_ERR); /* Really bad things */ + +#ifdef YP + pwd = (struct passwd *)&local_password; +#endif + pw_init(); + + pwd->pw_change = 0; + lc = login_getclass(NULL); + crypt_type = login_getcapstr(lc, "passwd_format", + password_hash, password_hash); + if (login_setcryptfmt(lc, crypt_type, NULL) == NULL) + syslog(LOG_ERR, "cannot set password cipher"); + login_close(lc); + makesalt(salt); + pwd->pw_passwd = crypt(pass, salt); + + pfd = pw_lock(); + tfd = pw_tmp(); + pw_copy(pfd, tfd, pwd, NULL); + + if (!pw_mkdb(user)) + pw_error((char *)NULL, 0, 1); + + return (PAM_SUCCESS); +} + +#ifdef YP +/* Stolen from src/usr.bin/passwd/yp_passwd.c, carrying copyrights of: + * Copyright (c) 1992/3 Theo de Raadt <deraadt@fsa.ca> + * Copyright (c) 1994 Olaf Kirch <okir@monad.swb.de> + * Copyright (c) 1995 Bill Paul <wpaul@ctr.columbia.edu> + */ +int +yp_passwd(const char *user __unused, const char *pass) +{ + struct master_yppasswd master_yppwd; + struct passwd *pwd; + struct rpc_err err; + struct timeval tv; + struct yppasswd yppwd; + CLIENT *clnt; + login_cap_t *lc; + int *status; + gid_t gid; + pid_t pid; + uid_t uid; + char *master, sockname[] = YP_SOCKNAME, salt[SALTSIZE + 1]; + + _use_yp = 1; + + uid = getuid(); + + master = get_yp_master(1); + if (master == NULL) + return (PAM_SERVICE_ERR); /* Major disaster */ + + /* + * It is presumed that by the time we get here, use_yp() + * has been called and that we have verified that the user + * actually exists. This being the case, the yp_password + * stucture has already been filled in for us. + */ + + /* Use the correct password */ + pwd = (struct passwd *)&yp_password; + + pwd->pw_change = 0; + + /* Initialize password information */ + if (suser_override) { + master_yppwd.newpw.pw_passwd = strdup(pwd->pw_passwd); + master_yppwd.newpw.pw_name = strdup(pwd->pw_name); + master_yppwd.newpw.pw_uid = pwd->pw_uid; + master_yppwd.newpw.pw_gid = pwd->pw_gid; + master_yppwd.newpw.pw_expire = pwd->pw_expire; + master_yppwd.newpw.pw_change = pwd->pw_change; + master_yppwd.newpw.pw_fields = pwd->pw_fields; + master_yppwd.newpw.pw_gecos = strdup(pwd->pw_gecos); + master_yppwd.newpw.pw_dir = strdup(pwd->pw_dir); + master_yppwd.newpw.pw_shell = strdup(pwd->pw_shell); + master_yppwd.newpw.pw_class = pwd->pw_class != NULL ? + strdup(pwd->pw_class) : strdup(""); + master_yppwd.oldpass = strdup(""); + master_yppwd.domain = yp_domain; + } else { + yppwd.newpw.pw_passwd = strdup(pwd->pw_passwd); + yppwd.newpw.pw_name = strdup(pwd->pw_name); + yppwd.newpw.pw_uid = pwd->pw_uid; + yppwd.newpw.pw_gid = pwd->pw_gid; + yppwd.newpw.pw_gecos = strdup(pwd->pw_gecos); + yppwd.newpw.pw_dir = strdup(pwd->pw_dir); + yppwd.newpw.pw_shell = strdup(pwd->pw_shell); + yppwd.oldpass = strdup(""); + } + + if (login_setcryptfmt(lc, "md5", NULL) == NULL) + syslog(LOG_ERR, "cannot set password cipher"); + login_close(lc); + + makesalt(salt); + if (suser_override) + master_yppwd.newpw.pw_passwd = crypt(pass, salt); + else + yppwd.newpw.pw_passwd = crypt(pass, salt); + + if (suser_override) { + if ((clnt = clnt_create(sockname, MASTER_YPPASSWDPROG, + MASTER_YPPASSWDVERS, "unix")) == NULL) { + syslog(LOG_ERR, + "Cannot contact rpc.yppasswdd on host %s: %s", + master, clnt_spcreateerror("")); + return (PAM_SERVICE_ERR); + } + } + else { + if ((clnt = clnt_create(master, YPPASSWDPROG, + YPPASSWDVERS, "udp")) == NULL) { + syslog(LOG_ERR, + "Cannot contact rpc.yppasswdd on host %s: %s", + master, clnt_spcreateerror("")); + return (PAM_SERVICE_ERR); + } + } + /* + * The yppasswd.x file said `unix authentication required', + * so I added it. This is the only reason it is in here. + * My yppasswdd doesn't use it, but maybe some others out there + * do. --okir + */ + clnt->cl_auth = authunix_create_default(); + + if (suser_override) + status = yppasswdproc_update_master_1(&master_yppwd, clnt); + else + status = yppasswdproc_update_1(&yppwd, clnt); + + clnt_geterr(clnt, &err); + + auth_destroy(clnt->cl_auth); + clnt_destroy(clnt); + + if (err.re_status != RPC_SUCCESS || status == NULL || *status) + return (PAM_SERVICE_ERR); + + if (err.re_status || status == NULL || *status) + return (PAM_SERVICE_ERR); + return (PAM_SUCCESS); +} +#endif /* YP */ + +/* Salt suitable for traditional DES and MD5 */ +void +makesalt(char salt[SALTSIZE]) +{ + int i; + + /* These are not really random numbers, they are just + * numbers that change to thwart construction of a + * dictionary. This is exposed to the public. + */ + for (i = 0; i < SALTSIZE; i += 4) + to64(&salt[i], arc4random(), 4); + salt[SALTSIZE] = '\0'; +} + +PAM_MODULE_ENTRY("pam_unix"); diff --git a/lib/libpam/modules/pam_wheel/Makefile b/lib/libpam/modules/pam_wheel/Makefile new file mode 100644 index 0000000..b09e115 --- /dev/null +++ b/lib/libpam/modules/pam_wheel/Makefile @@ -0,0 +1,32 @@ +# Copyright 2001 Mark R V Murray +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ + +LIB= pam_wheel +SHLIB_NAME= ${LIB}.so.${SHLIB_MAJOR} +SRCS= pam_wheel.c +MAN= pam_wheel.8 + +.include <bsd.lib.mk> diff --git a/lib/libpam/modules/pam_wheel/pam_wheel.8 b/lib/libpam/modules/pam_wheel/pam_wheel.8 new file mode 100644 index 0000000..bd412c8 --- /dev/null +++ b/lib/libpam/modules/pam_wheel/pam_wheel.8 @@ -0,0 +1,112 @@ +.\" Copyright (c) 2001 Mark R V Murray +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ +.\" +.Dd July 8, 2001 +.Dt PAM_WHEEL 8 +.Os +.Sh NAME +.Nm pam_wheel +.Nd Wheel PAM module +.Sh SYNOPSIS +.Op Ar service-name +.Ar module-type +.Ar control-flag +.Pa pam_wheel +.Op Ar options +.Sh DESCRIPTION +The Wheel authentication service module for PAM, +.Nm +provides functionality for only one PAM category: +authentication. +In terms of the +.Ar module-type +parameter, this is the +.Dq Li auth +feature. +It also provides a null function for session management. +.Ss Wheel Authentication Module +The Wheel authentication component +.Pq Fn pam_sm_authenticate , +permit authentication to members of a group, +which defaults to +.Dq Li wheel . +.Pp +The following options may be passed to the authentication module: +.Bl -tag -width ".Cm auth_as_self" +.It Cm debug +.Xr syslog 3 +debugging information at +.Dv LOG_DEBUG +level. +.It Cm no_warn +suppress warning messages to the user. +These messages include +reasons why the user's +authentication attempt was declined. +.It Cm auth_as_self +check for +.Dq Li wheel +membership against +the current login name +(given by +.Xr getlogin 2 ) . +.It Cm trust +return +.Dv PAM_SUCCESS +instead of +.Dv PAM_IGNORE +if the user is a member of the group (default is +.Dq Li wheel ) . +.It Cm deny +invert the operation +if the user is a member of the +(default +.Dq Li wheel ) +group. +Returns failure instead of success. +Mainly of use with the +.Cm group Ns = Ns Ar foo +option. +.It Cm group Ns = Ns Ar foo +checking for membership of group +.Ar foo +instead of the default group +.Dq Li wheel . +.It Cm noroot_ok +return +.Dv PAM_SUCCESS +instead of +.Dv PAM_IGNORE +if the user is authenticating +to a user +that is not the superuser. +.El +.Sh SEE ALSO +.Xr getlogin 2 , +.Xr syslog 3 , +.Xr group 5 , +.Xr pam.conf 5 , +.Xr pam 8 diff --git a/lib/libpam/modules/pam_wheel/pam_wheel.c b/lib/libpam/modules/pam_wheel/pam_wheel.c new file mode 100644 index 0000000..f9d9d21 --- /dev/null +++ b/lib/libpam/modules/pam_wheel/pam_wheel.c @@ -0,0 +1,232 @@ +/*- + * Copyright (c) 2001 Mark R V Murray + * All rights reserved. + * Copyright (c) 2001 Networks Associates Technology, Inc. + * All rights reserved. + * + * Portions of this software were developed for the FreeBSD Project by + * ThinkSec AS and NAI Labs, the Security Research Division of Network + * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 + * ("CBOSS"), as part of the DARPA CHATS research program. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#define _BSD_SOURCE + +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <syslog.h> +#include <stdarg.h> +#include <sys/types.h> +#include <pwd.h> +#include <grp.h> + +#define PAM_SM_AUTH +#define PAM_SM_ACCOUNT +#define PAM_SM_SESSION +#define PAM_SM_PASSWORD + +#include <security/pam_appl.h> +#include <security/pam_modules.h> +#include <security/pam_mod_misc.h> + +enum { PAM_OPT_DENY=PAM_OPT_STD_MAX, PAM_OPT_GROUP, PAM_OPT_TRUST, + PAM_OPT_AUTH_AS_SELF, PAM_OPT_NOROOT_OK }; + +static struct opttab other_options[] = { + { "deny", PAM_OPT_DENY }, + { "group", PAM_OPT_GROUP }, + { "trust", PAM_OPT_TRUST }, + { "auth_as_self", PAM_OPT_AUTH_AS_SELF }, + { "noroot_ok", PAM_OPT_NOROOT_OK }, + { NULL, 0 } +}; + +/* Is member in list? */ +static int +in_list(char *const *list, const char *member) +{ + for (; *list; list++) + if (strcmp(*list, member) == 0) + return 1; + return 0; +} + +PAM_EXTERN int +pam_sm_authenticate(pam_handle_t * pamh, int flags __unused, int argc, const char **argv) +{ + struct options options; + struct passwd *pwd; + struct group *grp; + int retval; + uid_t tuid; + const char *user, *targetuser; + char *use_group; + + pam_std_option(&options, other_options, argc, argv); + + PAM_LOG("Options processed"); + + retval = pam_get_user(pamh, &targetuser, NULL); + if (retval != PAM_SUCCESS) + PAM_RETURN(retval); + pwd = getpwnam(targetuser); + if (pwd != NULL) + tuid = pwd->pw_uid; + else + PAM_RETURN(PAM_AUTH_ERR); + + PAM_LOG("Got target user: %s uid: %d", targetuser, tuid); + + if (pam_test_option(&options, PAM_OPT_AUTH_AS_SELF, NULL)) { + pwd = getpwnam(getlogin()); + user = strdup(pwd->pw_name); + } + else { + user = targetuser; + pwd = getpwnam(user); + } + if (pwd == NULL) + PAM_RETURN(PAM_AUTH_ERR); + + PAM_LOG("Got user: %s", user); + PAM_LOG("User's primary uid, gid: %d, %d", pwd->pw_uid, pwd->pw_gid); + + /* Ignore if already uid 0 */ + if (pwd->pw_uid == 0) + PAM_RETURN(PAM_IGNORE); + + PAM_LOG("Not superuser"); + + /* If authenticating as something non-superuser, return OK */ + if (pam_test_option(&options, PAM_OPT_NOROOT_OK, NULL)) + if (tuid != 0) + PAM_RETURN(PAM_SUCCESS); + + PAM_LOG("Checking group"); + + if (!pam_test_option(&options, PAM_OPT_GROUP, &use_group)) { + if ((grp = getgrnam("wheel")) == NULL) + grp = getgrgid(0); + } + else + grp = getgrnam(use_group); + + if (grp == NULL || grp->gr_mem == NULL) { + if (pam_test_option(&options, PAM_OPT_DENY, NULL)) + PAM_RETURN(PAM_IGNORE); + else { + PAM_VERBOSE_ERROR("Permission denied"); + PAM_RETURN(PAM_AUTH_ERR); + } + } + + PAM_LOG("Got group: %s", grp->gr_name); + + if (pwd->pw_gid == grp->gr_gid || in_list(grp->gr_mem, pwd->pw_name)) { + if (pam_test_option(&options, PAM_OPT_DENY, NULL)) { + PAM_VERBOSE_ERROR("Member of group %s; denied", + grp->gr_name); + PAM_RETURN(PAM_PERM_DENIED); + } + if (pam_test_option(&options, PAM_OPT_TRUST, NULL)) + PAM_RETURN(PAM_SUCCESS); + PAM_RETURN(PAM_IGNORE); + } + + if (pam_test_option(&options, PAM_OPT_DENY, NULL)) + PAM_RETURN(PAM_SUCCESS); + + PAM_VERBOSE_ERROR("Not member of group %s; denied", grp->gr_name); + + PAM_RETURN(PAM_PERM_DENIED); +} + +PAM_EXTERN int +pam_sm_setcred(pam_handle_t * pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, other_options, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_SUCCESS); +} + +PAM_EXTERN int +pam_sm_acct_mgmt(pam_handle_t *pamh __unused, int flags __unused, int argc ,const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_chauthtok(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_open_session(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_EXTERN int +pam_sm_close_session(pam_handle_t *pamh __unused, int flags __unused, int argc, const char **argv) +{ + struct options options; + + pam_std_option(&options, NULL, argc, argv); + + PAM_LOG("Options processed"); + + PAM_RETURN(PAM_IGNORE); +} + +PAM_MODULE_ENTRY("pam_wheel"); |