summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/providers/ipa/ipa_access.c309
-rw-r--r--src/providers/ipa/ipa_access.h3
2 files changed, 183 insertions, 129 deletions
diff --git a/src/providers/ipa/ipa_access.c b/src/providers/ipa/ipa_access.c
index 3fb819187..d1ba6c766 100644
--- a/src/providers/ipa/ipa_access.c
+++ b/src/providers/ipa/ipa_access.c
@@ -164,6 +164,144 @@ static errno_t hbac_sysdb_data_recv(TALLOC_CTX *mem_ctx,
return EOK;
}
+static errno_t set_local_and_remote_host_info(TALLOC_CTX *mem_ctx,
+ size_t host_count,
+ struct sysdb_attrs **host_list,
+ const char *local_hostname,
+ const char *remote_hostname,
+ struct hbac_host_info **local_hhi,
+ struct hbac_host_info **remote_hhi)
+
+{
+ size_t c;
+ int ret;
+ struct hbac_host_info *hhi;
+ struct ldb_message_element *el;
+ TALLOC_CTX *tmp_ctx;
+
+ if (local_hostname == NULL || *local_hostname == '\0') {
+ DEBUG(1, ("Missing local hostname.\n"));
+ ret = EINVAL;
+ goto done;
+ }
+
+ if (host_count == 0) {
+ DEBUG(1, ("No host data available.\n"));
+ ret = EINVAL;
+ goto done;
+ }
+
+ tmp_ctx = talloc_new(mem_ctx);
+ if (tmp_ctx == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ for (c = 0; c < host_count; c++) {
+ hhi = talloc_zero(tmp_ctx, struct hbac_host_info);
+ if (hhi == NULL) {
+ DEBUG(1, ("talloc_zero failed.\n"));
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = sysdb_attrs_get_el(host_list[c], SYSDB_ORIG_DN, &el);
+ if (ret != EOK) {
+ DEBUG(1, ("sysdb_attrs_get_el failed.\n"));
+ goto done;
+ }
+ if (el->num_values == 0) {
+ DEBUG(1, ("Missing OriginalDN.\n"));
+ ret = EINVAL;
+ goto done;
+ }
+ DEBUG(9, ("OriginalDN: [%.*s].\n", el->values[0].length,
+ (char *)el->values[0].data));
+ hhi->dn = talloc_strndup(hhi, (char *)el->values[0].data,
+ el->values[0].length);
+ if (hhi->dn == NULL) {
+ DEBUG(1, ("talloc_strndup failed.\n"));
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = sysdb_attrs_get_el(host_list[c], IPA_HOST_SERVERHOSTNAME, &el);
+ if (ret != EOK) {
+ DEBUG(1, ("sysdb_attrs_get_el failed.\n"));
+ goto done;
+ }
+ if (el->num_values == 0) {
+ DEBUG(1, ("Missing ServerHostName.\n"));
+ ret = EINVAL;
+ goto done;
+ }
+ DEBUG(9, ("ServerHostName: [%.*s].\n", el->values[0].length,
+ (char *)el->values[0].data));
+ hhi->serverhostname = talloc_strndup(hhi, (char *)el->values[0].data,
+ el->values[0].length);
+ if (hhi->serverhostname == NULL) {
+ DEBUG(1, ("talloc_strndup failed.\n"));
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = sysdb_attrs_get_el(host_list[c], IPA_HOST_FQDN, &el);
+ if (ret != EOK) {
+ DEBUG(1, ("sysdb_attrs_get_el failed.\n"));
+ goto done;
+ }
+ if (el->num_values == 0) {
+ DEBUG(1, ("Missing FQDN.\n"));
+ ret = EINVAL;
+ goto done;
+ }
+ DEBUG(9, ("FQDN: [%.*s].\n", el->values[0].length,
+ (char *)el->values[0].data));
+ hhi->fqdn = talloc_strndup(hhi, (char *)el->values[0].data,
+ el->values[0].length);
+ if (hhi->fqdn == NULL) {
+ DEBUG(1, ("talloc_strndup failed.\n"));
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = sysdb_attrs_get_string_array(host_list[c], SYSDB_ORIG_MEMBEROF,
+ hhi, &hhi->memberof);
+ if (ret != EOK) {
+ if (ret != ENOENT) {
+ DEBUG(1, ("sysdb_attrs_get_string_array failed.\n"));
+ goto done;
+ }
+
+ hhi->memberof = talloc_array(hhi, const char *, 1);
+ if (hhi->memberof == NULL) {
+ DEBUG(1, ("talloc_array failed.\n"));
+ ret = ENOMEM;
+ goto done;
+ }
+ hhi->memberof[0] = NULL;
+ }
+
+ if (strcmp(hhi->fqdn, local_hostname) == 0 ||
+ strcmp(hhi->serverhostname, local_hostname) == 0) {
+ *local_hhi = talloc_steal(mem_ctx, hhi);
+ }
+
+ if (remote_hostname != NULL && *remote_hostname != '\0') {
+ if (strcmp(hhi->fqdn, remote_hostname) == 0 ||
+ strcmp(hhi->serverhostname, remote_hostname) == 0) {
+ *remote_hhi = talloc_steal(mem_ctx, hhi);
+ }
+ }
+ }
+
+ ret = EOK;
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
static void ipa_access_reply(struct hbac_ctx *hbac_ctx, int pam_status)
{
struct be_req *be_req = hbac_ctx->be_req;
@@ -607,7 +745,7 @@ static struct tevent_req *hbac_get_host_info_send(TALLOC_CTX *memctx,
goto fail;
}
- state->host_attrs = talloc_array(state, const char *, 7);
+ state->host_attrs = talloc_array(state, const char *, 8);
if (state->host_attrs == NULL) {
DEBUG(1, ("Failed to allocate host attribute list.\n"));
ret = ENOMEM;
@@ -619,7 +757,8 @@ static struct tevent_req *hbac_get_host_info_send(TALLOC_CTX *memctx,
state->host_attrs[3] = "objectClass";
state->host_attrs[4] = SYSDB_ORIG_DN;
state->host_attrs[5] = SYSDB_ORIG_MEMBEROF;
- state->host_attrs[6] = NULL;
+ state->host_attrs[6] = IPA_UNIQUE_ID;
+ state->host_attrs[7] = NULL;
if (hbac_ctx_is_offline(state->hbac_ctx)) {
ret = hbac_sysdb_data_recv(state, hbac_ctx_sysdb(state->hbac_ctx),
@@ -628,7 +767,7 @@ static struct tevent_req *hbac_get_host_info_send(TALLOC_CTX *memctx,
state->host_attrs,
&state->host_reply_count,
&state->host_reply_list);
- if (ret) {
+ if (ret != EOK) {
DEBUG(1, ("hbac_sysdb_data_recv failed.\n"));
goto fail;
}
@@ -687,15 +826,27 @@ static void hbac_get_host_memberof_done(struct tevent_req *subreq)
hbac_get_host_memberof(req, false);
}
-static bool hbac_is_known_host(struct hbac_host_info **hhi, const char *fqdn)
+static bool hbac_is_known_host(size_t host_reply_count,
+ struct sysdb_attrs **host_reply_list,
+ const char *fqdn)
{
- if (!hhi || !fqdn) {
+ int i;
+ const char *new_fqdn;
+ int ret;
+
+ if (!host_reply_list || !fqdn) {
return false;
}
- int i;
- for (i = 0; hhi[i] != NULL; i++) {
- if(strcmp(hhi[i]->fqdn, fqdn) == 0) {
+ for (i = 0; i < host_reply_count; i++) {
+ ret = sysdb_attrs_get_string(host_reply_list[i], IPA_HOST_FQDN,
+ &new_fqdn);
+ if (ret != 0) {
+ DEBUG(1, ("missing FQDN in new HBAC host record\n"));
+ continue;
+ }
+
+ if(strcmp(new_fqdn, fqdn) == 0) {
return true;
}
}
@@ -713,7 +864,6 @@ static void hbac_get_host_memberof(struct tevent_req *req, bool offline)
int ret;
int i;
struct ldb_message_element *el;
- struct hbac_host_info **hhi;
char *object_name;
const char *fqdn_attrs[] = { IPA_HOST_FQDN, NULL };
const char *fqdn;
@@ -721,104 +871,6 @@ static void hbac_get_host_memberof(struct tevent_req *req, bool offline)
size_t cached_count;
struct ldb_message **cached_entries = 0;
- hhi = talloc_array(state, struct hbac_host_info *, state->host_reply_count + 1);
- if (hhi == NULL) {
- DEBUG(1, ("talloc_array failed.\n"));
- ret = ENOMEM;
- goto fail;
- }
- memset(hhi, 0,
- sizeof(struct hbac_host_info *) * (state->host_reply_count + 1));
-
- if (state->host_reply_count == 0) {
- DEBUG(1, ("No hosts not found in IPA server.\n"));
- }
-
- for (i = 0; i < state->host_reply_count; i++) {
- hhi[i] = talloc_zero(hhi, struct hbac_host_info);
- if (hhi[i] == NULL) {
- ret = ENOMEM;
- goto fail;
- }
-
- ret = sysdb_attrs_get_el(state->host_reply_list[i], SYSDB_ORIG_DN, &el);
- if (ret != EOK) {
- DEBUG(1, ("sysdb_attrs_get_el failed.\n"));
- goto fail;
- }
- if (el->num_values == 0) {
- ret = EINVAL;
- goto fail;
- }
- DEBUG(9, ("OriginalDN: [%.*s].\n", el->values[0].length,
- (char *)el->values[0].data));
- hhi[i]->dn = talloc_strndup(hhi, (char *)el->values[0].data,
- el->values[0].length);
- if (hhi[i]->dn == NULL) {
- ret = ENOMEM;
- goto fail;
- }
-
- ret = sysdb_attrs_get_el(state->host_reply_list[i],
- IPA_HOST_SERVERHOSTNAME, &el);
- if (ret != EOK) {
- DEBUG(1, ("sysdb_attrs_get_el failed.\n"));
- goto fail;
- }
- if (el->num_values == 0) {
- ret = EINVAL;
- goto fail;
- }
- DEBUG(9, ("ServerHostName: [%.*s].\n", el->values[0].length,
- (char *)el->values[0].data));
- hhi[i]->serverhostname = talloc_strndup(hhi, (char *)el->values[0].data,
- el->values[0].length);
- if (hhi[i]->serverhostname == NULL) {
- ret = ENOMEM;
- goto fail;
- }
-
- ret = sysdb_attrs_get_el(state->host_reply_list[i],
- IPA_HOST_FQDN, &el);
- if (ret != EOK) {
- DEBUG(1, ("sysdb_attrs_get_el failed.\n"));
- goto fail;
- }
- if (el->num_values == 0) {
- ret = EINVAL;
- goto fail;
- }
- DEBUG(9, ("FQDN: [%.*s].\n", el->values[0].length,
- (char *)el->values[0].data));
- hhi[i]->fqdn = talloc_strndup(hhi, (char *)el->values[0].data,
- el->values[0].length);
- if (hhi[i]->fqdn == NULL) {
- ret = ENOMEM;
- goto fail;
- }
-
- ret = sysdb_attrs_get_string_array(state->host_reply_list[i],
- offline ? SYSDB_ORIG_MEMBEROF :
- IPA_MEMBEROF,
- hhi, &(hhi[i]->memberof));
- if (ret != EOK) {
- if (ret != ENOENT) {
- DEBUG(1, ("sysdb_attrs_get_string_array failed.\n"));
- goto fail;
- }
-
- hhi[i]->memberof = talloc_array(hhi, const char *, 1);
- if (hhi[i]->memberof == NULL) {
- DEBUG(1, ("talloc_array failed.\n"));
- ret = ENOMEM;
- goto fail;
- }
- hhi[i]->memberof[0] = NULL;
- }
- }
-
- state->hbac_host_info = hhi;
-
if (offline) {
tevent_req_done(req);
return;
@@ -854,7 +906,8 @@ static void hbac_get_host_memberof(struct tevent_req *req, bool offline)
fqdn = ldb_msg_find_attr_as_string(cached_entries[i], IPA_HOST_FQDN, NULL);
if (!fqdn) {
DEBUG(1, ("missing FQDN in cached HBAC host record\n"));
- } else if (hbac_is_known_host(hhi, fqdn)) {
+ } else if (hbac_is_known_host(state->host_reply_count,
+ state->host_reply_list, fqdn)) {
continue;
} else {
DEBUG(9, ("deleting obsolete HBAC host record for %s\n", fqdn));
@@ -922,14 +975,21 @@ fail:
}
static int hbac_get_host_info_recv(struct tevent_req *req, TALLOC_CTX *memctx,
- struct hbac_host_info ***hhi)
+ size_t *hbac_hosts_count,
+ struct sysdb_attrs ***hbac_hosts_list)
{
+ size_t c;
struct hbac_get_host_info_state *state = tevent_req_data(req,
struct hbac_get_host_info_state);
TEVENT_REQ_RETURN_ON_ERROR(req);
- *hhi = talloc_steal(memctx, state->hbac_host_info);
+ *hbac_hosts_count = state->host_reply_count;
+ *hbac_hosts_list = talloc_steal(memctx, state->host_reply_list);
+ for (c = 0; c < state->host_reply_count; c++) {
+ talloc_steal(memctx, state->host_reply_list[c]);
+ }
+
return EOK;
}
@@ -1910,10 +1970,9 @@ static void hbac_get_host_info_done(struct tevent_req *req)
int pam_status = PAM_SYSTEM_ERR;
const char *ipa_hostname;
struct hbac_host_info *local_hhi = NULL;
- int i;
- talloc_zfree(hbac_ctx->hbac_host_info);
- ret = hbac_get_host_info_recv(req, hbac_ctx, &hbac_ctx->hbac_host_info);
+ ret = hbac_get_host_info_recv(req, hbac_ctx, &hbac_ctx->hbac_hosts_count,
+ &hbac_ctx->hbac_hosts_list);
talloc_zfree(req);
if (!hbac_check_step_result(hbac_ctx, ret)) {
@@ -1926,21 +1985,15 @@ static void hbac_get_host_info_done(struct tevent_req *req)
goto fail;
}
- for (i = 0; hbac_ctx->hbac_host_info[i] != NULL; i++) {
- if (strcmp(hbac_ctx->hbac_host_info[i]->fqdn, ipa_hostname) == 0 ||
- strcmp(hbac_ctx->hbac_host_info[i]->serverhostname,
- ipa_hostname) == 0) {
- local_hhi = hbac_ctx->hbac_host_info[i];
- }
- if (hbac_ctx->pd->rhost != NULL && *hbac_ctx->pd->rhost != '\0') {
- if (strcmp(hbac_ctx->hbac_host_info[i]->fqdn,
- hbac_ctx->pd->rhost) == 0 ||
- strcmp(hbac_ctx->hbac_host_info[i]->serverhostname,
- hbac_ctx->pd->rhost) == 0) {
- hbac_ctx->remote_hhi = hbac_ctx->hbac_host_info[i];
- }
- }
- }
+ ret = set_local_and_remote_host_info(hbac_ctx, hbac_ctx->hbac_hosts_count,
+ hbac_ctx->hbac_hosts_list, ipa_hostname,
+ hbac_ctx->pd->rhost, &local_hhi,
+ &hbac_ctx->remote_hhi);
+ if (ret != EOK) {
+ DEBUG(1, ("set_local_and_remote_host_info failed.\n"));
+ goto fail;
+ }
+
if (local_hhi == NULL) {
DEBUG(1, ("Missing host info for [%s].\n", ipa_hostname));
pam_status = PAM_PERM_DENIED;
diff --git a/src/providers/ipa/ipa_access.h b/src/providers/ipa/ipa_access.h
index b43c712f1..ba5670082 100644
--- a/src/providers/ipa/ipa_access.h
+++ b/src/providers/ipa/ipa_access.h
@@ -52,7 +52,8 @@ struct hbac_ctx {
struct time_rules_ctx *tr_ctx;
struct be_req *be_req;
struct pam_data *pd;
- struct hbac_host_info **hbac_host_info;
+ struct sysdb_attrs **hbac_hosts_list;
+ size_t hbac_hosts_count;
struct hbac_host_info *remote_hhi;
struct sysdb_attrs **hbac_rule_list;
size_t hbac_rule_count;