From ec369a83dd65ea691d9159a5a4bdeb8c734c658c Mon Sep 17 00:00:00 2001 From: Daniel Gollub Date: Fri, 10 Oct 2014 17:51:00 +0200 Subject: Add source addr parameter for tac_connect_single This allows to specify from which source address/interface the TACACS+ client connection gets initiated. Bump SO-versioning due to API change. --- Makefile.am | 2 +- debian/control | 6 +++--- debian/libtac0.install | 1 - debian/libtac1.install | 1 + libtac/include/libtac.h | 2 +- libtac/lib/connect.c | 13 +++++++++++-- pam_tacplus.c | 6 +++--- 7 files changed, 20 insertions(+), 11 deletions(-) delete mode 100644 debian/libtac0.install create mode 100644 debian/libtac1.install diff --git a/Makefile.am b/Makefile.am index dd73b01..a369073 100644 --- a/Makefile.am +++ b/Makefile.am @@ -41,7 +41,7 @@ libtac/lib/xalloc.c \ libtac/lib/xalloc.h \ $(libtac_include_HEADERS) libtac_la_CFLAGS = $(AM_CFLAGS) -Ilibtac/include -libtac_la_LDFLAGS = -version-info 0:0:0 -shared +libtac_la_LDFLAGS = -version-info 1:0:0 -shared moduledir = @pamdir@ module_LTLIBRARIES = pam_tacplus.la diff --git a/debian/control b/debian/control index af07574..6dde527 100644 --- a/debian/control +++ b/debian/control @@ -8,13 +8,13 @@ Homepage: https://github.com/jeroennijhof/pam_tacplus Package: libpam-tacplus Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, libpam-runtime, libtac0 +Depends: ${shlibs:Depends}, ${misc:Depends}, libpam-runtime, libtac1 Description: PAM module for using TACACS+ as an authentication service This PAM module support authentication, authorization (account management) and accounting (session management) performed using TACACS+ protocol designed by Cisco. -Package: libtac0 +Package: libtac1 Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: TACACS+ protocol library @@ -24,7 +24,7 @@ Description: TACACS+ protocol library Package: libtac-dev Section: libdevel Architecture: any -Depends: ${misc:Depends}, libtac0 (= ${binary:Version}), libc6-dev|libc-dev +Depends: ${misc:Depends}, libtac1 (= ${binary:Version}), libc6-dev|libc-dev Description: Development files for TACACS+ protocol library Contains C header files and development files for libtac, a TACACS+ protocol implementation. diff --git a/debian/libtac0.install b/debian/libtac0.install deleted file mode 100644 index 3de3b10..0000000 --- a/debian/libtac0.install +++ /dev/null @@ -1 +0,0 @@ -usr/lib/*/*.so.* diff --git a/debian/libtac1.install b/debian/libtac1.install new file mode 100644 index 0000000..3de3b10 --- /dev/null +++ b/debian/libtac1.install @@ -0,0 +1 @@ +usr/lib/*/*.so.* diff --git a/libtac/include/libtac.h b/libtac/include/libtac.h index aad4cbf..18f98f6 100644 --- a/libtac/include/libtac.h +++ b/libtac/include/libtac.h @@ -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 *, const char *); +int tac_connect_single(struct addrinfo *, const char *, struct addrinfo *); char *tac_ntop(const struct sockaddr *); int tac_authen_send(int, const char *, char *, char *, diff --git a/libtac/lib/connect.c b/libtac/lib/connect.c index 1226797..a186220 100644 --- a/libtac/lib/connect.c +++ b/libtac/lib/connect.c @@ -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])) >= 0 ) { + if((fd=tac_connect_single(server[tries], key[tries], NULL)) >= 0 ) { /* tac_secret was set in tac_connect_single on success */ break; } @@ -67,7 +67,7 @@ int tac_connect(struct addrinfo **server, char **key, int servers) { * >= 0 : valid fd * < 0 : error status code, see LIBTAC_STATUS_... */ -int tac_connect_single(struct addrinfo *server, const char *key) { +int tac_connect_single(struct addrinfo *server, const char *key, struct addrinfo *srcaddr) { int retval = LIBTAC_STATUS_CONN_ERR; /* default retval */ int fd = -1; int flags, rc; @@ -100,6 +100,15 @@ int tac_connect_single(struct addrinfo *server, const char *key) { return LIBTAC_STATUS_CONN_ERR; } + /* bind if source address got explicity defined */ + if (srcaddr) { + if (bind(fd, srcaddr->ai_addr, srcaddr->ai_addrlen) < 0) { + TACSYSLOG((LOG_ERR, "%s: Failed to bind source address: %s", + __FUNCTION__, strerror(errno))) + return LIBTAC_STATUS_CONN_ERR; + } + } + rc = connect(fd, server->ai_addr, server->ai_addrlen); /* FIX this..for some reason errno = 0 on AIX... */ if((rc == -1) && (errno != EINPROGRESS) && (errno != 0)) { diff --git a/pam_tacplus.c b/pam_tacplus.c index b76b317..600331b 100644 --- a/pam_tacplus.c +++ b/pam_tacplus.c @@ -169,7 +169,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); + tac_fd = tac_connect_single(tac_srv[srv_i].addr, tac_srv[srv_i].key, NULL); if (tac_fd < 0) { _pam_log(LOG_WARNING, "%s: error sending %s (fd)", __FUNCTION__, typemsg); @@ -268,7 +268,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].addr, tac_srv[srv_i].key); + tac_fd = tac_connect_single(tac_srv[srv_i].addr, tac_srv[srv_i].key, NULL); if (tac_fd < 0) { _pam_log(LOG_ERR, "connection failed srv %d: %m", srv_i); continue; @@ -489,7 +489,7 @@ int pam_sm_acct_mgmt (pam_handle_t * pamh, int flags, if(tac_protocol != NULL && tac_protocol[0] != '\0') tac_add_attrib(&attr, "protocol", tac_protocol); - tac_fd = tac_connect_single(active_server.addr, active_server.key); + tac_fd = tac_connect_single(active_server.addr, active_server.key, NULL); if(tac_fd < 0) { _pam_log (LOG_ERR, "TACACS+ server unavailable"); if(arep.msg != NULL) -- cgit v1.2.3