From 716eff476a0a874358784988772671c26d34af81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Wed, 16 May 2018 13:47:30 +0000 Subject: [PATCH] Forward Reply-Message attributes to the user, unless suppressed by the new no_reply_message option. MFC after: 1 week Sponsored by: The University of Oslo --- lib/libpam/modules/pam_radius/pam_radius.8 | 32 +++++++++--- lib/libpam/modules/pam_radius/pam_radius.c | 61 +++++++++++++++++++--- 2 files changed, 78 insertions(+), 15 deletions(-) diff --git a/lib/libpam/modules/pam_radius/pam_radius.8 b/lib/libpam/modules/pam_radius/pam_radius.8 index d71b41434419..9d12c0b0b6ce 100644 --- a/lib/libpam/modules/pam_radius/pam_radius.8 +++ b/lib/libpam/modules/pam_radius/pam_radius.8 @@ -1,8 +1,9 @@ -.\" Copyright (c) 1999 -.\" Andrzej Bialecki . All rights reserved. -.\" +.\"- .\" Copyright (c) 1992, 1993, 1994 .\" The Regents of the University of California. All rights reserved. +.\" Copyright (c) 1999 Andrzej Bialecki +.\" All rights reserved. +.\" Copyright (c) 2018 The University of Oslo .\" All rights reserved. .\" .\" This code is derived from software donated to Berkeley by @@ -34,7 +35,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 28, 2002 +.Dd May 16, 2018 .Dt PAM_RADIUS 8 .Os .Sh NAME @@ -80,6 +81,10 @@ specifies a non-standard location for the RADIUS client configuration file .Pa /etc/radius.conf ) . .It Cm nas_id Ns = Ns Ar identifier specifies a NAS identifier to send instead of the hostname. +.It Cm nas_ipaddr Ns Op No = Ns Ar address +specifies a NAS IP address to be sent. +If option is present, but there is no value provided then IP address +corresponding to the current hostname will be used. .It Cm template_user Ns = Ns Ar username specifies a user whose .Xr passwd 5 @@ -97,10 +102,21 @@ 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. -.It Cm nas_ipaddr Ns Op No = Ns Ar address -specifies a NAS IP address to be sent. -If option is present, but there is no value provided then IP address -corresponding to the current hostname will be used. +.It Cm no_reply_message +suppress printing of the contents of any +.Cm Reply-Message +attributes found in +.Cm Access-Accept +and +.Cm Access-Reject +responses. +These are normally conveyed to the user as either informational or +error messages, depending on whether the access request was accepted +or rejected. +.It Cm no_warn +suppress warning messages to the user. +These messages include reasons why the user's authentication attempt +was declined. .El .Sh FILES .Bl -tag -width /etc/radius.conf -compact diff --git a/lib/libpam/modules/pam_radius/pam_radius.c b/lib/libpam/modules/pam_radius/pam_radius.c index c71d3b954da0..377652382dc4 100644 --- a/lib/libpam/modules/pam_radius/pam_radius.c +++ b/lib/libpam/modules/pam_radius/pam_radius.c @@ -5,6 +5,8 @@ * All rights reserved. * Copyright (c) 2001-2003 Networks Associates Technology, Inc. * All rights reserved. + * Copyright (c) 2015-2018 The University of Oslo + * 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 @@ -59,6 +61,7 @@ __FBSDID("$FreeBSD$"); #define PAM_OPT_TEMPLATE_USER "template_user" #define PAM_OPT_NAS_ID "nas_id" #define PAM_OPT_NAS_IPADDR "nas_ipaddr" +#define PAM_OPT_NO_REPLYMSG "no_reply_message" #define MAX_CHALLENGE_MSGS 10 #define PASSWORD_PROMPT "RADIUS Password:" @@ -149,15 +152,23 @@ do_accept(pam_handle_t *pamh, struct rad_handle *radh) 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); - } + switch (attrtype) { + case RAD_USER_NAME: + if ((s = rad_cvt_string(attrval, attrlen)) == NULL) + goto enomem; pam_set_item(pamh, PAM_USER, s); free(s); + break; + case RAD_REPLY_MESSAGE: + if ((s = rad_cvt_string(attrval, attrlen)) == NULL) + goto enomem; + if (!openpam_get_option(pamh, PAM_OPT_NO_REPLYMSG)) + pam_info(pamh, "%s", s); + free(s); + break; + default: + PAM_LOG("%s(): ignoring RADIUS attribute %d", + __func__, attrtype); } } if (attrtype == -1) { @@ -165,6 +176,41 @@ do_accept(pam_handle_t *pamh, struct rad_handle *radh) return (-1); } return (0); +enomem: + syslog(LOG_CRIT, "%s(): out of memory", __func__); + return (-1); +} + +static int +do_reject(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) { + switch (attrtype) { + case RAD_REPLY_MESSAGE: + if ((s = rad_cvt_string(attrval, attrlen)) == NULL) + goto enomem; + if (!openpam_get_option(pamh, PAM_OPT_NO_REPLYMSG)) + pam_error(pamh, "%s", s); + free(s); + break; + default: + PAM_LOG("%s(): ignoring RADIUS attribute %d", + __func__, attrtype); + } + } + if (attrtype < 0) { + syslog(LOG_CRIT, "rad_get_attr: %s", rad_strerror(radh)); + return (-1); + } + return (0); +enomem: + syslog(LOG_CRIT, "%s(): out of memory", __func__); + return (-1); } static int @@ -332,6 +378,7 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags __unused, return (PAM_SUCCESS); case RAD_ACCESS_REJECT: + retval = do_reject(pamh, radh); rad_close(radh); PAM_VERBOSE_ERROR("Radius rejection"); return (PAM_AUTH_ERR);