summaryrefslogtreecommitdiff
path: root/src/providers/ipa
diff options
context:
space:
mode:
authorJan Zeleny <jzeleny@redhat.com>2012-07-27 04:28:24 -0400
committerJakub Hrozek <jhrozek@redhat.com>2012-07-31 14:11:51 +0200
commit679a0abefcb838484a7e7278056da0f2524963c1 (patch)
treeffbf9d0afc19df2de91c53dd2370f5c54241bb09 /src/providers/ipa
parent95d170adf00b15dd9863a82eb22837409ab69bf0 (diff)
downloadsssd-679a0abefcb838484a7e7278056da0f2524963c1.tar.gz
sssd-679a0abefcb838484a7e7278056da0f2524963c1.tar.bz2
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')
-rw-r--r--src/providers/ipa/ipa_selinux.c66
1 files changed, 55 insertions, 11 deletions
diff --git a/src/providers/ipa/ipa_selinux.c b/src/providers/ipa/ipa_selinux.c
index 0a2dd083..b5a84269 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,