>From 7073772c035cc35a3d1dfdc5ee8840e24b867079 Mon Sep 17 00:00:00 2001
From: Jan Zeleny <jzeleny@redhat.com>
Date: Fri, 27 Jul 2012 03:35:38 -0400
Subject: [PATCH] Write SELinux config files in responder instead of PAM
 module

---
 Makefile.am                    |    2 +-
 src/responder/pam/pamsrv_cmd.c |  104 ++++++++++++++++++++++++++++++++++++++--
 src/sss_client/pam_sss.c       |   77 -----------------------------
 3 files changed, 100 insertions(+), 83 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 15e34720a0f13b19b237dc709ddd080b3a6b1bed..d14bb7a993c1144fc8df7a36de253075536a37c9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -566,6 +566,7 @@ sssd_pam_SOURCES = \
 sssd_pam_LDADD = \
     $(TDB_LIBS) \
     $(SSSD_LIBS) \
+    $(SELINUX_LIBS) \
     libsss_util.la
 
 if BUILD_SUDO
@@ -1128,7 +1129,6 @@ pam_sss_la_SOURCES = \
 
 pam_sss_la_LDFLAGS = \
     -lpam \
-    $(SELINUX_LIBS) \
     -module \
     -avoid-version \
     -Wl,--version-script,$(srcdir)/src/sss_client/sss_pam.exports
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index 9c4c77060b1289352f58113ab221a6ae3acfb3e1..ec99557f97d85bc624d4908dc20c12c94af796b3 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -33,6 +33,7 @@
 #include "responder/pam/pam_helpers.h"
 #include "db/sysdb.h"
 #include "db/sysdb_selinux.h"
+#include <selinux/selinux.h>
 
 enum pam_verbosity {
     PAM_VERBOSITY_NO_MESSAGES = 0,
@@ -353,6 +354,103 @@ fail:
     return ret;
 }
 
+#define ALL_SERVICES "*"
+
+static errno_t write_selinux_string(struct pam_data *pd, char *string)
+{
+    char *path = NULL;
+    char *tmp_path = NULL;
+    ssize_t written;
+    int len;
+    int fd = 0;
+    mode_t oldmask;
+    TALLOC_CTX *tmp_ctx;
+    char *full_string = NULL;
+    errno_t ret = EOK;
+
+    tmp_ctx = talloc_new(NULL);
+    if (tmp_ctx == NULL) {
+        DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new() failed\n"));
+        return ENOMEM;
+    }
+
+    path = talloc_asprintf(tmp_ctx, "%s/logins/%s", selinux_policy_root(), pd->user);
+    if (path == NULL) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    tmp_path = talloc_asprintf(tmp_ctx, "%sXXXXXX", path);
+    if (path == NULL) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    len = strlen(string);
+    if (len == 0) {
+        errno = 0;
+        if (unlink(path) < 0) {
+            ret = errno;
+        } else {
+            ret = EOK;
+        }
+        goto done;
+    }
+
+    oldmask = umask(022);
+    fd = mkstemp(tmp_path);
+    umask(oldmask);
+    if (fd < 0) {
+        DEBUG(SSSDBG_OP_FAILURE, ("creating the temp file for SELinux "
+                                  "data failed. %s", tmp_path));
+        ret = EIO;
+        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;
+    }
+
+    ret = EOK;
+
+done:
+    if (fd > 0) {
+        close(fd);
+    }
+
+    if (ret == EOK) {
+        rename(tmp_path, path);
+    } else {
+        if (tmp_path) {
+            unlink(tmp_path);
+        }
+    }
+
+    talloc_free(tmp_ctx);
+    return ret;
+}
+
 static errno_t get_selinux_string(struct pam_auth_req *preq)
 {
     struct sysdb_ctx *sysdb;
@@ -494,11 +592,7 @@ static errno_t get_selinux_string(struct pam_auth_req *preq)
     }
 
     if (file_content) {
-        len = strlen(file_content)+1;
-        if (len > 0) {
-            ret = pam_add_response(pd, SSS_PAM_SELINUX_MAP, len,
-                                   (uint8_t *)file_content);
-        }
+        ret = write_selinux_string(pd, file_content);
     }
 
 done:
diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c
index 3fecfabe24c9e119c0989602562d73e5938f2d3e..3460633d4a7252f4afda02664c3af0cbb3b34935 100644
--- a/src/sss_client/pam_sss.c
+++ b/src/sss_client/pam_sss.c
@@ -41,9 +41,6 @@
 #include <security/pam_modules.h>
 #include <security/pam_ext.h>
 #include <security/pam_modutil.h>
-#ifdef HAVE_SELINUX
-#include <selinux/selinux.h>
-#endif
 #include "sss_pam_macros.h"
 
 #include "sss_cli.h"
@@ -57,8 +54,6 @@
 #define FLAGS_USE_AUTHTOK    (1 << 2)
 
 #define PWEXP_FLAG "pam_sss:password_expired_flag"
-#define ALL_SERVICES "*:"
-#define ALL_SERVICES_LEN 2
 
 #define PW_RESET_MSG_FILENAME_TEMPLATE SSSD_CONF_DIR"/customize/%s/pam_sss_pw_reset_message.%s"
 #define PW_RESET_MSG_MAX_SIZE 4096
@@ -1083,16 +1078,6 @@ static int send_and_receive(pam_handle_t *pamh, struct pam_items *pi,
     size_t replen;
     int pam_status = PAM_SYSTEM_ERR;
 
-#ifdef HAVE_SELINUX
-    char *path = NULL;
-    char *tmp_path = NULL;
-    char *services = NULL;
-    ssize_t written;
-    int len;
-    int fd;
-    mode_t oldmask;
-#endif /* HAVE_SELINUX */
-
     print_pam_items(pi);
 
     ret = pack_message_v3(pi, &rd.len, &buf);
@@ -1185,63 +1170,6 @@ static int send_and_receive(pam_handle_t *pamh, struct pam_items *pi,
                     pam_status = PAM_SUCCESS;
                     break;
                 }
-
-#ifdef HAVE_SELINUX
-                if (asprintf(&path, "%s/logins/%s", selinux_policy_root(),
-                             pi->pam_user) <  0 ||
-                    asprintf(&tmp_path, "%sXXXXXX", path) < 0) {
-                    pam_status = PAM_SYSTEM_ERR;
-                    goto done;
-                }
-
-                oldmask = umask(022);
-                fd = mkstemp(tmp_path);
-                umask(oldmask);
-                if (fd < 0) {
-                    logger(pamh, LOG_ERR, "creating the temp file for SELinux "
-                           "data failed. %s", tmp_path);
-                    pam_status = PAM_SYSTEM_ERR;
-                    goto done;
-                }
-
-                /* First write filter for all services */
-                services = strdup(ALL_SERVICES);
-                if (services == NULL) {
-                    pam_status = PAM_SYSTEM_ERR;
-                    goto done;
-                }
-
-                errno = 0;
-                written = sss_atomic_write_s(fd, (void *)services, ALL_SERVICES_LEN);
-                if (written == -1) {
-                    ret = errno;
-                    logger(pamh, LOG_ERR, "writing to SELinux data file %s"
-                            "failed [%d]: %s", tmp_path, ret, strerror(ret));
-                    pam_status = PAM_SYSTEM_ERR;
-                    goto done;
-                }
-                len = strlen(pi->selinux_user);
-
-                errno = 0;
-                written = sss_atomic_write_s(fd, pi->selinux_user, len);
-                if (written == -1) {
-                    ret = errno;
-                    logger(pamh, LOG_ERR, "writing to SELinux data file %s"
-                            "failed [%d]: %s", tmp_path, ret, strerror(ret));
-                    pam_status = PAM_SYSTEM_ERR;
-                    goto done;
-                }
-
-                if (written != len) {
-                    logger(pamh, LOG_ERR, "Expected to write %d bytes, wrote %d",
-                           written, len);
-                    goto done;
-                }
-
-                close(fd);
-
-                rename(tmp_path, path);
-#endif /* HAVE_SELINUX */
             }
             break;
         case SSS_PAM_OPEN_SESSION:
@@ -1259,11 +1187,6 @@ done:
         free(buf);
     }
     free(repbuf);
-#ifdef HAVE_SELINUX
-    free(path);
-    free(tmp_path);
-    free(services);
-#endif /* HAVE_SELINUX */
 
     return pam_status;
 }
-- 
1.7.7.6

