[TACACS+] Add audisp-tacplus for per-command accounting. (#8750)

This pull request integrate audisp-tacplus to SONiC for per-command accounting.

#### Why I did it
To support TACACS per-command accounting, we integrate audisp-tacplus project to sonic.

#### How I did it
1. Add auditd service to SONiC
2. Port and patch audisp-tacplus to SONiC

#### How to verify it
UT with CUnit to cover all new code in usersecret-filter.c
Also pass all current UT.

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

#### Description for the changelog
Add audisp-tacplus for per-command accounting.

#### A picture of a cute animal (not mandatory but encouraged)
This commit is contained in:
liuh-80 2021-12-01 11:50:09 +08:00 committed by GitHub
parent 06a61dede0
commit 739c45645c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 1757 additions and 8 deletions

View File

@ -324,7 +324,8 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in
haveged \ haveged \
fdisk \ fdisk \
gpg \ gpg \
jq jq \
auditd
if [[ $CONFIGURED_ARCH == amd64 ]]; then if [[ $CONFIGURED_ARCH == amd64 ]]; then
## Pre-install the fundamental packages for amd64 (x86) ## Pre-install the fundamental packages for amd64 (x86)

View File

@ -277,6 +277,9 @@ sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/libnss-tacplus_*.deb || \
# Install bash-tacplus # Install bash-tacplus
sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/bash-tacplus_*.deb || \ sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/bash-tacplus_*.deb || \
sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f
# Install audisp-tacplus
sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/audisp-tacplus_*.deb || \
sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f
# Disable tacplus by default # Disable tacplus by default
sudo LANG=C chroot $FILESYSTEM_ROOT pam-auth-update --remove tacplus sudo LANG=C chroot $FILESYSTEM_ROOT pam-auth-update --remove tacplus
sudo sed -i -e '/^passwd/s/ tacplus//' $FILESYSTEM_ROOT/etc/nsswitch.conf sudo sed -i -e '/^passwd/s/ tacplus//' $FILESYSTEM_ROOT/etc/nsswitch.conf

View File

@ -16,8 +16,6 @@ LIBTAC_DEV = libtac-dev_$(PAM_TACPLUS_VERSION)_$(CONFIGURED_ARCH).deb
$(LIBTAC_DEV)_DEPENDS += $(LIBTAC2) $(LIBTAC_DEV)_DEPENDS += $(LIBTAC2)
$(eval $(call add_derived_package,$(LIBTAC2),$(LIBTAC_DEV))) $(eval $(call add_derived_package,$(LIBTAC2),$(LIBTAC_DEV)))
# libnss-tacplus packages # libnss-tacplus packages
NSS_TACPLUS_VERSION = 1.0.4-1 NSS_TACPLUS_VERSION = 1.0.4-1
@ -29,6 +27,16 @@ $(LIBNSS_TACPLUS)_RDEPENDS += $(LIBTAC2)
$(LIBNSS_TACPLUS)_SRC_PATH = $(SRC_PATH)/tacacs/nss $(LIBNSS_TACPLUS)_SRC_PATH = $(SRC_PATH)/tacacs/nss
SONIC_MAKE_DEBS += $(LIBNSS_TACPLUS) SONIC_MAKE_DEBS += $(LIBNSS_TACPLUS)
# audisp-tacplus packages
AUDISP_TACPLUS_VERSION = 1.0.2
export AUDISP_TACPLUS_VERSION
AUDISP_TACPLUS = audisp-tacplus_$(AUDISP_TACPLUS_VERSION)_$(CONFIGURED_ARCH).deb
$(AUDISP_TACPLUS)_DEPENDS += $(LIBTAC_DEV)
$(AUDISP_TACPLUS)_RDEPENDS += $(LIBTAC2)
$(AUDISP_TACPLUS)_SRC_PATH = $(SRC_PATH)/tacacs/audisp
SONIC_MAKE_DEBS += $(AUDISP_TACPLUS)
# bash-tacplus packages # bash-tacplus packages
BASH_TACPLUS_VERSION = 1.0.0 BASH_TACPLUS_VERSION = 1.0.0
@ -41,7 +49,6 @@ $(BASH_TACPLUS)_RDEPENDS += $(LIBTAC2)
$(BASH_TACPLUS)_SRC_PATH = $(SRC_PATH)/tacacs/bash_tacplus $(BASH_TACPLUS)_SRC_PATH = $(SRC_PATH)/tacacs/bash_tacplus
SONIC_DPKG_DEBS += $(BASH_TACPLUS) SONIC_DPKG_DEBS += $(BASH_TACPLUS)
# The .c, .cpp, .h & .hpp files under src/{$DBG_SRC_ARCHIVE list} # The .c, .cpp, .h & .hpp files under src/{$DBG_SRC_ARCHIVE list}
# are archived into debug one image to facilitate debugging. # are archived into debug one image to facilitate debugging.
# #

View File

@ -949,7 +949,8 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \
$(SONIC_UTILITIES_DATA) \ $(SONIC_UTILITIES_DATA) \
$(SONIC_HOST_SERVICES_DATA) \ $(SONIC_HOST_SERVICES_DATA) \
$(BASH) \ $(BASH) \
$(BASH_TACPLUS)) \ $(BASH_TACPLUS) \
$(AUDISP_TACPLUS)) \
$$(addprefix $(TARGET_PATH)/,$$($$*_DOCKERS)) \ $$(addprefix $(TARGET_PATH)/,$$($$*_DOCKERS)) \
$$(addprefix $(TARGET_PATH)/,$$(SONIC_PACKAGES_LOCAL)) \ $$(addprefix $(TARGET_PATH)/,$$(SONIC_PACKAGES_LOCAL)) \
$$(addprefix $(FILES_PATH)/,$$($$*_FILES)) \ $$(addprefix $(FILES_PATH)/,$$($$*_FILES)) \

View File

@ -349,7 +349,10 @@ RUN apt-get update && apt-get install -y \
libdbus-1-dev \ libdbus-1-dev \
libgirepository1.0-dev \ libgirepository1.0-dev \
libsystemd-dev \ libsystemd-dev \
pkg-config pkg-config \
# For audisp-tacplus
libauparse-dev \
auditd
RUN apt-get -y build-dep openssh RUN apt-get -y build-dep openssh

View File

@ -354,7 +354,10 @@ RUN apt-get update && apt-get install -y \
libdbus-1-dev \ libdbus-1-dev \
libgirepository1.0-dev \ libgirepository1.0-dev \
libsystemd-dev \ libsystemd-dev \
pkg-config pkg-config \
# For audisp-tacplus
libauparse-dev \
auditd
# For iproute2 # For iproute2
RUN apt-get install -y -t buster-backports \ RUN apt-get install -y -t buster-backports \

View File

@ -239,6 +239,9 @@ RUN apt-get update && apt-get install -y \
libcunit1-dev \ libcunit1-dev \
# For initramfs # For initramfs
bash-completion \ bash-completion \
# For audisp-tacplus
libauparse-dev \
auditd \
{% if CONFIGURED_ARCH == "amd64" -%} {% if CONFIGURED_ARCH == "amd64" -%}
# For sonic vs image build # For sonic vs image build
dosfstools \ dosfstools \

View File

@ -295,7 +295,10 @@ RUN apt-get update && apt-get install -y \
libxml2-utils \ libxml2-utils \
xsltproc \ xsltproc \
python-lxml \ python-lxml \
libexpat1-dev libexpat1-dev \
# For audisp-tacplus
libauparse-dev \
auditd
# Install dependencies for dhcp relay test # Install dependencies for dhcp relay test
RUN pip3 install parameterized==0.8.1 RUN pip3 install parameterized==0.8.1

View File

@ -100,6 +100,18 @@ def obfuscate(data):
else: else:
return data return data
def get_pid(procname):
for dirname in os.listdir('/proc'):
if dirname == 'curproc':
continue
try:
with open('/proc/{}/cmdline'.format(dirname), mode='r') as fd:
content = fd.read()
except Exception as ex:
continue
if procname in content:
return dirname
return ""
class Feature(object): class Feature(object):
""" Represents a feature configuration from CONFIG_DB data. """ """ Represents a feature configuration from CONFIG_DB data. """
@ -534,6 +546,18 @@ class AaaCfg(object):
if modify_conf: if modify_conf:
self.modify_conf_file() self.modify_conf_file()
def notify_audisp_tacplus_reload_config(self):
pid = get_pid("/sbin/audisp-tacplus")
syslog.syslog(syslog.LOG_INFO, "Found audisp-tacplus PID: {}".format(pid))
if pid == "":
return
# audisp-tacplus will reload TACACS+ config when receive SIGHUP
try:
os.kill(int(pid), signal.SIGHUP)
except Exception as ex:
syslog.syslog(syslog.LOG_WARNING, "Send SIGHUP to audisp-tacplus failed with exception: {}".format(ex))
def handle_radius_source_intf_ip_chg(self, key): def handle_radius_source_intf_ip_chg(self, key):
modify_conf=False modify_conf=False
if 'src_intf' in self.radius_global: if 'src_intf' in self.radius_global:
@ -769,6 +793,9 @@ class AaaCfg(object):
with open(NSS_TACPLUS_CONF, 'w') as f: with open(NSS_TACPLUS_CONF, 'w') as f:
f.write(nss_tacplus_conf) f.write(nss_tacplus_conf)
# Notify auditd plugin to reload tacacs config.
self.notify_audisp_tacplus_reload_config()
# Set debug in nss-radius conf # Set debug in nss-radius conf
template_file = os.path.abspath(NSS_RADIUS_CONF_TEMPLATE) template_file = os.path.abspath(NSS_RADIUS_CONF_TEMPLATE)
template = env.get_template(template_file) template = env.get_template(template_file)

View File

@ -1,5 +1,8 @@
* *
!.gitignore !.gitignore
audisp/*
!audisp/Makefile
!audisp/*.patch
!bash_tacplus/* !bash_tacplus/*
nsm/* nsm/*
!nsm/Makefile !nsm/Makefile

View File

@ -0,0 +1,30 @@
.ONESHELL:
SHELL = /bin/bash
.SHELLFLAGS += -e
MAIN_TARGET = audisp-tacplus_$(AUDISP_TACPLUS_VERSION)_$(CONFIGURED_ARCH).deb
$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% :
# Obtain audisp-tacplus
rm -rf ./audisp-tacplus
git clone https://github.com/daveolson53/audisp-tacplus.git
# checkout by sha1
pushd ./audisp-tacplus
git checkout 559c9f22edd4f2dea0ecedffb3ad9502b12a75b6
# Apply patches
cp -r ../patches patches
quilt push -a
# fix aclocal depency issue by run auto.sh
./auto.sh
# build package
dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $(SONIC_DPKG_ADMINDIR)
popd
mv $(DERIVED_TARGETS) $* $(DEST)/
$(addprefix $(DEST)/, $(DERIVED_TARGETS)): $(DEST)/% : $(DEST)/$(MAIN_TARGET)

View File

@ -0,0 +1,426 @@
From 3a552cb456ebc233ef55970509a58a5c378acd7b Mon Sep 17 00:00:00 2001
From: liuh-80 <58683130+liuh-80@users.noreply.github.com>
Date: Tue, 9 Nov 2021 16:34:12 +0800
Subject: [PATCH 1/3] Porting to sonic.
Fixed issue in this patch:
1. The upstream project using 'libtacplus-map' library to lookup_logname, remove that depency by implement by ourself because libtacplus-map not porting to sonic, also because the libnss-tacplus in sonic not using libtacplus-map for user name mapping, sonic using a different solution for user login handling.
2. The libpam-tacplus been changed to support 'source address', which add new parameter to tacacs functions.
3. Upstream project using a patched version of libpam_tacplus, so some method in that not exist in sonic version.
4. For tacacs config file parse and load, code change using the shared method in tacsupport lib.
---
Makefile.am | 3 +-
Makefile.in | 3 +-
audisp-tacplus.c | 234 +++++++++++++-------------------------------
audisp-tacplus.conf | 2 +-
debian/control | 6 +-
5 files changed, 76 insertions(+), 172 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index ad70ca0..caead49 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -6,7 +6,7 @@ EXTRA_DIST = ChangeLog README audisp_tacplus.spec \
audisp_tacplus_SOURCES = audisp-tacplus.c
audisp_tacplus_CFLAGS = -O
-audisp_tacplus_LDADD = -lauparse -ltacplus_map
+audisp_tacplus_LDADD = -lauparse -ltacsupport -ltac
sbin_PROGRAMS = audisp-tacplus
man_MANS = audisp-tacplus.8
@@ -27,7 +27,6 @@ install-data-hook:
${INSTALL} -m 755 audisp-tacplus $(DESTDIR)$(sbindir)
${INSTALL} -d $(DESTDIR)$(sysconfdir)/audisp/plugins.d
${INSTALL} -d $(DESTDIR)$(sysconfdir)/audit/rules.d
- ${INSTALL} -m 600 audisp-tac_plus.conf $(DESTDIR)$(sysconfdir)/audisp/
${INSTALL} -m 644 audisp-tacplus.conf $(DESTDIR)$(sysconfdir)/audisp/plugins.d
${INSTALL} -m 644 -o 0 audisp-tacplus.rules $(DESTDIR)$(sysconfdir)/audit/rules.d
diff --git a/Makefile.in b/Makefile.in
index d124c16..5482a9a 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -345,8 +345,7 @@ target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-EXTRA_DIST = ChangeLog README audisp_tacplus.spec \
- audisp-tac_plus.conf audisp-tacplus.conf
+EXTRA_DIST = ChangeLog README audisp_tacplus.spec audisp-tacplus.conf
audisp_tacplus_SOURCES = audisp-tacplus.c
audisp_tacplus_CFLAGS = -O
diff --git a/audisp-tacplus.c b/audisp-tacplus.c
index 42841e5..5e3fb63 100644
--- a/audisp-tacplus.c
+++ b/audisp-tacplus.c
@@ -45,8 +45,10 @@
#include <sys/types.h>
#include <sys/wait.h>
+#include <pwd.h>
#include <stdio.h>
#include <stdint.h>
+#include <stdlib.h>
#include <inttypes.h>
#include <signal.h>
#include <string.h>
@@ -54,10 +56,14 @@
#include <errno.h>
#include <libaudit.h>
#include <auparse.h>
+#include <unistd.h>
+#include <limits.h>
+#include <libtac/libtac.h>
+#include <trace.h>
-#include <tacplus/libtac.h>
-#include <tacplus/map_tacplus_user.h>
+/* Tacacs+ support lib */
+#include <libtac/support.h>
#define _VMAJ 1
#define _VMIN 0
@@ -71,6 +77,9 @@ static unsigned connected_ok;
char *configfile = "/etc/audisp/audisp-tac_plus.conf";
+/* Tacacs control flag */
+int tacacs_ctrl;
+
/* Local declarations */
static void handle_event(auparse_state_t *au,
auparse_cb_event_t cb_event_type, void *user_data);
@@ -93,179 +102,74 @@ hup_handler(int sig __attribute__ ((unused)))
hup = 1;
}
-typedef struct {
- struct addrinfo *addr;
- char *key;
-} tacplus_server_t;
-
-/* set from configuration file parsing */
-static tacplus_server_t tac_srv[TAC_PLUS_MAXSERVERS];
-static int tac_srv_no, tac_key_no;
-static char tac_service[64];
-static char tac_protocol[64];
-static char vrfname[64];
-static int debug = 0;
-static int acct_all; /* send accounting to all servers, not just 1st */
-
static const char *progname = "audisp-tacplus"; /* for syslogs and errors */
static void
-audisp_tacplus_config(char *cfile, int level)
+reload_config(void)
{
- FILE *conf;
- char lbuf[256];
-
- conf = fopen(cfile, "r");
- if(conf == NULL) {
- syslog(LOG_WARNING, "%s: can't open config file %s: %m",
- progname, cfile);
- return;
- }
+ hup = 0;
- while(fgets(lbuf, sizeof lbuf, conf)) {
- if(*lbuf == '#' || isspace(*lbuf))
- continue; /* skip comments, white space lines, etc. */
- strtok(lbuf, " \t\n\r\f"); /* terminate buffer at first whitespace */
- if(!strncmp(lbuf, "include=", 8)) {
- /*
- * allow include files, useful for centralizing tacacs
- * server IP address and secret.
- */
- if(lbuf[8]) /* else treat as empty config */
- audisp_tacplus_config(&lbuf[8], level+1);
- }
- else if(!strncmp(lbuf, "debug=", 6))
- debug = strtoul(lbuf+6, NULL, 0);
- else if(!strncmp(lbuf, "acct_all=", 9))
- acct_all = strtoul(lbuf+9, NULL, 0);
- else if(!strncmp(lbuf, "vrf=", 4))
- tac_xstrcpy(vrfname, lbuf + 4, sizeof(vrfname));
- else if(!strncmp(lbuf, "service=", 8))
- tac_xstrcpy(tac_service, lbuf + 8, sizeof(tac_service));
- else if(!strncmp(lbuf, "protocol=", 9))
- tac_xstrcpy(tac_protocol, lbuf + 9, sizeof(tac_protocol));
- else if(!strncmp(lbuf, "login=", 6))
- tac_xstrcpy(tac_login, lbuf + 6, sizeof(tac_login));
- else if (!strncmp (lbuf, "timeout=", 8)) {
- tac_timeout = (int)strtoul(lbuf+8, NULL, 0);
- if (tac_timeout < 0) /* explict neg values disable poll() use */
- tac_timeout = 0;
- else /* poll() only used if timeout is explictly set */
- tac_readtimeout_enable = 1;
- }
- else if(!strncmp(lbuf, "secret=", 7)) {
- int i;
- /* no need to complain if too many on this one */
- if(tac_key_no < TAC_PLUS_MAXSERVERS) {
- if((tac_srv[tac_key_no].key = strdup(lbuf+7)))
- tac_key_no++;
- else
- syslog(LOG_ERR, "%s: unable to copy server secret %s",
- __FUNCTION__, lbuf+7);
- }
- /* handle case where 'secret=' was given after a 'server='
- * parameter, fill in the current secret */
- for(i = tac_srv_no-1; i >= 0; i--) {
- if (tac_srv[i].key)
- continue;
- tac_srv[i].key = strdup(lbuf+7);
- }
- }
- else if(!strncmp(lbuf, "server=", 7)) {
- if(tac_srv_no < TAC_PLUS_MAXSERVERS) {
- struct addrinfo hints, *servers, *server;
- int rv;
- char *port, server_buf[sizeof lbuf];
-
- memset(&hints, 0, sizeof hints);
- hints.ai_family = AF_UNSPEC; /* use IPv4 or IPv6, whichever */
- hints.ai_socktype = SOCK_STREAM;
-
- strcpy(server_buf, lbuf + 7);
-
- port = strchr(server_buf, ':');
- if(port != NULL) {
- *port = '\0';
- port++;
- }
- if((rv = getaddrinfo(server_buf, (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;
- /* use current key, if our index not yet set */
- if(tac_key_no && !tac_srv[tac_srv_no].key)
- tac_srv[tac_srv_no].key =
- strdup(tac_srv[tac_key_no-1].key);
- tac_srv_no++;
- }
- }
- else {
- syslog(LOG_ERR,
- "skip invalid server: %s (getaddrinfo: %s)",
- server_buf, gai_strerror(rv));
- }
- }
- else {
- syslog(LOG_ERR, "maximum number of servers (%d) exceeded, "
- "skipping", TAC_PLUS_MAXSERVERS);
- }
- }
- else if(debug) /* ignore unrecognized lines, unless debug on */
- syslog(LOG_WARNING, "%s: unrecognized parameter: %s",
- progname, lbuf);
- }
+ connected_ok = 0; /* reset connected state (for possible vrf) */
- if(level == 0 && (!tac_service[0] || tac_srv_no == 0))
- syslog(LOG_ERR, "%s version %d.%d.%d: missing tacacs fields in file %s, %d servers",
- progname, _VMAJ, _VMIN, _VPATCH, configfile, tac_srv_no);
+ /* load config file: configfile */
+ tacacs_ctrl = parse_config_file(configfile);
- if(debug) {
- int n;
- syslog(LOG_NOTICE, "%s version %d.%d.%d tacacs service=%s", progname,
- _VMAJ, _VMIN, _VPATCH, tac_service);
+ trace("tacacs config updated:\n");
+ int server_idx;
+ for(server_idx = 0; server_idx < tac_srv_no; server_idx++) {
+ trace("Server %d, address:%s, key length:%d\n", server_idx, tac_ntop(tac_srv[server_idx].addr->ai_addr),strlen(tac_srv[server_idx].key));
+ }
- for(n = 0; n < tac_srv_no; n++)
- syslog(LOG_DEBUG, "%s: tacacs server[%d] { addr=%s, key='%s' }",
- progname, n, tac_ntop(tac_srv[n].addr->ai_addr),
- tac_srv[n].key);
+ trace("TACACS+ control flag: 0x%x\n", tacacs_ctrl);
+
+ if (tacacs_ctrl & AUTHORIZATION_FLAG_TACACS) {
+ trace("TACACS+ per-command authorization enabled.\n");
}
- fclose(conf);
+ if (tacacs_ctrl & AUTHORIZATION_FLAG_LOCAL) {
+ trace("Local per-command authorization enabled.\n");
+ }
+
+ if (tacacs_ctrl & PAM_TAC_DEBUG) {
+ trace("TACACS+ debug enabled.\n");
+ }
}
-
-static void
-reload_config(void)
+/*
+ * Get user name by UID, and return NULL when not found user name by UID.
+ * The returned username should be free by caller.
+ * Also assign hostname to host, the host also should be free by caller.
+ */
+char *lookup_logname(uid_t auid, char** host)
{
- int i, nservers;
-
- hup = 0;
+ /* get user name. */
+ struct passwd *pws;
+ pws = getpwuid(auid);
+ if (pws == NULL) {
+ /* Failed to get user information. */
+ return NULL;
+ }
- /* reset the config variables that we use, freeing memory where needed */
- nservers = tac_srv_no;
- tac_srv_no = 0;
- tac_key_no = 0;
- vrfname[0] = '\0';
- tac_service[0] = '\0';
- tac_protocol[0] = '\0';
- tac_login[0] = '\0';
- debug = 0;
- acct_all = 0;
- tac_timeout = 0;
-
- for(i = 0; i < nservers; i++) {
- if(tac_srv[i].key) {
- free(tac_srv[i].key);
- tac_srv[i].key = NULL;
- }
- tac_srv[i].addr = NULL;
+ int new_buffer_size = strlen(pws->pw_name) + 1;
+ char* username = malloc(new_buffer_size);
+ if (username == NULL) {
+ /* Failed to allocate new buffer. */
+ return NULL;
}
- connected_ok = 0; /* reset connected state (for possible vrf) */
+ memset(username, 0, new_buffer_size);
+ strncpy(username, pws->pw_name, new_buffer_size-1);
+
+ /* get hostname. */
+ *host = malloc(HOST_NAME_MAX+1);
+ memset(host, 0, HOST_NAME_MAX+1);
+ if (gethostname(host, HOST_NAME_MAX) != 0)
+ {
+ free(*host);
+ *host = NULL;
+ }
- audisp_tacplus_config(configfile, 0);
+ return username;
}
int
@@ -273,6 +177,9 @@ main(int argc, char *argv[])
{
char tmp[MAX_AUDIT_MESSAGE_LENGTH+1];
struct sigaction sa;
+
+ /* initialize random seed*/
+ srand(time(NULL));
/* if there is an argument, it is an alternate configuration file */
if(argc > 1)
@@ -334,7 +241,7 @@ send_acct_msg(int tac_fd, int type, char *user, char *tty, char *host,
int retval;
struct areply re;
- attr=(struct tac_attrib *)tac_xcalloc(1, sizeof(struct tac_attrib));
+ attr=(struct tac_attrib *)xcalloc(1, sizeof(struct tac_attrib));
snprintf(buf, sizeof buf, "%lu", (unsigned long)time(NULL));
tac_add_attrib(&attr, "start_time", buf);
@@ -378,8 +285,7 @@ send_tacacs_acct(char *user, char *tty, char *host, char *cmdmsg, int type,
int retval, srv_i, srv_fd;
for(srv_i = 0; srv_i < tac_srv_no; srv_i++) {
- srv_fd = tac_connect_single(tac_srv[srv_i].addr, tac_srv[srv_i].key,
- NULL, vrfname[0]?vrfname:NULL);
+ srv_fd = tac_connect_single(tac_srv[srv_i].addr, tac_srv[srv_i].key, tac_source_addr, tac_timeout, __vrfname);
if(srv_fd < 0) {
syslog(LOG_WARNING, "connection to %s failed (%d) to send"
" accounting record: %m",
@@ -393,7 +299,7 @@ send_tacacs_acct(char *user, char *tty, char *host, char *cmdmsg, int type,
close(srv_fd);
if(!retval) {
connected_ok = 1;
- if(!acct_all)
+ if(!(tacacs_ctrl & PAM_TAC_ACCT))
break; /* only send to first responding server */
}
}
@@ -501,7 +407,7 @@ static void get_acct_record(auparse_state_t *au, int type)
taskno = (uint16_t) pid;
}
else /* should never happen, if it does, records won't match */
- taskno = tac_magic();
+ taskno = (u_int32_t)rand();
if(get_field(au, "auid")) {
auser = (char *)auparse_interpret_field(au);
@@ -520,7 +426,7 @@ static void get_acct_record(auparse_state_t *au, int type)
* the NSS library, the username in auser will likely already be the login
* name.
*/
- loguser = lookup_logname(NULL, auid, session, &host, NULL);
+ loguser = lookup_logname(auid, &host);
if(!loguser) {
char *user = NULL;
diff --git a/audisp-tacplus.conf b/audisp-tacplus.conf
index ccb8517..ba77880 100644
--- a/audisp-tacplus.conf
+++ b/audisp-tacplus.conf
@@ -7,7 +7,7 @@ active = yes
# This can be used to specify an different config file than
# /etc/audisp/audisp-tac_plus.conf if desired
-# args =
+args=/etc/tacplus_nss.conf
# These parameters should normally not be changed.
direction = out
diff --git a/debian/control b/debian/control
index 5306bd9..28c7324 100644
--- a/debian/control
+++ b/debian/control
@@ -2,9 +2,9 @@ Source: audisp-tacplus
Section: admin
Priority: optional
Maintainer: Dave Olson <olson@cumulusnetworks.com>
-Build-Depends: debhelper (>= 9), autotools-dev, autoconf, libpam-tacplus-dev,
+Build-Depends: debhelper (>= 9), autotools-dev, autoconf,
libtac-dev (>= 1.4.1~),
- libaudit-dev, libauparse-dev, libtacplus-map-dev,
+ libaudit-dev, libauparse-dev,
dpkg-dev (>= 1.16.1~), git
Standards-Version: 3.9.6
Homepage: https://github.com/daveolson53/audisp_tacplus
@@ -12,7 +12,7 @@ Homepage: https://github.com/daveolson53/audisp_tacplus
Package: audisp-tacplus
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, libpam-tacplus, libtac2 (>= 1.4.1~),
- libtacplus-map1, libauparse0, libaudit1, auditd
+ libauparse0, libaudit1, auditd
Description: audisp module for TACACS+ accounting
This audisp module is an audisp auditd plugin. It is designed to do TACACS+
accounting for commands run by TACACS+ authenticated sessions.
--
2.17.1.windows.2

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,97 @@
From 79b07171c2c2651e535a468d7a56621a2a7049b9 Mon Sep 17 00:00:00 2001
From: liuh-80 <58683130+liuh-80@users.noreply.github.com>
Date: Tue, 23 Nov 2021 13:34:00 +0800
Subject: [PATCH 3/3] Add local accounting.
---
Makefile.am | 2 +-
audisp-tacplus.c | 11 ++++++++++-
local_accounting.c | 17 +++++++++++++++++
local_accounting.h | 7 +++++++
4 files changed, 35 insertions(+), 2 deletions(-)
create mode 100644 local_accounting.c
create mode 100644 local_accounting.h
diff --git a/Makefile.am b/Makefile.am
index b6cb92b..dacc8fd 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,7 +4,7 @@
EXTRA_DIST = ChangeLog README audisp_tacplus.spec \
audisp-tac_plus.conf audisp-tacplus.conf
-audisp_tacplus_SOURCES = audisp-tacplus.c password.c regex_helper.c trace.c sudoers_helper.c
+audisp_tacplus_SOURCES = audisp-tacplus.c password.c regex_helper.c trace.c local_accounting.c sudoers_helper.c
audisp_tacplus_CFLAGS = -O
audisp_tacplus_LDADD = -lauparse -ltacsupport -ltac
sbin_PROGRAMS = audisp-tacplus
diff --git a/audisp-tacplus.c b/audisp-tacplus.c
index 229694b..7a4ab9e 100644
--- a/audisp-tacplus.c
+++ b/audisp-tacplus.c
@@ -69,6 +69,9 @@
#include "password.h"
#include "sudoers_helper.h"
+/* Local accounting */
+#include "local_accounting.h"
+
#define _VMAJ 1
#define _VMIN 0
#define _VPATCH 0
@@ -526,7 +529,13 @@ static void get_acct_record(auparse_state_t *au, int type)
* unknown, and in some cases, host may be not be set.
*/
remove_password(logbase);
- send_tacacs_acct(loguser, tty?tty:"UNK", host?host:"UNK", logbase, acct_type, taskno);
+ if (tacacs_ctrl & ACCOUNTING_FLAG_TACACS) {
+ send_tacacs_acct(loguser, tty?tty:"UNK", host?host:"UNK", logbase, acct_type, taskno);
+ }
+
+ if (tacacs_ctrl & ACCOUNTING_FLAG_LOCAL) {
+ accounting_to_syslog(loguser, tty?tty:"UNK", host?host:"UNK", logbase, acct_type, taskno);
+ }
if(host)
free(host);
diff --git a/local_accounting.c b/local_accounting.c
new file mode 100644
index 0000000..e23acec
--- /dev/null
+++ b/local_accounting.c
@@ -0,0 +1,17 @@
+#include <stdint.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <syslog.h>
+#include <stdlib.h>
+
+#include "trace.h"
+
+/* Accounting log format. */
+#define ACCOUNTING_LOG_FORMAT "Accounting: user: %s, tty: %s, host: %s, command: %s, type: %d, task ID: %d"
+
+/* Write the accounting information to syslog. */
+void accounting_to_syslog(char *user, char *tty, char *host, char *cmdmsg, int type, uint16_t task_id)
+{
+ trace(ACCOUNTING_LOG_FORMAT, user, tty, host, cmdmsg, type, task_id);
+}
\ No newline at end of file
diff --git a/local_accounting.h b/local_accounting.h
new file mode 100644
index 0000000..9e880a7
--- /dev/null
+++ b/local_accounting.h
@@ -0,0 +1,7 @@
+#ifndef LOCAL_ACCOUNTING_H
+#define LOCAL_ACCOUNTING_H
+
+/* Write accounting information to syslog. */
+extern void accounting_to_syslog(char *user, char *tty, char *host, char *cmdmsg, int type, uint16_t task_id);
+
+#endif /* LOCAL_ACCOUNTING_H */
\ No newline at end of file
--
2.17.1.windows.2

View File

@ -0,0 +1,3 @@
0001-Porting-to-sonic.patch
0002-Remove-user-secret-from-accounting-log.patch
0003-Add-local-accounting.patch