From 3fb00d2de5a73ac9c106bdaafb083b57da390469 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Wed, 2 Jun 2010 11:36:11 +0200 Subject: [PATCH 2/2] Save all data to sysdb in one transaction --- src/providers/ipa/ipa_access.c | 389 ++++++++++++++-------------------------- 1 files changed, 137 insertions(+), 252 deletions(-) diff --git a/src/providers/ipa/ipa_access.c b/src/providers/ipa/ipa_access.c index 25302f8..4ca1359 100644 --- a/src/providers/ipa/ipa_access.c +++ b/src/providers/ipa/ipa_access.c @@ -302,6 +302,123 @@ static void ipa_access_reply(struct be_req *be_req, int pam_status) } } +static errno_t hbac_save_list(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, + bool delete_subdir, const char *subdir, + struct sss_domain_info *domain, + const char *naming_attribute, size_t count, + struct sysdb_attrs **list) +{ + int ret; + size_t c; + struct ldb_dn *base_dn; + const char *object_name; + struct ldb_message_element *el; + + if (delete_subdir) { + base_dn = sysdb_custom_subtree_dn(sysdb, mem_ctx, domain->name, subdir); + if (base_dn == NULL) { + return ENOMEM; + } + + ret = sysdb_delete_recursive(mem_ctx, sysdb, base_dn, true); + if (ret != EOK) { + DEBUG(1, ("sysdb_delete_recursive failed.\n")); + return ret; + } + } + + for (c = 0; c < count; c++) { + ret = sysdb_attrs_get_el(list[c], naming_attribute, &el); + if (ret != EOK) { + DEBUG(1, ("sysdb_attrs_get_el failed.\n")); + return ret; + } + if (el->num_values == 0) { + DEBUG(1, ("IPA_UNIQUE_ID not found.\n")); + return EINVAL; + } + object_name = talloc_strndup(mem_ctx, (const char *)el->values[0].data, + el->values[0].length); + if (object_name == NULL) { + DEBUG(1, ("talloc_strndup failed.\n")); + return ENOMEM; + } + DEBUG(9, ("Object name: [%s].\n", object_name)); + + ret = sysdb_store_custom(mem_ctx, sysdb, domain, object_name, subdir, + list[c]); + if (ret != EOK) { + DEBUG(1, ("sysdb_store_custom failed.\n")); + return ret; + } + } + + return EOK; +} + +static errno_t hbac_save_data_to_sysdb(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + struct hbac_ctx *hbac_ctx, + struct sss_domain_info *domain) +{ + int ret; + bool in_transaction = false; + TALLOC_CTX *tmp_ctx = NULL; + + ret = sysdb_transaction_start(sysdb); + if (ret != EOK) { + DEBUG(1, ("sysdb_transaction_start failed.\n")); + return ret; + } + in_transaction = true; + + tmp_ctx = talloc_new(mem_ctx); + if (tmp_ctx == NULL) { + DEBUG(1, ("talloc_new failed.\n")); + return ENOMEM; + } + + ret = hbac_save_list(tmp_ctx, sysdb, true, HBAC_SERVICES_SUBDIR, domain, + IPA_UNIQUE_ID, hbac_ctx->hbac_services_count, + hbac_ctx->hbac_services_list); + if (ret != EOK) { + DEBUG(1, ("hbac_save_list failed.\n")); + goto fail; + } + + ret = hbac_save_list(tmp_ctx, sysdb, true, HBAC_RULES_SUBDIR, domain, + IPA_UNIQUE_ID, hbac_ctx->hbac_rule_count, + hbac_ctx->hbac_rule_list); + if (ret != EOK) { + DEBUG(1, ("hbac_save_list failed.\n")); + goto fail; + } + + ret = hbac_save_list(tmp_ctx, sysdb, false, HBAC_HOSTS_SUBDIR, domain, + IPA_HOST_FQDN, hbac_ctx->hbac_hosts_count, + hbac_ctx->hbac_hosts_list); + if (ret != EOK) { + DEBUG(1, ("hbac_save_list failed.\n")); + goto fail; + } + + ret = sysdb_transaction_commit(sysdb); + if (ret != EOK) { + DEBUG(1, ("sysdb_transaction_commit failed.\n")); + goto fail; + } + in_transaction = false; + + return EOK; + +fail: + if (in_transaction) { + sysdb_transaction_cancel(sysdb); + } + talloc_free(tmp_ctx); + return ret; +} + struct hbac_get_service_data_state { struct tevent_context *ev; struct sdap_id_ctx *sdap_ctx; @@ -485,12 +602,6 @@ static void hbac_services_get_done(struct tevent_req *subreq) struct hbac_get_service_data_state *state = tevent_req_data(req, struct hbac_get_service_data_state); int ret; - bool in_transaction = false; - struct ldb_dn *base_dn; - int i; - struct ldb_message_element *el; - char *object_name; - ret = hbac_sdap_data_recv(subreq, state, &state->services_reply_count, &state->services_reply_list); @@ -500,78 +611,8 @@ static void hbac_services_get_done(struct tevent_req *subreq) return; } - if (state->services_reply_count == 0 || state->offline) { - tevent_req_done(req); - return; - } - - ret = sysdb_transaction_start(state->sysdb); - if (ret != EOK) { - DEBUG(1, ("sysdb_transaction_start failed.\n")); - tevent_req_error(req, ret); - return; - } - in_transaction = true; - - base_dn = sysdb_custom_subtree_dn(state->sysdb, state, - state->sdap_ctx->be->domain->name, - HBAC_SERVICES_SUBDIR); - if (base_dn == NULL) { - ret = ENOMEM; - goto fail; - } - - ret = sysdb_delete_recursive(state, state->sysdb, base_dn, true); - if (ret) { - DEBUG(1, ("sysdb_delete_recursive failed.\n")); - goto fail; - } - - for (i = 0; i < state->services_reply_count; i++) { - ret = sysdb_attrs_get_el(state->services_reply_list[i], IPA_UNIQUE_ID, - &el); - if (ret != EOK) { - DEBUG(1, ("sysdb_attrs_get_el failed.\n")); - goto fail; - } - if (el->num_values == 0) { - ret = EINVAL; - goto fail; - } - object_name = talloc_strndup(state, (const char *)el->values[0].data, - el->values[0].length); - if (object_name == NULL) { - ret = ENOMEM; - goto fail; - } - DEBUG(9, ("Object name: [%s].\n", object_name)); - - ret = sysdb_store_custom(state, state->sysdb, - state->sdap_ctx->be->domain, object_name, - HBAC_SERVICES_SUBDIR, - state->services_reply_list[i]); - if (ret) { - DEBUG(1, ("sysdb_store_custom failed.\n")); - goto fail; - } - } - - ret = sysdb_transaction_commit(state->sysdb); - if (ret) { - DEBUG(1, ("sysdb_transaction_commit failed.\n")); - goto fail; - } - in_transaction = false; - tevent_req_done(req); return; - -fail: - if (in_transaction) { - sysdb_transaction_cancel(state->sysdb); - } - tevent_req_error(req, ret); - return; } static int hbac_get_service_data_recv(struct tevent_req *req, @@ -719,7 +760,6 @@ struct hbac_get_host_info_state { }; static void hbac_get_host_info_connect_done(struct tevent_req *subreq); -static void hbac_get_host_memberof(struct tevent_req *req); static void hbac_get_host_memberof_done(struct tevent_req *subreq); static struct tevent_req *hbac_get_host_info_send(TALLOC_CTX *memctx, @@ -813,7 +853,14 @@ static struct tevent_req *hbac_get_host_info_send(TALLOC_CTX *memctx, DEBUG(1, ("hbac_sysdb_data_recv failed.\n")); goto fail; } - hbac_get_host_memberof(req); + + if (state->host_reply_count == 0) { + DEBUG(1, ("No hosts not found in IPA server.\n")); + ret = ENOENT; + goto fail; + } + + tevent_req_done(req); tevent_req_post(req, ev); return req; } @@ -913,85 +960,14 @@ static void hbac_get_host_memberof_done(struct tevent_req *subreq) return; } - hbac_get_host_memberof(req); -} - -static void hbac_get_host_memberof(struct tevent_req *req) -{ - struct hbac_get_host_info_state *state = - tevent_req_data(req, struct hbac_get_host_info_state); - bool in_transaction = false; - int ret; - int i; - struct ldb_message_element *el; - char *object_name; - if (state->host_reply_count == 0) { DEBUG(1, ("No hosts not found in IPA server.\n")); - ret = ENOENT; - goto fail; - } - - if (state->offline) { - tevent_req_done(req); + tevent_req_error(req, ENOENT); return; } - ret = sysdb_transaction_start(state->sysdb); - if (ret != EOK) { - tevent_req_error(req, ret); - return; - } - in_transaction = true; - - for (i = 0; i < state->host_reply_count; i++) { - - 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; - } - object_name = talloc_strndup(state, (const char *)el->values[0].data, - el->values[0].length); - if (object_name == NULL) { - ret = ENOMEM; - goto fail; - } - DEBUG(9, ("Fqdn [%s].\n", object_name)); - - ret = sysdb_store_custom(state, state->sysdb, - state->sdap_ctx->be->domain, - object_name, - HBAC_HOSTS_SUBDIR, - state->host_reply_list[i]); - - if (ret) { - DEBUG(1, ("sysdb_store_custom failed.\n")); - goto fail; - } - } - - ret = sysdb_transaction_commit(state->sysdb); - if (ret) { - DEBUG(1, ("sysdb_transaction_commit failed.\n")); - goto fail; - } - in_transaction = false; - tevent_req_done(req); return; - -fail: - if (in_transaction) { - sysdb_transaction_cancel(state->sysdb); - } - tevent_req_error(req, ret); - return; } static int hbac_get_host_info_recv(struct tevent_req *req, TALLOC_CTX *memctx, @@ -1033,7 +1009,6 @@ struct hbac_get_rules_state { }; static void hbac_get_rules_connect_done(struct tevent_req *subreq); -static void hbac_rule_get(struct tevent_req *req); static void hbac_rule_get_done(struct tevent_req *subreq); static struct tevent_req *hbac_get_rules_send(TALLOC_CTX *memctx, @@ -1145,7 +1120,7 @@ static struct tevent_req *hbac_get_rules_send(TALLOC_CTX *memctx, DEBUG(1, ("hbac_sysdb_data_recv failed.\n")); goto fail; } - hbac_rule_get(req); + tevent_req_done(req); tevent_req_post(req, ev); return req; } @@ -1244,108 +1219,8 @@ static void hbac_rule_get_done(struct tevent_req *subreq) return; } - hbac_rule_get(req); -} - -static void hbac_rule_get(struct tevent_req *req) -{ - struct hbac_get_rules_state *state = - tevent_req_data(req, struct hbac_get_rules_state); - bool in_transaction = false; - int ret; - int i; - struct ldb_message_element *el; - struct ldb_dn *hbac_base_dn; - char *object_name; - - 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) { - DEBUG(1, ("sysdb_attrs_get_el failed.\n")); - 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 || state->offline) { - tevent_req_done(req); - return; - } - - ret = sysdb_transaction_start(state->sysdb); - if (ret != EOK) { - tevent_req_error(req, ret); - return; - } - in_transaction = true; - - hbac_base_dn = sysdb_custom_subtree_dn(state->sysdb, state, - state->sdap_ctx->be->domain->name, - HBAC_RULES_SUBDIR); - if (hbac_base_dn == NULL) { - ret = ENOMEM; - goto fail; - } - ret = sysdb_delete_recursive(state, state->sysdb, hbac_base_dn, true); - if (ret) { - DEBUG(1, ("sysdb_delete_recursive_send failed.\n")); - goto fail; - } - - - for (i = 0; i < state->hbac_reply_count; i++) { - - ret = sysdb_attrs_get_el(state->hbac_reply_list[i], - IPA_UNIQUE_ID, &el); - if (ret != EOK) { - DEBUG(1, ("sysdb_attrs_get_el failed.\n")); - goto fail; - } - if (el->num_values == 0) { - ret = EINVAL; - goto fail; - } - object_name = talloc_strndup(state, (const char *)el->values[0].data, - el->values[0].length); - if (object_name == NULL) { - ret = ENOMEM; - goto fail; - } - DEBUG(9, ("IPAUniqueId: [%s].\n", object_name)); - - ret = sysdb_store_custom(state, state->sysdb, - state->sdap_ctx->be->domain, - object_name, - HBAC_RULES_SUBDIR, - state->hbac_reply_list[i]); - - if (ret) { - DEBUG(1, ("sysdb_store_custom_send failed.\n")); - goto fail; - } - } - - ret = sysdb_transaction_commit(state->sysdb); - if (ret) { - DEBUG(1, ("sysdb_transaction_commit failed.\n")); - goto fail; - } - in_transaction = false; - tevent_req_done(req); return; - -fail: - if (in_transaction) { - sysdb_transaction_cancel(state->sysdb); - } - tevent_req_error(req, ret); - return; } static int hbac_get_rules_recv(struct tevent_req *req, TALLOC_CTX *memctx, @@ -2035,6 +1910,16 @@ static void hbac_get_service_data_done(struct tevent_req *req) goto failed; } + if (!hbac_ctx->offline) { + ret = hbac_save_data_to_sysdb(hbac_ctx, be_req->be_ctx->sysdb, + hbac_ctx, be_req->be_ctx->domain); + if (ret != EOK) { + DEBUG(1, ("Failed to save data, " + "offline authentication might not work.\n")); + /* This is not a fatal error. */ + } + } + ret = hbac_get_user_info(hbac_ctx, be_req->be_ctx, pd->user, &hbac_ctx->user_dn, &hbac_ctx->groups_count, &hbac_ctx->groups); -- 1.7.0.1