Skip to content
This repository has been archived by the owner on Feb 28, 2024. It is now read-only.

Fix memory leakage related to tac_svr #73

Merged
merged 5 commits into from
Dec 3, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions pam_tacplus.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,23 @@

/* address of server discovered by pam_sm_authenticate */
static tacplus_server_t active_server;
struct addrinfo active_addrinfo;
struct sockaddr active_sockaddr;
char active_key[TAC_SECRET_MAX_LEN+1];

/* accounting task identifier */
static short int task_id = 0;

/* copy a server's information into active_server */
static void set_active_server (const tacplus_server_t *tac_svr)
{
active_addrinfo.ai_addr = &active_sockaddr;
tac_copy_addr_info (&active_addrinfo, tac_svr->addr);
strncpy (active_key, tac_svr->key ? tac_svr->key : "", TAC_SECRET_MAX_LEN-1);
active_server.addr = &active_addrinfo;
active_server.key = active_key;
}

/* Helper functions */
int _pam_send_account(int tac_fd, int type, const char *user, char *tty,
char *r_addr, char *cmd) {
Expand Down Expand Up @@ -277,12 +290,14 @@ int pam_sm_authenticate(pam_handle_t * pamh, int flags, int argc,
NULL, tac_timeout);
if (tac_fd < 0) {
_pam_log(LOG_ERR, "connection failed srv %d: %m", srv_i);
active_server.addr = NULL;
continue;
}
if (tac_authen_send(tac_fd, user, pass, tty, r_addr,
TAC_PLUS_AUTHEN_LOGIN) < 0) {
close(tac_fd);
_pam_log(LOG_ERR, "error sending auth req to TACACS+ server");
active_server.addr = NULL;
continue;
}
communicating = 1;
Expand Down Expand Up @@ -321,8 +336,7 @@ int pam_sm_authenticate(pam_handle_t * pamh, int flags, int argc,
}
status = PAM_SUCCESS;
communicating = 0;
active_server.addr = tac_srv[srv_i].addr;
active_server.key = tac_srv[srv_i].key;
set_active_server(&tac_srv[srv_i]);

if (ctrl & PAM_TAC_DEBUG)
syslog(LOG_DEBUG, "%s: active srv %d", __FUNCTION__, srv_i);
Expand Down Expand Up @@ -612,6 +626,7 @@ int pam_sm_acct_mgmt(pam_handle_t * pamh, int flags, int argc,
free(arep.msg);

close(tac_fd);
active_server.addr = NULL;
return PAM_AUTH_ERR;
}

Expand Down Expand Up @@ -843,9 +858,7 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags, int argc,
}
status = PAM_SUCCESS;
communicating = 0;

active_server.addr = tac_srv[srv_i].addr;
active_server.key = tac_srv[srv_i].key;
set_active_server(&tac_srv[srv_i]);

if (ctrl & PAM_TAC_DEBUG)
syslog(LOG_DEBUG, "%s: active srv %d", __FUNCTION__, srv_i);
Expand Down
51 changes: 48 additions & 3 deletions support.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ int tac_srv_no = 0;
char tac_service[64];
char tac_protocol[64];
char tac_prompt[64];
struct addrinfo tac_srv_addr[TAC_PLUS_MAXSERVERS];
struct sockaddr tac_sock_addr[TAC_PLUS_MAXSERVERS];
char tac_srv_key[TAC_PLUS_MAXSERVERS][TAC_SECRET_MAX_LEN+1];

void _pam_log(int err, const char *format,...) {
char msg[256];
Expand Down Expand Up @@ -172,6 +175,47 @@ int tacacs_get_password (pam_handle_t * pamh, int flags,
return PAM_SUCCESS;
}

void tac_copy_addr_info (struct addrinfo *p_dst, const struct addrinfo *p_src)
{
if (p_dst && p_src) {
p_dst->ai_flags = p_src->ai_flags;
p_dst->ai_family = p_src->ai_family;
p_dst->ai_socktype = p_src->ai_socktype;
p_dst->ai_protocol = p_src->ai_protocol;
p_dst->ai_addrlen = p_src->ai_addrlen;
memcpy (p_dst->ai_addr, p_src->ai_addr, sizeof(struct sockaddr));
p_dst->ai_canonname = NULL; /* we do not care it */
p_dst->ai_next = NULL; /* no more chain */
}
}

static void set_tac_srv_addr (unsigned int srv_no, const struct addrinfo *addr)
{
if (srv_no < TAC_PLUS_MAXSERVERS) {
if (addr) {
tac_srv_addr[srv_no].ai_addr = &tac_sock_addr[srv_no];
tac_copy_addr_info (&tac_srv_addr[srv_no], addr);
tac_srv[srv_no].addr = &tac_srv_addr[srv_no];
}
else {
tac_srv[srv_no].addr = NULL;
}
}
}

static void set_tac_srv_key (unsigned int srv_no, const char *key)
{
if (srv_no < TAC_PLUS_MAXSERVERS) {
if (key) {
strncpy (tac_srv_key[srv_no], key, TAC_SECRET_MAX_LEN-1);
tac_srv[srv_no].key = tac_srv_key[srv_no];
}
else {
tac_srv[srv_no].key = NULL;
}
}
}

int _pam_parse (int argc, const char **argv) {
int ctrl = 0;
const char *current_secret = NULL;
Expand Down Expand Up @@ -239,10 +283,11 @@ int _pam_parse (int argc, const char **argv) {
}
if ((rv = getaddrinfo(server_name, (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].addr = server;
tac_srv[tac_srv_no].key = current_secret;
set_tac_srv_addr (tac_srv_no, server);
set_tac_srv_key (tac_srv_no, current_secret);
tac_srv_no++;
}
freeaddrinfo (servers);
} else {
_pam_log (LOG_ERR,
"skip invalid server: %s (getaddrinfo: %s)",
Expand All @@ -262,7 +307,7 @@ int _pam_parse (int argc, const char **argv) {
if (tac_srv[i].key != NULL)
break;

tac_srv[i].key = current_secret;
set_tac_srv_key (i, current_secret);
}
} else if (!strncmp (*argv, "timeout=", 8)) {
/* FIXME atoi() doesn't handle invalid numeric strings well */
Expand Down
3 changes: 3 additions & 0 deletions support.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@

#include <security/pam_modules.h>

#define TAC_SECRET_MAX_LEN 64

typedef struct {
struct addrinfo *addr;
const char *key;
Expand All @@ -37,6 +39,7 @@ extern int tac_srv_no;
extern char tac_service[64];
extern char tac_protocol[64];
extern char tac_prompt[64];
void tac_copy_addr_info (struct addrinfo *p_dst, const struct addrinfo *p_src);

int _pam_parse (int, const char **);
unsigned long _resolve_name (char *);
Expand Down