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:
parent
9a733fde99
commit
4df2bc9b44
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
#
|
||||
|
3
slave.mk
3
slave.mk
@ -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))) \
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 \
|
||||
|
@ -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 it’s currently missing
|
||||
|
@ -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
|
||||
|
3
src/tacacs/.gitignore
vendored
3
src/tacacs/.gitignore
vendored
@ -1,5 +1,8 @@
|
||||
*
|
||||
!.gitignore
|
||||
audisp/*
|
||||
!audisp/Makefile
|
||||
!audisp/*.patch
|
||||
nsm/*
|
||||
!nsm/Makefile
|
||||
!nsm/*.patch
|
||||
|
30
src/tacacs/audisp/Makefile
Normal file
30
src/tacacs/audisp/Makefile
Normal 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)
|
426
src/tacacs/audisp/patches/0001-Porting-to-sonic.patch
Normal file
426
src/tacacs/audisp/patches/0001-Porting-to-sonic.patch
Normal 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
97
src/tacacs/audisp/patches/0003-Add-local-accounting.patch
Normal file
97
src/tacacs/audisp/patches/0003-Add-local-accounting.patch
Normal 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
|
||||
|
3
src/tacacs/audisp/patches/series
Normal file
3
src/tacacs/audisp/patches/series
Normal file
@ -0,0 +1,3 @@
|
||||
0001-Porting-to-sonic.patch
|
||||
0002-Remove-user-secret-from-accounting-log.patch
|
||||
0003-Add-local-accounting.patch
|
Loading…
Reference in New Issue
Block a user