|
| 1 | +From 9c26e734cf9e5cec950dc8b8f474f89d87833bcd Mon Sep 17 00:00:00 2001 |
| 2 | +From: Venkatesan Mahalingam < [email protected]> |
| 3 | +Date: Wed, 1 Jul 2020 18:57:28 -0700 |
| 4 | +Subject: [PATCH] Add support to specify source address for TACACS+ |
| 5 | + |
| 6 | +--- |
| 7 | + pam_tacplus.c | 8 ++++---- |
| 8 | + support.c | 31 +++++++++++++++++++++++++++++++ |
| 9 | + support.h | 1 + |
| 10 | + 3 files changed, 36 insertions(+), 4 deletions(-) |
| 11 | + |
| 12 | +diff --git a/pam_tacplus.c b/pam_tacplus.c |
| 13 | +index 38e2a70..ec8ea27 100644 |
| 14 | +--- a/pam_tacplus.c |
| 15 | ++++ b/pam_tacplus.c |
| 16 | +@@ -177,7 +177,7 @@ int _pam_account(pam_handle_t *pamh, int argc, const char **argv, |
| 17 | + |
| 18 | + status = PAM_SESSION_ERR; |
| 19 | + for(srv_i = 0; srv_i < tac_srv_no; srv_i++) { |
| 20 | +- tac_fd = tac_connect_single(tac_srv[srv_i].addr, tac_srv[srv_i].key, NULL, tac_timeout, __vrfname); |
| 21 | ++ tac_fd = tac_connect_single(tac_srv[srv_i].addr, tac_srv[srv_i].key, tac_source_addr, tac_timeout, __vrfname); |
| 22 | + if (tac_fd < 0) { |
| 23 | + _pam_log(LOG_WARNING, "%s: error sending %s (fd)", |
| 24 | + __FUNCTION__, typemsg); |
| 25 | +@@ -276,7 +276,7 @@ int pam_sm_authenticate (pam_handle_t * pamh, int flags, |
| 26 | + if (ctrl & PAM_TAC_DEBUG) |
| 27 | + syslog(LOG_DEBUG, "%s: trying srv %d", __FUNCTION__, srv_i ); |
| 28 | + |
| 29 | +- tac_fd = tac_connect_single(tac_srv[srv_i].addr, tac_srv[srv_i].key, NULL, tac_timeout, __vrfname); |
| 30 | ++ tac_fd = tac_connect_single(tac_srv[srv_i].addr, tac_srv[srv_i].key, tac_source_addr, tac_timeout, __vrfname); |
| 31 | + if (tac_fd < 0) { |
| 32 | + _pam_log(LOG_ERR, "%s: connection to srv %d failed", __FUNCTION__, srv_i); |
| 33 | + continue; |
| 34 | +@@ -579,7 +579,7 @@ int pam_sm_acct_mgmt (pam_handle_t * pamh, int flags, |
| 35 | + if(tac_protocol[0] != '\0') |
| 36 | + tac_add_attrib(&attr, "protocol", tac_protocol); |
| 37 | + |
| 38 | +- tac_fd = tac_connect_single(active_server.addr, active_server.key, NULL, tac_timeout, __vrfname); |
| 39 | ++ tac_fd = tac_connect_single(active_server.addr, active_server.key, tac_source_addr, tac_timeout, __vrfname); |
| 40 | + if(tac_fd < 0) { |
| 41 | + _pam_log (LOG_ERR, "TACACS+ server unavailable"); |
| 42 | + if(arep.msg != NULL) |
| 43 | +@@ -762,7 +762,7 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags, |
| 44 | + if (ctrl & PAM_TAC_DEBUG) |
| 45 | + syslog(LOG_DEBUG, "%s: trying srv %d", __FUNCTION__, srv_i ); |
| 46 | + |
| 47 | +- tac_fd = tac_connect_single(tac_srv[srv_i].addr, tac_srv[srv_i].key, NULL, tac_timeout, __vrfname); |
| 48 | ++ tac_fd = tac_connect_single(tac_srv[srv_i].addr, tac_srv[srv_i].key, tac_source_addr, tac_timeout, __vrfname); |
| 49 | + if (tac_fd < 0) { |
| 50 | + _pam_log(LOG_ERR, "connection failed srv %d: %m", srv_i); |
| 51 | + continue; |
| 52 | +diff --git a/support.c b/support.c |
| 53 | +index 7c00618..3e55e2f 100644 |
| 54 | +--- a/support.c |
| 55 | ++++ b/support.c |
| 56 | +@@ -37,6 +37,8 @@ char tac_service[64]; |
| 57 | + char tac_protocol[64]; |
| 58 | + char tac_prompt[64]; |
| 59 | + char *__vrfname=NULL; |
| 60 | ++char tac_source_ip[64]; |
| 61 | ++struct addrinfo *tac_source_addr = NULL; |
| 62 | + |
| 63 | + void _pam_log(int err, const char *format,...) { |
| 64 | + char msg[256]; |
| 65 | +@@ -183,6 +185,12 @@ int _pam_parse (int argc, const char **argv) { |
| 66 | + tac_protocol[0] = 0; |
| 67 | + tac_prompt[0] = 0; |
| 68 | + tac_login[0] = 0; |
| 69 | ++ tac_source_ip[0] = 0; |
| 70 | ++ |
| 71 | ++ if (tac_source_addr != NULL) { |
| 72 | ++ freeaddrinfo(tac_source_addr); |
| 73 | ++ tac_source_addr = NULL; |
| 74 | ++ } |
| 75 | + |
| 76 | + for (ctrl = 0; argc-- > 0; ++argv) { |
| 77 | + if (!strcmp (*argv, "debug")) { /* all */ |
| 78 | +@@ -274,6 +282,10 @@ int _pam_parse (int argc, const char **argv) { |
| 79 | + } |
| 80 | + } else if(!strncmp(*argv, "vrf=", 4)) { |
| 81 | + __vrfname = strdup(*argv + 4); |
| 82 | ++ } else if (!strncmp (*argv, "source_ip=", strlen("source_ip="))) { |
| 83 | ++ /* source ip for the packets */ |
| 84 | ++ strncpy (tac_source_ip, *argv + strlen("source_ip="), sizeof(tac_source_ip)); |
| 85 | ++ set_source_ip (tac_source_ip, &tac_source_addr); |
| 86 | + } else { |
| 87 | + _pam_log (LOG_WARNING, "unrecognized option: %s", *argv); |
| 88 | + } |
| 89 | +@@ -292,8 +304,27 @@ int _pam_parse (int argc, const char **argv) { |
| 90 | + _pam_log(LOG_DEBUG, "tac_protocol='%s'", tac_protocol); |
| 91 | + _pam_log(LOG_DEBUG, "tac_prompt='%s'", tac_prompt); |
| 92 | + _pam_log(LOG_DEBUG, "tac_login='%s'", tac_login); |
| 93 | ++ _pam_log(LOG_DEBUG, "tac_source_ip='%s'", tac_source_ip); |
| 94 | + } |
| 95 | + |
| 96 | + return ctrl; |
| 97 | + } /* _pam_parse */ |
| 98 | + |
| 99 | ++/* set source ip address for the outgoing tacacs packets */ |
| 100 | ++void set_source_ip(const char *tac_source_ip, |
| 101 | ++ struct addrinfo **source_address) { |
| 102 | ++ |
| 103 | ++ struct addrinfo hints; |
| 104 | ++ int rv; |
| 105 | ++ |
| 106 | ++ /* set the source ip address for the tacacs packets */ |
| 107 | ++ memset(&hints, 0, sizeof(hints)); |
| 108 | ++ hints.ai_family = AF_UNSPEC; |
| 109 | ++ hints.ai_socktype = SOCK_STREAM; |
| 110 | ++ if ((rv = getaddrinfo(tac_source_ip, NULL, &hints, |
| 111 | ++ source_address)) != 0) { |
| 112 | ++ _pam_log(LOG_ERR, "error setting the source ip information"); |
| 113 | ++ } else { |
| 114 | ++ _pam_log(LOG_DEBUG, "source ip is set"); |
| 115 | ++ } |
| 116 | ++} |
| 117 | +diff --git a/support.h b/support.h |
| 118 | +index 9cbd040..09b8a85 100644 |
| 119 | +--- a/support.h |
| 120 | ++++ b/support.h |
| 121 | +@@ -37,6 +37,7 @@ extern int tac_srv_no; |
| 122 | + extern char tac_service[64]; |
| 123 | + extern char tac_protocol[64]; |
| 124 | + extern char tac_prompt[64]; |
| 125 | ++extern struct addrinfo *tac_source_addr; |
| 126 | + |
| 127 | + int _pam_parse (int, const char **); |
| 128 | + unsigned long _resolve_name (char *); |
| 129 | +-- |
| 130 | +2.7.4 |
| 131 | + |
0 commit comments