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

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

##### Work item tracking
- Microsoft ADO **(number only)**: 24433713

#### 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.

#### Tested branch (Please provide the tested image version)
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.

- [ ]  SONiC.202012-15723.312602-e230e2d3e

#### Description for the changelog
Add audisp-tacplus for per-command accounting.
This commit is contained in:
Hua Liu 2023-07-13 09:46:47 +08:00 committed by GitHub
parent 9a733fde99
commit 4df2bc9b44
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 1757 additions and 6 deletions

View File

@ -322,7 +322,11 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in
python3-pip \
cron \
haveged \
jq
jq \
auditd
# Change auditd log file path to fix auditd can't startup issue.
sudo LANG=C chroot $FILESYSTEM_ROOT /bin/bash -c "sudo sed -i 's/^\s*log_file\s*=.*/log_file = \/var\/log\/audit.log/g' /etc/audit/auditd.conf"
if [[ $CONFIGURED_ARCH == amd64 ]]; then
## Pre-install the fundamental packages for amd64 (x86)

View File

@ -281,6 +281,9 @@ sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/libpam-tacplus_*.deb || \
sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f
sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/libnss-tacplus_*.deb || \
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
sudo LANG=C chroot $FILESYSTEM_ROOT pam-auth-update --remove tacplus
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)
$(eval $(call add_derived_package,$(LIBTAC2),$(LIBTAC_DEV)))
# libnss-tacplus packages
NSS_TACPLUS_VERSION = 1.0.4-1
@ -29,6 +27,17 @@ $(LIBNSS_TACPLUS)_RDEPENDS += $(LIBTAC2)
$(LIBNSS_TACPLUS)_SRC_PATH = $(SRC_PATH)/tacacs/nss
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)
# The .c, .cpp, .h & .hpp files under src/{$DBG_SRC_ARCHIVE list}
# are archived into debug one image to facilitate debugging.
#

View File

@ -890,7 +890,8 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \
$(PYTHON_SWSSCOMMON) \
$(PYTHON3_SWSSCOMMON) \
$(SONIC_UTILITIES_DATA) \
$(SONIC_HOST_SERVICES_DATA)) \
$(SONIC_HOST_SERVICES_DATA) \
$(AUDISP_TACPLUS)) \
$$(addprefix $(TARGET_PATH)/,$$($$*_DOCKERS)) \
$$(addprefix $(FILES_PATH)/,$$($$*_FILES)) \
$(if $(findstring y,$(ENABLE_ZTP)),$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(SONIC_ZTP))) \

View File

@ -304,7 +304,10 @@ RUN apt-get update && apt-get install -y \
libboost-regex1.71-dev \
googletest \
libgtest-dev \
libgcc-8-dev
libgcc-8-dev \
# For audisp-tacplus
libauparse-dev \
auditd
RUN apt-get -y build-dep openssh

View File

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

View File

@ -259,7 +259,10 @@ RUN apt-get update && apt-get install -y \
libxml2-utils \
xsltproc \
python-lxml \
libexpat1-dev
libexpat1-dev \
# For audisp-tacplus
libauparse-dev \
auditd
## Config dpkg
## install the configuration file if its currently missing

View File

@ -80,6 +80,18 @@ def obfuscate(data):
else:
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 ""
def run_cmd(cmd, log_err = True):
try:
@ -235,6 +247,18 @@ class AaaCfg(object):
syslog.syslog(syslog.LOG_INFO, "file size check pass: {} size is ({}) bytes".format(filename, size))
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 modify_single_file(self, filename, operations=None):
if operations:
cmd = "sed -e {0} {1} > {1}.new; mv -f {1} {1}.old; mv -f {1}.new {1}".format(' -e '.join(operations), filename)
@ -319,6 +343,9 @@ class AaaCfg(object):
with open(NSS_TACPLUS_CONF, 'w') as f:
f.write(nss_tacplus_conf)
# Notify auditd plugin to reload tacacs config.
self.notify_audisp_tacplus_reload_config()
class KdumpCfg(object):
def __init__(self, CfgDb):
self.config_db = CfgDb

View File

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

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