tacacs management vrf changes (#2217)
This commit is contained in:
parent
a888e15e5c
commit
a9a7ce1091
@ -1,4 +1,4 @@
|
||||
# THIS IS AN AUTO-GENERATED FILE
|
||||
#THIS IS AN AUTO-GENERATED FILE
|
||||
#
|
||||
# /etc/pam.d/common-auth- authentication settings common to all services
|
||||
# This file is included from other service-specific PAM config files,
|
||||
@ -15,16 +15,16 @@ auth [success=1 default=ignore] pam_unix.so nullok try_first_pass
|
||||
{% elif auth['login'] == 'local,tacacs+' %}
|
||||
auth [success=done new_authtok_reqd=done default=ignore{{ ' auth_err=die' if not auth['failthrough'] }}] pam_unix.so nullok try_first_pass
|
||||
{% for server in servers | sub(0, -1) %}
|
||||
auth [success=done new_authtok_reqd=done default=ignore{{ ' auth_err=die' if not auth['failthrough'] }}] pam_tacplus.so server={{ server.ip }}:{{ server.tcp_port }} secret={{ server.passkey }} login={{ server.auth_type }} timeout={{ server.timeout }} try_first_pass
|
||||
auth [success=done new_authtok_reqd=done default=ignore{{ ' auth_err=die' if not auth['failthrough'] }}] pam_tacplus.so server={{ server.ip }}:{{ server.tcp_port }} secret={{ server.passkey }} login={{ server.auth_type }} timeout={{ server.timeout }} {% if server.vrf %} vrf={{ server.vrf }} {% endif %} try_first_pass
|
||||
{% endfor %}
|
||||
{% if servers | count %}
|
||||
{% set last_server = servers | last %}
|
||||
auth [success=1 default=ignore] pam_tacplus.so server={{ last_server.ip }}:{{ last_server.tcp_port }} secret={{ last_server.passkey }} login={{ last_server.auth_type }} timeout={{ last_server.timeout }} try_first_pass
|
||||
auth [success=1 default=ignore] pam_tacplus.so server={{ last_server.ip }}:{{ last_server.tcp_port }} secret={{ last_server.passkey }} login={{ last_server.auth_type }} timeout={{ last_server.timeout }} {% if server.vrf %} vrf={{ last_server.vrf }} {% endif %} try_first_pass
|
||||
|
||||
{% endif %}
|
||||
{% elif auth['login'] == 'tacacs+' or auth['login'] == 'tacacs+,local' %}
|
||||
{% for server in servers %}
|
||||
auth [success=done new_authtok_reqd=done default=ignore{{ ' auth_err=die' if not auth['failthrough'] }}] pam_tacplus.so server={{ server.ip }}:{{ server.tcp_port }} secret={{ server.passkey }} login={{ server.auth_type }} timeout={{ server.timeout }} try_first_pass
|
||||
auth [success=done new_authtok_reqd=done default=ignore{{ ' auth_err=die' if not auth['failthrough'] }}] pam_tacplus.so server={{ server.ip }}:{{ server.tcp_port }} secret={{ server.passkey }} login={{ server.auth_type }} timeout={{ server.timeout }} {%if server.vrf %} vrf={{ server.vrf }} {% endif %} try_first_pass
|
||||
{% endfor %}
|
||||
auth [success=1 default=ignore] pam_unix.so nullok try_first_pass
|
||||
|
||||
|
@ -11,7 +11,7 @@ debug=on
|
||||
# Default: None (no TACACS+ server)
|
||||
# server=1.1.1.1:49,secret=test,timeout=3
|
||||
{% for server in servers %}
|
||||
server={{ server.ip }}:{{ server.tcp_port }},secret={{ server.passkey }},timeout={{ server.timeout }}
|
||||
server={{ server.ip }}:{{ server.tcp_port }},secret={{ server.passkey }},timeout={{ server.timeout }}{% if server.vrf %},vrf={{ server.vrf }}{% endif %}{{''}}
|
||||
{% endfor %}
|
||||
|
||||
# user_priv - set the map between TACACS+ user privilege and local user's passwd
|
||||
|
43
src/tacacs/nss/0003-management-vrf-support.patch
Normal file
43
src/tacacs/nss/0003-management-vrf-support.patch
Normal file
@ -0,0 +1,43 @@
|
||||
From b20aad31e186e27cc83432b405555420f94c6049 Mon Sep 17 00:00:00 2001
|
||||
From: Kannan KVS <kannan_kvs@dell.com>
|
||||
Date: Mon, 8 Oct 2018 03:10:55 -0700
|
||||
Subject: [PATCH] MANAGEMENT_VRF_TACACS_NSS_CHANGES
|
||||
|
||||
---
|
||||
nss_tacplus.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/nss_tacplus.c b/nss_tacplus.c
|
||||
index 6e4fddd..1e222dd 100644
|
||||
--- a/nss_tacplus.c
|
||||
+++ b/nss_tacplus.c
|
||||
@@ -76,6 +76,7 @@ static useradd_info_t useradd_grp_list[MAX_TACACS_USER_PRIV + 1];
|
||||
|
||||
static char *tac_service = "shell";
|
||||
static char *tac_protocol = "ssh";
|
||||
+static char vrfname[64];
|
||||
static bool debug = false;
|
||||
static bool many_to_one = false;
|
||||
|
||||
@@ -124,6 +125,9 @@ static int parse_tac_server(char *srv_buf)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
+ else if(!strncmp(token, "vrf=", 4)){
|
||||
+ strncpy(vrfname, token + 4, sizeof(vrfname));
|
||||
+ }
|
||||
else if(!strncmp(token, "secret=", 7)) {
|
||||
if(tac_srv[tac_srv_no].key)
|
||||
free(tac_srv[tac_srv_no].key);
|
||||
@@ -633,7 +637,7 @@ connect_tacacs(struct tac_attrib **attr, int srvr)
|
||||
return -1;
|
||||
|
||||
fd = tac_connect_single(tac_srv[srvr].addr, tac_srv[srvr].key, NULL,
|
||||
- tac_srv[srvr].timeout);
|
||||
+ tac_srv[srvr].timeout, vrfname[0] ? vrfname : NULL);
|
||||
if(fd >= 0) {
|
||||
*attr = NULL; /* so tac_add_attr() allocates memory */
|
||||
tac_add_attrib(attr, "service", tac_service);
|
||||
--
|
||||
2.7.4
|
||||
|
@ -14,6 +14,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% :
|
||||
# Apply patch
|
||||
git am ../0001-Modify-user-map-profile.patch
|
||||
git am ../0002-Enable-modifying-local-user-permission.patch
|
||||
git am ../0003-management-vrf-support.patch
|
||||
|
||||
dpkg-buildpackage -rfakeroot -b -us -uc
|
||||
popd
|
||||
|
240
src/tacacs/pam/0004-management-vrf-support.patch
Normal file
240
src/tacacs/pam/0004-management-vrf-support.patch
Normal file
@ -0,0 +1,240 @@
|
||||
From 6005f4a884f250787bdc070235879b14186ade2c Mon Sep 17 00:00:00 2001
|
||||
From: Kannan KVS <kannan_kvs@dell.com>
|
||||
Date: Mon, 8 Oct 2018 02:58:42 -0700
|
||||
Subject: [PATCH] MANAGEMENT_VRF_TACACS_PAM_CHANGES
|
||||
|
||||
---
|
||||
libtac/include/libtac.h | 4 ++--
|
||||
libtac/lib/connect.c | 21 +++++++++++++++++----
|
||||
pam_tacplus.c | 12 +++++++-----
|
||||
support.c | 3 +++
|
||||
tacc.c | 15 ++++++++++-----
|
||||
5 files changed, 39 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/libtac/include/libtac.h b/libtac/include/libtac.h
|
||||
index 6dc42ab..0c9d3d2 100644
|
||||
--- a/libtac/include/libtac.h
|
||||
+++ b/libtac/include/libtac.h
|
||||
@@ -135,8 +135,8 @@ extern int tac_readtimeout_enable;
|
||||
/* connect.c */
|
||||
extern int tac_timeout;
|
||||
|
||||
-int tac_connect(struct addrinfo **, char **, int);
|
||||
-int tac_connect_single(const struct addrinfo *, const char *, struct addrinfo *, int);
|
||||
+int tac_connect(struct addrinfo **, char **, int, char *);
|
||||
+int tac_connect_single(const struct addrinfo *, const char *, struct addrinfo *, int, char *);
|
||||
char *tac_ntop(const struct sockaddr *);
|
||||
|
||||
int tac_authen_send(int, const char *, const char *, const char *,
|
||||
diff --git a/libtac/lib/connect.c b/libtac/lib/connect.c
|
||||
index 47f598a..5035135 100644
|
||||
--- a/libtac/lib/connect.c
|
||||
+++ b/libtac/lib/connect.c
|
||||
@@ -42,7 +42,7 @@ int tac_timeout = 5;
|
||||
* >= 0 : valid fd
|
||||
* < 0 : error status code, see LIBTAC_STATUS_...
|
||||
*/
|
||||
-int tac_connect(struct addrinfo **server, char **key, int servers) {
|
||||
+int tac_connect(struct addrinfo **server, char **key, int servers, char *iface) {
|
||||
int tries;
|
||||
int fd=-1;
|
||||
|
||||
@@ -50,7 +50,7 @@ int tac_connect(struct addrinfo **server, char **key, int servers) {
|
||||
TACSYSLOG((LOG_ERR, "%s: no TACACS+ servers defined", __FUNCTION__))
|
||||
} else {
|
||||
for ( tries = 0; tries < servers; tries++ ) {
|
||||
- if((fd=tac_connect_single(server[tries], key[tries], NULL, tac_timeout)) >= 0 ) {
|
||||
+ if((fd=tac_connect_single(server[tries], key[tries], NULL, tac_timeout, iface)) >= 0 ) {
|
||||
/* tac_secret was set in tac_connect_single on success */
|
||||
break;
|
||||
}
|
||||
@@ -66,8 +66,9 @@ int tac_connect(struct addrinfo **server, char **key, int servers) {
|
||||
/* return value:
|
||||
* >= 0 : valid fd
|
||||
* < 0 : error status code, see LIBTAC_STATUS_...
|
||||
+ * If iface is non-null, try to BIND to that interface, to support specific routing, including VRF.
|
||||
*/
|
||||
-int tac_connect_single(const struct addrinfo *server, const char *key, struct addrinfo *srcaddr, int timeout) {
|
||||
+int tac_connect_single(const struct addrinfo *server, const char *key, struct addrinfo *srcaddr, int timeout, char *iface) {
|
||||
int retval = LIBTAC_STATUS_CONN_ERR; /* default retval */
|
||||
int fd = -1;
|
||||
int flags, rc;
|
||||
@@ -91,6 +92,19 @@ int tac_connect_single(const struct addrinfo *server, const char *key, struct ad
|
||||
return LIBTAC_STATUS_CONN_ERR;
|
||||
}
|
||||
|
||||
+ if (iface) {
|
||||
+ /* do not fail if the bind fails, connection may still succeed */
|
||||
+ if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, iface,
|
||||
+ strlen(iface)+1) < 0) {
|
||||
+ TACSYSLOG((LOG_WARNING, ":%s: Binding socket to device %s failed.",
|
||||
+ __FUNCTION__, iface))
|
||||
+ } else {
|
||||
+ TACDEBUG((LOG_DEBUG, "%s: Binding socket to device %s succeeded.",
|
||||
+ __FUNCTION__, iface))
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+
|
||||
/* get flags for restoration later */
|
||||
flags = fcntl(fd, F_GETFL, 0);
|
||||
|
||||
@@ -166,7 +180,6 @@ int tac_connect_single(const struct addrinfo *server, const char *key, struct ad
|
||||
}
|
||||
|
||||
/* connected ok */
|
||||
- TACDEBUG((LOG_DEBUG, "%s: connected to %s", __FUNCTION__, ip))
|
||||
retval = fd;
|
||||
|
||||
/* set current tac_secret */
|
||||
diff --git a/pam_tacplus.c b/pam_tacplus.c
|
||||
index 2b7d2cd..38e2a70 100644
|
||||
--- a/pam_tacplus.c
|
||||
+++ b/pam_tacplus.c
|
||||
@@ -53,6 +53,8 @@ static tacplus_server_t active_server;
|
||||
/* accounting task identifier */
|
||||
static short int task_id = 0;
|
||||
|
||||
+extern char *__vrfname;
|
||||
+
|
||||
|
||||
/* Helper functions */
|
||||
int _pam_send_account(int tac_fd, int type, const char *user, char *tty,
|
||||
@@ -175,7 +177,7 @@ int _pam_account(pam_handle_t *pamh, int argc, const char **argv,
|
||||
|
||||
status = PAM_SESSION_ERR;
|
||||
for(srv_i = 0; srv_i < tac_srv_no; srv_i++) {
|
||||
- tac_fd = tac_connect_single(tac_srv[srv_i].addr, tac_srv[srv_i].key, NULL, tac_timeout);
|
||||
+ tac_fd = tac_connect_single(tac_srv[srv_i].addr, tac_srv[srv_i].key, NULL, tac_timeout, __vrfname);
|
||||
if (tac_fd < 0) {
|
||||
_pam_log(LOG_WARNING, "%s: error sending %s (fd)",
|
||||
__FUNCTION__, typemsg);
|
||||
@@ -274,9 +276,9 @@ 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].addr, tac_srv[srv_i].key, NULL, tac_timeout);
|
||||
+ tac_fd = tac_connect_single(tac_srv[srv_i].addr, tac_srv[srv_i].key, NULL, tac_timeout, __vrfname);
|
||||
if (tac_fd < 0) {
|
||||
- _pam_log(LOG_ERR, "connection failed srv %d: %m", srv_i);
|
||||
+ _pam_log(LOG_ERR, "%s: connection to srv %d failed", __FUNCTION__, srv_i);
|
||||
continue;
|
||||
}
|
||||
if (tac_authen_send(tac_fd, user, pass, tty, r_addr, TAC_PLUS_AUTHEN_LOGIN) < 0) {
|
||||
@@ -577,7 +579,7 @@ int pam_sm_acct_mgmt (pam_handle_t * pamh, int flags,
|
||||
if(tac_protocol[0] != '\0')
|
||||
tac_add_attrib(&attr, "protocol", tac_protocol);
|
||||
|
||||
- tac_fd = tac_connect_single(active_server.addr, active_server.key, NULL, tac_timeout);
|
||||
+ tac_fd = tac_connect_single(active_server.addr, active_server.key, NULL, tac_timeout, __vrfname);
|
||||
if(tac_fd < 0) {
|
||||
_pam_log (LOG_ERR, "TACACS+ server unavailable");
|
||||
if(arep.msg != NULL)
|
||||
@@ -760,7 +762,7 @@ int pam_sm_chauthtok(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].addr, tac_srv[srv_i].key, NULL, tac_timeout);
|
||||
+ tac_fd = tac_connect_single(tac_srv[srv_i].addr, tac_srv[srv_i].key, NULL, tac_timeout, __vrfname);
|
||||
if (tac_fd < 0) {
|
||||
_pam_log(LOG_ERR, "connection failed srv %d: %m", srv_i);
|
||||
continue;
|
||||
diff --git a/support.c b/support.c
|
||||
index 44efee3..be0142d 100644
|
||||
--- a/support.c
|
||||
+++ b/support.c
|
||||
@@ -36,6 +36,7 @@ int tac_srv_no = 0;
|
||||
char tac_service[64];
|
||||
char tac_protocol[64];
|
||||
char tac_prompt[64];
|
||||
+char *__vrfname=NULL;
|
||||
|
||||
void _pam_log(int err, const char *format,...) {
|
||||
char msg[256];
|
||||
@@ -271,6 +272,8 @@ int _pam_parse (int argc, const char **argv) {
|
||||
} else {
|
||||
tac_readtimeout_enable = 1;
|
||||
}
|
||||
+ } else if(!strncmp(*argv, "vrf=", 4)) {
|
||||
+ __vrfname = strdup(*argv + 4);
|
||||
} else {
|
||||
_pam_log (LOG_WARNING, "unrecognized option: %s", *argv);
|
||||
}
|
||||
diff --git a/tacc.c b/tacc.c
|
||||
index d7c6e1a..fcc7d8c 100644
|
||||
--- a/tacc.c
|
||||
+++ b/tacc.c
|
||||
@@ -76,6 +76,7 @@ int tac_encryption = 1;
|
||||
typedef unsigned char flag;
|
||||
flag quiet = 0;
|
||||
char *user = NULL; /* global, because of signal handler */
|
||||
+char *iface = NULL; /* -I interface or VRF to use for connection */
|
||||
|
||||
/* command line options */
|
||||
static struct option long_options[] = {
|
||||
@@ -97,6 +98,7 @@ static struct option long_options[] = {
|
||||
{ "service", required_argument, NULL, 'S' },
|
||||
{ "protocol", required_argument, NULL, 'P' },
|
||||
{ "remote", required_argument, NULL, 'r' },
|
||||
+ { "interface", required_argument, NULL, 'I' },
|
||||
{ "login", required_argument, NULL, 'L' },
|
||||
|
||||
/* modifiers */
|
||||
@@ -107,7 +109,7 @@ static struct option long_options[] = {
|
||||
{ 0, 0, 0, 0 } };
|
||||
|
||||
/* command line letters */
|
||||
-char *opt_string = "TRAVhu:p:s:k:c:qr:wnS:P:L:";
|
||||
+char *opt_string = "TRAVIhu:p:s:k:c:qr:wnS:P:L:";
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char *pass = NULL;
|
||||
@@ -168,6 +170,9 @@ int main(int argc, char **argv) {
|
||||
showversion(argv[0]);
|
||||
case 'h':
|
||||
showusage(argv[0]);
|
||||
+ case 'I':
|
||||
+ iface = optarg;
|
||||
+ break;
|
||||
case 'u':
|
||||
user = optarg;
|
||||
break;
|
||||
@@ -283,7 +288,7 @@ int main(int argc, char **argv) {
|
||||
tac_add_attrib(&attr, "service", service);
|
||||
tac_add_attrib(&attr, "protocol", protocol);
|
||||
|
||||
- tac_fd = tac_connect_single(tac_server, tac_secret, NULL, 60);
|
||||
+ tac_fd = tac_connect_single(tac_server, tac_secret, NULL, 60, iface);
|
||||
if (tac_fd < 0) {
|
||||
if (!quiet)
|
||||
printf("Error connecting to TACACS+ server: %m\n");
|
||||
@@ -321,7 +326,7 @@ int main(int argc, char **argv) {
|
||||
tac_add_attrib(&attr, "service", service);
|
||||
tac_add_attrib(&attr, "protocol", protocol);
|
||||
|
||||
- tac_fd = tac_connect_single(tac_server, tac_secret, NULL, 60);
|
||||
+ tac_fd = tac_connect_single(tac_server, tac_secret, NULL, 60, iface);
|
||||
if (tac_fd < 0) {
|
||||
if (!quiet)
|
||||
printf("Error connecting to TACACS+ server: %m\n");
|
||||
@@ -404,7 +409,7 @@ int main(int argc, char **argv) {
|
||||
sprintf(buf, "%hu", task_id);
|
||||
tac_add_attrib(&attr, "task_id", buf);
|
||||
|
||||
- tac_fd = tac_connect_single(tac_server, tac_secret, NULL, 60);
|
||||
+ tac_fd = tac_connect_single(tac_server, tac_secret, NULL, 60, iface);
|
||||
if (tac_fd < 0) {
|
||||
if (!quiet)
|
||||
printf("Error connecting to TACACS+ server: %m\n");
|
||||
@@ -445,7 +450,7 @@ void authenticate(const struct addrinfo *tac_server, const char *tac_secret,
|
||||
int ret;
|
||||
struct areply arep;
|
||||
|
||||
- tac_fd = tac_connect_single(tac_server, tac_secret, NULL, 60);
|
||||
+ tac_fd = tac_connect_single(tac_server, tac_secret, NULL, 60, iface);
|
||||
if (tac_fd < 0) {
|
||||
if (!quiet)
|
||||
printf("Error connecting to TACACS+ server: %m\n");
|
||||
--
|
||||
2.7.4
|
||||
|
@ -17,6 +17,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% :
|
||||
git apply ../0001-Don-t-init-declarations-in-a-for-loop.patch
|
||||
git apply ../0002-Fix-libtac2-bin-install-directory-error.patch
|
||||
git apply ../0003-Obfuscate-key-before-printing-to-syslog.patch
|
||||
git apply ../0004-management-vrf-support.patch
|
||||
|
||||
dpkg-buildpackage -rfakeroot -b -us -uc
|
||||
popd
|
||||
|
Loading…
Reference in New Issue
Block a user