Skip to content

Commit

Permalink
In auditd, allow expression of space left as a percentage
Browse files Browse the repository at this point in the history
  • Loading branch information
RH-steve-grubb committed Dec 18, 2018
1 parent c218a04 commit 58005af
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 13 deletions.
1 change: 1 addition & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
- Treat all network originating events as VER2 so dispatcher doesn't format it
- If an event has a node name make it VER2 so dispatcher doesnt format it
- In audisp-remote do an initial connection attempt (#1625156)
- In auditd, allow expression of space left as a percentage (#1650670)

2.8.3
- Correct msg function name in LRU debug code
Expand Down
4 changes: 2 additions & 2 deletions docs/auditd.conf.5
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ This option should contain a valid email address or alias. The default address i
.TP
.I space_left
This is a numeric value in megabytes that tells the audit daemon when
to perform a configurable action because the system is starting to run low on disk space.
to perform a configurable action because the system is starting to run low on disk space. You may also append a percent sign (e.g. 5%) to the number to have the audit daemon calculate the number based on the disk partition size.
.TP
.I space_left_action
This parameter tells the system what action to take when the system has
Expand Down Expand Up @@ -166,7 +166,7 @@ option will cause the audit daemon to shutdown the computer system.
This is a numeric value in megabytes that tells the audit daemon when
to perform a configurable action because the system
.B is running low
on disk space. This should be considered the last chance to do something before running out of disk space. The numeric value for this parameter should be lower than the number for space_left.
on disk space. This should be considered the last chance to do something before running out of disk space. The numeric value for this parameter should be lower than the number for space_left. You may also append a percent sign (e.g. 1%) to the number to have the audit daemon calculate the number based on the disk partition size.
.TP
.I admin_space_left_action
This parameter tells the system what action to take when the system has
Expand Down
106 changes: 95 additions & 11 deletions src/auditd-config.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include <libgen.h>
#include <arpa/inet.h>
#include <limits.h> /* INT_MAX */
#include <sys/vfs.h>
#include "auditd-config.h"
#include "libaudit.h"
#include "private.h"
Expand Down Expand Up @@ -319,11 +320,13 @@ void clear_config(struct daemon_conf *config)
config->max_log_size = 0L;
config->max_log_size_action = SZ_IGNORE;
config->space_left = 0L;
config->space_left_percent = 0;
config->space_left_action = FA_IGNORE;
config->space_left_exe = NULL;
config->action_mail_acct = strdup("root");
config->verify_email = 1;
config->admin_space_left= 0L;
config->admin_space_left_percent = 0;
config->admin_space_left_action = FA_IGNORE;
config->admin_space_left_exe = NULL;
config->disk_full_action = FA_IGNORE;
Expand Down Expand Up @@ -929,21 +932,30 @@ static int freq_parser(struct nv_pair *nv, int line,
static int space_left_parser(struct nv_pair *nv, int line,
struct daemon_conf *config)
{
const char *ptr = nv->value;
char *p, *ptr = (char *)nv->value;
unsigned long i;
int percent = 0;

audit_msg(LOG_DEBUG, "space_left_parser called with: %s", nv->value);
config->space_left_percent = 0;

/* check that all chars are numbers */
for (i=0; ptr[i]; i++) {
if (!isdigit(ptr[i])) {
if (!isdigit(ptr[i]) && ptr[i] != '%') {
audit_msg(LOG_ERR,
"Value %s should only be numbers - line %d",
nv->value, line);
"Value %c %s should only be numbers or percent - line %d",
ptr[i],nv->value, line);
return 1;
}
}

/* Check for percent sign */
p = strchr(ptr, '%');
if (p) {
percent = 1;
*p = ' ';
}

/* convert to unsigned long */
errno = 0;
i = strtoul(nv->value, NULL, 10);
Expand All @@ -953,7 +965,16 @@ static int space_left_parser(struct nv_pair *nv, int line,
strerror(errno), line);
return 1;
}
config->space_left = i;
if (percent) {
if (i > 99) {
audit_msg(LOG_ERR,
"Percentages should be less than 100 - line %d", line);
return 1;
}
config->space_left_percent = i;
config->space_left = 0L;
} else
config->space_left = i;
return 0;
}

Expand Down Expand Up @@ -1137,22 +1158,31 @@ static int verify_email_parser(struct nv_pair *nv, int line,
static int admin_space_left_parser(struct nv_pair *nv, int line,
struct daemon_conf *config)
{
const char *ptr = nv->value;
char *p, *ptr = (char *)nv->value;
unsigned long i;
int percent = 0;

audit_msg(LOG_DEBUG, "admin_space_left_parser called with: %s",
nv->value);
config->admin_space_left_percent = 0;

/* check that all chars are numbers */
for (i=0; ptr[i]; i++) {
if (!isdigit(ptr[i])) {
if (!isdigit(ptr[i]) && ptr[i] != '%') {
audit_msg(LOG_ERR,
"Value %s should only be numbers - line %d",
nv->value, line);
"Value %c %s should only be numbers or percent - line %d",
ptr[i],nv->value, line);
return 1;
}
}

/* Check for percent sign */
p = strchr(ptr, '%');
if (p) {
percent = 1;
*p = ' ';
}

/* convert to unsigned long */
errno = 0;
i = strtoul(nv->value, NULL, 10);
Expand All @@ -1162,7 +1192,16 @@ static int admin_space_left_parser(struct nv_pair *nv, int line,
strerror(errno), line);
return 1;
}
config->admin_space_left = i;
if (percent) {
if (i > 99) {
audit_msg(LOG_ERR,
"Percentages should be less than 100 - line %d", line);
return 1;
}
config->admin_space_left_percent = i;
config->admin_space_left = 0L;
} else
config->admin_space_left = i;
return 0;
}

Expand Down Expand Up @@ -1803,7 +1842,50 @@ static int plugin_dir_parser(struct nv_pair *nv, int line,
return 0;
}

/*
* Query file system and calculate in MB the given percentage is.
* Returns 0 on error and a number otherwise.
*/
static unsigned long calc_percent(float percent, int fd)
{
int rc;
struct statfs buf;

rc = fstatfs(fd, &buf);
if (rc == 0) {
unsigned long free_space;
// All blocks * percentage = free blocks threshold
fsblkcnt_t free_blocks = buf.f_blocks * (percent/100.0);
// That is then converted into megabytes and returned
free_space = (buf.f_bsize * free_blocks) / MEGABYTE;

return free_space;
}
return 0;
}

/*
* This function translates a percentage of disk space to the
* actual MB value for space left actions.
*/
void setup_percentages(struct daemon_conf *config, int fd)
{
if (!config->write_logs)
return;
if (config->daemonize != D_BACKGROUND)
return;

if (config->space_left_percent)
config->space_left =
calc_percent(config->space_left_percent, fd);
if (config->admin_space_left_percent)
config->admin_space_left =
calc_percent(config->admin_space_left_percent, fd);
if (config->space_left <= config->admin_space_left)
audit_msg(LOG_ERR,
"Error - space_left(%lu) must be larger than admin_space_left(%lu)",
config->space_left, config->admin_space_left);
}

/*
* This function is where we do the integrated check of the audit config
Expand All @@ -1813,7 +1895,9 @@ static int plugin_dir_parser(struct nv_pair *nv, int line,
static int sanity_check(struct daemon_conf *config)
{
/* Error checking */
if (config->space_left <= config->admin_space_left) {
if (config->space_left_percent == 0 &&
config->admin_space_left_percent == 0 &&
config->space_left <= config->admin_space_left) {
audit_msg(LOG_ERR,
"Error - space_left(%lu) must be larger than admin_space_left(%lu)",
config->space_left, config->admin_space_left);
Expand Down
3 changes: 3 additions & 0 deletions src/auditd-config.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,13 @@ struct daemon_conf
unsigned long max_log_size;
size_action max_log_size_action;
unsigned long space_left;
unsigned int space_left_percent;
failure_action_t space_left_action;
const char *space_left_exe;
const char *action_mail_acct;
unsigned int verify_email;
unsigned long admin_space_left;
unsigned int admin_space_left_percent;
failure_action_t admin_space_left_action;
const char *admin_space_left_exe;
failure_action_t disk_full_action;
Expand Down Expand Up @@ -103,6 +105,7 @@ void clear_config(struct daemon_conf *config);
const char *audit_lookup_format(int fmt);
int create_log_file(const char *val);
int resolve_node(struct daemon_conf *config);
void setup_percentages(struct daemon_conf *config, int fd);

void init_config_manager(void);
#ifdef AUDITD_EVENT_H
Expand Down
28 changes: 28 additions & 0 deletions src/auditd-event.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,19 @@ void write_logging_state(FILE *f)
fprintf(f, "logs detected last rotate/shift = %u\n", known_logs);
fprintf(f, "space left on partition = %s\n",
fs_space_left ? "yes" : "no");
if (config->daemonize != D_BACKGROUND && config->write_logs) {
int rc;
struct statfs buf;
rc = fstatfs(log_fd, &buf);
if (rc == 0) {
fprintf(f, "Logging partition free space %lu MB\n",
(buf.f_bavail * buf.f_bsize)/MEGABYTE);
fprintf(f, "space_left setting %lu MB\n",
config->space_left);
fprintf(f, "admin_space_left setting %lu MB\n",
config->admin_space_left);
}
}
fprintf(f, "logging suspended = %s\n",
logging_suspended ? "yes" : "no");
fprintf(f, "file system space action performed = %s\n",
Expand Down Expand Up @@ -140,6 +153,7 @@ int init_event(struct daemon_conf *conf)
fix_disk_permissions();
if (open_audit_log())
return 1;
setup_percentages(config, log_fd);
} else {
log_fd = 1; // stdout
log_file = fdopen(log_fd, "a");
Expand Down Expand Up @@ -1442,6 +1456,12 @@ static void reconfigure(struct auditd_event *e)
need_space_check = 1;
}

// space left percent
if (oconf->space_left_percent != nconf->space_left_percent) {
oconf->space_left_percent = nconf->space_left_percent;
need_space_check = 1;
}

// space left action
if (oconf->space_left_action != nconf->space_left_action) {
oconf->space_left_action = nconf->space_left_action;
Expand All @@ -1466,6 +1486,13 @@ static void reconfigure(struct auditd_event *e)
need_space_check = 1;
}

// admin space left percent
if (oconf->admin_space_left_percent != nconf->admin_space_left_percent){
oconf->admin_space_left_percent =
nconf->admin_space_left_percent;
need_space_check = 1;
}

// admin space action
if (oconf->admin_space_left_action != nconf->admin_space_left_action) {
oconf->admin_space_left_action = nconf->admin_space_left_action;
Expand Down Expand Up @@ -1509,6 +1536,7 @@ static void reconfigure(struct auditd_event *e)
* having to call check_log_file_size to restore it. */
int saved_suspend = logging_suspended;

setup_percentages(oconf, log_fd);
fs_space_warning = 0;
fs_admin_space_warning = 0;
fs_space_left = 1;
Expand Down

0 comments on commit 58005af

Please sign in to comment.