210 lines
6.7 KiB
Diff
210 lines
6.7 KiB
Diff
From 4d31f2c294db6090047e4d5348322b32ea0aaac1 Mon Sep 17 00:00:00 2001
|
|
From: Jakub Hrozek <jhrozek@redhat.com>
|
|
Date: Thu, 9 Apr 2015 22:18:35 +0200
|
|
Subject: [PATCH 60/99] selinux: Only call semanage if the context actually
|
|
changes
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
https://fedorahosted.org/sssd/ticket/2624
|
|
|
|
Add a function to query the libsemanage database for a user context and
|
|
only update the database if the context differes from the one set on the
|
|
server.
|
|
|
|
Adds talloc dependency to libsss_semanage.
|
|
|
|
Reviewed-by: Michal Židek <mzidek@redhat.com>
|
|
(cherry picked from commit 1e0fa55fb377db788e065de917ba8e149eb56161)
|
|
---
|
|
Makefile.am | 5 +++
|
|
src/providers/ipa/selinux_child.c | 35 ++++++++++++++++---
|
|
src/util/sss_semanage.c | 71 +++++++++++++++++++++++++++++++++++++++
|
|
src/util/util.h | 2 ++
|
|
4 files changed, 109 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/Makefile.am b/Makefile.am
|
|
index 973f8cb35d75982c1b66f94af96a9e4cfe39d467..65b9773d8804992f7553609b77553b3b3944a54d 100644
|
|
--- a/Makefile.am
|
|
+++ b/Makefile.am
|
|
@@ -770,10 +770,15 @@ endif
|
|
libsss_util_la_LDFLAGS = -avoid-version
|
|
|
|
pkglib_LTLIBRARIES += libsss_semanage.la
|
|
+libsss_semanage_la_CFLAGS = \
|
|
+ $(AM_CFLAGS) \
|
|
+ $(TALLOC_CFLAGS) \
|
|
+ $(NULL)
|
|
libsss_semanage_la_SOURCES = \
|
|
src/util/sss_semanage.c \
|
|
$(NULL)
|
|
libsss_semanage_la_LIBADD = \
|
|
+ $(TALLOC_LIBS) \
|
|
libsss_debug.la \
|
|
$(NULL)
|
|
if BUILD_SEMANAGE
|
|
diff --git a/src/providers/ipa/selinux_child.c b/src/providers/ipa/selinux_child.c
|
|
index 81c1de877ef08a299d07837fefcd195d465849fa..7c5731d66b7d0ed17b7be18c4adaa65394002fc4 100644
|
|
--- a/src/providers/ipa/selinux_child.c
|
|
+++ b/src/providers/ipa/selinux_child.c
|
|
@@ -165,6 +165,29 @@ static int sc_set_seuser(const char *login_name, const char *seuser_name,
|
|
return ret;
|
|
}
|
|
|
|
+static bool seuser_needs_update(struct input_buffer *ibuf)
|
|
+{
|
|
+ bool needs_update = true;
|
|
+ char *db_seuser = NULL;
|
|
+ char *db_mls_range = NULL;
|
|
+ errno_t ret;
|
|
+
|
|
+ ret = get_seuser(ibuf, ibuf->username, &db_seuser, &db_mls_range);
|
|
+ DEBUG(SSSDBG_TRACE_INTERNAL,
|
|
+ "get_seuser: ret: %d seuser: %s mls: %s\n",
|
|
+ ret, db_seuser ? db_seuser : "unknown",
|
|
+ db_mls_range ? db_mls_range : "unknown");
|
|
+ if (ret == EOK && db_seuser && db_mls_range &&
|
|
+ strcmp(db_seuser, ibuf->seuser) == 0 &&
|
|
+ strcmp(db_mls_range, ibuf->mls_range) == 0) {
|
|
+ needs_update = false;
|
|
+ }
|
|
+
|
|
+ talloc_free(db_seuser);
|
|
+ talloc_free(db_mls_range);
|
|
+ return needs_update;
|
|
+}
|
|
+
|
|
int main(int argc, const char *argv[])
|
|
{
|
|
int opt;
|
|
@@ -177,6 +200,7 @@ int main(int argc, const char *argv[])
|
|
struct input_buffer *ibuf = NULL;
|
|
struct response *resp = NULL;
|
|
ssize_t written;
|
|
+ bool needs_update;
|
|
|
|
struct poptOption long_options[] = {
|
|
POPT_AUTOHELP
|
|
@@ -296,10 +320,13 @@ int main(int argc, const char *argv[])
|
|
|
|
DEBUG(SSSDBG_TRACE_FUNC, "performing selinux operations\n");
|
|
|
|
- ret = sc_set_seuser(ibuf->username, ibuf->seuser, ibuf->mls_range);
|
|
- if (ret != EOK) {
|
|
- DEBUG(SSSDBG_CRIT_FAILURE, "Cannot set SELinux login context.\n");
|
|
- goto fail;
|
|
+ needs_update = seuser_needs_update(ibuf);
|
|
+ if (needs_update == true) {
|
|
+ ret = sc_set_seuser(ibuf->username, ibuf->seuser, ibuf->mls_range);
|
|
+ if (ret != EOK) {
|
|
+ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot set SELinux login context.\n");
|
|
+ goto fail;
|
|
+ }
|
|
}
|
|
|
|
ret = prepare_response(main_ctx, ret, &resp);
|
|
diff --git a/src/util/sss_semanage.c b/src/util/sss_semanage.c
|
|
index c0342498cbd0495733a0bf701a06a02cfb705fc7..01a2f41d8752e127f2aa1b72faa61c23f315edd7 100644
|
|
--- a/src/util/sss_semanage.c
|
|
+++ b/src/util/sss_semanage.c
|
|
@@ -369,6 +369,71 @@ done:
|
|
return ret;
|
|
}
|
|
|
|
+int get_seuser(TALLOC_CTX *mem_ctx, const char *login_name,
|
|
+ char **_seuser, char **_mls_range)
|
|
+{
|
|
+ errno_t ret;
|
|
+ const char *seuser;
|
|
+ const char *mls_range;
|
|
+ semanage_handle_t *sm_handle = NULL;
|
|
+ semanage_seuser_t *sm_user = NULL;
|
|
+ semanage_seuser_key_t *sm_key = NULL;
|
|
+
|
|
+ sm_handle = sss_semanage_init();
|
|
+ if (sm_handle == NULL) {
|
|
+ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create SELinux handle\n");
|
|
+ ret = EIO;
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ ret = semanage_seuser_key_create(sm_handle, login_name, &sm_key);
|
|
+ if (ret != EOK) {
|
|
+ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create key for %s\n", login_name);
|
|
+ ret = EIO;
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ ret = semanage_seuser_query(sm_handle, sm_key, &sm_user);
|
|
+ if (ret < 0) {
|
|
+ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot query for %s\n", login_name);
|
|
+ ret = EIO;
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ seuser = semanage_seuser_get_sename(sm_user);
|
|
+ if (seuser != NULL) {
|
|
+ *_seuser = talloc_strdup(mem_ctx, seuser);
|
|
+ if (*_seuser == NULL) {
|
|
+ ret = ENOMEM;
|
|
+ goto done;
|
|
+ }
|
|
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
+ "SELinux user for %s: %s\n", login_name, *_seuser);
|
|
+ } else {
|
|
+ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot get sename for %s\n", login_name);
|
|
+ }
|
|
+
|
|
+ mls_range = semanage_seuser_get_mlsrange(sm_user);
|
|
+ if (mls_range != NULL) {
|
|
+ *_mls_range = talloc_strdup(mem_ctx, mls_range);
|
|
+ if (*_mls_range == NULL) {
|
|
+ ret = ENOMEM;
|
|
+ goto done;
|
|
+ }
|
|
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
+ "SELinux range for %s: %s\n", login_name, *_mls_range);
|
|
+ } else {
|
|
+ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot get mlsrange for %s\n", login_name);
|
|
+ }
|
|
+
|
|
+ ret = EOK;
|
|
+done:
|
|
+ semanage_seuser_key_free(sm_key);
|
|
+ semanage_seuser_free(sm_user);
|
|
+ sss_semanage_close(sm_handle);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
#else /* HAVE_SEMANAGE */
|
|
int set_seuser(const char *login_name, const char *seuser_name,
|
|
const char *mls)
|
|
@@ -380,4 +445,10 @@ int del_seuser(const char *login_name)
|
|
{
|
|
return EOK;
|
|
}
|
|
+
|
|
+int get_seuser(TALLOC_CTX *mem_ctx, const char *login_name,
|
|
+ char **_seuser, char **_mls_range)
|
|
+{
|
|
+ return EOK;
|
|
+}
|
|
#endif /* HAVE_SEMANAGE */
|
|
diff --git a/src/util/util.h b/src/util/util.h
|
|
index 91df09914abfa1a72e9280ab708e11abf9e07e18..81a8709d6840a9c5cd2acb23c40fdea7f9714e98 100644
|
|
--- a/src/util/util.h
|
|
+++ b/src/util/util.h
|
|
@@ -642,6 +642,8 @@ 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 get_seuser(TALLOC_CTX *mem_ctx, const char *login_name,
|
|
+ char **_seuser, char **_mls_range);
|
|
|
|
/* 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.4.0
|
|
|