Skip to content

Commit

Permalink
[TACACS+]: Extract tacacs support functions into library and fix memo…
Browse files Browse the repository at this point in the history
…ry leak issue. (sonic-net#8659)

This pull request extract tacacs support functions into library to share TACACS config file parse code with other project. Also fix memory leak issue in parse config code.

Why I did it
    To support TACACS per command authorization, we need reuse the TACACS config file parse code in bash plugin project.

How I did it
    Add libtacsupport.pc.in to extract tacacs support functions into library.
    Fix memory leak issue in TACACS config parse code by convert the dynamic memory allocation memory to static memory allocation.

How to verify it
    Pass all current UT.
    Check shared library generated manually.

Which release branch to backport (provide reason below if selected)
    N/A

Description for the changelog
    Extract tacacs support functions into library, this will share TACACS config file parse code with other project.
    Also fix memory leak issue in parse config code.
  • Loading branch information
liuh-80 committed Jul 3, 2023
1 parent bc58e2d commit 6f3e5ea
Show file tree
Hide file tree
Showing 5 changed files with 703 additions and 35 deletions.
97 changes: 63 additions & 34 deletions src/tacacs/pam/0006-Add-support-for-source-ip-address.patch
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
From 9c26e734cf9e5cec950dc8b8f474f89d87833bcd Mon Sep 17 00:00:00 2001
From 49526a27e90647ed4e48c1d1d88e0c75a1ce221b Mon Sep 17 00:00:00 2001
From: Venkatesan Mahalingam <venkatesan_mahalinga@dell.com>
Date: Wed, 1 Jul 2020 18:57:28 -0700
Subject: [PATCH] Add support to specify source address for TACACS+
Date: Thu, 2 Jul 2020 09:57:28 +0800
Subject: [PATCH 1/4] Add support to specify source address for TACACS+

---
pam_tacplus.c | 8 ++++----
support.c | 31 +++++++++++++++++++++++++++++++
support.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++--
support.h | 1 +
3 files changed, 36 insertions(+), 4 deletions(-)
3 files changed, 57 insertions(+), 6 deletions(-)

diff --git a/pam_tacplus.c b/pam_tacplus.c
index 38e2a70..ec8ea27 100644
index 7544b2e..9fc6be7 100644
--- a/pam_tacplus.c
+++ b/pam_tacplus.c
@@ -177,7 +177,7 @@ int _pam_account(pam_handle_t *pamh, int argc, const char **argv,
Expand Down Expand Up @@ -50,7 +50,7 @@ index 38e2a70..ec8ea27 100644
_pam_log(LOG_ERR, "connection failed srv %d: %m", srv_i);
continue;
diff --git a/support.c b/support.c
index 7c00618..3e55e2f 100644
index 8f42a0c..164df62 100644
--- a/support.c
+++ b/support.c
@@ -37,6 +37,8 @@ char tac_service[64];
Expand All @@ -62,60 +62,89 @@ index 7c00618..3e55e2f 100644

void _pam_log(int err, const char *format,...) {
char msg[256];
@@ -183,6 +185,12 @@ int _pam_parse (int argc, const char **argv) {
@@ -171,6 +173,44 @@ int tacacs_get_password (pam_handle_t * pamh, int flags
return PAM_SUCCESS;
}

+/* set source ip address for the outgoing tacacs packets */
+void set_source_ip(const char *tac_source_ip) {
+ /*
+ addrinfo created by getaddrinfo must be released with freeaddrinfo.
+ so source ip address will be stored in following static variables.
+ */
+ static struct addrinfo tac_source_address;
+ static struct sockaddr tac_source_sock_addr;
+ static struct sockaddr_in6 tac_source_sock6_addr;
+
+ struct addrinfo hints, *source_address;
+ int rv;
+
+ /* set the source ip address for the tacacs packets */
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ if ((rv = getaddrinfo(tac_source_ip, NULL, &hints,
+ &source_address)) != 0) {
+ _pam_log(LOG_ERR, "error setting the source ip information");
+ } else {
+ tac_source_addr = &tac_source_address;
+ memcpy(tac_source_addr, source_address, sizeof(struct addrinfo));
+
+ if (source_address->ai_family == AF_INET6) {
+ tac_source_addr->ai_addr = (struct sockaddr *)&(tac_source_sock6_addr);
+ memcpy(tac_source_addr->ai_addr, source_address->ai_addr, sizeof(struct sockaddr_in6));
+ }
+ else {
+ tac_source_addr->ai_addr = &(tac_source_sock_addr);
+ memcpy(tac_source_addr->ai_addr, source_address->ai_addr, sizeof(struct sockaddr));
+ }
+
+ freeaddrinfo(source_address);
+ _pam_log(LOG_DEBUG, "source ip is set");
+ }
+}
+
int _pam_parse (int argc, const char **argv) {
int ctrl = 0;
const char *current_secret = NULL;
@@ -183,6 +223,12 @@ int _pam_parse (int argc, const char **argv) {
tac_protocol[0] = 0;
tac_prompt[0] = 0;
tac_login[0] = 0;
+ tac_source_ip[0] = 0;
+
+ if (tac_source_addr != NULL) {
+ freeaddrinfo(tac_source_addr);
+ /* reset source address */
+ tac_source_addr = NULL;
+ }

for (ctrl = 0; argc-- > 0; ++argv) {
if (!strcmp (*argv, "debug")) { /* all */
@@ -274,6 +282,10 @@ int _pam_parse (int argc, const char **argv) {
@@ -274,6 +320,10 @@ int _pam_parse (int argc, const char **argv) {
}
} else if(!strncmp(*argv, "vrf=", 4)) {
__vrfname = strdup(*argv + 4);
+ } else if (!strncmp (*argv, "source_ip=", strlen("source_ip="))) {
+ /* source ip for the packets */
+ strncpy (tac_source_ip, *argv + strlen("source_ip="), sizeof(tac_source_ip));
+ set_source_ip (tac_source_ip, &tac_source_addr);
+ set_source_ip(tac_source_ip);
} else {
_pam_log (LOG_WARNING, "unrecognized option: %s", *argv);
}
@@ -292,8 +304,27 @@ int _pam_parse (int argc, const char **argv) {
@@ -292,8 +342,8 @@ int _pam_parse (int argc, const char **argv) {
_pam_log(LOG_DEBUG, "tac_protocol='%s'", tac_protocol);
_pam_log(LOG_DEBUG, "tac_prompt='%s'", tac_prompt);
_pam_log(LOG_DEBUG, "tac_login='%s'", tac_login);
+ _pam_log(LOG_DEBUG, "tac_source_ip='%s'", tac_source_ip);
}

return ctrl;
} /* _pam_parse */

+/* set source ip address for the outgoing tacacs packets */
+void set_source_ip(const char *tac_source_ip,
+ struct addrinfo **source_address) {
+
+ struct addrinfo hints;
+ int rv;
+
+ /* set the source ip address for the tacacs packets */
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ if ((rv = getaddrinfo(tac_source_ip, NULL, &hints,
+ source_address)) != 0) {
+ _pam_log(LOG_ERR, "error setting the source ip information");
+ } else {
+ _pam_log(LOG_DEBUG, "source ip is set");
+ }
+}
-} /* _pam_parse */
-
+} /* _pam_parse */
\ No newline at end of file
diff --git a/support.h b/support.h
index 9cbd040..09b8a85 100644
index 9cbd040..b1faf43 100644
--- a/support.h
+++ b/support.h
@@ -37,6 +37,7 @@ extern int tac_srv_no;
Expand All @@ -127,5 +156,5 @@ index 9cbd040..09b8a85 100644
int _pam_parse (int, const char **);
unsigned long _resolve_name (char *);
--
2.7.4
2.17.1.windows.2

Loading

0 comments on commit 6f3e5ea

Please sign in to comment.