[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:
parent
06a61dede0
commit
739c45645c
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
#
|
#
|
||||||
|
3
slave.mk
3
slave.mk
@ -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)) \
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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 \
|
||||||
|
@ -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 \
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
3
src/tacacs/.gitignore
vendored
3
src/tacacs/.gitignore
vendored
@ -1,5 +1,8 @@
|
|||||||
*
|
*
|
||||||
!.gitignore
|
!.gitignore
|
||||||
|
audisp/*
|
||||||
|
!audisp/Makefile
|
||||||
|
!audisp/*.patch
|
||||||
!bash_tacplus/*
|
!bash_tacplus/*
|
||||||
nsm/*
|
nsm/*
|
||||||
!nsm/Makefile
|
!nsm/Makefile
|
||||||
|
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