lslebodn pushed to sssd (f22). "Fix slow login with ipa and SELinux (..more)"

notifications at fedoraproject.org notifications at fedoraproject.org
Wed Apr 15 12:24:56 UTC 2015


>From 93a3c951b06b6b14185ee15627055063cfd5d129 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn at redhat.com>
Date: Wed, 15 Apr 2015 14:17:32 +0200
Subject: Fix slow login with ipa and SELinux

- Resolves: upstream #2624 - Only set the selinux context if the context
                             differs from the local one

diff --git a/0018-selinux-Disconnect-before-closing-the-handle.patch b/0018-selinux-Disconnect-before-closing-the-handle.patch
new file mode 100644
index 0000000..7407760
--- /dev/null
+++ b/0018-selinux-Disconnect-before-closing-the-handle.patch
@@ -0,0 +1,69 @@
+From 8f4a60a1fb0c24cfb01bc683a31b52786df68ccc Mon Sep 17 00:00:00 2001
+From: Jakub Hrozek <jhrozek at redhat.com>
+Date: Fri, 10 Apr 2015 10:55:22 +0200
+Subject: [PATCH 18/20] selinux: Disconnect before closing the handle
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+libsemanage documentation says:
+~~~~
+be sure that a semanage_disconnect() was previously called if the handle
+was connected.
+~~~~
+
+Otherwise we get a memory leak.
+
+Reviewed-by: Michal Židek <mzidek at redhat.com>
+---
+ src/util/sss_semanage.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/src/util/sss_semanage.c b/src/util/sss_semanage.c
+index b85831c3d3f262f49b19082e96aa62ccf3afeaa8..d141de1c671e6d62a731e56b10ee14069f27ae87 100644
+--- a/src/util/sss_semanage.c
++++ b/src/util/sss_semanage.c
+@@ -68,6 +68,13 @@ static void sss_semanage_error_callback(void *varg,
+     free(message);
+ }
+ 
++static void sss_semanage_close(semanage_handle_t *handle)
++{
++    /* Calling disconnect on a disconnected handle is safe */
++    semanage_disconnect(handle);
++    semanage_handle_destroy(handle);
++}
++
+ static semanage_handle_t *sss_semanage_init(void)
+ {
+     int ret;
+@@ -110,7 +117,7 @@ static semanage_handle_t *sss_semanage_init(void)
+ 
+     return handle;
+ fail:
+-    semanage_handle_destroy(handle);
++    sss_semanage_close(handle);
+     return NULL;
+ }
+ 
+@@ -278,7 +285,7 @@ int set_seuser(const char *login_name, const char *seuser_name,
+     ret = EOK;
+ done:
+     semanage_seuser_key_free(key);
+-    semanage_handle_destroy(handle);
++    sss_semanage_close(handle);
+     return ret;
+ }
+ 
+@@ -350,7 +357,7 @@ int del_seuser(const char *login_name)
+ 
+     ret = EOK;
+ done:
+-    semanage_handle_destroy(handle);
++    sss_semanage_close(handle);
+     return ret;
+ }
+ 
+-- 
+2.3.5
+
diff --git a/0019-selinux-Begin-and-end-the-transaction-on-the-same-ne.patch b/0019-selinux-Begin-and-end-the-transaction-on-the-same-ne.patch
new file mode 100644
index 0000000..828c740
--- /dev/null
+++ b/0019-selinux-Begin-and-end-the-transaction-on-the-same-ne.patch
@@ -0,0 +1,67 @@
+From 342165ced656d64ec78bdb6f8897e15666cc08d2 Mon Sep 17 00:00:00 2001
+From: Jakub Hrozek <jhrozek at redhat.com>
+Date: Fri, 10 Apr 2015 11:06:44 +0200
+Subject: [PATCH 19/20] selinux: Begin and end the transaction on the same
+ nesting level
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Transaction should be started and commited on the same code nesting or
+abstraction level. Also, transactions are really costly with libselinux
+and splitting them from initialization will make init function reusable
+by read-only libsemanage functions.
+
+Reviewed-by: Michal Židek <mzidek at redhat.com>
+---
+ src/util/sss_semanage.c | 20 ++++++++++++++------
+ 1 file changed, 14 insertions(+), 6 deletions(-)
+
+diff --git a/src/util/sss_semanage.c b/src/util/sss_semanage.c
+index d141de1c671e6d62a731e56b10ee14069f27ae87..c0342498cbd0495733a0bf701a06a02cfb705fc7 100644
+--- a/src/util/sss_semanage.c
++++ b/src/util/sss_semanage.c
+@@ -109,12 +109,6 @@ static semanage_handle_t *sss_semanage_init(void)
+         goto fail;
+     }
+ 
+-    ret = semanage_begin_transaction(handle);
+-    if (ret != 0) {
+-        DEBUG(SSSDBG_CRIT_FAILURE, "Cannot begin SELinux transaction\n");
+-        goto fail;
+-    }
+-
+     return handle;
+ fail:
+     sss_semanage_close(handle);
+@@ -243,6 +237,13 @@ int set_seuser(const char *login_name, const char *seuser_name,
+         goto done;
+     }
+ 
++    ret = semanage_begin_transaction(handle);
++    if (ret != 0) {
++        DEBUG(SSSDBG_CRIT_FAILURE, "Cannot begin SELinux transaction\n");
++        ret = EIO;
++        goto done;
++    }
++
+     ret = semanage_seuser_key_create(handle, login_name, &key);
+     if (ret != 0) {
+         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create SELinux user key\n");
+@@ -303,6 +304,13 @@ int del_seuser(const char *login_name)
+         goto done;
+     }
+ 
++    ret = semanage_begin_transaction(handle);
++    if (ret != 0) {
++        DEBUG(SSSDBG_CRIT_FAILURE, "Cannot begin SELinux transaction\n");
++        ret = EIO;
++        goto done;
++    }
++
+     ret = semanage_seuser_key_create(handle, login_name, &key);
+     if (ret != 0) {
+         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create SELinux user key\n");
+-- 
+2.3.5
+
diff --git a/0020-selinux-Only-call-semanage-if-the-context-actually-c.patch b/0020-selinux-Only-call-semanage-if-the-context-actually-c.patch
new file mode 100644
index 0000000..7ec762b
--- /dev/null
+++ b/0020-selinux-Only-call-semanage-if-the-context-actually-c.patch
@@ -0,0 +1,207 @@
+From 92a0931dfc57ec386b4c797ff4a144d2de7ffc25 Mon Sep 17 00:00:00 2001
+From: Jakub Hrozek <jhrozek at redhat.com>
+Date: Thu, 9 Apr 2015 22:18:35 +0200
+Subject: [PATCH 20/20] 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 at redhat.com>
+---
+ 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 605fd1ff5e479078d579ac7524507546261d469c..ed89028ebdbb85752f1f7f06ef8464613ee96377 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -784,10 +784,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 bf3a9a057aed77e93949370f8651af2631d91432..d217688f81d7a2e49cd3eaaf0d1be609a0f679ea 100644
+--- a/src/util/util.h
++++ b/src/util/util.h
+@@ -635,5 +635,7 @@ 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);
+ 
+ #endif /* __SSSD_UTIL_H__ */
+-- 
+2.3.5
+
diff --git a/sssd.spec b/sssd.spec
index 8912ee0..5a4ad53 100644
--- a/sssd.spec
+++ b/sssd.spec
@@ -27,7 +27,7 @@
 
 Name: sssd
 Version: 1.12.4
-Release: 3%{?dist}
+Release: 4%{?dist}
 Group: Applications/System
 Summary: System Security Services Daemon
 License: GPLv3+
@@ -53,6 +53,9 @@ Patch0014: 0014-SPEC-Replace-python_-macros-with-python2_.patch
 Patch0015: 0015-SPEC-Build-python3-bindings-on-available-platforms.patch
 Patch0016: 0016-selinux-Delete-existing-user-mapping-on-empty-defaul.patch
 Patch0017: 0017-selinux-Handle-setup-with-empty-default-and-no-confi.patch
+Patch0018: 0018-selinux-Disconnect-before-closing-the-handle.patch
+Patch0019: 0019-selinux-Begin-and-end-the-transaction-on-the-same-ne.patch
+Patch0020: 0020-selinux-Only-call-semanage-if-the-context-actually-c.patch
 
 ### Dependencies ###
 Requires: sssd-common = %{version}-%{release}
@@ -1017,6 +1020,11 @@ if [ $1 -eq 0 ]; then
 fi
 
 %changelog
+* Wed Apr 15 2015 Lukas Slebodnik <lslebodn at redhat.com> - 1.12.4-4
+- Fix slow login with ipa and SELinux
+- Resolves: upstream #2624 - Only set the selinux context if the context
+                             differs from the local one
+
 * Mon Mar 23 2015 Lukas Slebodnik <lslebodn at redhat.com> - 1.12.4-3
 - Fix regressions with ipa and SELinux
 - Resolves: upstream #2587 - With empty ipaselinuxusermapdefault security
-- 
cgit v0.10.2


	http://pkgs.fedoraproject.org/cgit/sssd.git/commit/?h=f22&id=93a3c951b06b6b14185ee15627055063cfd5d129


More information about the scm-commits mailing list