aboutsummaryrefslogtreecommitdiff
path: root/src/rc
diff options
context:
space:
mode:
authorJason Zaman <jason@perfinion.com>2014-07-15 22:27:34 +0400
committerWilliam Hubbs <w.d.hubbs@gmail.com>2014-07-16 13:09:38 -0500
commit9c689542c3246e793310db938374bc97600435e6 (patch)
tree2a4585902ad54cbc5292016b96a9ac854614524c /src/rc
parent525d7140b12a8e259f9d919f24148e369e9ff7d1 (diff)
checkpath: restore the SELinux context
X-Gentoo-Bug: 516956 X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=516956
Diffstat (limited to 'src/rc')
-rw-r--r--src/rc/Makefile6
-rw-r--r--src/rc/checkpath.c28
-rw-r--r--src/rc/rc-selinux-util.c126
-rw-r--r--src/rc/rc-selinux-util.h33
4 files changed, 186 insertions, 7 deletions
diff --git a/src/rc/Makefile b/src/rc/Makefile
index 5f5aa631..fb5265c6 100644
--- a/src/rc/Makefile
+++ b/src/rc/Makefile
@@ -4,7 +4,11 @@ SRCS= checkpath.c fstabinfo.c mountinfo.c start-stop-daemon.c \
rc-misc.c rc-plugin.c rc-service.c rc-status.c rc-update.c \
runscript.c rc.c swclock.c
-CLEANFILES= version.h
+ifeq (${MKSELINUX},yes)
+SRCS+= rc-selinux-util.c
+endif
+
+CLEANFILES= version.h rc-selinux-util.o
BINDIR= ${PREFIX}/bin
SBINDIR= ${PREFIX}/sbin
diff --git a/src/rc/checkpath.c b/src/rc/checkpath.c
index 6a0f8939..6945b670 100644
--- a/src/rc/checkpath.c
+++ b/src/rc/checkpath.c
@@ -46,6 +46,10 @@
#include "einfo.h"
#include "rc-misc.h"
+#ifdef HAVE_SELINUX
+#include "rc-selinux-util.h"
+#endif
+
typedef enum {
inode_unknown = 0,
inode_file = 1,
@@ -55,13 +59,9 @@ typedef enum {
extern const char *applet;
-/* TODO: SELinux
- * This needs a LOT of SELinux loving
- * See systemd's src/label.c:label_mkdir
- */
static int
do_check(char *path, uid_t uid, gid_t gid, mode_t mode, inode_t type,
- bool trunc, bool chowner)
+ bool trunc, bool chowner, bool selinux_on)
{
struct stat st;
int fd, flags;
@@ -149,6 +149,11 @@ do_check(char *path, uid_t uid, gid_t gid, mode_t mode, inode_t type,
}
}
+#ifdef HAVE_SELINUX
+ if (selinux_on)
+ selinux_util_label(path);
+#endif
+
return 0;
}
@@ -226,6 +231,7 @@ checkpath(int argc, char **argv)
bool trunc = false;
bool chowner = false;
bool writable = false;
+ bool selinux_on = false;
while ((opt = getopt_long(argc, argv, getoptstring,
longopts, (int *) 0)) != -1)
@@ -276,13 +282,23 @@ checkpath(int argc, char **argv)
if (gr)
gid = gr->gr_gid;
+#ifdef HAVE_SELINUX
+ if (1 == selinux_util_open())
+ selinux_on = true;
+#endif
+
while (optind < argc) {
if (writable)
exit(!is_writable(argv[optind]));
- if (do_check(argv[optind], uid, gid, mode, type, trunc, chowner))
+ if (do_check(argv[optind], uid, gid, mode, type, trunc, chowner, selinux_on))
retval = EXIT_FAILURE;
optind++;
}
+#ifdef HAVE_SELINUX
+ if (selinux_on)
+ selinux_util_close();
+#endif
+
return retval;
}
diff --git a/src/rc/rc-selinux-util.c b/src/rc/rc-selinux-util.c
new file mode 100644
index 00000000..6cbb5db9
--- /dev/null
+++ b/src/rc/rc-selinux-util.c
@@ -0,0 +1,126 @@
+/*
+ rc-selinux.c
+ SELinux helpers to get and set contexts.
+*/
+
+/*
+ * Copyright (c) 2014 Jason Zaman <jason@perfinion.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stddef.h>
+#include <errno.h>
+
+#include <sys/stat.h>
+
+#include <selinux/selinux.h>
+#include <selinux/label.h>
+
+#include "rc-selinux-util.h"
+
+static struct selabel_handle *hnd = NULL;
+
+int
+selinux_util_label(const char *path)
+{
+ int retval = 0;
+ int enforce;
+ struct stat st;
+ security_context_t con;
+
+ enforce = security_getenforce();
+ if (retval < 0)
+ return retval;
+
+ if (NULL == hnd)
+ return (enforce) ? -1 : 0;
+
+ retval = lstat(path, &st);
+ if (retval < 0) {
+ if (ENOENT == errno)
+ return 0;
+ return (enforce) ? -1 : 0;
+ }
+
+ /* lookup the context */
+ retval = selabel_lookup_raw(hnd, &con, path, st.st_mode);
+ if (retval < 0) {
+ if (ENOENT == errno)
+ return 0;
+ return (enforce) ? -1 : 0;
+ }
+
+ /* apply the context */
+ retval = lsetfilecon(path, con);
+ freecon(con);
+ if (retval < 0) {
+ if (ENOENT == errno)
+ return 0;
+ if (ENOTSUP == errno)
+ return 0;
+ return (enforce) ? -1 : 0;
+ }
+
+ return 0;
+}
+
+/*
+ * Open the label handle
+ * returns 1 on success, 0 if no selinux, negative on error
+ */
+int
+selinux_util_open(void)
+{
+ int retval = 0;
+
+ retval = is_selinux_enabled();
+ if (retval <= 0)
+ return retval;
+
+ hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0);
+ if (NULL == hnd)
+ return -2;
+
+ return 1;
+}
+
+/*
+ * Close the label handle
+ * returns 1 on success, 0 if no selinux, negative on error
+ */
+int
+selinux_util_close(void)
+{
+ int retval = 0;
+
+ retval = is_selinux_enabled();
+ if (retval <= 0)
+ return retval;
+
+ if (hnd) {
+ selabel_close(hnd);
+ hnd = NULL;
+ }
+
+ return 0;
+}
diff --git a/src/rc/rc-selinux-util.h b/src/rc/rc-selinux-util.h
new file mode 100644
index 00000000..69624b39
--- /dev/null
+++ b/src/rc/rc-selinux-util.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2014 Jason Zaman <jason@perfinion.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef RC_SELINUX_UTIL_H
+#define RC_SELINUX_UTIL_H
+
+int selinux_util_open(void);
+int selinux_util_label(const char *path);
+int selinux_util_close(void);
+
+#endif