diff options
author | Jan Zeleny <jzeleny@redhat.com> | 2012-07-27 04:28:24 -0400 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2012-07-31 14:11:51 +0200 |
commit | 679a0abefcb838484a7e7278056da0f2524963c1 (patch) | |
tree | ffbf9d0afc19df2de91c53dd2370f5c54241bb09 /src/providers/ipa/ipa_selinux.c | |
parent | 95d170adf00b15dd9863a82eb22837409ab69bf0 (diff) | |
download | sssd-679a0abefcb838484a7e7278056da0f2524963c1.tar.gz sssd-679a0abefcb838484a7e7278056da0f2524963c1.tar.xz sssd-679a0abefcb838484a7e7278056da0f2524963c1.zip |
Support fetching of host from sysdb in SELinux code
The host record will be fetched if HBAC is used as access provider since
the record is already downloaded and it can be trusted to be valid.
Diffstat (limited to 'src/providers/ipa/ipa_selinux.c')
-rw-r--r-- | src/providers/ipa/ipa_selinux.c | 66 |
1 files changed, 55 insertions, 11 deletions
diff --git a/src/providers/ipa/ipa_selinux.c b/src/providers/ipa/ipa_selinux.c index 0a2dd0830..b5a84269e 100644 --- a/src/providers/ipa/ipa_selinux.c +++ b/src/providers/ipa/ipa_selinux.c @@ -245,6 +245,17 @@ static void ipa_get_selinux_connect_done(struct tevent_req *subreq) struct ipa_id_ctx *id_ctx = state->selinux_ctx->id_ctx; struct be_ctx *bctx = state->be_req->be_ctx; + const char *access_name; + const char *selinux_name; + struct ldb_dn *host_dn; + const char *attrs[] = { SYSDB_ORIG_DN, + SYSDB_ORIG_MEMBEROF, + NULL }; + size_t count; + struct ldb_message **msgs; + struct sysdb_attrs **hosts; + struct sss_domain_info *domain; + ret = sdap_id_op_connect_recv(subreq, &dp_error); talloc_zfree(subreq); @@ -260,10 +271,42 @@ static void ipa_get_selinux_connect_done(struct tevent_req *subreq) state->hostname = dp_opt_get_string(state->selinux_ctx->id_ctx->ipa_options->basic, IPA_HOSTNAME); - /* FIXME: detect if HBAC is configured - * - if yes, we can skip host retrieval and get it directly from sysdb - * and shortcut to ipa_get_config_step() - */ + access_name = state->be_req->be_ctx->bet_info[BET_ACCESS].mod_name; + selinux_name = state->be_req->be_ctx->bet_info[BET_SELINUX].mod_name; + if (strcasecmp(access_name, selinux_name) == 0) { + domain = sysdb_ctx_get_domain(bctx->sysdb); + host_dn = sysdb_custom_dn(bctx->sysdb, state, domain->name, + state->hostname, HBAC_HOSTS_SUBDIR); + if (host_dn == NULL) { + ret = ENOMEM; + goto fail; + } + + /* Look up the host to get its originalMemberOf entries */ + ret = sysdb_search_entry(state, bctx->sysdb, host_dn, + LDB_SCOPE_BASE, NULL, + attrs, &count, &msgs); + if (ret == ENOENT || count == 0) { + /* We need to query the server */ + goto server; + } else if (ret != EOK) { + goto fail; + } else if (count > 1) { + DEBUG(SSSDBG_OP_FAILURE, ("More than one result for a BASE search!\n")); + ret = EIO; + goto fail; + } + + ret = sysdb_msg2attrs(state, count, msgs, &hosts); + if (ret != EOK) { + goto fail; + } + + state->host = hosts[0]; + return ipa_get_config_step(req); + } + +server: subreq = ipa_host_info_send(state, bctx->ev, bctx->sysdb, sdap_id_op_handle(state->op), id_ctx->sdap_id_ctx->opts, @@ -291,7 +334,6 @@ static void ipa_get_selinux_hosts_done(struct tevent_req *subreq) struct tevent_req); struct ipa_get_selinux_state *state = tevent_req_data(req, struct ipa_get_selinux_state); - struct be_ctx *bctx = state->be_req->be_ctx; size_t host_count, hostgroup_count; struct sysdb_attrs **hostgroups; struct sysdb_attrs **host; @@ -304,12 +346,6 @@ static void ipa_get_selinux_hosts_done(struct tevent_req *subreq) } state->host = host[0]; - ret = sss_selinux_extract_user(state, bctx->sysdb, - state->pd->user, &state->user); - if (ret != EOK) { - goto done; - } - return ipa_get_config_step(req); done: @@ -320,6 +356,7 @@ done: static void ipa_get_config_step(struct tevent_req *req) { + errno_t ret; const char *domain; struct tevent_req *subreq; struct ipa_get_selinux_state *state = tevent_req_data(req, @@ -327,6 +364,13 @@ static void ipa_get_config_step(struct tevent_req *req) struct be_ctx *bctx = state->be_req->be_ctx; struct ipa_id_ctx *id_ctx = state->selinux_ctx->id_ctx; + ret = sss_selinux_extract_user(state, bctx->sysdb, + state->pd->user, &state->user); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + domain = dp_opt_get_string(state->selinux_ctx->id_ctx->ipa_options->basic, IPA_KRB5_REALM); subreq = ipa_get_config_send(state, bctx->ev, |