From 3cee0494d3bc79adf496251b42dc2b0ff7848380 Mon Sep 17 00:00:00 2001 From: Jeroen Date: Sat, 20 Aug 2011 00:15:08 +0200 Subject: Added _pam_get_rhost() and _pam_get_user() --- ChangeLog | 2 ++ libtac/include/libtac.h | 4 +-- pam_tacplus.c | 83 ++++++++++++++++--------------------------------- support.c | 43 +++++++++++++++++++------ support.h | 2 ++ 5 files changed, 66 insertions(+), 68 deletions(-) diff --git a/ChangeLog b/ChangeLog index ddf002c..953e76a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,8 @@ * Finally got rid of all goto illness! * Changed tabsize to 4 * Fixed missing xalloc.h in authen_s.c +* Get PAM_RHOST from PAM stack and use it as rem_addr +* Added _pam_get_rhost() and _pam_get_user() * The following is done by Darren Besler: - add ability to set more elements of tacacs+ packet from parameters or globals diff --git a/libtac/include/libtac.h b/libtac/include/libtac.h index fbe16ba..d7a2071 100644 --- a/libtac/include/libtac.h +++ b/libtac/include/libtac.h @@ -42,8 +42,8 @@ extern "C" { #if defined(DEBUGTAC) && !defined(TACDEBUG) #define TACDEBUG(x) syslog x; #else -#define TACDEBUG(x) syslog x; -// #define TACDEBUG(x) +//#define TACDEBUG(x) syslog x; +#define TACDEBUG(x) #endif #define TACSYSLOG(x) syslog x; diff --git a/pam_tacplus.c b/pam_tacplus.c index e668297..b6f8003 100644 --- a/pam_tacplus.c +++ b/pam_tacplus.c @@ -86,7 +86,7 @@ static short int task_id = 0; /* Helper functions */ -int _pam_send_account(int tac_fd, int type, const char *user, char *tty) { +int _pam_send_account(int tac_fd, int type, const char *user, char *tty, char *rem_addr) { char buf[40]; struct tac_attrib *attr; int retval; @@ -107,7 +107,7 @@ int _pam_send_account(int tac_fd, int type, const char *user, char *tty) { tac_add_attrib(&attr, "service", tac_service); tac_add_attrib(&attr, "protocol", tac_protocol); - retval = tac_account_send(tac_fd, type, user, tty, "", attr); + retval = tac_account_send(tac_fd, type, user, tty, rem_addr, attr); /* this is no longer needed */ tac_free_attrib(&attr); @@ -140,12 +140,9 @@ int _pam_send_account(int tac_fd, int type, const char *user, char *tty) { int _pam_account(pam_handle_t *pamh, int argc, const char **argv, int type) { int retval; static int ctrl; -#if (defined(__linux__) || defined(__NetBSD__)) char *user = NULL; -#else - const char *user = NULL; -#endif char *tty = NULL; + char *rem_addr = NULL; char *typemsg; int status = PAM_SESSION_ERR; @@ -158,27 +155,22 @@ int _pam_account(pam_handle_t *pamh, int argc, const char **argv, int type) { if (ctrl & PAM_TAC_DEBUG) syslog(LOG_DEBUG, "%s: tac_srv_no=%d", __FUNCTION__, tac_srv_no); -#if (defined(__linux__) || defined(__NetBSD__)) - retval = pam_get_item(pamh, PAM_USER, (const void **) (const void*) &user); -#else - retval = pam_get_item(pamh, PAM_USER, (void **) (void*) &user); -#endif - if(retval != PAM_SUCCESS || user == NULL || *user == '\0') { - _pam_log(LOG_ERR, "%s: unable to obtain username", __FUNCTION__); - return PAM_SESSION_ERR; - } + if ((user = _pam_get_user(pamh)) == NULL) + return PAM_USER_UNKNOWN; if (ctrl & PAM_TAC_DEBUG) syslog(LOG_DEBUG, "%s: username [%s] obtained", __FUNCTION__, user); tty = _pam_get_terminal(pamh); - if(!strncmp(tty, "/dev/", 5)) tty += 5; - if (ctrl & PAM_TAC_DEBUG) syslog(LOG_DEBUG, "%s: tty [%s] obtained", __FUNCTION__, tty); + rem_addr = _pam_get_rhost(pamh); + if (ctrl & PAM_TAC_DEBUG) + syslog(LOG_DEBUG, "%s: rhost [%s] obtained", __FUNCTION__, rem_addr); + /* checks for specific data required by TACACS+, which should be supplied in command line */ if(tac_service == NULL || *tac_service == '\0') { @@ -216,7 +208,7 @@ int _pam_account(pam_handle_t *pamh, int argc, const char **argv, int type) { if (ctrl & PAM_TAC_DEBUG) syslog(LOG_DEBUG, "%s: connected with fd=%d", __FUNCTION__, tac_fd); - retval = _pam_send_account(tac_fd, type, user, tty); + retval = _pam_send_account(tac_fd, type, user, tty, rem_addr); if(retval < 0) { _pam_log(LOG_ERR, "%s: error sending %s", __FUNCTION__, typemsg); @@ -246,7 +238,7 @@ int _pam_account(pam_handle_t *pamh, int argc, const char **argv, int type) { if (ctrl & PAM_TAC_DEBUG) syslog(LOG_DEBUG, "%s: connected with fd=%d (srv %d)", __FUNCTION__, tac_fd, srv_i); - retval = _pam_send_account(tac_fd, type, user, tty); + retval = _pam_send_account(tac_fd, type, user, tty, rem_addr); /* return code from function in this mode is status of the last server we tried to send packet to */ @@ -283,18 +275,15 @@ int pam_sm_authenticate (pam_handle_t * pamh, int flags, int argc, const char **argv) { int ctrl, retval; -#if (defined(__linux__) || defined(__NetBSD__)) - const char *user; -#else char *user; -#endif char *pass; char *tty; + char *rem_addr; int srv_i; int tac_fd; int status = PAM_AUTH_ERR; - user = pass = tty = NULL; + user = pass = tty = rem_addr = NULL; ctrl = _pam_parse (argc, argv); @@ -302,11 +291,8 @@ int pam_sm_authenticate (pam_handle_t * pamh, int flags, syslog (LOG_DEBUG, "%s: called (pam_tacplus v%hu.%hu.%hu)" , __FUNCTION__, PAM_TAC_VMAJ, PAM_TAC_VMIN, PAM_TAC_VPAT); - retval = pam_get_user (pamh, &user, "Username: "); - if (retval != PAM_SUCCESS || user == NULL || *user == '\0') { - _pam_log (LOG_ERR, "unable to obtain username"); + if ((user = _pam_get_user(pamh)) == NULL) return PAM_USER_UNKNOWN; - } if (ctrl & PAM_TAC_DEBUG) syslog (LOG_DEBUG, "%s: user [%s] obtained", __FUNCTION__, user); @@ -329,13 +315,15 @@ int pam_sm_authenticate (pam_handle_t * pamh, int flags, syslog (LOG_DEBUG, "%s: password obtained", __FUNCTION__); tty = _pam_get_terminal(pamh); - if (!strncmp (tty, "/dev/", 5)) tty += 5; - if (ctrl & PAM_TAC_DEBUG) syslog (LOG_DEBUG, "%s: tty [%s] obtained", __FUNCTION__, tty); + rem_addr = _pam_get_rhost(pamh); + if (ctrl & PAM_TAC_DEBUG) + syslog (LOG_DEBUG, "%s: rhost [%s] obtained", __FUNCTION__, rem_addr); + for (srv_i = 0; srv_i < tac_srv_no; srv_i++) { int msg = TAC_PLUS_AUTHEN_STATUS_FAIL; if (ctrl & PAM_TAC_DEBUG) @@ -351,7 +339,7 @@ int pam_sm_authenticate (pam_handle_t * pamh, int flags, continue; } - if (tac_authen_send(tac_fd, user, pass, tty, "") < 0) { + if (tac_authen_send(tac_fd, user, pass, tty, rem_addr) < 0) { _pam_log (LOG_ERR, "error sending auth req to TACACS+ server"); status = PAM_AUTHINFO_UNAVAIL; } else { @@ -428,17 +416,14 @@ int pam_sm_acct_mgmt (pam_handle_t * pamh, int flags, int argc, const char **argv) { int retval, ctrl, status=PAM_AUTH_ERR; -#if (defined(__linux__) || defined(__NetBSD__)) - const char *user; -#else char *user; -#endif char *tty; + char *rem_addr; struct areply arep; struct tac_attrib *attr = NULL; int tac_fd; - user = tty = NULL; + user = tty = rem_addr = NULL; /* this also obtains service name for authorization this should be normally performed by pam_get_item(PAM_SERVICE) @@ -454,26 +439,21 @@ int pam_sm_acct_mgmt (pam_handle_t * pamh, int flags, tac_ntop(active_server->ai_addr, active_server->ai_addrlen)); } -#if (defined(__linux__) || defined(__NetBSD__)) - retval = pam_get_item(pamh, PAM_USER, (const void **) (const void*) &user); -#else - retval = pam_get_item(pamh, PAM_USER, (void **) (void*) &user); -#endif - if (retval != PAM_SUCCESS || user == NULL || *user == '\0') { - _pam_log (LOG_ERR, "unable to obtain username"); + if ((user = _pam_get_user(pamh)) == NULL) return PAM_USER_UNKNOWN; - } if (ctrl & PAM_TAC_DEBUG) syslog(LOG_DEBUG, "%s: username obtained [%s]", __FUNCTION__, user); tty = _pam_get_terminal(pamh); - if(!strncmp(tty, "/dev/", 5)) tty += 5; - if (ctrl & PAM_TAC_DEBUG) syslog(LOG_DEBUG, "%s: tty obtained [%s]", __FUNCTION__, tty); + + rem_addr = _pam_get_rhost(pamh); + if (ctrl & PAM_TAC_DEBUG) + syslog(LOG_DEBUG, "%s: rhost obtained [%s]", __FUNCTION__, rem_addr); /* checks if user has been successfully authenticated by TACACS+; we cannot solely authorize user if it hasn't @@ -506,7 +486,7 @@ int pam_sm_acct_mgmt (pam_handle_t * pamh, int flags, return PAM_AUTH_ERR; } - retval = tac_author_send(tac_fd, user, tty, "", attr); + retval = tac_author_send(tac_fd, user, tty, rem_addr, attr); tac_free_attrib(&attr); @@ -561,15 +541,6 @@ int pam_sm_acct_mgmt (pam_handle_t * pamh, int flags, if (ctrl & PAM_TAC_DEBUG) syslog(LOG_DEBUG, "%s: returned attribute `%s%s' from server", __FUNCTION__, attribute, value); - /* set PAM_RHOST if 'addr' attribute was returned from server */ - if(!strncmp(attribute, "addr", 4) && isdigit((int)*value)) { - retval = pam_set_item(pamh, PAM_RHOST, value); - if (retval != PAM_SUCCESS) - syslog(LOG_WARNING, "%s: unable to set remote address for PAM", __FUNCTION__); - else if(ctrl & PAM_TAC_DEBUG) - syslog(LOG_DEBUG, "%s: set remote addr to `%s'", __FUNCTION__, value); - } - /* make returned attributes available for other PAM modules via PAM environment */ if (pam_putenv(pamh, strncat(attribute, value, strlen(value))) != PAM_SUCCESS) syslog(LOG_WARNING, "%s: unable to set PAM environment", __FUNCTION__); diff --git a/support.c b/support.c index 864772e..33362d9 100644 --- a/support.c +++ b/support.c @@ -59,11 +59,35 @@ void *_xcalloc (size_t size) { #define _xcalloc xcalloc #endif +void _pam_log(int err, const char *format,...) { + char msg[256]; + va_list args; + + va_start(args, format); + vsnprintf(msg, sizeof(msg), format, args); + openlog("PAM-tacplus", LOG_PID, LOG_AUTH); + syslog(err, "%s", msg); + va_end(args); + closelog(); +} + +char *_pam_get_user(pam_handle_t *pamh) { + int retval; + char *user; + + retval = pam_get_user(pamh, (void *)&user, "Username: "); + if (retval != PAM_SUCCESS || user == NULL || *user == '\0') { + _pam_log(LOG_ERR, "unable to obtain username"); + user = NULL; + } + return user; +} + char *_pam_get_terminal(pam_handle_t *pamh) { int retval; char *tty; - retval = pam_get_item (pamh, PAM_TTY, (void *)&tty); + retval = pam_get_item(pamh, PAM_TTY, (void *)&tty); if (retval != PAM_SUCCESS || tty == NULL || *tty == '\0') { tty = ttyname(STDIN_FILENO); if(tty == NULL || *tty == '\0') @@ -72,16 +96,15 @@ char *_pam_get_terminal(pam_handle_t *pamh) { return tty; } -void _pam_log(int err, const char *format,...) { - char msg[256]; - va_list args; +char *_pam_get_rhost(pam_handle_t *pamh) { + int retval; + char *rhost; - va_start(args, format); - vsnprintf(msg, sizeof(msg), format, args); - openlog("PAM-tacplus", LOG_PID, LOG_AUTH); - syslog(err, "%s", msg); - va_end(args); - closelog(); + retval = pam_get_item(pamh, PAM_RHOST, (void *)&rhost); + if (retval != PAM_SUCCESS || rhost == NULL || *rhost == '\0') { + rhost = "unknown"; + } + return rhost; } /* stolen from pam_stress */ diff --git a/support.h b/support.h index 6ae8216..f5173fa 100644 --- a/support.h +++ b/support.h @@ -34,4 +34,6 @@ extern int converse (pam_handle_t * pamh, int nargs ,struct pam_response **response); extern void _pam_log (int err, const char *format,...); extern void *_xcalloc (size_t size); +extern char *_pam_get_user(pam_handle_t *pamh); extern char *_pam_get_terminal(pam_handle_t *pamh); +extern char *_pam_get_rhost(pam_handle_t *pamh); -- cgit v1.2.3