From 5503c579fd38ef8ff277f68aae1422c2b8f4c136 Mon Sep 17 00:00:00 2001 From: Joerg Sonnenberger Date: Tue, 12 Jul 2005 22:34:55 +0000 Subject: [PATCH] Import current pam_tacplus from FreeBSD HEAD. --- lib/pam_module/pam_tacplus/Makefile | 11 + lib/pam_module/pam_tacplus/pam_tacplus.8 | 131 +++++++++++ lib/pam_module/pam_tacplus/pam_tacplus.c | 281 +++++++++++++++++++++++ 3 files changed, 423 insertions(+) create mode 100644 lib/pam_module/pam_tacplus/Makefile create mode 100644 lib/pam_module/pam_tacplus/pam_tacplus.8 create mode 100644 lib/pam_module/pam_tacplus/pam_tacplus.c diff --git a/lib/pam_module/pam_tacplus/Makefile b/lib/pam_module/pam_tacplus/Makefile new file mode 100644 index 0000000000..baf4dec47b --- /dev/null +++ b/lib/pam_module/pam_tacplus/Makefile @@ -0,0 +1,11 @@ +# $DragonFly: src/lib/pam_module/pam_tacplus/Makefile,v 1.1 2005/07/12 22:34:55 joerg Exp $ + +LIB= pam_tacplus +SRCS= pam_tacplus.c +WARNS?= 6 +NOMAN= + +LDADD= -ltacplus +DPADD= ${LIBTACPLUS} + +.include diff --git a/lib/pam_module/pam_tacplus/pam_tacplus.8 b/lib/pam_module/pam_tacplus/pam_tacplus.8 new file mode 100644 index 0000000000..87e6478bc6 --- /dev/null +++ b/lib/pam_module/pam_tacplus/pam_tacplus.8 @@ -0,0 +1,131 @@ +.\" Copyright (c) 1999 +.\" Andrzej Bialecki . 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: src/lib/libpam/modules/pam_tacplus/pam_tacplus.8,v 1.4 2004/07/02 23:52:18 ru Exp $ +.\" $DragonFly: src/lib/pam_module/pam_tacplus/pam_tacplus.8,v 1.1 2005/07/12 22:34:55 joerg Exp $ +.\" +.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/pam_module/pam_tacplus/pam_tacplus.c b/lib/pam_module/pam_tacplus/pam_tacplus.c new file mode 100644 index 0000000000..1d66fb2595 --- /dev/null +++ b/lib/pam_module/pam_tacplus/pam_tacplus.c @@ -0,0 +1,281 @@ +/*- + * Copyright 1998 Juniper Networks, Inc. + * All rights reserved. + * Copyright (c) 2001-2003 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: src/lib/libpam/modules/pam_tacplus/pam_tacplus.c,v 1.14 2003/05/31 17:19:03 des Exp $ + * $DragonFly: src/lib/pam_module/pam_tacplus/pam_tacplus.c,v 1.1 2005/07/12 22:34:55 joerg Exp $ + */ + +#include + +#include +#include +#include +#include +#include +#include + +#define PAM_SM_AUTH + +#include +#include +#include + +#define PAM_OPT_CONF "conf" +#define PAM_OPT_TEMPLATE_USER "template_user" + +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 __unused, const char *argv[] __unused) +{ + int retval; + struct tac_handle *tach; + const char *conf_file, *template_user; + + conf_file = openpam_get_option(pamh, PAM_OPT_CONF); + template_user = openpam_get_option(pamh, PAM_OPT_TEMPLATE_USER); + + tach = tac_open(); + if (tach == NULL) { + syslog(LOG_CRIT, "tac_open failed"); + return (PAM_SERVICE_ERR); + } + if (tac_config(tach, conf_file) == -1) { + syslog(LOG_ALERT, "tac_config: %s", tac_strerror(tach)); + tac_close(tach); + 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); + 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) + return (retval); + + PAM_LOG("Done user"); + + retval = do_item(pamh, tach, PAM_TTY, tac_set_port, "tac_set_port"); + if (retval != PAM_SUCCESS) + 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) + 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); + return (PAM_AUTHINFO_UNAVAIL); + } + status = TAC_AUTHEN_STATUS(sflags); + openpam_set_option(pamh, PAM_OPT_ECHO_PASS, + TAC_AUTHEN_NOECHO(sflags) ? NULL : ""); + 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) + return (retval); + user = (const char *)item; + if (getpwnam(user) == NULL) { + pam_set_item(pamh, PAM_USER, + template_user); + PAM_LOG("Using template user"); + } + } + return (PAM_SUCCESS); + + case TAC_AUTHEN_STATUS_FAIL: + tac_close(tach); + PAM_VERBOSE_ERROR("TACACS+ authentication failed"); + return (PAM_AUTH_ERR); + + case TAC_AUTHEN_STATUS_GETUSER: + case TAC_AUTHEN_STATUS_GETPASS: + if ((srvr_msg = get_msg(tach)) == NULL) + return (PAM_SERVICE_ERR); + if (status == TAC_AUTHEN_STATUS_GETUSER) + retval = pam_get_user(pamh, &user_msg, + *srvr_msg ? srvr_msg : NULL); + else if (status == TAC_AUTHEN_STATUS_GETPASS) + retval = pam_get_authtok(pamh, + PAM_AUTHTOK, &user_msg, + *srvr_msg ? srvr_msg : "Password:"); + free(srvr_msg); + if (retval != PAM_SUCCESS) { + /* XXX - send a TACACS+ abort packet */ + tac_close(tach); + return (retval); + } + if (set_msg(tach, user_msg) == -1) + return (PAM_SERVICE_ERR); + break; + + case TAC_AUTHEN_STATUS_GETDATA: + if ((srvr_msg = get_msg(tach)) == NULL) + return (PAM_SERVICE_ERR); + retval = pam_prompt(pamh, + openpam_get_option(pamh, PAM_OPT_ECHO_PASS) ? + PAM_PROMPT_ECHO_ON : PAM_PROMPT_ECHO_OFF, + &data_msg, "%s", *srvr_msg ? srvr_msg : "Data:"); + free(srvr_msg); + if (retval != PAM_SUCCESS) { + /* XXX - send a TACACS+ abort packet */ + tac_close(tach); + return (retval); + } + retval = set_msg(tach, data_msg); + memset(data_msg, 0, strlen(data_msg)); + free(data_msg); + if (retval == -1) + 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); + 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); + return (PAM_AUTHINFO_UNAVAIL); + } + } +} + +PAM_EXTERN int +pam_sm_setcred(pam_handle_t *pamh __unused, int flags __unused, + int argc __unused, const char *argv[] __unused) +{ + + return (PAM_IGNORE); +} + +PAM_MODULE_ENTRY("pam_tacplus"); -- 2.41.0