Fix slow login with ipa and SELinux
- Resolves: upstream #2624 - Only set the selinux context if the context differs from the local one
This commit is contained in:
parent
9a0389188d
commit
c4cf951d60
69
0018-selinux-Disconnect-before-closing-the-handle.patch
Normal file
69
0018-selinux-Disconnect-before-closing-the-handle.patch
Normal file
@ -0,0 +1,69 @@
|
||||
From 8f4a60a1fb0c24cfb01bc683a31b52786df68ccc Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@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@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
|
||||
|
@ -0,0 +1,67 @@
|
||||
From 342165ced656d64ec78bdb6f8897e15666cc08d2 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@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@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
|
||||
|
207
0020-selinux-Only-call-semanage-if-the-context-actually-c.patch
Normal file
207
0020-selinux-Only-call-semanage-if-the-context-actually-c.patch
Normal file
@ -0,0 +1,207 @@
|
||||
From 92a0931dfc57ec386b4c797ff4a144d2de7ffc25 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@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@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
|
||||
|
@ -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}
|
||||
@ -1012,6 +1015,11 @@ if [ $1 -eq 0 ]; then
|
||||
fi
|
||||
|
||||
%changelog
|
||||
* Wed Apr 15 2015 Lukas Slebodnik <lslebodn@redhat.com> - 1.12.4-6
|
||||
- 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@redhat.com> - 1.12.4-5
|
||||
- Fix regressions with ipa and SELinux
|
||||
- Resolves: upstream #2587 - With empty ipaselinuxusermapdefault security
|
||||
|
Loading…
Reference in New Issue
Block a user