>From 58147115f15d12da6375aff88b01d560fa46f44d Mon Sep 17 00:00:00 2001
From: Michal Zidek <mzidek@redhat.com>
Date: Thu, 7 Feb 2013 19:35:37 +0100
Subject: [PATCH 1/3] Move SELinux processing to provider.

The SELinux processing was distributed between provider and
pam responder which resulted in hard to maintain code. This
patch moves the logic to provider.

IT ALSO REQUIRES CHANGE IN THE SELINUX POLICY, because
the provider also writes the content of selinux login
file to disk (which was done by responder before).

https://fedorahosted.org/sssd/ticket/1743
---
 src/db/sysdb_selinux.c          | 107 ------------
 src/providers/ipa/ipa_selinux.c | 363 ++++++++++++++++++++++++++++++++++++----
 src/responder/pam/pamsrv_cmd.c  | 309 ----------------------------------
 src/util/sss_selinux.c          |   8 +-
 src/util/sss_selinux.h          |   2 +-
 5 files changed, 337 insertions(+), 452 deletions(-)

diff --git a/src/db/sysdb_selinux.c b/src/db/sysdb_selinux.c
index b27e0a9..80cfe53 100644
--- a/src/db/sysdb_selinux.c
+++ b/src/db/sysdb_selinux.c
@@ -336,113 +336,6 @@ sysdb_get_selinux_usermaps(TALLOC_CTX *mem_ctx,
     return EOK;
 }
 
-errno_t sysdb_search_selinux_usermap_by_username(TALLOC_CTX *mem_ctx,
-                                                 struct sysdb_ctx *sysdb,
-                                                 struct sss_domain_info *domain,
-                                                 const char *username,
-                                                 struct ldb_message ***_usermaps)
-{
-    TALLOC_CTX *tmp_ctx;
-    struct ldb_message **msgs = NULL;
-    const char *attrs[] = { SYSDB_NAME,
-                            SYSDB_USER_CATEGORY,
-                            SYSDB_HOST_CATEGORY,
-                            SYSDB_ORIG_MEMBER_USER,
-                            SYSDB_ORIG_MEMBER_HOST,
-                            SYSDB_SELINUX_HOST_PRIORITY,
-                            SYSDB_SELINUX_USER,
-                            NULL };
-    struct sysdb_attrs *user;
-    struct sysdb_attrs *tmp_attrs;
-    struct ldb_message **usermaps = NULL;
-    size_t msgs_count = 0;
-    size_t usermaps_cnt;
-    uint32_t priority = 0;
-    uint32_t host_priority = 0;
-    uint32_t top_priority = 0;
-    errno_t ret;
-    int i;
-
-    tmp_ctx = talloc_new(NULL);
-    if (!tmp_ctx) {
-        return ENOMEM;
-    }
-
-    /* Now extract user attributes */
-    ret = sss_selinux_extract_user(tmp_ctx, sysdb, domain, username, &user);
-    if (ret != EOK) {
-        goto done;
-    }
-
-    /* Now extract all SELinux user maps */
-    ret = sysdb_get_selinux_usermaps(tmp_ctx, sysdb, domain,
-                                     attrs, &msgs_count, &msgs);
-    if (ret) {
-        goto done;
-    }
-
-    /* Now filter those that match */
-    tmp_attrs = talloc_zero(tmp_ctx, struct sysdb_attrs);
-    if (tmp_attrs == NULL) {
-        ret = ENOMEM;
-        goto done;
-    }
-
-    usermaps = talloc_zero_array(tmp_ctx, struct ldb_message *, msgs_count + 1);
-    if (usermaps == NULL) {
-        ret = ENOMEM;
-        goto done;
-    }
-
-    usermaps_cnt = 0;
-    for (i = 0; i < msgs_count; i++) {
-        tmp_attrs->a = msgs[i]->elements;
-        tmp_attrs->num = msgs[i]->num_elements;
-
-        if (sss_selinux_match(tmp_attrs, user, NULL, &priority)) {
-            priority &= ~(SELINUX_PRIORITY_HOST_NAME |
-                          SELINUX_PRIORITY_HOST_GROUP |
-                          SELINUX_PRIORITY_HOST_CAT);
-
-            /* Now figure out host priority */
-            ret = sysdb_attrs_get_uint32_t(tmp_attrs,
-                                           SYSDB_SELINUX_HOST_PRIORITY,
-                                           &host_priority);
-            if (ret != EOK) {
-                continue;
-            }
-
-            priority += host_priority;
-            if (priority < top_priority) {
-                /* This rule has lower priority than what we already have,
-                 * skip it */
-                continue;
-            } else if (priority > top_priority) {
-                /* If the rule has higher priority, drop what we already
-                 * have */
-                while (usermaps_cnt > 0) {
-                    usermaps_cnt--;
-                    talloc_zfree(usermaps[usermaps_cnt]);
-                }
-                top_priority = priority;
-            }
-
-
-            usermaps[usermaps_cnt] = talloc_steal(usermaps, msgs[i]);
-            usermaps_cnt++;
-        } else {
-            talloc_zfree(msgs[i]);
-        }
-    }
-
-    *_usermaps = talloc_steal(mem_ctx, usermaps);
-
-    ret = EOK;
-done:
-    talloc_zfree(tmp_ctx);
-    return ret;
-}
-
 errno_t sysdb_search_selinux_config(TALLOC_CTX *mem_ctx,
                                     struct sysdb_ctx *sysdb,
                                     struct sss_domain_info *domain,
diff --git a/src/providers/ipa/ipa_selinux.c b/src/providers/ipa/ipa_selinux.c
index 29e9887..b5f5039 100644
--- a/src/providers/ipa/ipa_selinux.c
+++ b/src/providers/ipa/ipa_selinux.c
@@ -21,7 +21,7 @@
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
-
+#include <selinux/selinux.h>
 #include <security/pam_modules.h>
 
 #include "db/sysdb_selinux.h"
@@ -65,12 +65,18 @@ static void ipa_get_config_step(struct tevent_req *req);
 static void ipa_get_selinux_config_done(struct tevent_req *subreq);
 static void ipa_get_selinux_maps_done(struct tevent_req *subreq);
 static void ipa_get_selinux_hbac_done(struct tevent_req *subreq);
-static errno_t ipa_selinux_process_maps(struct sysdb_attrs *user,
+static errno_t ipa_selinux_process_maps(TALLOC_CTX *mem_ctx,
+                                        struct sysdb_attrs *user,
                                         struct sysdb_attrs *host,
                                         struct sysdb_attrs **selinux_maps,
                                         size_t selinux_map_count,
                                         struct sysdb_attrs **hbac_rules,
-                                        size_t hbac_rule_count);
+                                        size_t hbac_rule_count,
+                                        struct sysdb_attrs ***usermaps);
+static errno_t prepare_selinux_file_content(struct sysdb_attrs **usermaps,
+                                            struct pam_data *pd,
+                                            const char *map_order,
+                                            const char *default_user);
 
 struct ipa_selinux_op_ctx {
     struct be_req *be_req;
@@ -199,6 +205,7 @@ static void ipa_selinux_handler_done(struct tevent_req *req)
     char *map_order = NULL;
     size_t hbac_count = 0;
     struct sysdb_attrs **hbac_rules = 0;
+    struct sysdb_attrs **best_match_maps;
 
     ret = ipa_get_selinux_recv(req, breq, &map_count, &maps,
                                &hbac_count, &hbac_rules,
@@ -207,10 +214,19 @@ static void ipa_selinux_handler_done(struct tevent_req *req)
         goto fail;
     }
 
-    ret = ipa_selinux_process_maps(op_ctx->user, op_ctx->host,
+    /* Process the maps and return list of best matches */
+    ret = ipa_selinux_process_maps(op_ctx, op_ctx->user, op_ctx->host,
                                    maps, map_count,
-                                   hbac_rules, hbac_count);
+                                   hbac_rules, hbac_count, &best_match_maps);
+    if (ret != EOK) {
+        goto fail;
+    }
+
+    ret = prepare_selinux_file_content(best_match_maps, pd, map_order,
+                                       default_user);
     if (ret != EOK) {
+        DEBUG(SSSDBG_CRIT_FAILURE,
+              ("Failed to create SELinux file content\n"));
         goto fail;
     }
 
@@ -272,22 +288,30 @@ ipa_selinux_process_seealso_maps(struct sysdb_attrs *user,
                                  struct sysdb_attrs **seealso_rules,
                                  size_t seealso_rules_count,
                                  struct sysdb_attrs **hbac_rules,
-                                 size_t hbac_rule_count);
+                                 size_t hbac_rule_count,
+                                 uint32_t top_priority,
+                                 struct sysdb_attrs **usermaps,
+                                 size_t best_match_maps_cnt);
 static errno_t
-ipa_selinux_process_maps(struct sysdb_attrs *user,
+ipa_selinux_process_maps(TALLOC_CTX *mem_ctx,
+                         struct sysdb_attrs *user,
                          struct sysdb_attrs *host,
                          struct sysdb_attrs **selinux_maps,
                          size_t selinux_map_count,
                          struct sysdb_attrs **hbac_rules,
-                         size_t hbac_rule_count)
+                         size_t hbac_rule_count,
+                         struct sysdb_attrs ***_usermaps)
 {
     TALLOC_CTX *tmp_ctx;
     int i;
     errno_t ret;
     uint32_t priority = 0;
+    uint32_t top_priority = 0;
     struct sysdb_attrs **seealso_rules;
-    size_t num_seealso_rules;
+    size_t num_seealso_rules = 0;
     const char *seealso_str;
+    struct sysdb_attrs **usermaps;
+    size_t best_match_maps_cnt = 0;
 
     tmp_ctx = talloc_new(NULL);
     if (!tmp_ctx) {
@@ -300,23 +324,36 @@ ipa_selinux_process_maps(struct sysdb_attrs *user,
         ret = ENOMEM;
         goto done;
     }
-    num_seealso_rules = 0;
+
+    usermaps = talloc_zero_array(tmp_ctx, struct sysdb_attrs *, selinux_map_count + 1);
+    if (usermaps == NULL) {
+        ret = ENOMEM;
+        goto done;
+    }
 
     for (i = 0; i < selinux_map_count; i++) {
-        if (sss_selinux_match(selinux_maps[i], user,
-                              host, &priority)) {
-            priority &= ~(SELINUX_PRIORITY_USER_NAME |
-                          SELINUX_PRIORITY_USER_GROUP |
-                          SELINUX_PRIORITY_USER_CAT);
-            ret = sysdb_attrs_add_uint32(selinux_maps[i],
-                                         SYSDB_SELINUX_HOST_PRIORITY,
-                                         priority);
-            if (ret != EOK) {
-                goto done;
+        if (sss_selinux_match(selinux_maps[i], user, host, &priority)) {
+            if (priority < top_priority) {
+                /* This rule has lower priority than what we already have,
+                 * skip it. */
+                continue;
+            } else if (priority > top_priority) {
+                /* This rule has higher priority, drop what we already have */
+                while (best_match_maps_cnt > 0) {
+                    best_match_maps_cnt--;
+                    talloc_zfree(usermaps[best_match_maps_cnt]);
+                }
+                top_priority = priority;
             }
+
+            usermaps[best_match_maps_cnt] = talloc_steal(usermaps, selinux_maps[i]);
+            best_match_maps_cnt++;
+
             continue;
         }
 
+        /* SELinux map did not matched -> check sealso attribute for
+         * possible HBAC match */
         ret = sysdb_attrs_get_string(selinux_maps[i],
                                      SYSDB_SELINUX_SEEALSO, &seealso_str);
         if (ret == ENOENT) {
@@ -331,11 +368,14 @@ ipa_selinux_process_maps(struct sysdb_attrs *user,
 
     ret = ipa_selinux_process_seealso_maps(user, host,
                                            seealso_rules, num_seealso_rules,
-                                           hbac_rules, hbac_rule_count);
+                                           hbac_rules, hbac_rule_count,
+                                           top_priority, usermaps, best_match_maps_cnt);
     if (ret != EOK) {
         goto done;
     }
 
+    *_usermaps = talloc_steal(mem_ctx, usermaps);
+
     ret = EOK;
 done:
     talloc_free(tmp_ctx);
@@ -348,15 +388,18 @@ ipa_selinux_process_seealso_maps(struct sysdb_attrs *user,
                                  struct sysdb_attrs **seealso_rules,
                                  size_t seealso_rules_count,
                                  struct sysdb_attrs **hbac_rules,
-                                 size_t hbac_rule_count)
+                                 size_t hbac_rule_count,
+                                 uint32_t top_priority,
+                                 struct sysdb_attrs **usermaps,
+                                 size_t best_match_maps_cnt)
 {
     int i, j;
     errno_t ret;
     struct ldb_message_element *el;
-    uint32_t priority = 0;
     struct sysdb_attrs *usermap;
     const char *seealso_dn;
     const char *hbac_dn;
+    uint32_t priority;
 
     for (i = 0; i < hbac_rule_count; i++) {
         ret = sysdb_attrs_get_string(hbac_rules[i], SYSDB_ORIG_DN, &hbac_dn);
@@ -399,16 +442,24 @@ ipa_selinux_process_seealso_maps(struct sysdb_attrs *user,
                 DEBUG(SSSDBG_TRACE_FUNC, ("HBAC rule [%s] matched, copying its"
                                           "attributes to SELinux user map [%s]\n",
                                           hbac_dn, seealso_dn));
-                priority &= ~(SELINUX_PRIORITY_USER_NAME |
-                              SELINUX_PRIORITY_USER_GROUP |
-                              SELINUX_PRIORITY_USER_CAT);
-                ret = sysdb_attrs_add_uint32(usermap,
-                                             SYSDB_SELINUX_HOST_PRIORITY,
-                                             priority);
-                if (ret != EOK) {
-                    return ret;
+
+                /* Selinux maps priority evaluation removed --DELETE this comment before pushing*/
+                if (priority < top_priority) {
+                    /* This rule has lower priority than what we already have,
+                     * skip it. */
+                    continue;
+                } else if (priority > top_priority) {
+                    /* This rule has higher priority, drop what we already have */
+                    while (best_match_maps_cnt > 0) {
+                        best_match_maps_cnt--;
+                        talloc_zfree(usermaps[best_match_maps_cnt]);
+                    }
+                    top_priority = priority;
                 }
 
+                usermaps[best_match_maps_cnt] = talloc_steal(usermaps, usermap);
+                best_match_maps_cnt++;
+
                 ret = sysdb_attrs_copy_values(hbac_rules[i], usermap, SYSDB_ORIG_MEMBER_USER);
                 if (ret != EOK) {
                     return ret;
@@ -428,6 +479,256 @@ ipa_selinux_process_seealso_maps(struct sysdb_attrs *user,
     return EOK;
 }
 
+
+static errno_t write_selinux_login_file(const char *username, char *string);
+static errno_t remove_selinux_login_file(const char *username);
+
+/* Prepare selinux file content and write it to the disk. */
+static errno_t prepare_selinux_file_content(struct sysdb_attrs **usermaps,
+                                            struct pam_data *pd,
+                                            const char *map_order,
+                                            const char *default_user)
+{
+    TALLOC_CTX *tmp_ctx;
+    char *file_content = NULL;
+    const char *tmp_str;
+    char *order = NULL;
+    char **order_array;
+    errno_t ret, err;
+    int i, j;
+    size_t order_count;
+    size_t len = 0;
+
+    tmp_ctx = talloc_new(NULL);
+    if (tmp_ctx == NULL) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    order = talloc_strdup(tmp_ctx, map_order);
+    if (order == NULL) {
+        ret = ENOMEM;
+        goto done;
+    }
+    len = strlen(order);
+
+    /* The "order" string contains one or more SELinux user records
+     * separated by $. Now we need to create an array of string from
+     * this one string. First find out how many elements in the array
+     * will be. This way only one alloc will be necessary for the array
+     */
+    order_count = 1;
+    for (i = 0; i < len; i++) {
+        if (order[i] == '$') order_count++;
+    }
+
+    order_array = talloc_array(tmp_ctx, char *, order_count);
+    if (order_array == NULL) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    /* Now fill the array with pointers to the original string. Also
+     * use binary zeros to make multiple string out of the one.
+     */
+    order_array[0] = order;
+    order_count = 1;
+    for (i = 0; i < len; i++) {
+        if (order[i] == '$') {
+            order[i] = '\0';
+            order_array[order_count] = &order[i+1];
+            order_count++;
+        }
+    }
+
+    /* If no maps match, we'll use the default SELinux user from the
+     * config */
+    file_content = talloc_strdup(tmp_ctx, default_user);
+    if (file_content == NULL) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    /* Iterate through the order array and try to find SELinux users
+     * in fetched maps. The order array contains all SELinux users
+     * allowed in the domain in the same order they should appear
+     * in the SELinux config file. If any user from the order array
+     * is not in fetched user maps, it means it should not be allowed
+     * for the user who is just logging in.
+     *
+     * Right now we have empty content of the SELinux config file,
+     * we shall add only those SELinux users that are present both in
+     * the order array and user maps applicable to the user who is
+     * logging in.
+     */
+    for (i = 0; i < order_count; i++) {
+        for (j = 0; usermaps[j] != NULL; j++) {
+            tmp_str = sss_selinux_map_get_seuser(usermaps[j]);
+
+            if (tmp_str && !strcasecmp(tmp_str, order_array[i])) {
+                /* If file_content contained something, overwrite it.
+                 * This record has higher priority.
+                 */
+                talloc_zfree(file_content);
+                file_content = talloc_strdup(tmp_ctx, tmp_str);
+                if (file_content == NULL) {
+                    ret = ENOMEM;
+                    goto done;
+                }
+                break;
+            }
+        }
+    }
+
+    ret = write_selinux_login_file(pd->user, file_content);
+done:
+    if (!file_content) {
+        err = remove_selinux_login_file(pd->user);
+        /* Don't overwrite original error condition if there was one */
+        if (ret == EOK) ret = err;
+    }
+    talloc_free(tmp_ctx);
+    return ret;
+}
+
+#ifdef HAVE_SELINUX_LOGIN_DIR
+
+#define ALL_SERVICES "*"
+#define selogin_path(mem_ctx, username) \
+    talloc_asprintf(mem_ctx, "%s/logins/%s", selinux_policy_root(), username)
+#endif
+
+static errno_t write_selinux_login_file(const char *username, char *string)
+{
+    char *path = NULL;
+    char *tmp_path = NULL;
+    ssize_t written;
+    int len;
+    int fd = -1;
+    mode_t oldmask;
+    TALLOC_CTX *tmp_ctx;
+    char *full_string = NULL;
+    int enforce;
+    errno_t ret = EOK;
+
+    len = strlen(string);
+    if (len == 0) {
+        return EINVAL;
+    }
+
+    tmp_ctx = talloc_new(NULL);
+    if (tmp_ctx == NULL) {
+        DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new() failed\n"));
+        return ENOMEM;
+    }
+
+    path = selogin_path(tmp_ctx, username);
+    if (path == NULL) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    tmp_path = talloc_asprintf(tmp_ctx, "%sXXXXXX", path);
+    if (tmp_path == NULL) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    oldmask = umask(022);
+    fd = mkstemp(tmp_path);
+    ret = errno;
+    umask(oldmask);
+    if (fd < 0) {
+        if (ret == ENOENT) {
+            /* if selinux is disabled and selogin dir does not exist,
+             * just ignore the error */
+            if (selinux_getenforcemode(&enforce) == 0 && enforce == -1) {
+                ret = EOK;
+                goto done;
+            }
+
+            /* continue if we can't get enforce mode or selinux is enabled */
+        }
+
+        DEBUG(SSSDBG_OP_FAILURE, ("unable to create temp file [%s] "
+              "for SELinux data [%d]: %s\n", tmp_path, ret, strerror(ret)));
+        goto done;
+    }
+
+    full_string = talloc_asprintf(tmp_ctx, "%s:%s", ALL_SERVICES, string);
+    if (full_string == NULL) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    len = strlen(full_string);
+
+    errno = 0;
+    written = sss_atomic_write_s(fd, full_string, len);
+    if (written == -1) {
+        ret = errno;
+        DEBUG(SSSDBG_OP_FAILURE, ("writing to SELinux data file %s"
+                                  "failed [%d]: %s", tmp_path, ret,
+                                  strerror(ret)));
+        goto done;
+    }
+
+    if (written != len) {
+        DEBUG(SSSDBG_OP_FAILURE, ("Expected to write %d bytes, wrote %d",
+                                  written, len));
+        ret = EIO;
+        goto done;
+    }
+
+    errno = 0;
+    if (rename(tmp_path, path) < 0) {
+        ret = errno;
+    } else {
+        ret = EOK;
+    }
+    close(fd);
+    fd = -1;
+
+done:
+    if (fd != -1) {
+        close(fd);
+        if (unlink(tmp_path) < 0) {
+            DEBUG(SSSDBG_MINOR_FAILURE, ("Could not remove file [%s]",
+                                         tmp_path));
+        }
+    }
+
+    talloc_free(tmp_ctx);
+    return ret;
+}
+
+static errno_t remove_selinux_login_file(const char *username)
+{
+    char *path;
+    errno_t ret;
+
+    path = selogin_path(NULL, username);
+    if (!path) return ENOMEM;
+
+    errno = 0;
+    ret = unlink(path);
+    if (ret < 0) {
+        ret = errno;
+        if (ret == ENOENT) {
+            /* Just return success if the file was not there */
+            ret = EOK;
+        } else {
+            DEBUG(SSSDBG_OP_FAILURE,
+                  ("Could not remove login file %s [%d]: %s\n",
+                   path, ret, strerror(ret)));
+        }
+    }
+
+    talloc_free(path);
+    return ret;
+}
+
+
 /* A more generic request to gather all SELinux and HBAC rules. Updates
  * cache if necessary
  */
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index 9d38c03..4b073aa 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -22,7 +22,6 @@
 
 #include <time.h>
 #include "util/util.h"
-#include "util/sss_selinux.h"
 #include "util/auth_utils.h"
 #include "db/sysdb.h"
 #include "confdb/confdb.h"
@@ -33,10 +32,6 @@
 #include "responder/pam/pamsrv.h"
 #include "responder/pam/pam_helpers.h"
 #include "db/sysdb.h"
-#include "db/sysdb_selinux.h"
-#ifdef HAVE_SELINUX_LOGIN_DIR
-#include <selinux/selinux.h>
-#endif
 
 enum pam_verbosity {
     PAM_VERBOSITY_NO_MESSAGES = 0,
@@ -371,298 +366,6 @@ fail:
     return ret;
 }
 
-#ifdef HAVE_SELINUX_LOGIN_DIR
-
-#define ALL_SERVICES "*"
-#define selogin_path(mem_ctx, username) \
-    talloc_asprintf(mem_ctx, "%s/logins/%s", selinux_policy_root(), username)
-
-static errno_t write_selinux_login_file(const char *username, char *string)
-{
-    char *path = NULL;
-    char *tmp_path = NULL;
-    ssize_t written;
-    int len;
-    int fd = -1;
-    mode_t oldmask;
-    TALLOC_CTX *tmp_ctx;
-    char *full_string = NULL;
-    int enforce;
-    errno_t ret = EOK;
-
-    len = strlen(string);
-    if (len == 0) {
-        return EINVAL;
-    }
-
-    tmp_ctx = talloc_new(NULL);
-    if (tmp_ctx == NULL) {
-        DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new() failed\n"));
-        return ENOMEM;
-    }
-
-    path = selogin_path(tmp_ctx, username);
-    if (path == NULL) {
-        ret = ENOMEM;
-        goto done;
-    }
-
-    tmp_path = talloc_asprintf(tmp_ctx, "%sXXXXXX", path);
-    if (tmp_path == NULL) {
-        ret = ENOMEM;
-        goto done;
-    }
-
-    oldmask = umask(022);
-    fd = mkstemp(tmp_path);
-    ret = errno;
-    umask(oldmask);
-    if (fd < 0) {
-        if (ret == ENOENT) {
-            /* if selinux is disabled and selogin dir does not exist,
-             * just ignore the error */
-            if (selinux_getenforcemode(&enforce) == 0 && enforce == -1) {
-                ret = EOK;
-                goto done;
-            }
-
-            /* continue if we can't get enforce mode or selinux is enabled */
-        }
-
-        DEBUG(SSSDBG_OP_FAILURE, ("unable to create temp file [%s] "
-              "for SELinux data [%d]: %s\n", tmp_path, ret, strerror(ret)));
-        goto done;
-    }
-
-    full_string = talloc_asprintf(tmp_ctx, "%s:%s", ALL_SERVICES, string);
-    if (full_string == NULL) {
-        ret = ENOMEM;
-        goto done;
-    }
-
-    len = strlen(full_string);
-
-    errno = 0;
-    written = sss_atomic_write_s(fd, full_string, len);
-    if (written == -1) {
-        ret = errno;
-        DEBUG(SSSDBG_OP_FAILURE, ("writing to SELinux data file %s"
-                                  "failed [%d]: %s", tmp_path, ret,
-                                  strerror(ret)));
-        goto done;
-    }
-
-    if (written != len) {
-        DEBUG(SSSDBG_OP_FAILURE, ("Expected to write %d bytes, wrote %d",
-                                  written, len));
-        ret = EIO;
-        goto done;
-    }
-
-    errno = 0;
-    if (rename(tmp_path, path) < 0) {
-        ret = errno;
-    } else {
-        ret = EOK;
-    }
-    close(fd);
-    fd = -1;
-
-done:
-    if (fd != -1) {
-        close(fd);
-        if (unlink(tmp_path) < 0) {
-            DEBUG(SSSDBG_MINOR_FAILURE, ("Could not remove file [%s]",
-                                         tmp_path));
-        }
-    }
-
-    talloc_free(tmp_ctx);
-    return ret;
-}
-
-static errno_t remove_selinux_login_file(const char *username)
-{
-    char *path;
-    errno_t ret;
-
-    path = selogin_path(NULL, username);
-    if (!path) return ENOMEM;
-
-    errno = 0;
-    ret = unlink(path);
-    if (ret < 0) {
-        ret = errno;
-        if (ret == ENOENT) {
-            /* Just return success if the file was not there */
-            ret = EOK;
-        } else {
-            DEBUG(SSSDBG_OP_FAILURE,
-                  ("Could not remove login file %s [%d]: %s\n",
-                   path, ret, strerror(ret)));
-        }
-    }
-
-    talloc_free(path);
-    return ret;
-}
-
-static errno_t process_selinux_mappings(struct pam_auth_req *preq)
-{
-    struct sysdb_ctx *sysdb;
-    TALLOC_CTX *tmp_ctx;
-    struct pam_data *pd = preq->pd;
-    char *file_content = NULL;
-    struct ldb_message **usermaps;
-    struct ldb_message *config;
-    const char *default_user = NULL;
-    const char *tmp_str;
-    char *order = NULL;
-    char **order_array;
-    errno_t ret, err;
-    int i, j;
-    size_t order_count;
-    size_t len = 0;
-
-    tmp_ctx = talloc_new(NULL);
-    if (tmp_ctx == NULL) {
-        ret = ENOMEM;
-        goto done;
-    }
-
-    sysdb = preq->domain->sysdb;
-    if (sysdb == NULL) {
-        DEBUG(SSSDBG_FATAL_FAILURE, ("Fatal: Sysdb CTX not found for "
-                                     "domain [%s]!\n", preq->domain->name));
-        ret = EINVAL;
-        goto done;
-    }
-
-    ret = sysdb_search_selinux_config(tmp_ctx, sysdb,
-                                      preq->domain, NULL, &config);
-    if (ret == ENOENT) {
-        DEBUG(SSSDBG_TRACE_INTERNAL, ("No SELinux support found for the domain\n"));
-        ret = EOK;
-        goto done;
-    } else if (ret != EOK) {
-        goto done;
-    }
-
-    default_user = ldb_msg_find_attr_as_string(config,
-                                               SYSDB_SELINUX_DEFAULT_USER,
-                                               NULL);
-    if (!default_user || default_user[0] == '\0') {
-        /* Skip creating the maps altogether if there is no default
-         * or empty default
-         */
-        ret = EOK;
-        goto done;
-    }
-
-    tmp_str = ldb_msg_find_attr_as_string(config,
-                                          SYSDB_SELINUX_DEFAULT_ORDER,
-                                          NULL);
-    if (tmp_str == NULL) {
-        DEBUG(SSSDBG_OP_FAILURE, ("No map order given!\n"));
-        ret = EINVAL;
-        goto done;
-    }
-
-    order = talloc_strdup(tmp_ctx, tmp_str);
-    if (order == NULL) {
-        ret = ENOMEM;
-        goto done;
-    }
-    len = strlen(order);
-
-    /* The "order" string contains one or more SELinux user records
-     * separated by $. Now we need to create an array of string from
-     * this one string. First find out how many elements in the array
-     * will be. This way only one alloc will be necessary for the array
-     */
-    order_count = 1;
-    for (i = 0; i < len; i++) {
-        if (order[i] == '$') order_count++;
-    }
-
-    order_array = talloc_array(tmp_ctx, char *, order_count);
-    if (order_array == NULL) {
-        ret = ENOMEM;
-        goto done;
-    }
-
-    /* Now fill the array with pointers to the original string. Also
-     * use binary zeros to make multiple string out of the one.
-     */
-    order_array[0] = order;
-    order_count = 1;
-    for (i = 0; i < len; i++) {
-        if (order[i] == '$') {
-            order[i] = '\0';
-            order_array[order_count] = &order[i+1];
-            order_count++;
-        }
-    }
-
-    /* Fetch all maps applicable to the user who is currently logging in */
-    ret = sysdb_search_selinux_usermap_by_username(tmp_ctx, sysdb,
-                                                   preq->domain, pd->user,
-                                                   &usermaps);
-    if (ret != EOK && ret != ENOENT) {
-        goto done;
-    }
-
-    /* If no maps match, we'll use the default SELinux user from the
-     * config */
-    file_content = talloc_strdup(tmp_ctx, default_user);
-    if (file_content == NULL) {
-        ret = ENOMEM;
-        goto done;
-    }
-
-    /* Iterate through the order array and try to find SELinux users
-     * in fetched maps. The order array contains all SELinux users
-     * allowed in the domain in the same order they should appear
-     * in the SELinux config file. If any user from the order array
-     * is not in fetched user maps, it means it should not be allowed
-     * for the user who is just logging in.
-     *
-     * Right now we have empty content of the SELinux config file,
-     * we shall add only those SELinux users that are present both in
-     * the order array and user maps applicable to the user who is
-     * logging in.
-     */
-    for (i = 0; i < order_count; i++) {
-        for (j = 0; usermaps[j] != NULL; j++) {
-            tmp_str = sss_selinux_map_get_seuser(usermaps[j]);
-
-            if (tmp_str && !strcasecmp(tmp_str, order_array[i])) {
-                /* If file_content contained something, overwrite it.
-                 * This record has higher priority.
-                 */
-                talloc_zfree(file_content);
-                file_content = talloc_strdup(tmp_ctx, tmp_str);
-                if (file_content == NULL) {
-                    ret = ENOMEM;
-                    goto done;
-                }
-                break;
-            }
-        }
-    }
-
-    ret = write_selinux_login_file(pd->user, file_content);
-done:
-    if (!file_content) {
-        err = remove_selinux_login_file(pd->user);
-        /* Don't overwrite original error condition if there was one */
-        if (ret == EOK) ret = err;
-    }
-    talloc_free(tmp_ctx);
-    return ret;
-}
-#endif
-
 static errno_t filter_responses(struct confdb_ctx *cdb,
                                 struct response_data *resp_list)
 {
@@ -863,18 +566,6 @@ static void pam_reply(struct pam_auth_req *preq)
         return;
     }
 
-#ifdef HAVE_SELINUX_LOGIN_DIR
-    if (pd->cmd == SSS_PAM_ACCT_MGMT &&
-        pd->pam_status == PAM_SUCCESS) {
-        /* Try to fetch data from sysdb
-         * (auth already passed -> we should have them) */
-        ret = process_selinux_mappings(preq);
-        if (ret != EOK) {
-            pd->pam_status = PAM_SYSTEM_ERR;
-        }
-    }
-#endif
-
     ret = sss_packet_new(cctx->creq, 0, sss_packet_get_cmd(cctx->creq->in),
                          &cctx->creq->out);
     if (ret != EOK) {
diff --git a/src/util/sss_selinux.c b/src/util/sss_selinux.c
index ee5ddab..dcac9ee 100644
--- a/src/util/sss_selinux.c
+++ b/src/util/sss_selinux.c
@@ -239,16 +239,16 @@ done:
     return ret;
 }
 
-const char *sss_selinux_map_get_seuser(struct ldb_message *usermap)
+const char *sss_selinux_map_get_seuser(struct sysdb_attrs *usermap)
 {
     int i;
     const uint8_t *name;
     const uint8_t *template = (const uint8_t *)SYSDB_SELINUX_USER;
 
-    for (i = 0; i < usermap->num_elements; i++) {
-        name = (const uint8_t *)usermap->elements[i].name;
+    for (i = 0; i < usermap->num; i++) {
+        name = (const uint8_t *)usermap->a[i].name;
         if (sss_utf8_case_eq(name, template) == 0) {
-            return (const char *)usermap->elements[i].values[0].data;
+            return (const char *)usermap->a[i].values[0].data;
         }
     }
 
diff --git a/src/util/sss_selinux.h b/src/util/sss_selinux.h
index 5dae5dd..ae5b2f3 100644
--- a/src/util/sss_selinux.h
+++ b/src/util/sss_selinux.h
@@ -50,6 +50,6 @@ bool sss_selinux_match(struct sysdb_attrs *usermap,
                        struct sysdb_attrs *host,
                        uint32_t *_priority);
 
-const char *sss_selinux_map_get_seuser(struct ldb_message *usermap);
+const char *sss_selinux_map_get_seuser(struct sysdb_attrs *usermap);
 
 #endif /* SSS_SELINUX_H_ */
-- 
1.7.11.2

