Skip to content

Commit

Permalink
Add command line option to auditd & audispd for config file path
Browse files Browse the repository at this point in the history
  • Loading branch information
RH-steve-grubb committed Oct 5, 2017
1 parent 783cbcf commit 703330b
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 35 deletions.
1 change: 1 addition & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
- In auparse_normalize, finish support for MAC_STATUS and MAC_CONFIG events
- Add support for filesystem filter type
- Add file system type table for fstype lookup
- Add command line option to auditd & audispd for config file path (Dan Born)

2.7.8
- Add config option to auditd to not verify email addr domain (#1406887)
Expand Down
113 changes: 97 additions & 16 deletions audisp/audispd.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <arpa/inet.h>
#include <limits.h>
#include <sys/uio.h>
#include <getopt.h>

#include "audispd-config.h"
#include "audispd-pconfig.h"
Expand All @@ -53,8 +54,10 @@ static daemon_conf_t daemon_config;
static conf_llist plugin_conf;
static int audit_fd;
static pthread_t inbound_thread;
static const char *config_file = "/etc/audisp/audispd.conf";
static const char *plugin_dir = "/etc/audisp/plugins.d/";
static const char *config_file = NULL;

/* '/' on the end is required. */
static char *plugin_dir = NULL;

/* Local function prototypes */
static void signal_plugins(int sig);
Expand All @@ -63,6 +66,27 @@ static int safe_exec(plugin_conf_t *conf);
static void *inbound_thread_main(void *arg);
static void process_inbound_event(int fd);

/*
* Output a usage message and exit with an error.
*/
static void usage(void)
{
fprintf(stderr, "%s",
"Usage: audispd [options]\n"
"-c,--config_file <config_file_path>: Override default "
"configuration file path\n"
"-d,--plugin_dir <plugin_dir_path>: Override default plugin "
"directory path\n");
exit(2);
}

static release_memory_exit(int code)
{
free(config_file);
free(plugin_dir);
exit(code);
}

/*
* SIGTERM handler
*/
Expand Down Expand Up @@ -331,9 +355,58 @@ static int reconfigure(void)

int main(int argc, char *argv[])
{
extern char *optarg;
extern int optind;
static const struct option opts[] = {
{"config_file", required_argument, NULL, 'c'},
{"plugin_dir", required_argument, NULL, 'd'},
{NULL, 0, NULL, 0}
};
lnode *conf;
struct sigaction sa;
int i;
size_t len;

while ((i = getopt_long(argc, argv, "i:c:d:", opts, NULL)) != -1) {
switch (i) {
case 'c':
config_file = strdup(optarg);
if (config_file == NULL)
goto mem_out;
break;
case 'd':
plugin_dir = malloc(len + 2);
if (plugin_dir) {
strcpy(plugin_dir, optarg);
if (plugin_dir[len - 1] != '/') {
plugin_dir[len] = '/';
plugin_dir[len + 1] = '\0';
}
} else {
mem_out:
printf(
"Failed allocating memory, exiting\n");
release_memory_exit(1);
}
break;
default:
usage();
}
}

/* check for trailing command line following options */
if (optind < argc)
usage();

if (config_file == NULL)
config_file = strdup("/etc/audisp/audispd.conf");
if (config_file == NULL)
goto mem_out;

if (plugin_dir == NULL)
plugin_dir = strdup("/etc/audisp/plugins.d/");
if (plugin_dir == NULL)
goto mem_out;

set_aumessage_mode(MSG_SYSLOG, DBG_NO);

Expand All @@ -359,15 +432,11 @@ int main(int argc, char *argv[])
sigaction(SIGCHLD, &sa, NULL);
setsid();

/* move stdin to its own fd */
if (argc == 3 && strcmp(argv[1], "--input") == 0)
audit_fd = open(argv[2], O_RDONLY);
else
audit_fd = dup(0);
audit_fd = dup(0);
if (audit_fd < 0) {
syslog(LOG_ERR, "Failed setting up input(%s, %d), exiting",
strerror(errno), audit_fd);
return 1;
release_memory_exit(1);
}

/* Make all descriptors point to dev null */
Expand All @@ -376,30 +445,39 @@ int main(int argc, char *argv[])
if (dup2(0, i) < 0 || dup2(1, i) < 0 || dup2(2, i) < 0) {
syslog(LOG_ERR, "Failed duping /dev/null %s, exiting",
strerror(errno));
return 1;
release_memory_exit(1);
}
close(i);
close(audit_fd);
} else {
syslog(LOG_ERR, "Failed opening /dev/null %s, exiting",
strerror(errno));
return 1;
close(audit_fd);
release_memory_exit(1);
}
if (fcntl(audit_fd, F_SETFD, FD_CLOEXEC) < 0) {
syslog(LOG_ERR, "Failed protecting input %s, exiting",
strerror(errno));
return 1;
close(audit_fd);
close(i);
release_memory_exit(1);
}

/* init the daemon's config */
if (load_config(&daemon_config, config_file))
return 6;
if (load_config(&daemon_config, config_file)) {
close(audit_fd);
close(i);
release_memory_exit(6);
}

load_plugin_conf(&plugin_conf);

/* if no plugins - exit */
if (plist_count(&plugin_conf) == 0) {
syslog(LOG_NOTICE, "No plugins found, exiting");
return 0;
close(audit_fd);
close(i);
release_memory_exit(0);
}

/* Plugins are started with the auditd priority */
Expand Down Expand Up @@ -427,7 +505,9 @@ int main(int argc, char *argv[])
/* Tell it to poll the audit fd */
if (add_event(audit_fd, process_inbound_event) < 0) {
syslog(LOG_ERR, "Cannot add event, exiting");
return 1;
close(audit_fd);
close(i);
release_memory_exit(1);
}

/* Create inbound thread */
Expand Down Expand Up @@ -472,6 +552,8 @@ int main(int argc, char *argv[])
/* Cleanup the queue */
destroy_queue();
free_config(&daemon_config);
free(config_file);
free(plugin_dir);

return 0;
}
Expand Down Expand Up @@ -880,4 +962,3 @@ static void process_inbound_event(int fd)
}
}
}

1 change: 1 addition & 0 deletions docs/audispd.8
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
audispd \- an event multiplexor
.SH SYNOPSIS
.B audispd
.RB [ \-c\ <config_file> ]\ [ \-d\ <plugin_dir> ]
.SH DESCRIPTION
\fBaudispd\fP is an audit event multiplexor. It has to be started by the audit daemon in order to get events. It takes audit events and distributes them to child programs that want to analyze events in realtime. When the audit daemon receives a SIGTERM or SIGHUP, it passes that signal to the dispatcher, too. The dispatcher in turn passes those signals to its child processes.

Expand Down
5 changes: 4 additions & 1 deletion docs/auditd.8
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
auditd \- The Linux Audit daemon
.SH SYNOPSIS
.B auditd
.RB [ \-f ]\ [ \-l ]\ [ \-n ]\ [ \-s\ disable|enable|nochange ]
.RB [ \-f ]\ [ \-l ]\ [ \-n ]\ [ \-s\ disable|enable|nochange ]\ [ \-c\ <config_file> ]
.SH DESCRIPTION
\fBauditd\fP is the userspace component to the Linux Auditing System. It's responsible for writing audit records to the disk. Viewing the logs is done with the
.B ausearch
Expand All @@ -29,6 +29,9 @@ no fork. This is useful for running off of inittab or systemd.
.TP
.B \-s=\fIENABLE_STATE\fR
specify when starting if auditd should change the current value for the kernel enabled flag. Valid values for ENABLE_STATE are "disable", "enable" or "nochange". The default is to enable (and disable when auditd terminates). The value of the enabled flag may be changed during the lifetime of auditd using 'auditctl \-e'.
.TP
.B \-c
Specify alternate config file path (default: /etc/audit/auditd.conf).
.SH SIGNALS
.TP
SIGHUP
Expand Down
36 changes: 22 additions & 14 deletions src/auditd-config.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,13 +240,21 @@ static const struct nv_list yes_no_values[] =

const char *email_command = "/usr/lib/sendmail";
static int allow_links = 0;
static const char *config_file = NULL;


void set_allow_links(int allow)
{
allow_links = allow;
}

int set_config_file(const char *val) {
config_file = strdup(val);
if (config_file == NULL)
return 1;
return 0;
}

/*
* Set everything to its default value
*/
Expand Down Expand Up @@ -310,15 +318,15 @@ int load_config(struct daemon_conf *config, log_test_t lt)
mode = O_RDONLY;
if (allow_links == 0)
mode |= O_NOFOLLOW;
rc = open(CONFIG_FILE, mode);
rc = open(config_file, mode);
if (rc < 0) {
if (errno != ENOENT) {
audit_msg(LOG_ERR, "Error opening config file (%s)",
strerror(errno));
return 1;
}
audit_msg(LOG_WARNING,
"Config file %s doesn't exist, skipping", CONFIG_FILE);
"Config file %s doesn't exist, skipping", config_file);
return 0;
}
fd = rc;
Expand All @@ -327,7 +335,7 @@ int load_config(struct daemon_conf *config, log_test_t lt)
* not symlink.
*/
audit_msg(LOG_DEBUG, "Config file %s opened for parsing",
CONFIG_FILE);
config_file);
if (fstat(fd, &st) < 0) {
audit_msg(LOG_ERR, "Error fstat'ing config file (%s)",
strerror(errno));
Expand All @@ -336,19 +344,19 @@ int load_config(struct daemon_conf *config, log_test_t lt)
}
if (st.st_uid != 0) {
audit_msg(LOG_ERR, "Error - %s isn't owned by root",
CONFIG_FILE);
config_file);
close(fd);
return 1;
}
if ((st.st_mode & S_IWOTH) == S_IWOTH) {
audit_msg(LOG_ERR, "Error - %s is world writable",
CONFIG_FILE);
config_file);
close(fd);
return 1;
}
if (!S_ISREG(st.st_mode)) {
audit_msg(LOG_ERR, "Error - %s is not a regular file",
CONFIG_FILE);
config_file);
close(fd);
return 1;
}
Expand All @@ -362,7 +370,7 @@ int load_config(struct daemon_conf *config, log_test_t lt)
return 1;
}

while (get_line(f, buf, sizeof(buf), &lineno, CONFIG_FILE)) {
while (get_line(f, buf, sizeof(buf), &lineno, config_file)) {
// convert line into name-value pair
const struct kw_pair *kw;
struct nv_pair nv;
Expand All @@ -373,17 +381,17 @@ int load_config(struct daemon_conf *config, log_test_t lt)
case 1: // not the right number of tokens.
audit_msg(LOG_ERR,
"Wrong number of arguments for line %d in %s",
lineno, CONFIG_FILE);
lineno, config_file);
break;
case 2: // no '=' sign
audit_msg(LOG_ERR,
"Missing equal sign for line %d in %s",
lineno, CONFIG_FILE);
lineno, config_file);
break;
default: // something else went wrong...
audit_msg(LOG_ERR,
"Unknown error for line %d in %s",
lineno, CONFIG_FILE);
lineno, config_file);
break;
}
if (nv.name == NULL) {
Expand All @@ -394,7 +402,7 @@ int load_config(struct daemon_conf *config, log_test_t lt)
fclose(f);
audit_msg(LOG_ERR,
"Not processing any more lines in %s",
CONFIG_FILE);
config_file);
return 1;
}

Expand All @@ -403,7 +411,7 @@ int load_config(struct daemon_conf *config, log_test_t lt)
if (kw->name == NULL) {
audit_msg(LOG_ERR,
"Unknown keyword \"%s\" in line %d of %s",
nv.name, lineno, CONFIG_FILE);
nv.name, lineno, config_file);
fclose(f);
return 1;
}
Expand All @@ -413,7 +421,7 @@ int load_config(struct daemon_conf *config, log_test_t lt)
audit_msg(LOG_ERR,
"Keyword \"%s\" has invalid option "
"\"%s\" in line %d of %s",
nv.name, nv.option, lineno, CONFIG_FILE);
nv.name, nv.option, lineno, config_file);
fclose(f);
return 1;
}
Expand Down Expand Up @@ -1748,6 +1756,7 @@ void free_config(struct daemon_conf *config)
free((void *)config->disk_error_exe);
free((void *)config->krb5_principal);
free((void *)config->krb5_key_file);
free(config_file);
}

int resolve_node(struct daemon_conf *config)
Expand Down Expand Up @@ -1840,4 +1849,3 @@ int resolve_node(struct daemon_conf *config)
config->node_name);
return rc;
}

5 changes: 4 additions & 1 deletion src/auditd-config.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ struct daemon_conf
};

void set_allow_links(int allow);

/* Return 0 on success. */
int set_config_file(const char *val);

int load_config(struct daemon_conf *config, log_test_t lt);
void clear_config(struct daemon_conf *config);
const char *audit_lookup_format(int fmt);
Expand All @@ -101,4 +105,3 @@ void shutdown_config(void);
void free_config(struct daemon_conf *config);

#endif

Loading

0 comments on commit 703330b

Please sign in to comment.