From 8db75e9ebbdaec1dde836380ca38d8cfec61cf3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C5=BDidek?= 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 Reviewed-by: Lukáš Slebodník Reviewed-by: Fabiano Fidêncio 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 #include #include -#include #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 -#ifdef HAVE_SEMANAGE +#if defined(HAVE_SEMANAGE) && defined(HAVE_SELINUX) #include +#include #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