diff options
-rw-r--r-- | debian/changelog | 41 | ||||
-rw-r--r-- | debian/control | 4 | ||||
-rw-r--r-- | debian/libpam-radius-auth.dirs | 1 | ||||
-rw-r--r-- | debian/libpam-radius-auth.install | 1 | ||||
-rw-r--r-- | debian/libpam-radius-auth.postinst | 9 | ||||
-rw-r--r-- | debian/libpam-radius-auth.prerm | 9 | ||||
-rw-r--r-- | debian/radius | 2 | ||||
-rwxr-xr-x | debian/rules | 3 | ||||
-rw-r--r-- | debian/source/format | 3 | ||||
-rw-r--r-- | radius_shell.8 | 51 | ||||
-rw-r--r-- | src/pam_radius_auth.c | 73 | ||||
-rw-r--r-- | src/radius_shell.c | 41 |
12 files changed, 176 insertions, 62 deletions
diff --git a/debian/changelog b/debian/changelog index 377a829..78fcafa 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,36 @@ +libpam-radius-auth (1.5.0-cl3u7) RELEASED; urgency=low + * Closes: CM-24829 - Fixed order setting vrf and binding to source address + + -- dev-support <dev-support@cumulusnetworks.com> Fri, 01 Mar 2019 14:21:25 -0800 + +libpam-radius-auth (1.5.0-cl3u6) RELEASED; urgency=low + * Do not show passwd when debugging enabled + + -- dev-support <dev-support@cumulusnetworks.com> Fri, 01 Mar 2019 14:21:25 -0800 + +libpam-radius-auth (1.5.0-cl3u5) RELEASED; urgency=low + * Closes: CM-23004 - local account password was allowed even when + RADIUS server could be reached and was authoritative for the accountname + + -- dev-support <dev-support@cumulusnetworks.com> Thu, 15 Nov 2018 13:51:34 -0800 + +libpam-radius-auth (1.5.0-cl3u4) RELEASED; urgency=low + * fixed radius_shell to ensure euid set also, when run as a local user + shell (so user can still login when the radius server is done). + + -- dev-support <dev-support@cumulusnetworks.com> Tue, 28 Aug 2018 11:52:21 -0700 + +libpam-radius-auth (1.5.0-cl3u3) RELEASED; urgency=low + * minor bug fix + + -- dev-support <dev-support@cumulusnetworks.com> Mon, 25 Jun 2018 22:07:29 -0700 + +libpam-radius-auth (1.5.0-cl3u2) RELEASED; urgency=low + * Closes: CM-20649 - Fixed problem that didn't create the home directory + for privileged login users. + + -- dev-support <dev-support@cumulusnetworks.com> Wed, 18 Apr 2018 18:24:48 -0700 + libpam-radius-auth (1.5.0-cl3u1) RELEASED; urgency=low * New Enabled - When the Vendor Specific Option (VSA) containing shell:priv-lvl is present and and the level value is >= to the level @@ -10,20 +43,20 @@ libpam-radius-auth (1.5.0-cl3u1) RELEASED; urgency=low groups at install, therefore privileged radius users can sudo, and can run 'net add', 'net commit', etc. - -- Dave Olson <olson@cumulusnetworks.com> Sun, 15 Apr 2018 14:53:33 -0700 + -- dev-support <dev-support@cumulusnetworks.com> Sun, 15 Apr 2018 14:53:33 -0700 libpam-radius-auth (1.4.1-cl3u3) RELEASED; urgency=low * Closes CM-19908 - Logging changed to use pam_syslog, log message format now has program invoking, not just pam_radius_auth - -- Dave Olson <olson@cumulusnetworks.com> Tue, 27 Feb 2018 14:47:22 -0800 + -- dev-support <dev-support@cumulusnetworks.com> Tue, 27 Feb 2018 14:47:22 -0800 libpam-radius-auth (1.4.1-cl3u2) RELEASED; urgency=low * Improved documentation in man pages - -- Dave Olson <olson@cumulusnetworks.com> Tue, 23 Jan 2018 16:03:38 -0800 + -- dev-support <dev-support@cumulusnetworks.com> Tue, 23 Jan 2018 16:03:38 -0800 libpam-radius-auth (1.4.1-cl3u1) RELEASED; urgency=low @@ -31,7 +64,7 @@ libpam-radius-auth (1.4.1-cl3u1) RELEASED; urgency=low to get UID, GID, and base of home directory, so radius users do not need to have an account created locally (or via LDAP) - -- Dave Olson <olson@cumulusnetworks.com> Fri, 16 Jun 2017 15:44:12 -0700 + -- dev-support <dev-support@cumulusnetworks.com> Fri, 16 Jun 2017 15:44:12 -0700 libpam-radius-auth (1.4.0) unstable; urgency=low diff --git a/debian/control b/debian/control index 969e8f5..ce22bf9 100644 --- a/debian/control +++ b/debian/control @@ -16,9 +16,9 @@ Description: PAM RADIUS client authentication module Package: radius-shell Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, libaudit1, libcap2-bin, libcap2, libnss-mapuser, vyatta-cfg-system +Depends: ${shlibs:Depends}, ${misc:Depends}, libaudit1, libcap2-bin, libcap2, libnss-mapuser Description: Shell front-end used for radius users. This provides a uid fixup program. Due to the limitations of the RADIUS protocol, we can't tell whether a user is privileged until - after authentication. This packages provides a shell front-end that + after authentication. This package provides a shell front-end that sets the uid to the auid, if set and > 1000, and not already matching. diff --git a/debian/libpam-radius-auth.dirs b/debian/libpam-radius-auth.dirs index 8db6b07..8fbaf60 100644 --- a/debian/libpam-radius-auth.dirs +++ b/debian/libpam-radius-auth.dirs @@ -1,4 +1,3 @@ lib/security etc usr/share/doc/libpam-radius-auth/html -usr/share/pam-configs diff --git a/debian/libpam-radius-auth.install b/debian/libpam-radius-auth.install index 7ca6146..128092b 100644 --- a/debian/libpam-radius-auth.install +++ b/debian/libpam-radius-auth.install @@ -1,2 +1,3 @@ pam_radius_auth.so lib/security +pam_radius_auth.conf etc index.html usr/share/doc/libpam-radius-auth/html diff --git a/debian/libpam-radius-auth.postinst b/debian/libpam-radius-auth.postinst new file mode 100644 index 0000000..de079ad --- /dev/null +++ b/debian/libpam-radius-auth.postinst @@ -0,0 +1,9 @@ +#! /bin/sh + +set -e + +# needed for install, upgrade, remove, and purge, including aborts +pam-auth-update --package + +#DEBHELPER# + diff --git a/debian/libpam-radius-auth.prerm b/debian/libpam-radius-auth.prerm new file mode 100644 index 0000000..19f03ae --- /dev/null +++ b/debian/libpam-radius-auth.prerm @@ -0,0 +1,9 @@ +#!/bin/sh + +set -e + +if [ "$1" = remove ]; then + pam-auth-update --package --remove radius +fi + +#DEBHELPER# diff --git a/debian/radius b/debian/radius index 7e318a2..0c180cb 100644 --- a/debian/radius +++ b/debian/radius @@ -4,7 +4,7 @@ Priority: 257 Auth-Type: Primary Auth: [default=1 success=ignore] pam_succeed_if.so uid > 1000 quiet - [authinfo_unavail=ignore success=end default=ignore] pam_radius_auth.so + [authinfo_unavail=ignore success=end auth_err=bad default=ignore] pam_radius_auth.so Account-Type: Primary Account: diff --git a/debian/rules b/debian/rules index 9ac6113..7066806 100755 --- a/debian/rules +++ b/debian/rules @@ -8,7 +8,7 @@ else CFLAGS += -O2 endif PAM_CONF_FILE=/etc/pam_radius_auth.conf -CFLAGS+=-Wno-format-truncation -Wno-strict-aliasing -DCONF_FILE=\"${PAM_CONF_FILE}\" +CFLAGS+=-g3 -Wno-strict-aliasing -Wno-format-truncation -DCONF_FILE=\"${PAM_CONF_FILE}\" ifeq ($(DEB_HOST_GNU_CPU),(hppa|m68k|mips|powerpc|s390|sparc|sparc64|sheb)) CFLAGS += -DHIGHFIRST @@ -23,6 +23,7 @@ export CFLAGS override_dh_install: dh_install -v --sourcedir=. --package=libpam-radius-auth dh_install -v --sourcedir=. --package=radius-shell + chmod 600 debian/*/${PAM_CONF_FILE} chmod 750 debian/*/sbin/radius_shell override_dh_fixperms: diff --git a/debian/source/format b/debian/source/format index af745b3..b9b0237 100644 --- a/debian/source/format +++ b/debian/source/format @@ -1 +1,2 @@ -3.0 (git) +1.0 + diff --git a/radius_shell.8 b/radius_shell.8 index 94b1930..2737f3d 100644 --- a/radius_shell.8 +++ b/radius_shell.8 @@ -4,7 +4,7 @@ radius_shell - front end shell for radius users .SH SYNOPSIS .B /sbin/radius_shell -is RADIUS client front end shell that will ensure that the uid is set +is RADIUS client front end shell that will ensure that the euid, and the uid is set to the auid (the accounting uid). .SH DESCRIPTION This shell front-end needed because at login, it's @@ -38,9 +38,58 @@ At this time, the login shell is only although the other shells listed in .I /etc/shells may be allowed in the future. +.SH NOTE +If a site wants to allow local fallback authentication of a user when +none of the RADIUS servers respond, a privileged user account with the +same name as a RADIUS privileged user should be added as a local account, +and the local account must have the same uid as the mapping privileged +user, and the shell must be this shell. +.P +For example, if the +.B radius_priv_user +account in +.I /etc/passwd +is: +.in +3 +.B "radius_priv_user:x:1002:1001::/home/radius_priv_user:/sbin/radius_shell" +.P +then the command to add a local privileged user account named +.B olsonadmin +would be +.in +3 +.B "sudo useradd -u 1002 -g 1001 -o -s /sbin/radius_shell olsonadmin" +.P +Additionally, if you want the user to be able to run +.I sudo +and +.IR nclu ( net ) +commands, you will also need to run the commands +.in +3 +.B "sudo adduser olsonadmin netedit" +.br +.B "sudo adduser olsonadmin sudo" +.br +.B "sudo systemctl restart netd" +.P +Finally, edit the password file to move the local user prior to the +.B radius_priv_user +line in the passwd file, using the command +.in +3 +.B "sudo vipw" +.in -3 +Set the local password for the user +.in +3 +.B "sudo passwd olsonadmin" +.in -3 +.P +These extra steps are needed to the limitations of mapping RADIUS users, and the +limitations of the RADIUS protocol. .SH "SEE ALSO" .BR setcap (8), .BR pam_radius_auth (8), +.BR adduser (8), +.BR useradd (8), +.BR vipw "(8), and" .BR nss_mapuser (5) .SH FILES .SH AUTHOR diff --git a/src/pam_radius_auth.c b/src/pam_radius_auth.c index 31db395..d98efb1 100644 --- a/src/pam_radius_auth.c +++ b/src/pam_radius_auth.c @@ -894,14 +894,6 @@ static int setup_sock(pam_handle_t * pamh, radius_server_t * server, sockaddrsz = server->family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6); - if (bind(server->sockfd, addr, sockaddrsz) < 0) { - _pam_log(pamh, LOG_ERR, "Bind for server %s failed: %m", hname); - /* mark sockfd as not usable, by closing and set to -1 */ - close(server->sockfd); - server->sockfd = -1; - return 1; - } - if (conf->vrfname[0]) { /* do not fail if the bind fails, connection may succeed */ if (setsockopt(server->sockfd, SOL_SOCKET, SO_BINDTODEVICE, @@ -915,6 +907,14 @@ static int setup_sock(pam_handle_t * pamh, radius_server_t * server, DPRINT(pamh, LOG_DEBUG, "Configured server %s vrf as: %s", server->hostname, conf->vrfname); } + + if (bind(server->sockfd, addr, sockaddrsz) < 0) { + _pam_log(pamh, LOG_ERR, "Bind for server %s failed: %m", hname); + /* mark sockfd as not usable, by closing and set to -1 */ + close(server->sockfd); + server->sockfd = -1; + return 1; + } return 0; } @@ -1352,7 +1352,9 @@ static void setup_userinfo(pam_handle_t * pamh, radius_conf_t *cfg, const char *user, int debug, int privileged) { - struct passwd *pw; + struct passwd *pw = NULL, *pwp = NULL; + uid_t uid = (uid_t)~0; + char *homedir = NULL; /* * set SUDO_PROMPT in env so that it prompts as the login user, not the @@ -1369,21 +1371,15 @@ setup_userinfo(pam_handle_t * pamh, radius_conf_t *cfg, const char *user, "failed to set PAM sudo prompt " "(%s)", nprompt); } - pw = getpwnam(user); /* this should never fail, at this point... */ - if (!pw) { - if (debug) - pam_syslog(pamh, LOG_DEBUG, - "Failed to get homedir for user (%s)", user); - return; - } /* * because the RADIUS protocol is single pass, we always have the * pw_uid of the unprivileged account at this point. Set things up - * so we use the uid of the privileged radius account. + * so we use the uid of the privileged radius account. We do this + * for the uid. The homedir from this will be the unmapped privileged + * radius user itself, not the login. */ if (privileged) { - struct passwd *pwp; if (!cfg->privusrmap[0] || !(pwp = getpwnam(cfg->privusrmap))) { _pam_log(pamh, LOG_WARNING, "Failed to find uid for" " privileged account %s, uid may be wrong" @@ -1391,11 +1387,18 @@ setup_userinfo(pam_handle_t * pamh, radius_conf_t *cfg, const char *user, cfg->privusrmap[0] ? cfg->privusrmap : "(unset in config)", user); } - else if (pwp && pw->pw_uid != pwp->pw_uid) { - syslog(LOG_DEBUG, "OLSON wrmap user=%s, but uid=%u, change to %u", - user, pw->pw_uid, pwp->pw_uid); - pw->pw_uid = pwp->pw_uid; - } + if (pwp) + uid = pwp->pw_uid; + } + + pw = getpwnam(user); + if (uid == (uid_t)~0 && pw) + uid = pw->pw_uid; + + if (uid == (uid_t)~0) { + pam_syslog(pamh, LOG_WARNING, + "Failed to get user UID for user (%s)", user); + return; /* can't do anything */ } /* @@ -1403,8 +1406,25 @@ setup_userinfo(pam_handle_t * pamh, radius_conf_t *cfg, const char *user, * the session, although they can result in name or uid lookups not * working correctly. */ - __write_mapfile(pamh, user, pw->pw_uid, privileged, debug); - __chk_homedir(pamh, user, pw->pw_dir, debug); + __write_mapfile(pamh, user, uid, privileged, debug); + + if(privileged) { /* now we can get the correct homedir for priv user */ + if (!(pwp = getpwnam(user))) { + _pam_log(pamh, LOG_WARNING, "Failed to find home dir" + " for privileged user %s", user); + } + else + homedir = pwp->pw_dir; + } + + if (!homedir && pw) /* not privileged, or priv and getpwnam failed */ + homedir = pw->pw_dir; + + if (!homedir) + pam_syslog(pamh, LOG_WARNING, + "Failed to get home directory for user (%s)", user); + else + __chk_homedir(pamh, user, homedir, debug); } /* this is used so that sm_auth returns an appropriate value */ @@ -1506,7 +1526,8 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t * pamh, int flags, int argc, if (password) { password = strdup(password); - DPRINT(pamh, LOG_DEBUG, "Got password %s", password); + /* do not show actual password; it's a security issue */ + DPRINT(pamh, LOG_DEBUG, "Got password from user"); } /* no previous password: maybe get one from the user */ diff --git a/src/radius_shell.c b/src/radius_shell.c index ee3b69b..81ecb65 100644 --- a/src/radius_shell.c +++ b/src/radius_shell.c @@ -44,24 +44,23 @@ #include <string.h> #include <errno.h> #include <stdio.h> -#include <stdbool.h> #include <sys/fsuid.h> #include <sys/capability.h> int main(int cnt, char **args) { - uid_t uid, auid; + uid_t uid, auid, euid; cap_value_t capability[] = { CAP_SETUID}; cap_t capabilities; - char *shell = NULL, *check = NULL, execshell[64]; - bool priv = true; + char *shell = NULL, *check = NULL, execshell[64], shellenv[64+6]; uid = getuid(); + euid = geteuid(); auid = audit_getloginuid(); - if (uid < 1000 || auid < 1000 || auid == (uid_t)-1 || uid == auid) { + if (uid < 1000 || auid < 1000 || auid == (uid_t)-1 || + (uid == auid && uid == euid)) { /* We try to be careful in what we will change */ - priv = false; goto execit; } @@ -71,9 +70,9 @@ int main(int cnt, char **args) if (setresuid(auid, auid, auid)) fprintf(stderr, "Failed to set uid to %u: %s\n", auid, strerror(errno)); - if (getuid() != auid) - fprintf(stderr, "Failed to set uid to %u it's still %u\n", - auid, getuid()); + if (getuid() != auid || geteuid() != auid) + fprintf(stderr, "Failed to set uid to %u but uid=%u, euid=%u\n", + auid, getuid(), geteuid()); execit: /* be paranoid, and clear our expected CAP_SETUID capability, @@ -113,25 +112,17 @@ execit: /* should really check this against /etc/shell */ snprintf(execshell, sizeof execshell, "/bin/%s", check); #else - if (priv) { - check = "vbash"; - if (*args[0] == '-') - shell = "-vbash"; - else - shell = "vbash"; - snprintf(execshell, sizeof execshell, "/bin/%s", check); - } - else { - check = "restricted-shell"; - if (*args[0] == '-') - shell = "-restricted-shell"; - else - shell = "restricted-shell"; - snprintf(execshell, sizeof execshell, "/opt/vyatta/bin/%s", check); - } + check = "bash"; + if (*args[0] == '-') + shell = "-bash"; + else + shell = "bash"; + snprintf(execshell, sizeof execshell, "/bin/%s", check); #endif args[0] = shell; + snprintf(shellenv, sizeof shellenv, "SHELL=%s", execshell); + putenv(shellenv); execv(execshell, args); fprintf(stderr, "Exec of shell %s failed: %s\n", execshell, strerror(errno)); |