diff --git a/src/rc/Makefile b/src/rc/Makefile index fc6b9aa..83f8d87 100644 --- a/src/rc/Makefile +++ b/src/rc/Makefile @@ -32,7 +32,7 @@ CLEANFILES+= ${ALL_LINKS} CPPFLAGS+= -I../includes -I../librc -I../libeinfo LDFLAGS+= -L../librc -L../libeinfo -LDADD+= -lutil -lrc -leinfo +LDADD+= -lutil -lrc -leinfo -lselinux include ../../Makefile.inc MK= ../../mk diff --git a/src/rc/checkpath.c b/src/rc/checkpath.c index 7ebbb64..d98a0ae 100644 --- a/src/rc/checkpath.c +++ b/src/rc/checkpath.c @@ -46,6 +46,11 @@ #include "einfo.h" #include "rc-misc.h" +#define SELINUX 1 +#ifdef SELINUX +#include +#endif + typedef enum { inode_unknown = 0, inode_file = 1, @@ -55,10 +60,44 @@ typedef enum { extern const char *applet; -/* TODO: SELinux - * This needs a LOT of SELinux loving - * See systemd's src/label.c:label_mkdir - */ +#ifdef SELINUX +static int selinux_set_file_context(char* path, mode_t mode) { + security_context_t context = NULL; + + if (is_selinux_enabled() > 0) { + if (matchpathcon(path, mode, &context) < 0) { + if (security_getenforce() != 0) { + eerror("%s: can't get default SELinux file context", path); + return -1; + } + ewarn("%s: can't get default SELinux file context", path); + } + if (setfscreatecon(context) < 0) { + if (security_getenforce() != 0) { + eerror("%s: can't set SELinux file creation context", path); + return -1; + } + ewarn("%s: can't set SELinux file creation context", path); + } + freecon(context); + } + return 0; +} + +static int selinux_reset_file_context() { + if (is_selinux_enabled() > 0) { + if (setfscreatecon(NULL) < 0) { + if (security_getenforce() != 0) { + eerror("can't reset SELinux context"); + return -1; + } + ewarn("can't reset SELinux context"); + } + } + return 0; +} +#endif + static int do_check(char *path, uid_t uid, gid_t gid, mode_t mode, inode_t type, bool trunc) { @@ -82,7 +121,13 @@ do_check(char *path, uid_t uid, gid_t gid, mode_t mode, inode_t type, bool trunc if (trunc) flags |= O_TRUNC; u = umask(0); +#ifdef SELINUX + selinux_set_file_context(path, mode); +#endif fd = open(path, flags, mode); +#ifdef SELINUX + selinux_reset_file_context(); +#endif umask(u); if (fd == -1) { eerror("%s: open: %s", applet, strerror(errno)); @@ -95,7 +140,13 @@ do_check(char *path, uid_t uid, gid_t gid, mode_t mode, inode_t type, bool trunc mode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH; u = umask(0); /* We do not recursively create parents */ +#ifdef SELINUX + selinux_set_file_context(path, mode); +#endif r = mkdir(path, mode); +#ifdef SELINUX + selinux_reset_file_context(); +#endif umask(u); if (r == -1 && errno != EEXIST) { eerror("%s: mkdir: %s", applet, @@ -108,7 +159,13 @@ do_check(char *path, uid_t uid, gid_t gid, mode_t mode, inode_t type, bool trunc if (!mode) /* 600 */ mode = S_IRUSR | S_IWUSR; u = umask(0); +#ifdef SELINUX + selinux_set_file_context(path, mode); +#endif r = mkfifo(path, mode); +#ifdef SELINUX + selinux_reset_file_context(); +#endif umask(u); if (r == -1 && errno != EEXIST) { eerror("%s: mkfifo: %s", applet,