Hi, I realized that although all attributes are saved the offline support the for ipa_access module was not present. These two patches should fix it.
0001 adds a general search request for custom attributes 0002 adds sysdb calls to ipa_access if the provider is offline bye, Sumit
From c28fed110190b87e1dde56e42f74dfabc7925bc1 Mon Sep 17 00:00:00 2001 From: Sumit Bose <sb...@redhat.com> Date: Mon, 30 Nov 2009 10:48:02 +0100 Subject: [PATCH 1/2] Add sysdb_search_custom request --- server/db/sysdb.h | 11 +++- server/db/sysdb_ops.c | 97 ++++++++++++++++++++++--- server/tests/sysdb-tests.c | 172 ++++++++++++++++++++++++++++---------------- 3 files changed, 206 insertions(+), 74 deletions(-) diff --git a/server/db/sysdb.h b/server/db/sysdb.h index d9f224c..086c837 100644 --- a/server/db/sysdb.h +++ b/server/db/sysdb.h @@ -538,6 +538,14 @@ struct tevent_req *sysdb_store_custom_send(TALLOC_CTX *mem_ctx, struct sysdb_attrs *attrs); int sysdb_store_custom_recv(struct tevent_req *req); +struct tevent_req *sysdb_search_custom_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sysdb_ctx *sysdb, + struct sysdb_handle *handle, + struct sss_domain_info *domain, + const char *filter, + const char *subtree_name, + const char **attrs); struct tevent_req *sysdb_search_custom_by_name_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sysdb_ctx *sysdb, @@ -548,7 +556,8 @@ struct tevent_req *sysdb_search_custom_by_name_send(TALLOC_CTX *mem_ctx, const char **attrs); int sysdb_search_custom_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - struct ldb_message **msg); + size_t *msgs_count, + struct ldb_message ***msg); struct tevent_req *sysdb_delete_custom_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, diff --git a/server/db/sysdb_ops.c b/server/db/sysdb_ops.c index da53fd3..c237473 100644 --- a/server/db/sysdb_ops.c +++ b/server/db/sysdb_ops.c @@ -3395,7 +3395,12 @@ struct tevent_req *sysdb_check_handle_send(TALLOC_CTX *mem_ctx, if (handle != NULL) { state->handle = talloc_memdup(state, handle, sizeof(struct sysdb_handle)); - tevent_req_done(req); + if (state->handle == NULL) { + DEBUG(1, ("talloc_memdup failed.\n")); + tevent_req_error(req, ENOMEM); + } else { + tevent_req_done(req); + } tevent_req_post(req, ev); return req; } @@ -3457,6 +3462,7 @@ struct sysdb_search_custom_state { const char **attrs; const char *filter; int scope; + bool expect_not_more_than_one; size_t msgs_count; struct ldb_message **msgs; @@ -3465,6 +3471,70 @@ struct sysdb_search_custom_state { static void sysdb_search_custom_check_handle_done(struct tevent_req *subreq); static void sysdb_search_custom_done(struct tevent_req *subreq); +struct tevent_req *sysdb_search_custom_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sysdb_ctx *sysdb, + struct sysdb_handle *handle, + struct sss_domain_info *domain, + const char *filter, + const char *subtree_name, + const char **attrs) +{ + struct tevent_req *req, *subreq; + struct sysdb_search_custom_state *state; + int ret; + + if (sysdb == NULL && handle == NULL) return NULL; + + if (filter == NULL || subtree_name == NULL) return NULL; + + req = tevent_req_create(mem_ctx, &state, struct sysdb_search_custom_state); + if (req == NULL) { + DEBUG(1, ("tevent_req_create failed.\n")); + return NULL; + } + + state->ev = ev; + state->handle = handle; + state->attrs = attrs; + state->filter = filter; + state->scope = LDB_SCOPE_SUBTREE; + state->expect_not_more_than_one = false; + state->msgs_count = 0; + state->msgs = NULL; + + if (sysdb == NULL) { + sysdb = handle->ctx; + } + state->basedn = sysdb_custom_subtree_dn(sysdb, state, domain->name, + subtree_name); + if (state->basedn == NULL) { + DEBUG(1, ("sysdb_custom_subtree_dn failed.\n")); + ret = ENOMEM; + goto fail; + } + if (!ldb_dn_validate(state->basedn)) { + DEBUG(1, ("Failed to create DN.\n")); + ret = EINVAL; + goto fail; + } + + subreq = sysdb_check_handle_send(state, state->ev, sysdb, state->handle); + if (!subreq) { + DEBUG(1, ("sysdb_check_handle_send failed.\n")); + ret = ENOMEM; + goto fail; + } + tevent_req_set_callback(subreq, sysdb_search_custom_check_handle_done, req); + + return req; + +fail: + tevent_req_error(req, ret); + tevent_req_post(req, ev); + return req; +} + struct tevent_req *sysdb_search_custom_by_name_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sysdb_ctx *sysdb, @@ -3493,6 +3563,7 @@ struct tevent_req *sysdb_search_custom_by_name_send(TALLOC_CTX *mem_ctx, state->attrs = attrs; state->filter = NULL; state->scope = LDB_SCOPE_BASE; + state->expect_not_more_than_one = true; state->msgs_count = 0; state->msgs = NULL; @@ -3571,24 +3642,27 @@ static void sysdb_search_custom_done(struct tevent_req *subreq) return; } + if (state->expect_not_more_than_one && state->msgs_count > 1) { + DEBUG(1, ("More than one result found.\n")); + tevent_req_error(req, EFAULT); + return; + } + tevent_req_done(req); } int sysdb_search_custom_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - struct ldb_message **msg) + size_t *msgs_count, + struct ldb_message ***msgs) { struct sysdb_search_custom_state *state = tevent_req_data(req, struct sysdb_search_custom_state); TEVENT_REQ_RETURN_ON_ERROR(req); - if (state->msgs_count > 1) { - DEBUG(1, ("More than one result found.\n")); - return EFAULT; - } - - *msg = talloc_move(mem_ctx, &state->msgs[0]); + *msgs_count = state->msgs_count; + *msgs = talloc_move(mem_ctx, &state->msgs); return EOK; } @@ -3690,13 +3764,14 @@ static void sysdb_store_custom_check_done(struct tevent_req *subreq) struct sysdb_store_custom_state); int ret; int i; - struct ldb_message *resp; + size_t resp_count = 0; + struct ldb_message **resp; struct ldb_message *msg; struct ldb_request *ldbreq; struct ldb_message_element *el; bool add_object = false; - ret = sysdb_search_custom_recv(subreq, state, &resp); + ret = sysdb_search_custom_recv(subreq, state, &resp_count, &resp); talloc_zfree(subreq); if (ret != EOK && ret != ENOENT) { tevent_req_error(req, ret); @@ -3727,7 +3802,7 @@ static void sysdb_store_custom_check_done(struct tevent_req *subreq) if (add_object) { msg->elements[i].flags = LDB_FLAG_MOD_ADD; } else { - el = ldb_msg_find_element(resp, state->attrs->a[i].name); + el = ldb_msg_find_element(resp[0], state->attrs->a[i].name); if (el == NULL) { msg->elements[i].flags = LDB_FLAG_MOD_ADD; } else { diff --git a/server/tests/sysdb-tests.c b/server/tests/sysdb-tests.c index d4f0e2f..3bf6ddc 100644 --- a/server/tests/sysdb-tests.c +++ b/server/tests/sysdb-tests.c @@ -879,68 +879,10 @@ static void test_store_custom_done(struct tevent_req *subreq) return test_return(data, ret); } -static void test_search_custom_by_name_done(struct tevent_req *subreq) +static void test_search_custom_done(struct tevent_req *req) { - struct test_data *data = tevent_req_callback_data(subreq, struct test_data); - int ret; - - ret = sysdb_search_custom_recv(subreq, data, &data->msg); - talloc_zfree(subreq); - if (ret != EOK) { - data->error = ret; - goto done; - } - - fail_unless(data->msg->num_elements == 1, - "Wrong number of results, expected [1] got [%d]", - data->msg->num_elements); - fail_unless(strcmp(data->msg->elements[0].name, TEST_ATTR_NAME) == 0, - "Wrong attribute name"); - fail_unless(data->msg->elements[0].num_values == 1, - "Wrong number of attribute values"); - fail_unless(strncmp((const char *)data->msg->elements[0].values[0].data, - TEST_ATTR_VALUE, data->msg->elements[0].values[0].length) == 0, - "Wrong attribute value"); - -done: - data->finished = true; - return; -} - -static void test_search_custom_update_done(struct tevent_req *subreq) -{ - struct test_data *data = tevent_req_callback_data(subreq, struct test_data); - int ret; - struct ldb_message_element *el; - - ret = sysdb_search_custom_recv(subreq, data, &data->msg); - talloc_zfree(subreq); - if (ret != EOK) { - data->error = ret; - goto done; - } - - fail_unless(data->msg->num_elements == 2, - "Wrong number of results, expected [1] got [%d]", - data->msg->num_elements); - - el = ldb_msg_find_element(data->msg, TEST_ATTR_NAME); - fail_unless(el != NULL, "Attribute [%s] not found", TEST_ATTR_NAME); - fail_unless(el->num_values == 1, "Wrong number ([%d] instead of 1) " - "of attribute values for [%s]", el->num_values, TEST_ATTR_NAME); - fail_unless(strncmp((const char *) el->values[0].data, TEST_ATTR_UPDATE_VALUE, - el->values[0].length) == 0, - "Wrong attribute value"); - - el = ldb_msg_find_element(data->msg, TEST_ATTR_ADD_NAME); - fail_unless(el != NULL, "Attribute [%s] not found", TEST_ATTR_ADD_NAME); - fail_unless(el->num_values == 1, "Wrong number ([%d] instead of 1) " - "of attribute values for [%s]", el->num_values, TEST_ATTR_ADD_NAME); - fail_unless(strncmp((const char *) el->values[0].data, TEST_ATTR_ADD_VALUE, - el->values[0].length) == 0, - "Wrong attribute value"); + struct test_data *data = tevent_req_callback_data(req, struct test_data); -done: data->finished = true; return; } @@ -1993,9 +1935,29 @@ START_TEST (test_sysdb_search_custom_by_name) } if (ret == EOK) { - tevent_req_set_callback(subreq, test_search_custom_by_name_done, data); + tevent_req_set_callback(subreq, test_search_custom_done, data); ret = test_loop(data); + + ret = sysdb_search_custom_recv(subreq, data, &data->msgs_count, + &data->msgs); + talloc_zfree(subreq); + fail_unless(ret == EOK, "sysdb_search_custom_by_name_send failed"); + + fail_unless(data->msgs_count == 1, + "Wrong number of objects, exptected [1] got [%d]", + data->msgs_count); + fail_unless(data->msgs[0]->num_elements == 1, + "Wrong number of results, expected [1] got [%d]", + data->msgs[0]->num_elements); + fail_unless(strcmp(data->msgs[0]->elements[0].name, TEST_ATTR_NAME) == 0, + "Wrong attribute name"); + fail_unless(data->msgs[0]->elements[0].num_values == 1, + "Wrong number of attribute values"); + fail_unless(strncmp((const char *)data->msgs[0]->elements[0].values[0].data, + TEST_ATTR_VALUE, + data->msgs[0]->elements[0].values[0].length) == 0, + "Wrong attribute value"); } fail_if(ret != EOK, "Could not search custom object"); @@ -2066,6 +2028,7 @@ START_TEST (test_sysdb_search_custom_update) struct tevent_req *subreq; int ret; char *object_name; + struct ldb_message_element *el; /* Setup */ ret = setup_sysdb_tests(&test_ctx); @@ -2098,9 +2061,93 @@ START_TEST (test_sysdb_search_custom_update) } if (ret == EOK) { - tevent_req_set_callback(subreq, test_search_custom_update_done, data); + tevent_req_set_callback(subreq, test_search_custom_done, data); + + ret = test_loop(data); + + ret = sysdb_search_custom_recv(subreq, data, &data->msgs_count, + &data->msgs); + talloc_zfree(subreq); + fail_unless(ret == EOK, "sysdb_search_custom_by_name_send failed"); + + fail_unless(data->msgs_count == 1, + "Wrong number of objects, exptected [1] got [%d]", + data->msgs_count); + fail_unless(data->msgs[0]->num_elements == 2, + "Wrong number of results, expected [2] got [%d]", + data->msgs[0]->num_elements); + + el = ldb_msg_find_element(data->msgs[0], TEST_ATTR_NAME); + fail_unless(el != NULL, "Attribute [%s] not found", TEST_ATTR_NAME); + fail_unless(el->num_values == 1, "Wrong number ([%d] instead of 1) " + "of attribute values for [%s]", el->num_values, TEST_ATTR_NAME); + fail_unless(strncmp((const char *) el->values[0].data, TEST_ATTR_UPDATE_VALUE, + el->values[0].length) == 0, + "Wrong attribute value"); + + el = ldb_msg_find_element(data->msgs[0], TEST_ATTR_ADD_NAME); + fail_unless(el != NULL, "Attribute [%s] not found", TEST_ATTR_ADD_NAME); + fail_unless(el->num_values == 1, "Wrong number ([%d] instead of 1) " + "of attribute values for [%s]", el->num_values, TEST_ATTR_ADD_NAME); + fail_unless(strncmp((const char *) el->values[0].data, TEST_ATTR_ADD_VALUE, + el->values[0].length) == 0, + "Wrong attribute value"); + + } + + fail_if(ret != EOK, "Could not search custom object"); + talloc_free(test_ctx); +} +END_TEST + +START_TEST (test_sysdb_search_custom) +{ + struct sysdb_test_ctx *test_ctx; + struct test_data *data; + struct tevent_req *subreq; + int ret; + const char *filter = "(distinguishedName=*)"; + + /* Setup */ + ret = setup_sysdb_tests(&test_ctx); + if (ret != EOK) { + fail("Could not set up the test"); + return; + } + + data = talloc_zero(test_ctx, struct test_data); + fail_unless(data != NULL, "talloc_zero failed"); + data->ctx = test_ctx; + data->ev = test_ctx->ev; + data->attrlist = talloc_array(test_ctx, const char *, 3); + fail_unless(data->attrlist != NULL, "talloc_array failed"); + data->attrlist[0] = TEST_ATTR_NAME; + data->attrlist[1] = TEST_ATTR_ADD_NAME; + data->attrlist[2] = NULL; + + subreq = sysdb_search_custom_send(data, data->ev, + data->ctx->sysdb, NULL, + data->ctx->domain, + filter, + CUSTOM_TEST_CONTAINER, + data->attrlist); + if (!subreq) { + ret = ENOMEM; + } + + if (ret == EOK) { + tevent_req_set_callback(subreq, test_search_custom_done, data); ret = test_loop(data); + + ret = sysdb_search_custom_recv(subreq, data, &data->msgs_count, + &data->msgs); + talloc_zfree(subreq); + fail_unless(ret == EOK, "sysdb_search_custom_send failed"); + + fail_unless(data->msgs_count == 10, + "Wrong number of objects, exptected [10] got [%d]", + data->msgs_count); } fail_if(ret != EOK, "Could not search custom object"); @@ -2484,6 +2531,7 @@ Suite *create_sysdb_suite(void) tcase_add_test(tc_sysdb, test_sysdb_search_custom_by_name); tcase_add_test(tc_sysdb, test_sysdb_update_custom); tcase_add_test(tc_sysdb, test_sysdb_search_custom_update); + tcase_add_test(tc_sysdb, test_sysdb_search_custom); tcase_add_test(tc_sysdb, test_sysdb_delete_custom); /* test recursive delete */ -- 1.6.5.2
From dc64e56d46808db6b828868c0d8ec39ef598af08 Mon Sep 17 00:00:00 2001 From: Sumit Bose <sb...@redhat.com> Date: Mon, 30 Nov 2009 10:50:01 +0100 Subject: [PATCH 2/2] Add offline support for ipa_access --- server/providers/ipa/ipa_access.c | 157 +++++++++++++++++++++++++++++++++---- server/providers/ipa/ipa_access.h | 1 + 2 files changed, 141 insertions(+), 17 deletions(-) diff --git a/server/providers/ipa/ipa_access.c b/server/providers/ipa/ipa_access.c index 675e7c2..292dd3a 100644 --- a/server/providers/ipa/ipa_access.c +++ b/server/providers/ipa/ipa_access.c @@ -56,6 +56,42 @@ #define HBAC_RULES_SUBDIR "hbac_rules" #define HBAC_HOSTS_SUBDIR "hbac_hosts" +static errno_t msgs2attrs_array(TALLOC_CTX *mem_ctx, size_t count, + struct ldb_message **msgs, + struct sysdb_attrs ***attrs) +{ + int i; + struct sysdb_attrs **a; + + a = talloc_array(mem_ctx, struct sysdb_attrs *, count); + if (a == NULL) { + DEBUG(1, ("talloc_array failed.\n")); + return ENOMEM; + } + + *a = talloc_array(mem_ctx, struct sysdb_attrs, count); + if (*a == NULL) { + DEBUG(1, ("talloc_array failed.\n")); + talloc_free(a); + return ENOMEM; + } + + for (i = 0; i < count; i++) { + a[i] = talloc(a, struct sysdb_attrs); + if (a[i] == NULL) { + DEBUG(1, ("talloc_array failed.\n")); + talloc_free(a); + return ENOMEM; + } + a[i]->num = msgs[i]->num_elements; + a[i]->a = talloc_steal(a[i], msgs[i]->elements); + } + + *attrs = a; + + return EOK; +} + static void ipa_access_reply(struct be_req *be_req, int pam_status) { struct pam_data *pd; @@ -288,6 +324,7 @@ struct hbac_get_host_info_state { struct sdap_id_ctx *sdap_ctx; struct sysdb_ctx *sysdb; struct sysdb_handle *handle; + bool offline; char *host_filter; char *host_search_base; @@ -300,13 +337,14 @@ struct hbac_get_host_info_state { }; static void hbac_get_host_info_connect_done(struct tevent_req *subreq); -static void host_get_host_memberof_done(struct tevent_req *subreq); +static void hbac_get_host_memberof_done(struct tevent_req *subreq); static void hbac_get_host_info_sysdb_transaction_started(struct tevent_req *subreq); static void hbac_get_host_info_store_prepare(struct tevent_req *req); static void hbac_get_host_info_store_done(struct tevent_req *subreq); static struct tevent_req *hbac_get_host_info_send(TALLOC_CTX *memctx, struct tevent_context *ev, + bool offline, struct sdap_id_ctx *sdap_ctx, struct sysdb_ctx *sysdb, const char *ipa_domain, @@ -333,6 +371,7 @@ static struct tevent_req *hbac_get_host_info_send(TALLOC_CTX *memctx, state->sdap_ctx = sdap_ctx; state->sysdb = sysdb; state->handle = NULL; + state->offline = offline; state->host_reply_list = NULL; state->host_reply_count = 0; @@ -369,7 +408,7 @@ static struct tevent_req *hbac_get_host_info_send(TALLOC_CTX *memctx, goto fail; } - state->host_attrs = talloc_array(state, const char *, 5); + state->host_attrs = talloc_array(state, const char *, 7); if (state->host_attrs == NULL) { DEBUG(1, ("Failed to allocate host attribute list.\n")); ret = ENOMEM; @@ -379,7 +418,25 @@ static struct tevent_req *hbac_get_host_info_send(TALLOC_CTX *memctx, state->host_attrs[1] = IPA_HOST_SERVERHOSTNAME; state->host_attrs[2] = IPA_HOST_FQDN; state->host_attrs[3] = "objectClass"; - state->host_attrs[4] = NULL; + state->host_attrs[4] = SYSDB_ORIG_DN; + state->host_attrs[5] = SYSDB_ORIG_MEMBEROF; + state->host_attrs[6] = NULL; + + if (offline) { + subreq = sysdb_search_custom_send(state, state->ev, state->sysdb, NULL, + state->sdap_ctx->be->domain, + state->host_filter, HBAC_HOSTS_SUBDIR, + state->host_attrs); + if (subreq == NULL) { + DEBUG(1, ("sysdb_search_custom_send.\n")); + ret = ENOMEM; + goto fail; + } + + tevent_req_set_callback(subreq, hbac_get_host_memberof_done, req); + + return req; + } if (sdap_ctx->gsh == NULL || ! sdap_ctx->gsh->connected) { if (sdap_ctx->gsh != NULL) { @@ -414,7 +471,7 @@ static struct tevent_req *hbac_get_host_info_send(TALLOC_CTX *memctx, goto fail; } - tevent_req_set_callback(subreq, host_get_host_memberof_done, req); + tevent_req_set_callback(subreq, hbac_get_host_memberof_done, req); return req; @@ -455,7 +512,8 @@ static void hbac_get_host_info_connect_done(struct tevent_req *subreq) goto fail; } - tevent_req_set_callback(subreq, host_get_host_memberof_done, req); + tevent_req_set_callback(subreq, hbac_get_host_memberof_done, req); + return; fail: @@ -463,7 +521,7 @@ fail: return; } -static void host_get_host_memberof_done(struct tevent_req *subreq) +static void hbac_get_host_memberof_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); @@ -474,9 +532,15 @@ static void host_get_host_memberof_done(struct tevent_req *subreq) int v; struct ldb_message_element *el; struct hbac_host_info **hhi; + struct ldb_message **msgs; - ret = sdap_get_generic_recv(subreq, state, &state->host_reply_count, - &state->host_reply_list); + if (state->offline) { + ret = sysdb_search_custom_recv(subreq, state, &state->host_reply_count, + &msgs); + } else { + ret = sdap_get_generic_recv(subreq, state, &state->host_reply_count, + &state->host_reply_list); + } talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); @@ -489,9 +553,19 @@ static void host_get_host_memberof_done(struct tevent_req *subreq) goto fail; } + if (state->offline) { + ret = msgs2attrs_array(state, state->host_reply_count, msgs, + &state->host_reply_list); + talloc_zfree(msgs); + if (ret != EOK) { + DEBUG(1, ("msgs2attrs_array failed.\n")); + goto fail; + } + } + hhi = talloc_array(state, struct hbac_host_info *, state->host_reply_count + 1); if (hhi == NULL) { - DEBUG(1, ("talloc failed.\n")); + DEBUG(1, ("talloc_array failed.\n")); ret = ENOMEM; goto fail; } @@ -562,7 +636,9 @@ static void host_get_host_memberof_done(struct tevent_req *subreq) } ret = sysdb_attrs_get_el(state->host_reply_list[i], - IPA_HOST_MEMBEROF, &el); + state->offline ? SYSDB_ORIG_MEMBEROF : + IPA_HOST_MEMBEROF, + &el); if (ret != EOK) { DEBUG(1, ("sysdb_attrs_get_el failed.\n")); goto fail; @@ -591,6 +667,11 @@ static void host_get_host_memberof_done(struct tevent_req *subreq) state->hbac_host_info = hhi; + if (state->offline) { + tevent_req_done(req); + return; + } + subreq = sysdb_transaction_send(state, state->ev, state->sysdb); if (subreq == NULL) { DEBUG(1, ("sysdb_transaction_send failed.\n")); @@ -732,6 +813,7 @@ struct hbac_get_rules_state { struct sdap_id_ctx *sdap_ctx; struct sysdb_ctx *sysdb; struct sysdb_handle *handle; + bool offline; const char *host_dn; const char **memberof; @@ -754,6 +836,7 @@ static void hbac_rule_store_done(struct tevent_req *subreq); static struct tevent_req *hbac_get_rules_send(TALLOC_CTX *memctx, struct tevent_context *ev, + bool offline, struct sdap_id_ctx *sdap_ctx, struct sysdb_ctx *sysdb, const char *ipa_domain, @@ -778,6 +861,7 @@ static struct tevent_req *hbac_get_rules_send(TALLOC_CTX *memctx, } state->ev = ev; + state->offline = offline; state->sdap_ctx = sdap_ctx; state->sysdb = sysdb; state->handle = NULL; @@ -797,7 +881,7 @@ static struct tevent_req *hbac_get_rules_send(TALLOC_CTX *memctx, goto fail; } - state->hbac_attrs = talloc_array(state, const char *, 15); + state->hbac_attrs = talloc_array(state, const char *, 16); if (state->hbac_attrs == NULL) { DEBUG(1, ("Failed to allocate HBAC attribute list.\n")); ret = ENOMEM; @@ -817,7 +901,8 @@ static struct tevent_req *hbac_get_rules_send(TALLOC_CTX *memctx, state->hbac_attrs[11] = "objectclass"; state->hbac_attrs[12] = IPA_MEMBER_HOST; state->hbac_attrs[13] = IPA_HOST_CATEGORY; - state->hbac_attrs[14] = NULL; + state->hbac_attrs[14] = SYSDB_ORIG_DN; + state->hbac_attrs[15] = NULL; state->hbac_filter = talloc_asprintf(state, "(&(objectclass=ipaHBACRule)" @@ -846,6 +931,22 @@ static struct tevent_req *hbac_get_rules_send(TALLOC_CTX *memctx, DEBUG(9, ("HBAC rule filter: [%s].\n", state->hbac_filter)); + if (offline) { + subreq = sysdb_search_custom_send(state, state->ev, state->sysdb, NULL, + state->sdap_ctx->be->domain, + state->hbac_filter, HBAC_RULES_SUBDIR, + state->hbac_attrs); + if (subreq == NULL) { + DEBUG(1, ("sysdb_search_custom_send failed.\n")); + ret = ENOMEM; + goto fail; + } + + tevent_req_set_callback(subreq, hbac_rule_get_done, req); + + return req; + } + if (sdap_ctx->gsh == NULL || ! sdap_ctx->gsh->connected) { if (sdap_ctx->gsh != NULL) { talloc_zfree(sdap_ctx->gsh); @@ -937,15 +1038,31 @@ static void hbac_rule_get_done(struct tevent_req *subreq) int ret; int i; struct ldb_message_element *el; + struct ldb_message **msgs; - ret = sdap_get_generic_recv(subreq, state, &state->hbac_reply_count, - &state->hbac_reply_list); + if (state->offline) { + ret = sysdb_search_custom_recv(subreq, state, &state->hbac_reply_count, + &msgs); + } else { + ret = sdap_get_generic_recv(subreq, state, &state->hbac_reply_count, + &state->hbac_reply_list); + } talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } + if (state->offline) { + ret = msgs2attrs_array(state, state->hbac_reply_count, msgs, + &state->hbac_reply_list); + talloc_zfree(msgs); + if (ret != EOK) { + DEBUG(1, ("msgs2attrs_array failed.\n")); + goto fail; + } + } + for (i = 0; i < state->hbac_reply_count; i++) { ret = sysdb_attrs_get_el(state->hbac_reply_list[i], SYSDB_ORIG_DN, &el); if (ret != EOK) { @@ -953,13 +1070,14 @@ static void hbac_rule_get_done(struct tevent_req *subreq) goto fail; } if (el->num_values == 0) { + DEBUG(1, ("Missing original DN.\n")); ret = EINVAL; goto fail; } DEBUG(9, ("OriginalDN: [%s].\n", (const char *)el->values[0].data)); } - if (state->hbac_reply_count == 0) { + if (state->hbac_reply_count == 0 || state->offline) { tevent_req_done(req); return; } @@ -1547,6 +1665,10 @@ void ipa_access_handler(struct be_req *be_req) hbac_ctx->sdap_ctx = ipa_access_ctx->sdap_ctx; hbac_ctx->ipa_options = ipa_access_ctx->ipa_options; hbac_ctx->tr_ctx = ipa_access_ctx->tr_ctx; + hbac_ctx->offline = be_is_offline(be_req->be_ctx); + + DEBUG(9, ("Connection status is [%s].\n", hbac_ctx->offline ? "offline" : + "online")); hostlist[0] = dp_opt_get_cstring(hbac_ctx->ipa_options, IPA_HOSTNAME); @@ -1567,6 +1689,7 @@ void ipa_access_handler(struct be_req *be_req) hostlist[2] = NULL; req = hbac_get_host_info_send(hbac_ctx, be_req->be_ctx->ev, + hbac_ctx->offline, hbac_ctx->sdap_ctx, be_req->be_ctx->sysdb, dp_opt_get_string(hbac_ctx->ipa_options, IPA_DOMAIN), @@ -1626,8 +1749,8 @@ static void hbac_get_host_info_done(struct tevent_req *req) ret = EINVAL; goto fail; } - req = hbac_get_rules_send(hbac_ctx, be_req->be_ctx->ev, hbac_ctx->sdap_ctx, - be_req->be_ctx->sysdb, + req = hbac_get_rules_send(hbac_ctx, be_req->be_ctx->ev, hbac_ctx->offline, + hbac_ctx->sdap_ctx, be_req->be_ctx->sysdb, dp_opt_get_string(hbac_ctx->ipa_options, IPA_DOMAIN), local_hhi->dn, local_hhi->memberof); diff --git a/server/providers/ipa/ipa_access.h b/server/providers/ipa/ipa_access.h index 486dac6..bd221c5 100644 --- a/server/providers/ipa/ipa_access.h +++ b/server/providers/ipa/ipa_access.h @@ -58,6 +58,7 @@ struct hbac_ctx { const char *user_dn; size_t groups_count; const char **groups; + bool offline; }; void ipa_access_handler(struct be_req *be_req); -- 1.6.5.2
_______________________________________________ sssd-devel mailing list sssd-devel@lists.fedorahosted.org https://fedorahosted.org/mailman/listinfo/sssd-devel