summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWalter de Jong <walter@heiho.net>2013-03-28 23:10:43 +0100
committerWalter de Jong <walter@heiho.net>2013-03-28 23:10:43 +0100
commit1119da92c3c47a2cb2a48d494f98ff10a6c32619 (patch)
tree80727ab0d5542f8dc05d59f292bfe05c51af73af
parente9fd08a5d571c852f1f47f0e4cead8161a919d0b (diff)
downloadpam_tacplus-1119da92c3c47a2cb2a48d494f98ff10a6c32619.tar.gz
pam_tacplus-1119da92c3c47a2cb2a48d494f98ff10a6c32619.zip
server is a struct { address, key }
-rw-r--r--libtac/include/libtac.h4
-rw-r--r--libtac/lib/header.c2
-rw-r--r--pam_tacplus.c57
-rw-r--r--support.c46
-rw-r--r--support.h9
5 files changed, 72 insertions, 46 deletions
diff --git a/libtac/include/libtac.h b/libtac/include/libtac.h
index 36dc9b0..bcc5880 100644
--- a/libtac/include/libtac.h
+++ b/libtac/include/libtac.h
@@ -113,7 +113,7 @@ extern int tac_ver_patch;
/* header.c */
extern int session_id;
extern int tac_encryption;
-extern char *tac_secret;
+extern const char *tac_secret;
extern char *tac_login;
extern int tac_priv_lvl;
extern int tac_authen_method;
@@ -126,7 +126,7 @@ extern int tac_readtimeout_enable;
extern int tac_timeout;
int tac_connect(struct addrinfo **, char **, int);
-int tac_connect_single(struct addrinfo *, char *);
+int tac_connect_single(struct addrinfo *, const char *);
char *tac_ntop(const struct sockaddr *, size_t);
int tac_authen_send(int, const char *, char *, char *,
diff --git a/libtac/lib/header.c b/libtac/lib/header.c
index f361225..dd04c92 100644
--- a/libtac/lib/header.c
+++ b/libtac/lib/header.c
@@ -33,7 +33,7 @@ int session_id;
int tac_encryption = 0;
/* Pointer to TACACS+ shared secret string. */
-char *tac_secret = NULL;
+const char *tac_secret = NULL;
/* Pointer to TACACS+ shared login string. */
char *tac_login = NULL; /* default is PAP */
diff --git a/pam_tacplus.c b/pam_tacplus.c
index 42d5f54..ea2478c 100644
--- a/pam_tacplus.c
+++ b/pam_tacplus.c
@@ -42,8 +42,8 @@
#endif
/* address of server discovered by pam_sm_authenticate */
-static struct addrinfo *active_server = NULL;
-static char *active_key = NULL;
+static tacplus_server_t *active_server = NULL;
+
/* accounting task identifier */
static short int task_id = 0;
@@ -169,7 +169,7 @@ int _pam_account(pam_handle_t *pamh, int argc, const char **argv,
while ((status == PAM_SESSION_ERR) && (srv_i < tac_srv_no)) {
int tac_fd;
- tac_fd = tac_connect_single(tac_srv[srv_i], tac_srv_key[srv_i]);
+ tac_fd = tac_connect_single(tac_srv[srv_i].addr, tac_srv[srv_i].key);
if(tac_fd < 0) {
_pam_log(LOG_WARNING, "%s: error sending %s (fd)",
__FUNCTION__, typemsg);
@@ -204,7 +204,7 @@ int _pam_account(pam_handle_t *pamh, int argc, const char **argv,
for(srv_i = 0; srv_i < tac_srv_no; srv_i++) {
int tac_fd;
- tac_fd = tac_connect_single(tac_srv[srv_i], tac_srv_key[srv_i]);
+ tac_fd = tac_connect_single(tac_srv[srv_i].addr, tac_srv[srv_i].key);
if(tac_fd < 0) {
_pam_log(LOG_WARNING, "%s: error sending %s (fd)",
__FUNCTION__, typemsg);
@@ -260,6 +260,7 @@ int pam_sm_authenticate (pam_handle_t * pamh, int flags,
int status = PAM_AUTH_ERR;
user = pass = tty = r_addr = NULL;
+ active_server = NULL;
ctrl = _pam_parse (argc, argv);
@@ -305,7 +306,7 @@ int pam_sm_authenticate (pam_handle_t * pamh, int flags,
if (ctrl & PAM_TAC_DEBUG)
syslog (LOG_DEBUG, "%s: trying srv %d", __FUNCTION__, srv_i );
- tac_fd = tac_connect_single(tac_srv[srv_i], tac_srv_key[srv_i]);
+ tac_fd = tac_connect_single(tac_srv[srv_i].addr, tac_srv[srv_i].key);
if (tac_fd < 0) {
_pam_log (LOG_ERR, "connection failed srv %d: %m", srv_i);
if (srv_i == tac_srv_no-1) {
@@ -335,9 +336,12 @@ int pam_sm_authenticate (pam_handle_t * pamh, int flags,
/* OK, we got authenticated; save the server that
accepted us for pam_sm_acct_mgmt and exit the loop */
status = PAM_SUCCESS;
- active_server = tac_srv[srv_i];
- active_key = tac_srv_key[srv_i];
+ active_server = &tac_srv[srv_i];
close(tac_fd);
+
+ if (ctrl & PAM_TAC_DEBUG)
+ syslog (LOG_DEBUG, "%s: active srv %d", __FUNCTION__, srv_i );
+
break;
}
}
@@ -348,9 +352,12 @@ int pam_sm_authenticate (pam_handle_t * pamh, int flags,
/* OK, we got authenticated; save the server that
accepted us for pam_sm_acct_mgmt and exit the loop */
status = PAM_SUCCESS;
- active_server = tac_srv[srv_i];
- active_key = tac_srv_key[srv_i];
+ active_server = &tac_srv[srv_i];
close(tac_fd);
+
+ if (ctrl & PAM_TAC_DEBUG)
+ syslog (LOG_DEBUG, "%s: active srv %d", __FUNCTION__, srv_i );
+
break;
}
}
@@ -417,7 +424,7 @@ int pam_sm_acct_mgmt (pam_handle_t * pamh, int flags,
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;
@@ -432,21 +439,21 @@ int pam_sm_acct_mgmt (pam_handle_t * pamh, int flags,
by TACACS+; we cannot solely authorize user if it hasn't
been authenticated or has been authenticated by method other
than TACACS+ */
- if(!active_server) {
+ if(active_server == NULL) {
_pam_log (LOG_ERR, "user not authenticated by TACACS+");
return PAM_AUTH_ERR;
}
if (ctrl & PAM_TAC_DEBUG)
syslog (LOG_DEBUG, "%s: active server is [%s]", __FUNCTION__,
- tac_ntop(active_server->ai_addr, active_server->ai_addrlen));
+ tac_ntop(active_server->addr->ai_addr, active_server->addr->ai_addrlen));
/* checks for specific data required by TACACS+, which should
be supplied in command line */
- if(tac_service == NULL || *tac_service == '\0') {
+ if(tac_service == NULL || !*tac_service) {
_pam_log (LOG_ERR, "TACACS+ service type not configured");
return PAM_AUTH_ERR;
}
- if(tac_protocol == NULL || *tac_protocol == '\0') {
+ if(tac_protocol == NULL || !*tac_protocol) {
_pam_log (LOG_ERR, "TACACS+ protocol type not configured");
return PAM_AUTH_ERR;
}
@@ -454,10 +461,12 @@ int pam_sm_acct_mgmt (pam_handle_t * pamh, int flags,
tac_add_attrib(&attr, "service", tac_service);
tac_add_attrib(&attr, "protocol", tac_protocol);
- tac_fd = tac_connect_single(active_server, active_key);
+ tac_fd = tac_connect_single(active_server->addr, active_server->key);
if(tac_fd < 0) {
_pam_log (LOG_ERR, "TACACS+ server unavailable");
- if(arep.msg != NULL) free (arep.msg);
+ if(arep.msg != NULL)
+ free (arep.msg);
+
close(tac_fd);
return PAM_AUTH_ERR;
}
@@ -468,7 +477,9 @@ int pam_sm_acct_mgmt (pam_handle_t * pamh, int flags,
if(retval < 0) {
_pam_log (LOG_ERR, "error getting authorization");
- if(arep.msg != NULL) free (arep.msg);
+ if(arep.msg != NULL)
+ free (arep.msg);
+
close(tac_fd);
return PAM_AUTH_ERR;
}
@@ -482,7 +493,9 @@ int pam_sm_acct_mgmt (pam_handle_t * pamh, int flags,
arep.status != AUTHOR_STATUS_PASS_REPL) {
_pam_log (LOG_ERR, "TACACS+ authorisation failed for [%s]", user);
- if(arep.msg != NULL) free (arep.msg);
+ if(arep.msg != NULL)
+ free (arep.msg);
+
close(tac_fd);
return PAM_PERM_DENIED;
}
@@ -528,8 +541,12 @@ int pam_sm_acct_mgmt (pam_handle_t * pamh, int flags,
}
/* free returned attributes */
- if(arep.attr != NULL) tac_free_attrib(&arep.attr);
- if(arep.msg != NULL) free (arep.msg);
+ if(arep.attr != NULL)
+ tac_free_attrib(&arep.attr);
+
+ if(arep.msg != NULL)
+ free (arep.msg);
+
close(tac_fd);
return status;
diff --git a/support.c b/support.c
index df09aba..101a8e0 100644
--- a/support.c
+++ b/support.c
@@ -27,10 +27,9 @@
#include "support.h"
#include "pam_tacplus.h"
-struct addrinfo *tac_srv[TAC_PLUS_MAXSERVERS];
+tacplus_server_t tac_srv[TAC_PLUS_MAXSERVERS];
int tac_srv_no = 0;
-char *tac_srv_key[TAC_PLUS_MAXSERVERS];
-int tac_srv_key_no = 0;
+
char *tac_service = NULL;
char *tac_protocol = NULL;
char *tac_prompt = NULL;
@@ -186,9 +185,11 @@ int tacacs_get_password (pam_handle_t * pamh, int flags
int _pam_parse (int argc, const char **argv) {
int ctrl = 0;
+ const char *current_secret = NULL;
/* otherwise the list will grow with each call */
- tac_srv_no = tac_srv_key_no = 0;
+ memset(tac_srv, 0, sizeof(tacplus_server_t) * TAC_PLUS_MAXSERVERS);
+ tac_srv_no = 0;
for (ctrl = 0; argc-- > 0; ++argv) {
if (!strcmp (*argv, "debug")) { /* all */
@@ -238,7 +239,8 @@ int _pam_parse (int argc, const char **argv) {
}
if ((rv = getaddrinfo(server_buf, (port == NULL) ? "49" : port, &hints, &servers)) == 0) {
for(server = servers; server != NULL && tac_srv_no < TAC_PLUS_MAXSERVERS; server = server->ai_next) {
- tac_srv[tac_srv_no] = server;
+ tac_srv[tac_srv_no].addr = server;
+ tac_srv[tac_srv_no].key = current_secret;
tac_srv_no++;
}
} else {
@@ -251,13 +253,16 @@ int _pam_parse (int argc, const char **argv) {
TAC_PLUS_MAXSERVERS);
}
} else if (!strncmp (*argv, "secret=", 7)) {
- if(tac_srv_key_no < TAC_PLUS_MAXSERVERS) {
- tac_srv_key[tac_srv_key_no] = (char *) _xcalloc (strlen (*argv + 7) + 1);
- strcpy (tac_srv_key[tac_srv_key_no], *argv + 7);
- tac_srv_key_no++;
- } else {
- _pam_log(LOG_ERR, "maximum number of secrets (%d) exceeded, skipping",
- TAC_PLUS_MAXSERVERS);
+ int i;
+
+ current_secret = *argv + 7; /* points right into argv (which is const) */
+
+ /* if 'secret=' was given after a 'server=' parameter, fill in the current secret */
+ for(i = tac_srv_no-1; i >= 0; i--) {
+ if (tac_srv[i].key != NULL)
+ break;
+
+ tac_srv[i].key = current_secret;
}
} else if (!strncmp (*argv, "timeout=", 8)) {
tac_timeout = atoi(*argv + 8);
@@ -269,15 +274,14 @@ int _pam_parse (int argc, const char **argv) {
}
}
- if (tac_srv_key_no == 0) {
- /* FIXME this should really be NULL
- but watch out with breaking other code
- */
- tac_srv_key[0] = "";
- tac_srv_key_no++;
- }
- for (;tac_srv_key_no < tac_srv_no;tac_srv_key_no++) {
- tac_srv_key[tac_srv_key_no] = tac_srv_key[0];
+ if (ctrl & PAM_TAC_DEBUG) {
+ int n;
+
+ _pam_log(LOG_DEBUG, "%d servers defined", tac_srv_no);
+
+ for(n = 0; n < tac_srv_no; n++) {
+ _pam_log(LOG_DEBUG, "server[%d] { addr=%s, key='%s' }", n, tac_ntop(tac_srv[n].addr->ai_addr, 0), tac_srv[n].key);
+ }
}
return ctrl;
diff --git a/support.h b/support.h
index 9662961..260dea6 100644
--- a/support.h
+++ b/support.h
@@ -26,9 +26,14 @@
#include <security/pam_modules.h>
-extern struct addrinfo *tac_srv[TAC_PLUS_MAXSERVERS];
-extern char *tac_srv_key[TAC_PLUS_MAXSERVERS];
+typedef struct {
+ struct addrinfo *addr;
+ const char *key;
+} tacplus_server_t;
+
+extern tacplus_server_t tac_srv[TAC_PLUS_MAXSERVERS];
extern int tac_srv_no;
+
extern char *tac_service;
extern char *tac_protocol;