|
|
905b4d |
From 7d5eda445b127f4fdb5ff2f680792d46aa82439b Mon Sep 17 00:00:00 2001
|
|
|
905b4d |
From: Michal Zidek <mzidek@redhat.com>
|
|
|
905b4d |
Date: Wed, 24 Sep 2014 16:51:55 +0200
|
|
|
905b4d |
Subject: [PATCH 03/22] IPA: Use set_seuser instead of writing selinux login
|
|
|
905b4d |
file
|
|
|
905b4d |
MIME-Version: 1.0
|
|
|
905b4d |
Content-Type: text/plain; charset=UTF-8
|
|
|
905b4d |
Content-Transfer-Encoding: 8bit
|
|
|
905b4d |
|
|
|
905b4d |
Remove the write/remove_selinux login file functions
|
|
|
905b4d |
and use set_seuser instead.
|
|
|
905b4d |
|
|
|
905b4d |
This patch will require change in selinux policy.
|
|
|
905b4d |
|
|
|
905b4d |
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
|
|
|
905b4d |
---
|
|
|
905b4d |
src/providers/ipa/ipa_selinux.c | 184 +++++++++++-----------------------------
|
|
|
905b4d |
1 file changed, 49 insertions(+), 135 deletions(-)
|
|
|
905b4d |
|
|
|
905b4d |
diff --git a/src/providers/ipa/ipa_selinux.c b/src/providers/ipa/ipa_selinux.c
|
|
|
905b4d |
index 5b65a7b04cb0d55b10de47c4ea306b6d4470dfe9..7db1c6ed2981e4c4a85d892171bbfa60b006980e 100644
|
|
|
905b4d |
--- a/src/providers/ipa/ipa_selinux.c
|
|
|
905b4d |
+++ b/src/providers/ipa/ipa_selinux.c
|
|
|
905b4d |
@@ -652,10 +652,10 @@ done:
|
|
|
905b4d |
return ret;
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
-static errno_t write_selinux_login_file(const char *orig_name,
|
|
|
905b4d |
- struct sss_domain_info *dom,
|
|
|
905b4d |
- char *string);
|
|
|
905b4d |
-static errno_t remove_selinux_login_file(const char *username);
|
|
|
905b4d |
+static errno_t
|
|
|
905b4d |
+set_seuser_helper(const char *orig_name, struct sss_domain_info *dom,
|
|
|
905b4d |
+ const char *seuser_mls_string);
|
|
|
905b4d |
+
|
|
|
905b4d |
|
|
|
905b4d |
/* Choose best selinux user based on given order and write
|
|
|
905b4d |
* the user to selinux login file. */
|
|
|
905b4d |
@@ -666,9 +666,9 @@ static errno_t choose_best_seuser(struct sysdb_attrs **usermaps,
|
|
|
905b4d |
const char *default_user)
|
|
|
905b4d |
{
|
|
|
905b4d |
TALLOC_CTX *tmp_ctx;
|
|
|
905b4d |
- char *file_content = NULL;
|
|
|
905b4d |
+ char *seuser_mls_str = NULL;
|
|
|
905b4d |
const char *tmp_str;
|
|
|
905b4d |
- errno_t ret, err;
|
|
|
905b4d |
+ errno_t ret;
|
|
|
905b4d |
int i, j;
|
|
|
905b4d |
|
|
|
905b4d |
tmp_ctx = talloc_new(NULL);
|
|
|
905b4d |
@@ -679,8 +679,8 @@ static errno_t choose_best_seuser(struct sysdb_attrs **usermaps,
|
|
|
905b4d |
|
|
|
905b4d |
/* If no maps match, we'll use the default SELinux user from the
|
|
|
905b4d |
* config */
|
|
|
905b4d |
- file_content = talloc_strdup(tmp_ctx, default_user);
|
|
|
905b4d |
- if (file_content == NULL) {
|
|
|
905b4d |
+ seuser_mls_str = talloc_strdup(tmp_ctx, default_user);
|
|
|
905b4d |
+ if (seuser_mls_str == NULL) {
|
|
|
905b4d |
ret = ENOMEM;
|
|
|
905b4d |
goto done;
|
|
|
905b4d |
}
|
|
|
905b4d |
@@ -702,12 +702,12 @@ static errno_t choose_best_seuser(struct sysdb_attrs **usermaps,
|
|
|
905b4d |
tmp_str = sss_selinux_map_get_seuser(usermaps[j]);
|
|
|
905b4d |
|
|
|
905b4d |
if (tmp_str && !strcasecmp(tmp_str, mo_ctx->order_array[i])) {
|
|
|
905b4d |
- /* If file_content contained something, overwrite it.
|
|
|
905b4d |
+ /* If seuser_mls_str contained something, overwrite it.
|
|
|
905b4d |
* This record has higher priority.
|
|
|
905b4d |
*/
|
|
|
905b4d |
- talloc_zfree(file_content);
|
|
|
905b4d |
- file_content = talloc_strdup(tmp_ctx, tmp_str);
|
|
|
905b4d |
- if (file_content == NULL) {
|
|
|
905b4d |
+ talloc_zfree(seuser_mls_str);
|
|
|
905b4d |
+ seuser_mls_str = talloc_strdup(tmp_ctx, tmp_str);
|
|
|
905b4d |
+ if (seuser_mls_str == NULL) {
|
|
|
905b4d |
ret = ENOMEM;
|
|
|
905b4d |
goto done;
|
|
|
905b4d |
}
|
|
|
905b4d |
@@ -716,44 +716,48 @@ static errno_t choose_best_seuser(struct sysdb_attrs **usermaps,
|
|
|
905b4d |
}
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
- ret = write_selinux_login_file(pd->user, user_domain, file_content);
|
|
|
905b4d |
+ ret = set_seuser_helper(pd->user, user_domain, seuser_mls_str);
|
|
|
905b4d |
done:
|
|
|
905b4d |
- if (!file_content) {
|
|
|
905b4d |
- err = remove_selinux_login_file(pd->user);
|
|
|
905b4d |
- /* Don't overwrite original error condition if there was one */
|
|
|
905b4d |
- if (ret == EOK) ret = err;
|
|
|
905b4d |
- }
|
|
|
905b4d |
talloc_free(tmp_ctx);
|
|
|
905b4d |
return ret;
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
-static errno_t write_selinux_login_file(const char *orig_name,
|
|
|
905b4d |
- struct sss_domain_info *dom,
|
|
|
905b4d |
- char *string)
|
|
|
905b4d |
+static errno_t
|
|
|
905b4d |
+set_seuser_helper(const char *orig_name, struct sss_domain_info *dom,
|
|
|
905b4d |
+ const char *seuser_mls_string)
|
|
|
905b4d |
{
|
|
|
905b4d |
- char *path = NULL;
|
|
|
905b4d |
- char *tmp_path = NULL;
|
|
|
905b4d |
- ssize_t written;
|
|
|
905b4d |
- size_t len;
|
|
|
905b4d |
- int fd = -1;
|
|
|
905b4d |
- mode_t oldmask;
|
|
|
905b4d |
+ errno_t ret;
|
|
|
905b4d |
+ char *seuser;
|
|
|
905b4d |
+ char *mls_range;
|
|
|
905b4d |
+ char *ptr;
|
|
|
905b4d |
+ char *username;
|
|
|
905b4d |
+ char *username_final;
|
|
|
905b4d |
TALLOC_CTX *tmp_ctx;
|
|
|
905b4d |
- char *full_string = NULL;
|
|
|
905b4d |
- int enforce;
|
|
|
905b4d |
- errno_t ret = EOK;
|
|
|
905b4d |
- const char *username;
|
|
|
905b4d |
-
|
|
|
905b4d |
- len = strlen(string);
|
|
|
905b4d |
- if (len == 0) {
|
|
|
905b4d |
- return EINVAL;
|
|
|
905b4d |
- }
|
|
|
905b4d |
|
|
|
905b4d |
tmp_ctx = talloc_new(NULL);
|
|
|
905b4d |
if (tmp_ctx == NULL) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
|
|
|
905b4d |
return ENOMEM;
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
+ /* Split seuser and mls_range */
|
|
|
905b4d |
+ seuser = talloc_strdup(tmp_ctx, seuser_mls_string);
|
|
|
905b4d |
+ if (seuser == NULL) {
|
|
|
905b4d |
+ ret = ENOMEM;
|
|
|
905b4d |
+ goto done;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ ptr = seuser;
|
|
|
905b4d |
+ while (*ptr != ':' && *ptr != '\0') {
|
|
|
905b4d |
+ ptr++;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+ if (*ptr == '\0') {
|
|
|
905b4d |
+ /* No mls_range specified */
|
|
|
905b4d |
+ mls_range = NULL;
|
|
|
905b4d |
+ } else {
|
|
|
905b4d |
+ *ptr = '\0'; /* split */
|
|
|
905b4d |
+ mls_range = ptr + 1;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
/* pam_selinux needs the username in the same format getpwnam() would
|
|
|
905b4d |
* return it
|
|
|
905b4d |
*/
|
|
|
905b4d |
@@ -763,113 +767,23 @@ static errno_t write_selinux_login_file(const char *orig_name,
|
|
|
905b4d |
goto done;
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
- path = selogin_path(tmp_ctx, username);
|
|
|
905b4d |
- if (path == NULL) {
|
|
|
905b4d |
- ret = ENOMEM;
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- tmp_path = talloc_asprintf(tmp_ctx, "%sXXXXXX", path);
|
|
|
905b4d |
- if (tmp_path == NULL) {
|
|
|
905b4d |
- ret = ENOMEM;
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- oldmask = umask(022);
|
|
|
905b4d |
- fd = mkstemp(tmp_path);
|
|
|
905b4d |
- ret = errno;
|
|
|
905b4d |
- umask(oldmask);
|
|
|
905b4d |
- if (fd < 0) {
|
|
|
905b4d |
- if (ret == ENOENT) {
|
|
|
905b4d |
- /* if selinux is disabled and selogin dir does not exist,
|
|
|
905b4d |
- * just ignore the error */
|
|
|
905b4d |
- if (selinux_getenforcemode(&enforce) == 0 && enforce == -1) {
|
|
|
905b4d |
- ret = EOK;
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- /* continue if we can't get enforce mode or selinux is enabled */
|
|
|
905b4d |
+ if (dom->fqnames) {
|
|
|
905b4d |
+ username_final = talloc_asprintf(tmp_ctx, dom->names->fq_fmt,
|
|
|
905b4d |
+ username, dom->name);
|
|
|
905b4d |
+ if (username_final == NULL) {
|
|
|
905b4d |
+ ret = ENOMEM;
|
|
|
905b4d |
+ goto done;
|
|
|
905b4d |
}
|
|
|
905b4d |
-
|
|
|
905b4d |
- DEBUG(SSSDBG_OP_FAILURE, "unable to create temp file [%s] "
|
|
|
905b4d |
- "for SELinux data [%d]: %s\n", tmp_path, ret, strerror(ret));
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- full_string = talloc_asprintf(tmp_ctx, "%s:%s", ALL_SERVICES, string);
|
|
|
905b4d |
- if (full_string == NULL) {
|
|
|
905b4d |
- ret = ENOMEM;
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- len = strlen(full_string);
|
|
|
905b4d |
-
|
|
|
905b4d |
- errno = 0;
|
|
|
905b4d |
- written = sss_atomic_write_s(fd, full_string, len);
|
|
|
905b4d |
- if (written == -1) {
|
|
|
905b4d |
- ret = errno;
|
|
|
905b4d |
- DEBUG(SSSDBG_OP_FAILURE, "writing to SELinux data file %s"
|
|
|
905b4d |
- "failed [%d]: %s", tmp_path, ret,
|
|
|
905b4d |
- strerror(ret));
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- if (written != len) {
|
|
|
905b4d |
- DEBUG(SSSDBG_OP_FAILURE, "Expected to write %zd bytes, wrote %zu",
|
|
|
905b4d |
- written, len);
|
|
|
905b4d |
- ret = EIO;
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- errno = 0;
|
|
|
905b4d |
- if (rename(tmp_path, path) < 0) {
|
|
|
905b4d |
- ret = errno;
|
|
|
905b4d |
} else {
|
|
|
905b4d |
- ret = EOK;
|
|
|
905b4d |
+ username_final = username;
|
|
|
905b4d |
}
|
|
|
905b4d |
- close(fd);
|
|
|
905b4d |
- fd = -1;
|
|
|
905b4d |
|
|
|
905b4d |
+ ret = set_seuser(username_final, seuser, mls_range);
|
|
|
905b4d |
done:
|
|
|
905b4d |
- if (fd != -1) {
|
|
|
905b4d |
- close(fd);
|
|
|
905b4d |
- if (unlink(tmp_path) < 0) {
|
|
|
905b4d |
- DEBUG(SSSDBG_MINOR_FAILURE, "Could not remove file [%s]",
|
|
|
905b4d |
- tmp_path);
|
|
|
905b4d |
- }
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
talloc_free(tmp_ctx);
|
|
|
905b4d |
return ret;
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
-static errno_t remove_selinux_login_file(const char *username)
|
|
|
905b4d |
-{
|
|
|
905b4d |
- char *path;
|
|
|
905b4d |
- errno_t ret;
|
|
|
905b4d |
-
|
|
|
905b4d |
- path = selogin_path(NULL, username);
|
|
|
905b4d |
- if (!path) return ENOMEM;
|
|
|
905b4d |
-
|
|
|
905b4d |
- errno = 0;
|
|
|
905b4d |
- ret = unlink(path);
|
|
|
905b4d |
- if (ret < 0) {
|
|
|
905b4d |
- ret = errno;
|
|
|
905b4d |
- if (ret == ENOENT) {
|
|
|
905b4d |
- /* Just return success if the file was not there */
|
|
|
905b4d |
- ret = EOK;
|
|
|
905b4d |
- } else {
|
|
|
905b4d |
- DEBUG(SSSDBG_OP_FAILURE,
|
|
|
905b4d |
- "Could not remove login file %s [%d]: %s\n",
|
|
|
905b4d |
- path, ret, strerror(ret));
|
|
|
905b4d |
- }
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- talloc_free(path);
|
|
|
905b4d |
- return ret;
|
|
|
905b4d |
-}
|
|
|
905b4d |
-
|
|
|
905b4d |
-
|
|
|
905b4d |
/* A more generic request to gather all SELinux and HBAC rules. Updates
|
|
|
905b4d |
* cache if necessary
|
|
|
905b4d |
*/
|
|
|
905b4d |
--
|
|
|
905b4d |
1.9.3
|
|
|
905b4d |
|