Blob Blame History Raw
From 8db75e9ebbdaec1dde836380ca38d8cfec61cf3d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michal=20=C5=BDidek?= <mzidek@redhat.com>
Date: Thu, 1 Feb 2018 11:34:21 +0100
Subject: [PATCH 204/205] SELINUX: Check if SELinux is managed in selinux_child
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

If SELinux policy is not managed at all, don't call any SELinux user
handling functions and instead return that no update is needed.

Pair-Programmed-With: Jakub Hrozek <jhrozek@redhat.com>
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>

Resolves:
https://pagure.io/SSSD/sssd/issue/3618
(cherry picked from commit 450b472a68abf442479755c7916c757907b35ea5)
---
 src/providers/ipa/selinux_child.c |  3 +-
 src/util/sss_semanage.c           | 82 +++++++++++++++++++++++++++++++--------
 src/util/util.h                   |  3 ++
 3 files changed, 70 insertions(+), 18 deletions(-)

diff --git a/src/providers/ipa/selinux_child.c b/src/providers/ipa/selinux_child.c
index 073475094ee491bd5453898c6ba65214fa14fe59..bc9460e122ce991087a744fd5335e6c468c6a64b 100644
--- a/src/providers/ipa/selinux_child.c
+++ b/src/providers/ipa/selinux_child.c
@@ -27,7 +27,6 @@
 #include <unistd.h>
 #include <sys/stat.h>
 #include <popt.h>
-#include <selinux/selinux.h>
 
 #include "util/util.h"
 #include "util/child_common.h"
@@ -173,7 +172,7 @@ static bool seuser_needs_update(struct input_buffer *ibuf)
     char *db_mls_range = NULL;
     errno_t ret;
 
-    ret = getseuserbyname(ibuf->username, &db_seuser, &db_mls_range);
+    ret = sss_get_seuser(ibuf->username, &db_seuser, &db_mls_range);
     DEBUG(SSSDBG_TRACE_INTERNAL,
           "getseuserbyname: ret: %d seuser: %s mls: %s\n",
           ret, db_seuser ? db_seuser : "unknown",
diff --git a/src/util/sss_semanage.c b/src/util/sss_semanage.c
index 37278cc986a1ea49dc2218a635d52b9d54ca089d..25b6bcdad2ad7e7ac710497f13d6a6e22360b0dd 100644
--- a/src/util/sss_semanage.c
+++ b/src/util/sss_semanage.c
@@ -22,8 +22,9 @@
 #include "config.h"
 
 #include <stdio.h>
-#ifdef HAVE_SEMANAGE
+#if defined(HAVE_SEMANAGE) && defined(HAVE_SELINUX)
 #include <semanage/semanage.h>
+#include <selinux/selinux.h>
 #endif
 
 #include "util/util.h"
@@ -32,7 +33,7 @@
 #define DEFAULT_SERANGE "s0"
 #endif
 
-#ifdef HAVE_SEMANAGE
+#if defined(HAVE_SEMANAGE) && defined(HAVE_SELINUX)
 /* turn libselinux messages into SSSD DEBUG() calls */
 static void sss_semanage_error_callback(void *varg,
                                         semanage_handle_t *handle,
@@ -73,33 +74,47 @@ static void sss_semanage_close(semanage_handle_t *handle)
     semanage_handle_destroy(handle);
 }
 
-static int sss_semanage_init(semanage_handle_t **_handle)
+static int sss_is_selinux_managed(semanage_handle_t *handle)
 {
     int ret;
-    semanage_handle_t *handle = NULL;
 
-    handle = semanage_handle_create();
-    if (!handle) {
-        DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create SELinux management handle\n");
-        ret = EIO;
-        goto done;
+    if (handle == NULL) {
+        return EINVAL;
     }
 
-    semanage_msg_set_callback(handle,
-                              sss_semanage_error_callback,
-                              NULL);
-
     ret = semanage_is_managed(handle);
     if (ret == 0) {
         DEBUG(SSSDBG_TRACE_FUNC, "SELinux policy not managed via libsemanage\n");
-        ret = ERR_SELINUX_NOT_MANAGED;
-        goto done;
+        return ERR_SELINUX_NOT_MANAGED;
     } else if (ret == -1) {
         DEBUG(SSSDBG_CRIT_FAILURE, "Call to semanage_is_managed failed\n");
+        return EIO;
+    }
+
+    return EOK;
+}
+
+static int sss_semanage_init(semanage_handle_t **_handle)
+{
+    int ret;
+    semanage_handle_t *handle = NULL;
+
+    handle = semanage_handle_create();
+    if (!handle) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create SELinux management handle\n");
         ret = EIO;
         goto done;
     }
 
+    semanage_msg_set_callback(handle,
+                              sss_semanage_error_callback,
+                              NULL);
+
+    ret = sss_is_selinux_managed(handle);
+    if (ret != EOK) {
+        goto done;
+    }
+
     ret = semanage_access_check(handle);
     if (ret < SEMANAGE_CAN_READ) {
         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot read SELinux policy store\n");
@@ -229,6 +244,34 @@ done:
     return ret;
 }
 
+int sss_get_seuser(const char *linuxuser,
+                   char **selinuxuser,
+                   char **level)
+{
+    int ret;
+    semanage_handle_t *handle;
+
+    handle = semanage_handle_create();
+    if (handle == NULL) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create SELinux management handle\n");
+        return EIO;
+    }
+
+    semanage_msg_set_callback(handle,
+                              sss_semanage_error_callback,
+                              NULL);
+
+    /* We only needed the handle for this call. Close the handle right
+     * after it */
+    ret = sss_is_selinux_managed(handle);
+    sss_semanage_close(handle);
+    if (ret != EOK) {
+        return ret;
+    }
+
+    return getseuserbyname(linuxuser, selinuxuser, level);
+}
+
 int set_seuser(const char *login_name, const char *seuser_name,
                const char *mls)
 {
@@ -382,7 +425,7 @@ done:
     sss_semanage_close(handle);
     return ret;
 }
-#else /* HAVE_SEMANAGE */
+#else /* HAVE_SEMANAGE && HAVE_SELINUX */
 int set_seuser(const char *login_name, const char *seuser_name,
                const char *mls)
 {
@@ -393,4 +436,11 @@ int del_seuser(const char *login_name)
 {
     return EOK;
 }
+
+int sss_get_seuser(const char *linuxuser,
+                   char **selinuxuser,
+                   char **level)
+{
+    return EOK;
+}
 #endif  /* HAVE_SEMANAGE */
diff --git a/src/util/util.h b/src/util/util.h
index 1719d8eec1b6b05877b9be3382589e442bff85be..74ce2dcecfe17d1cea96cfb5c4b7edb8fd46f09f 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -658,6 +658,9 @@ errno_t restore_creds(struct sss_creds *saved_creds);
 int set_seuser(const char *login_name, const char *seuser_name,
                const char *mlsrange);
 int del_seuser(const char *login_name);
+int sss_get_seuser(const char *linuxuser,
+                   char **selinuxuser,
+                   char **level);
 
 /* convert time from generalized form to unix time */
 errno_t sss_utc_to_time_t(const char *str, const char *format, time_t *unix_time);
-- 
2.14.3