From 300c772767c1b12077cac1d148ac89738b058f97 Mon Sep 17 00:00:00 2001 From: Jan Zeleny Date: Jul 27 2012 12:46:16 +0000 Subject: Write SELinux config files in responder instead of PAM module --- diff --git a/Makefile.am b/Makefile.am index c992c97..0712864 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 @@ -1131,7 +1132,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 9c4c770..3104078 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 enum pam_verbosity { PAM_VERBOSITY_NO_MESSAGES = 0, @@ -353,6 +354,99 @@ fail: return ret; } +#define ALL_SERVICES "*" + +static errno_t write_selinux_string(const char *username, 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; + + 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 = talloc_asprintf(tmp_ctx, "%s/logins/%s", selinux_policy_root(), + username); + if (path == NULL) { + ret = ENOMEM; + goto done; + } + + tmp_path = talloc_asprintf(tmp_ctx, "%sXXXXXX", path); + if (path == NULL) { + ret = ENOMEM; + 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; + } + + errno = 0; + if (rename(tmp_path, path) < 0) { + ret = errno; + } else { + ret = EOK; + } + +done: + if (fd > 0) { + 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 get_selinux_string(struct pam_auth_req *preq) { struct sysdb_ctx *sysdb; @@ -494,11 +588,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->user, file_content); } done: diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c index 3fecfab..efbc48b 100644 --- a/src/sss_client/pam_sss.c +++ b/src/sss_client/pam_sss.c @@ -41,9 +41,6 @@ #include #include #include -#ifdef HAVE_SELINUX -#include -#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 @@ -87,7 +82,6 @@ struct pam_items { pid_t cli_pid; const char *login_name; char *domain_name; - char *selinux_user; }; #define DEBUG_MGS_LEN 1024 @@ -967,17 +961,6 @@ static int eval_response(pam_handle_t *pamh, size_t buflen, uint8_t *buf, D(("do_pam_conversation failed.")); } break; - case SSS_PAM_SELINUX_MAP: - if (pi->selinux_user) { - free(pi->selinux_user); - } - pi->selinux_user = (char *)malloc(len + 1); - if (!pi->selinux_user) { - D(("Insufficient memory.")); - return PAM_SYSTEM_ERR; - } - memcpy(pi->selinux_user, &buf[p], len + 1); - break; default: D(("Unknown response type [%d]", type)); } @@ -999,7 +982,6 @@ static int get_pam_items(pam_handle_t *pamh, struct pam_items *pi) pi->pam_newauthtok_type = SSS_AUTHTOK_TYPE_EMPTY; pi->pam_newauthtok = NULL; pi->pam_newauthtok_size = 0; - pi->selinux_user = NULL; ret = pam_get_item(pamh, PAM_SERVICE, (const void **) &(pi->pam_service)); if (ret != PAM_SUCCESS) return ret; @@ -1083,16 +1065,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); @@ -1180,68 +1152,6 @@ static int send_and_receive(pam_handle_t *pamh, struct pam_items *pi, pi->pam_user, pam_status, pam_strerror(pamh,pam_status)); } - } else { - if (pi->selinux_user == NULL) { - 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 +1169,6 @@ done: free(buf); } free(repbuf); -#ifdef HAVE_SELINUX - free(path); - free(tmp_path); - free(services); -#endif /* HAVE_SELINUX */ return pam_status; } diff --git a/src/sss_client/sss_cli.h b/src/sss_client/sss_cli.h index b634e49..f60bd99 100644 --- a/src/sss_client/sss_cli.h +++ b/src/sss_client/sss_cli.h @@ -368,10 +368,6 @@ enum response_type { * the user.This should only be used in the case where * it is not possile to use SSS_PAM_USER_INFO. * @param A zero terminated string. */ - SSS_PAM_SELINUX_MAP, /**< A content of a SELinux user mapping file. This - * file should be then written to a particular - * subdir in /etc/selinux for pam_selinux to read - * @param A zero terminated string. */ }; /**