summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2012-08-05 22:37:09 +0200
committerJakub Hrozek <jhrozek@redhat.com>2012-08-16 13:31:03 +0200
commitf004e23af14fe020d81b8f97f30b448105b79606 (patch)
treee39023d6237dabf0643f3ea6176f0bb354e15c92
parent79402313dc0d7f854b4334dd427e03b7baf0b9db (diff)
downloadsssd_unused-f004e23af14fe020d81b8f97f30b448105b79606.zip
sssd_unused-f004e23af14fe020d81b8f97f30b448105b79606.tar.gz
sssd_unused-f004e23af14fe020d81b8f97f30b448105b79606.tar.xz
Only create the SELinux login file if there are mappings on the server
https://fedorahosted.org/sssd/ticket/1455 In case there are no rules on the IPA server, we must simply avoid generating the login file. That would make us fall back to the system-wide default defined in /etc/selinux/targeted/seusers. The IPA default must be only used if there *are* rules on the server, but none matches.
-rw-r--r--src/db/sysdb_selinux.c7
-rw-r--r--src/responder/pam/pamsrv_cmd.c122
2 files changed, 78 insertions, 51 deletions
diff --git a/src/db/sysdb_selinux.c b/src/db/sysdb_selinux.c
index eaf07b5..9764895 100644
--- a/src/db/sysdb_selinux.c
+++ b/src/db/sysdb_selinux.c
@@ -364,7 +364,7 @@ errno_t sysdb_search_selinux_usermap_by_username(TALLOC_CTX *mem_ctx,
struct ldb_message **msgs = NULL;
struct sysdb_attrs *user;
struct sysdb_attrs *tmp_attrs;
- struct ldb_message **usermaps;
+ struct ldb_message **usermaps = NULL;
struct sss_domain_info *domain;
struct ldb_dn *basedn;
size_t msgs_count = 0;
@@ -462,11 +462,6 @@ errno_t sysdb_search_selinux_usermap_by_username(TALLOC_CTX *mem_ctx,
}
}
- if (usermaps[0] == NULL) {
- ret = ENOENT;
- goto done;
- }
-
*_usermaps = talloc_steal(mem_ctx, usermaps);
ret = EOK;
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index 944845a..238b4fa 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -359,8 +359,10 @@ fail:
#ifdef HAVE_SELINUX
#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_string(const char *username, char *string)
+static errno_t write_selinux_login_file(const char *username, char *string)
{
char *path = NULL;
char *tmp_path = NULL;
@@ -383,8 +385,7 @@ static errno_t write_selinux_string(const char *username, char *string)
return ENOMEM;
}
- path = talloc_asprintf(tmp_ctx, "%s/logins/%s", selinux_policy_root(),
- username);
+ path = selogin_path(tmp_ctx, username);
if (path == NULL) {
ret = ENOMEM;
goto done;
@@ -452,7 +453,33 @@ done:
return ret;
}
-static errno_t get_selinux_string(struct pam_auth_req *preq)
+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;
@@ -464,7 +491,7 @@ static errno_t get_selinux_string(struct pam_auth_req *preq)
const char *tmp_str;
char *order = NULL;
char **order_array;
- errno_t ret;
+ errno_t ret, err;
int i, j;
size_t order_count;
size_t len = 0;
@@ -550,53 +577,58 @@ static errno_t get_selinux_string(struct pam_auth_req *preq)
&usermaps);
if (ret != EOK && ret != ENOENT) {
goto done;
+ } else if (ret == ENOENT) {
+ DEBUG(SSSDBG_TRACE_FUNC, ("No maps defined on the server\n"));
+ ret = EOK;
+ goto done;
}
- if (ret == ENOENT) {
- DEBUG(SSSDBG_TRACE_FUNC, ("No user maps found, using default!"));
- file_content = talloc_strdup(tmp_ctx, default_user);
- if (file_content == NULL) {
- ret = ENOMEM;
- goto done;
- }
- } else {
- /* 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;
+ /* 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;
}
}
}
- if (file_content) {
- ret = write_selinux_string(pd->user, file_content);
- }
-
+ 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;
}
@@ -802,7 +834,7 @@ static void pam_reply(struct pam_auth_req *preq)
pd->pam_status == PAM_SUCCESS) {
/* Try to fetch data from sysdb
* (auth already passed -> we should have them) */
- ret = get_selinux_string(preq);
+ ret = process_selinux_mappings(preq);
if (ret != EOK) {
pd->pam_status = PAM_SYSTEM_ERR;
}