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

notifications at fedoraproject.org notifications at fedoraproject.org
Wed Apr 15 12:30:57 UTC 2015


>From 32425edf4424b38d643b8d4a528ccb7779e91daf Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn at redhat.com>
Date: Wed, 15 Apr 2015 14:30:16 +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/0003-selinux-Disconnect-before-closing-the-handle.patch b/0003-selinux-Disconnect-before-closing-the-handle.patch
new file mode 100644
index 0000000..7b16e35
--- /dev/null
+++ b/0003-selinux-Disconnect-before-closing-the-handle.patch
@@ -0,0 +1,70 @@
+From 24553c550248ac1a989f43921d2a3b45295b42cd 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 3/5] 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>
+(cherry picked from commit aa00d67b2a8e07c9080e7798defdc6c774c93465)
+---
+ 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/0004-selinux-Begin-and-end-the-transaction-on-the-same-ne.patch b/0004-selinux-Begin-and-end-the-transaction-on-the-same-ne.patch
new file mode 100644
index 0000000..ee7e132
--- /dev/null
+++ b/0004-selinux-Begin-and-end-the-transaction-on-the-same-ne.patch
@@ -0,0 +1,68 @@
+From 47987b0af3b1898a0ed5a772dbc4438b59fba8c8 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 4/5] 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>
+(cherry picked from commit 748b38a7991d78cbf4726f2a14ace5e926629a54)
+---
+ 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/0005-selinux-Only-call-semanage-if-the-context-actually-c.patch b/0005-selinux-Only-call-semanage-if-the-context-actually-c.patch
new file mode 100644
index 0000000..ee1b9ca
--- /dev/null
+++ b/0005-selinux-Only-call-semanage-if-the-context-actually-c.patch
@@ -0,0 +1,208 @@
+From 566c45a78757c73700ce9535d70fa37c8077e678 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 5/5] 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>
+(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 29d148c4a0cbda6882b4a619d6c71d2efcc8fb43..73970024a6ce55bfe91c5e14d5127d189e321716 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -767,10 +767,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 841c392..3fbf5ec 100644
--- a/sssd.spec
+++ b/sssd.spec
@@ -27,7 +27,7 @@
 
 Name: sssd
 Version: 1.12.4
-Release: 2%{?dist}
+Release: 3%{?dist}
 Group: Applications/System
 Summary: System Security Services Daemon
 License: GPLv3+
@@ -38,6 +38,9 @@ BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
 ### Patches ###
 Patch0001: 0001-selinux-Delete-existing-user-mapping-on-empty-defaul.patch
 Patch0002: 0002-selinux-Handle-setup-with-empty-default-and-no-confi.patch
+Patch0003: 0003-selinux-Disconnect-before-closing-the-handle.patch
+Patch0004: 0004-selinux-Begin-and-end-the-transaction-on-the-same-ne.patch
+Patch0005: 0005-selinux-Only-call-semanage-if-the-context-actually-c.patch
 
 ### Dependencies ###
 Requires: sssd-common = %{version}-%{release}
@@ -904,6 +907,11 @@ if [ $1 -eq 0 ]; then
 fi
 
 %changelog
+* Wed Apr 15 2015 Lukas Slebodnik <lslebodn at redhat.com> - 1.12.4-3
+- 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-2
 - 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=f21&id=32425edf4424b38d643b8d4a528ccb7779e91daf


More information about the scm-commits mailing list