summaryrefslogtreecommitdiffstats
path: root/src/responder/pam
diff options
context:
space:
mode:
authorMichal Zidek <mzidek@redhat.com>2013-02-07 19:35:37 +0100
committerJakub Hrozek <jhrozek@redhat.com>2013-03-19 17:50:53 +0100
commitb42bb7d9dbf9a4c44a03e7bf1bab471a8a85e858 (patch)
tree990fcb7fa6901faf4f2b7befea8912324106dad5 /src/responder/pam
parent1f469537545a20b62cb35966033be24e1c0cae39 (diff)
downloadsssd-b42bb7d9dbf9a4c44a03e7bf1bab471a8a85e858.tar.gz
sssd-b42bb7d9dbf9a4c44a03e7bf1bab471a8a85e858.tar.xz
sssd-b42bb7d9dbf9a4c44a03e7bf1bab471a8a85e858.zip
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
Diffstat (limited to 'src/responder/pam')
-rw-r--r--src/responder/pam/pamsrv_cmd.c309
1 files changed, 0 insertions, 309 deletions
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index 69791a0e5..647f82762 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) {