summaryrefslogtreecommitdiffstats
path: root/src/providers/ipa
diff options
context:
space:
mode:
authorMichal Zidek <mzidek@redhat.com>2014-09-24 16:51:55 +0200
committerJakub Hrozek <jhrozek@redhat.com>2014-10-20 21:26:29 +0200
commit9c47c8c59b5c9078f342f82367cd0ad7857acef8 (patch)
treee2c7e4332db7be0343bc5226f92e79446c413f8f /src/providers/ipa
parent180c7a75ee8507d459c7de21882dc714c59c3cc9 (diff)
downloadsssd-9c47c8c59b5c9078f342f82367cd0ad7857acef8.tar.gz
sssd-9c47c8c59b5c9078f342f82367cd0ad7857acef8.tar.xz
sssd-9c47c8c59b5c9078f342f82367cd0ad7857acef8.zip
IPA: Use set_seuser instead of writing selinux login file
Remove the write/remove_selinux login file functions and use set_seuser instead. This patch will require change in selinux policy. Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
Diffstat (limited to 'src/providers/ipa')
-rw-r--r--src/providers/ipa/ipa_selinux.c182
1 files changed, 48 insertions, 134 deletions
diff --git a/src/providers/ipa/ipa_selinux.c b/src/providers/ipa/ipa_selinux.c
index 5b65a7b04..7db1c6ed2 100644
--- a/src/providers/ipa/ipa_selinux.c
+++ b/src/providers/ipa/ipa_selinux.c
@@ -652,10 +652,10 @@ done:
return ret;
}
-static errno_t write_selinux_login_file(const char *orig_name,
- struct sss_domain_info *dom,
- char *string);
-static errno_t remove_selinux_login_file(const char *username);
+static errno_t
+set_seuser_helper(const char *orig_name, struct sss_domain_info *dom,
+ const char *seuser_mls_string);
+
/* Choose best selinux user based on given order and write
* the user to selinux login file. */
@@ -666,9 +666,9 @@ static errno_t choose_best_seuser(struct sysdb_attrs **usermaps,
const char *default_user)
{
TALLOC_CTX *tmp_ctx;
- char *file_content = NULL;
+ char *seuser_mls_str = NULL;
const char *tmp_str;
- errno_t ret, err;
+ errno_t ret;
int i, j;
tmp_ctx = talloc_new(NULL);
@@ -679,8 +679,8 @@ static errno_t choose_best_seuser(struct sysdb_attrs **usermaps,
/* 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) {
+ seuser_mls_str = talloc_strdup(tmp_ctx, default_user);
+ if (seuser_mls_str == NULL) {
ret = ENOMEM;
goto done;
}
@@ -702,12 +702,12 @@ static errno_t choose_best_seuser(struct sysdb_attrs **usermaps,
tmp_str = sss_selinux_map_get_seuser(usermaps[j]);
if (tmp_str && !strcasecmp(tmp_str, mo_ctx->order_array[i])) {
- /* If file_content contained something, overwrite it.
+ /* If seuser_mls_str 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) {
+ talloc_zfree(seuser_mls_str);
+ seuser_mls_str = talloc_strdup(tmp_ctx, tmp_str);
+ if (seuser_mls_str == NULL) {
ret = ENOMEM;
goto done;
}
@@ -716,160 +716,74 @@ static errno_t choose_best_seuser(struct sysdb_attrs **usermaps,
}
}
- ret = write_selinux_login_file(pd->user, user_domain, file_content);
+ ret = set_seuser_helper(pd->user, user_domain, seuser_mls_str);
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;
}
-static errno_t write_selinux_login_file(const char *orig_name,
- struct sss_domain_info *dom,
- char *string)
+static errno_t
+set_seuser_helper(const char *orig_name, struct sss_domain_info *dom,
+ const char *seuser_mls_string)
{
- char *path = NULL;
- char *tmp_path = NULL;
- ssize_t written;
- size_t len;
- int fd = -1;
- mode_t oldmask;
+ errno_t ret;
+ char *seuser;
+ char *mls_range;
+ char *ptr;
+ char *username;
+ char *username_final;
TALLOC_CTX *tmp_ctx;
- char *full_string = NULL;
- int enforce;
- errno_t ret = EOK;
- const char *username;
-
- 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;
}
- /* pam_selinux needs the username in the same format getpwnam() would
- * return it
- */
- username = sss_get_cased_name(tmp_ctx, orig_name, dom->case_preserve);
- if (username == NULL) {
- ret = ENOMEM;
- goto done;
- }
-
- path = selogin_path(tmp_ctx, username);
- if (path == NULL) {
+ /* Split seuser and mls_range */
+ seuser = talloc_strdup(tmp_ctx, seuser_mls_string);
+ if (seuser == NULL) {
ret = ENOMEM;
goto done;
}
- tmp_path = talloc_asprintf(tmp_ctx, "%sXXXXXX", path);
- if (tmp_path == NULL) {
- ret = ENOMEM;
- goto done;
+ ptr = seuser;
+ while (*ptr != ':' && *ptr != '\0') {
+ ptr++;
}
-
- 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;
+ if (*ptr == '\0') {
+ /* No mls_range specified */
+ mls_range = NULL;
+ } else {
+ *ptr = '\0'; /* split */
+ mls_range = ptr + 1;
}
- full_string = talloc_asprintf(tmp_ctx, "%s:%s", ALL_SERVICES, string);
- if (full_string == NULL) {
+ /* pam_selinux needs the username in the same format getpwnam() would
+ * return it
+ */
+ username = sss_get_cased_name(tmp_ctx, orig_name, dom->case_preserve);
+ if (username == 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 %zd bytes, wrote %zu",
- written, len);
- ret = EIO;
- goto done;
- }
-
- errno = 0;
- if (rename(tmp_path, path) < 0) {
- ret = errno;
+ if (dom->fqnames) {
+ username_final = talloc_asprintf(tmp_ctx, dom->names->fq_fmt,
+ username, dom->name);
+ if (username_final == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
} else {
- ret = EOK;
+ username_final = username;
}
- close(fd);
- fd = -1;
+ ret = set_seuser(username_final, seuser, mls_range);
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
*/