diff options
author | Christian Poessinger <christian@poessinger.com> | 2021-05-02 18:13:57 +0200 |
---|---|---|
committer | Christian Poessinger <christian@poessinger.com> | 2021-05-02 18:13:57 +0200 |
commit | cf571ca6c722d3d2b0c359dddf835a3f406b194b (patch) | |
tree | 4be4d38d93d9bd7ccb5501598f4b8e7b4f364167 /src | |
parent | defad29d4ce43f1be5e05fba902fc31f6aafa5f2 (diff) | |
download | libpam-radius-auth-cf571ca6c722d3d2b0c359dddf835a3f406b194b.tar.gz libpam-radius-auth-cf571ca6c722d3d2b0c359dddf835a3f406b194b.zip |
Update package to 1.5.0-cl3u7
Diffstat (limited to 'src')
-rw-r--r-- | src/pam_radius_auth.c | 73 | ||||
-rw-r--r-- | src/radius_shell.c | 41 |
2 files changed, 63 insertions, 51 deletions
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)); |