Skip to content

Commit

Permalink
feat: new plugin check_selinux
Browse files Browse the repository at this point in the history
Signed-off-by: Davide Madrisan <[email protected]>
  • Loading branch information
madrisan committed Apr 6, 2024
1 parent 476cab5 commit f3ea022
Show file tree
Hide file tree
Showing 13 changed files with 244 additions and 14 deletions.
1 change: 1 addition & 0 deletions include/mountlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,6 @@ struct mount_entry
};

struct mount_entry *read_file_system_list (bool need_fs_type);
int file_system_type_exists (char *fs_type, char **fs_mp);

#endif /* mountlist.h */
29 changes: 29 additions & 0 deletions include/npl_selinux.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-License-Identifier: GPL-3.0-or-later
/* npl_selinux.h -- a library for getting informations about SELinux
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */

#ifndef _NPL_SELINUX_H
#define _NPL_SELINUX_H 1

#define SELINUXMNT "/sys/fs/selinux"
#define OLDSELINUXMNT "/selinux"
#define SELINUXFS "selinuxfs"

/* Return 1 if we are running on a SELinux kernel, or 0 otherwise.
* selinux_fs is set to the selinux filesystem mount point.
*/
int is_selinux_enabled (void);

#endif /* npl_selinux.h */
4 changes: 2 additions & 2 deletions include/sysfsparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ extern "C"

char *sysfsparser_getline (const char *filename, ...)
_attribute_format_printf_(1, 2);
unsigned long long sysfsparser_getvalue (const char *filename, ...)
_attribute_format_printf_(1, 2);
int sysfsparser_getvalue (unsigned long long *value, const char *filename, ...)
_attribute_format_printf_(2, 3);

/* Lookup a pattern and get the value from line
* Format is:
Expand Down
1 change: 1 addition & 0 deletions lib/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ libutils_a_SOURCES = \
mountlist.c \
netinfo.c \
netinfo-private.c \
npl_selinux.c \
perfdata.c \
pressure.c \
processes.c \
Expand Down
5 changes: 4 additions & 1 deletion lib/cpudesc.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,10 @@ get_processor_is_online (unsigned int cpu)
if (false == path_exist)
return -1;

return sysfsparser_getvalue (PATH_SYS_CPU "/cpu%u/online", cpu);
unsigned long long value;

sysfsparser_getvalue (&value, PATH_SYS_CPU "/cpu%u/online", cpu);
return value;
}

enum /* CPU modes */
Expand Down
5 changes: 4 additions & 1 deletion lib/cputopology.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,10 @@ get_processor_number_online (void)
int
get_processor_number_kernel_max ()
{
return sysfsparser_getvalue (PATH_SYS_CPU "/kernel_max") + 1;
unsigned long long value;

sysfsparser_getvalue (&value, PATH_SYS_CPU "/kernel_max");
return value + 1;
}

static inline int
Expand Down
4 changes: 2 additions & 2 deletions lib/meminfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,8 @@ void proc_sysmem_read (struct proc_sysmem *sysmem)
else
{
dbg ("...let's calculate the value...\n");
unsigned long kb_min_free =
sysfsparser_getvalue (PATH_VM_MIN_FREE_KB);
unsigned long long kb_min_free;
sysfsparser_getvalue (&kb_min_free, PATH_VM_MIN_FREE_KB);
/* should be equal to sum of all 'low' fields in /proc/zoneinfo */
unsigned long watermark_low = kb_min_free * 5 / 4;

Expand Down
22 changes: 22 additions & 0 deletions lib/mountlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,25 @@ read_file_system_list (bool need_fs_type)
return NULL;
}
}

int
file_system_type_exists (char *fs_type, char **fs_mp)
{
int exists = 0;
struct mount_entry *mount_list, *me;

if (NULL == fs_type)
return -1;

mount_list = read_file_system_list (false);

for (me = mount_list; me; me = me->me_next)
if (STREQ (me->me_type, fs_type))
{
*fs_mp = me->me_mountdir;
exists = 1;
break;
}

return exists;
}
60 changes: 60 additions & 0 deletions lib/npl_selinux.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// SPDX-License-Identifier: GPL-3.0-or-later
/*
* License: GPLv3+
* Copyright (c) 2024 Davide Madrisan <[email protected]>
*
* A library for checking SELinux status.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. */

#include <stddef.h>

#include "messages.h"
#include "mountlist.h"
#include "npl_selinux.h"
#include "sysfsparser.h"
#include "system.h"

char *selinux_mnt = NULL;

/* Return 1 if selinuxfs exists as a kernel filesystem, or 0 otherwise. */
static int
selinuxfs_exists ()
{
int exists;

exists = file_system_type_exists (SELINUXFS, &selinux_mnt);
if (exists < 0)
plugin_error (STATE_UNKNOWN, 0,
"an error occurred while checking for a SELinux filesystem");
return exists;
}

int
is_selinux_enabled (void)
{
int fs_exists = selinuxfs_exists ();
unsigned long long value;

if (0 == fs_exists)
return 0;
if (0 == sysfsparser_path_exist ("%s/enforce", selinux_mnt))
return 0;

if ((sysfsparser_getvalue (&value, "%s/enforce", selinux_mnt) < 0))
plugin_error (STATE_UNKNOWN, 0,
"an error occurred while checking for the SELinux status");

return value;
}
14 changes: 7 additions & 7 deletions lib/sysfsparser.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,11 +188,11 @@ sysfsparser_getline (const char *format, ...)
return line;
}

unsigned long long
sysfsparser_getvalue (const char *format, ...)
int
sysfsparser_getvalue (unsigned long long *value, const char *format, ...)
{
char *line, *endptr, *filename;
unsigned long long value;
int retvalue = 0;
va_list args;

va_start (args, format);
Expand All @@ -201,15 +201,15 @@ sysfsparser_getvalue (const char *format, ...)
va_end (args);

if (NULL == (line = sysfsparser_getline ("%s", filename)))
return 0;
return -1;

errno = 0;
value = strtoull (line, &endptr, 0);
*value = strtoull (line, &endptr, 0);
if ((endptr == line) || (errno == ERANGE))
value = 0;
retvalue = -1;

free (line);
return value;
return retvalue;
}

int
Expand Down
3 changes: 3 additions & 0 deletions plugins/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ libexec_PROGRAMS = \
check_paging \
check_pressure \
check_readonlyfs \
check_selinux \
check_temperature \
check_tcpcount \
check_uptime \
Expand Down Expand Up @@ -91,6 +92,7 @@ check_network_SOURCES = check_network.c
check_paging_SOURCES = check_paging.c
check_pressure_SOURCES = check_pressure.c
check_readonlyfs_SOURCES = check_readonlyfs.c
check_selinux_SOURCES = check_selinux.c
if HAVE_PROC_MEMINFO
check_swap_SOURCES = check_swap.c
endif
Expand Down Expand Up @@ -123,6 +125,7 @@ check_network_LDADD = $(LDADD) $(CEIL_LIBS)
check_multipath_LDADD = $(LDADD)
check_paging_LDADD = $(LDADD) $(LIBPROCPS_LIBS)
check_readonlyfs_LDADD = $(LDADD)
check_selinux_LDADD = $(LDADD)
if HAVE_PROC_MEMINFO
check_swap_LDADD = $(LDADD)
endif
Expand Down
2 changes: 1 addition & 1 deletion plugins/check_network.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* License: GPLv3+
* Copyright (c) 2014,2015,2020 Davide Madrisan <[email protected]>
*
* A Nagios plugin that displays some network interfaces.statistics.
* A Nagios plugin that displays some network interfaces statistics.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down
108 changes: 108 additions & 0 deletions plugins/check_selinux.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// SPDX-License-Identifier: GPL-3.0-or-later
/*
* License: GPLv3+
* Copyright (c) 2024 Davide Madrisan <[email protected]>
*
* A Nagios plugin that checks if SELinux is enabled.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>

#include "common.h"
#include "messages.h"
#include "npl_selinux.h"
#include "progname.h"
#include "progversion.h"
#include "system.h"
#include "xasprintf.h"

extern char *selinux_mnt;

static const char *program_copyright =
"Copyright (C) 2024 Davide Madrisan <" PACKAGE_BUGREPORT ">\n";

static struct option const longopts[] = {
{(char *) "help", no_argument, NULL, GETOPT_HELP_CHAR},
{(char *) "version", no_argument, NULL, GETOPT_VERSION_CHAR},
{NULL, 0, NULL, 0}
};

static _Noreturn void
usage (FILE * out)
{
fprintf (out, "%s (" PACKAGE_NAME ") v%s\n", program_name, program_version);
fputs ("This plugin checks if SELinux is enabled.\n", out);
fputs (program_copyright, out);
fputs (USAGE_HEADER, out);
fprintf (out, " %s -w COUNTER|PERC -c COUNTER|PERC\n", program_name);
fputs (USAGE_OPTIONS, out);
fputs (USAGE_HELP, out);
fputs (USAGE_VERSION, out);
fputs (USAGE_EXAMPLES, out);
fprintf (out, " %s ...\n",
program_name);

exit (out == stderr ? STATE_UNKNOWN : STATE_OK);
}

static _Noreturn void
print_version (void)
{
printf ("%s (" PACKAGE_NAME ") v%s\n", program_name, program_version);
fputs (program_copyright, stdout);
fputs (GPLv3_DISCLAIMER, stdout);

exit (STATE_OK);
}

int
main (int argc, char **argv)
{
int c, is_enabled;
nagstatus status = STATE_OK;

set_program_name (argv[0]);

while ((c = getopt_long (argc, argv,
GETOPT_HELP_VERSION_STRING,
longopts, NULL)) != -1)
{
switch (c)
{
default:
usage (stderr);

case_GETOPT_HELP_CHAR
case_GETOPT_VERSION_CHAR

}
}

is_enabled = is_selinux_enabled ();
status = is_enabled ? STATE_OK : STATE_CRITICAL;

printf ("%s %s - selinux %s%s | selinux_enabled=%d\n"
, program_name_short
, state_text (status)
, status == STATE_OK ? "enabled" : "disabled"
, selinux_mnt ? xasprintf (" (%s)", selinux_mnt) : ""
, is_enabled);

return status;
}

0 comments on commit f3ea022

Please sign in to comment.