responder_get_domains.c revision 2b5704cd96a085b99d3b0d4f80f4414adc134750
c0f9698cd951b7223f251ff2511c4b22a6e4ba60Jan Zeleny Jan Zeleny <jzeleny@redhat.com>
c0f9698cd951b7223f251ff2511c4b22a6e4ba60Jan Zeleny Copyright (C) 2011 Red Hat
c0f9698cd951b7223f251ff2511c4b22a6e4ba60Jan Zeleny This program is free software; you can redistribute it and/or modify
c0f9698cd951b7223f251ff2511c4b22a6e4ba60Jan Zeleny it under the terms of the GNU General Public License as published by
c0f9698cd951b7223f251ff2511c4b22a6e4ba60Jan Zeleny the Free Software Foundation; either version 3 of the License, or
c0f9698cd951b7223f251ff2511c4b22a6e4ba60Jan Zeleny (at your option) any later version.
c0f9698cd951b7223f251ff2511c4b22a6e4ba60Jan Zeleny This program is distributed in the hope that it will be useful,
c0f9698cd951b7223f251ff2511c4b22a6e4ba60Jan Zeleny but WITHOUT ANY WARRANTY; without even the implied warranty of
c0f9698cd951b7223f251ff2511c4b22a6e4ba60Jan Zeleny MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
c0f9698cd951b7223f251ff2511c4b22a6e4ba60Jan Zeleny GNU General Public License for more details.
c0f9698cd951b7223f251ff2511c4b22a6e4ba60Jan Zeleny You should have received a copy of the GNU General Public License
c0f9698cd951b7223f251ff2511c4b22a6e4ba60Jan Zeleny along with this program. If not, see <http://www.gnu.org/licenses/>.
8ba8222afca3026fd67af08e224b1d9e848aceaaJakub Hrozek/* ========== Get subdomains for a domain ================= */
8ba8222afca3026fd67af08e224b1d9e848aceaaJakub Hrozekstatic DBusMessage *sss_dp_get_domains_msg(void *pvt);
c0f9698cd951b7223f251ff2511c4b22a6e4ba60Jan Zeleny const char *hint;
8ba8222afca3026fd67af08e224b1d9e848aceaaJakub Hrozekstatic struct tevent_req *
8ba8222afca3026fd67af08e224b1d9e848aceaaJakub Hrozekget_subdomains_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx,
8ba8222afca3026fd67af08e224b1d9e848aceaaJakub Hrozek const char *hint)
8ba8222afca3026fd67af08e224b1d9e848aceaaJakub Hrozek req = tevent_req_create(mem_ctx, &state, struct sss_dp_req_state);
8ba8222afca3026fd67af08e224b1d9e848aceaaJakub Hrozek info = talloc_zero(state, struct sss_dp_domains_info);
8ba8222afca3026fd67af08e224b1d9e848aceaaJakub Hrozek key = talloc_asprintf(state, "domains@%s", dom->name);
8ba8222afca3026fd67af08e224b1d9e848aceaaJakub Hrozek ret = sss_dp_issue_request(state, rctx, key, dom,
c0f9698cd951b7223f251ff2511c4b22a6e4ba60Jan Zeleny info = talloc_get_type(pvt, struct sss_dp_domains_info);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n");
ef2455b63380ecd17bea94270ceaabe15dcf6456Jakub Hrozek "Sending get domains request for [%s][%s]\n",
c0f9698cd951b7223f251ff2511c4b22a6e4ba60Jan Zeleny /* Send the hint argument to provider as well. This will
c0f9698cd951b7223f251ff2511c4b22a6e4ba60Jan Zeleny * be useful for some cases of transitional trust where
c0f9698cd951b7223f251ff2511c4b22a6e4ba60Jan Zeleny * the server might not know all trusted domains
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE ,"Failed to build message\n");
8ba8222afca3026fd67af08e224b1d9e848aceaaJakub Hrozek return sss_dp_req_recv(mem_ctx, req, dp_err, dp_ret, err_msg);
8ba8222afca3026fd67af08e224b1d9e848aceaaJakub Hrozek/* ====== Iterate over all domains, searching for their subdomains ======= */
8ba8222afca3026fd67af08e224b1d9e848aceaaJakub Hrozekstatic errno_t process_subdomains(struct sss_domain_info *dom);
99bac83188601c2b07e0b141aac7dc7d882b464aSumit Bosestatic void set_time_of_last_request(struct resp_ctx *rctx);
8ba8222afca3026fd67af08e224b1d9e848aceaaJakub Hrozekstatic errno_t check_last_request(struct resp_ctx *rctx, const char *hint);
8ba8222afca3026fd67af08e224b1d9e848aceaaJakub Hrozek const char *hint;
8ba8222afca3026fd67af08e224b1d9e848aceaaJakub Hrozeksss_dp_get_domains_process(struct tevent_req *subreq);
8ba8222afca3026fd67af08e224b1d9e848aceaaJakub Hrozekstruct tevent_req *sss_dp_get_domains_send(TALLOC_CTX *mem_ctx,
8ba8222afca3026fd67af08e224b1d9e848aceaaJakub Hrozek const char *hint)
8ba8222afca3026fd67af08e224b1d9e848aceaaJakub Hrozek req = tevent_req_create(mem_ctx, &state, struct sss_dp_get_domains_state);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "No domains configured.\n");
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Last call was too recent, nothing to do!\n");
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC, "check_domain_request failed with [%d][%s]\n",
8ba8222afca3026fd67af08e224b1d9e848aceaaJakub Hrozek while(state->dom != NULL && !NEED_CHECK_PROVIDER(state->dom->provider)) {
8ba8222afca3026fd67af08e224b1d9e848aceaaJakub Hrozek /* All domains were local */
ef2455b63380ecd17bea94270ceaabe15dcf6456Jakub Hrozek subreq = get_subdomains_send(req, rctx, state->dom, state->hint);
8ba8222afca3026fd67af08e224b1d9e848aceaaJakub Hrozek tevent_req_set_callback(subreq, sss_dp_get_domains_process, req);
8ba8222afca3026fd67af08e224b1d9e848aceaaJakub Hrozeksss_dp_get_domains_process(struct tevent_req *subreq)
8ba8222afca3026fd67af08e224b1d9e848aceaaJakub Hrozek struct tevent_req *req = tevent_req_callback_data(subreq,
8ba8222afca3026fd67af08e224b1d9e848aceaaJakub Hrozek struct sss_dp_get_domains_state *state = tevent_req_data(req,
8ba8222afca3026fd67af08e224b1d9e848aceaaJakub Hrozek ret = get_next_domain_recv(req, subreq, &dp_err, &dp_ret, &err_msg);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "process_subdomains failed, "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "trying next domain.\n");
8ba8222afca3026fd67af08e224b1d9e848aceaaJakub Hrozek /* Advance to the next domain */
8ba8222afca3026fd67af08e224b1d9e848aceaaJakub Hrozek /* Skip local domains */
8ba8222afca3026fd67af08e224b1d9e848aceaaJakub Hrozek while(state->dom != NULL && !NEED_CHECK_PROVIDER(state->dom->provider)) {
8ba8222afca3026fd67af08e224b1d9e848aceaaJakub Hrozek /* All domains were local */
ef2455b63380ecd17bea94270ceaabe15dcf6456Jakub Hrozek subreq = get_subdomains_send(req, state->rctx, state->dom, state->hint);
8ba8222afca3026fd67af08e224b1d9e848aceaaJakub Hrozek tevent_req_set_callback(subreq, sss_dp_get_domains_process, req);
8ba8222afca3026fd67af08e224b1d9e848aceaaJakub Hrozekprocess_subdomains(struct sss_domain_info *domain)
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_FUNC_DATA, "sysdb_master_domain_get_info " \
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce /* Retrieve all subdomains of this domain from sysdb
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce * and create their struct sss_domain_info representations
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_FUNC_DATA, "sysdb_update_subdomains failed.\n");
c0f9698cd951b7223f251ff2511c4b22a6e4ba60Jan Zeleny ret = gettimeofday(&domain->subdomains_last_checked, NULL);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "Failed to update sub-domains "
c0f9698cd951b7223f251ff2511c4b22a6e4ba60Jan Zelenyerrno_t sss_dp_get_domains_recv(struct tevent_req *req)
99bac83188601c2b07e0b141aac7dc7d882b464aSumit Bosestatic void set_time_of_last_request(struct resp_ctx *rctx)
99bac83188601c2b07e0b141aac7dc7d882b464aSumit Bose ret = gettimeofday(&rctx->get_domains_last_call, NULL);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC, "gettimeofday failed [%d][%s].\n",
c0f9698cd951b7223f251ff2511c4b22a6e4ba60Jan Zelenystatic errno_t check_last_request(struct resp_ctx *rctx, const char *hint)
c0f9698cd951b7223f251ff2511c4b22a6e4ba60Jan Zeleny /* Timeout, expired, fetch domains again */
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce diff = now - dom->subdomains_last_checked.tv_sec;
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce /* not a subdomain */
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce /* Timeout, expired, fetch domains again */
909a86af4eb99f5d311d7136cab78dca535ae304Sumit Bosestatic void get_domains_at_startup_done(struct tevent_req *req)
0528fdec17d0031996e919fcd852459e86592c35Jakub Hrozek state = tevent_req_callback_data(req, struct get_domains_state);
0528fdec17d0031996e919fcd852459e86592c35Jakub Hrozek DEBUG(SSSDBG_MINOR_FAILURE, "sss_dp_get_domains request failed.\n");
0528fdec17d0031996e919fcd852459e86592c35Jakub Hrozek ret = sss_ncache_reset_repopulate_permanent(state->rctx,
0528fdec17d0031996e919fcd852459e86592c35Jakub Hrozek DEBUG(SSSDBG_MINOR_FAILURE, "sss_dp_get_domains request failed.\n");
909a86af4eb99f5d311d7136cab78dca535ae304Sumit Bosestatic void get_domains_at_startup(struct tevent_context *ev,
0528fdec17d0031996e919fcd852459e86592c35Jakub Hrozek state = talloc_get_type(pvt, struct get_domains_state);
0528fdec17d0031996e919fcd852459e86592c35Jakub Hrozek req = sss_dp_get_domains_send(state, state->rctx, true, NULL);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "sss_dp_get_domains_send failed.\n");
0528fdec17d0031996e919fcd852459e86592c35Jakub Hrozek tevent_req_set_callback(req, get_domains_at_startup_done, state);
909a86af4eb99f5d311d7136cab78dca535ae304Sumit Boseerrno_t schedule_get_domains_task(TALLOC_CTX *mem_ctx,
0528fdec17d0031996e919fcd852459e86592c35Jakub Hrozek state = talloc(mem_ctx, struct get_domains_state);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "tevent_create_immediate failed.\n");
0528fdec17d0031996e919fcd852459e86592c35Jakub Hrozek tevent_schedule_immediate(imm, ev, get_domains_at_startup, state);
7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926Jakub Hrozekstatic void sss_parse_inp_done(struct tevent_req *subreq);
7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926Jakub Hrozek req = tevent_req_create(mem_ctx, &state, struct sss_parse_inp_state);
2b5704cd96a085b99d3b0d4f80f4414adc134750Pavel Březina state->default_domain = talloc_strdup(state, default_domain);
2b5704cd96a085b99d3b0d4f80f4414adc134750Pavel Březina if (default_domain != NULL && state->default_domain == NULL) {
7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926Jakub Hrozek /* If the subdomains haven't been checked yet, we need to always
7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926Jakub Hrozek * attach to the post-startup subdomain request and only then parse
7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926Jakub Hrozek * the input. Otherwise, we might not be able to parse input with a
7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926Jakub Hrozek * flat domain name specifier */
7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926Jakub Hrozek ret = sss_parse_name_for_domains(state, rctx->domains,
7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926Jakub Hrozek /* Was able to use cached domains */
7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926Jakub Hrozek DEBUG(SSSDBG_OP_FAILURE, "Invalid name received [%s]\n", rawinp);
7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926Jakub Hrozek /* EAGAIN - check the DP for subdomains */
7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926Jakub Hrozek DEBUG(SSSDBG_FUNC_DATA, "Requesting info for [%s] from [%s]\n",
7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926Jakub Hrozek state->name, state->domname ? state->domname : "<ALL>");
7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926Jakub Hrozek /* We explicitly use force=false here. This request should decide itself
7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926Jakub Hrozek * if it's time to re-use the cached subdomain list or refresh. If the
7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926Jakub Hrozek * caller needs to specify the 'force' parameter, they should use the
7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926Jakub Hrozek * sss_dp_get_domains_send() request itself
7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926Jakub Hrozek subreq = sss_dp_get_domains_send(state, rctx, false, state->domname);
7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926Jakub Hrozek tevent_req_set_callback(subreq, sss_parse_inp_done, req);
7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926Jakub Hrozekstatic void sss_parse_inp_done(struct tevent_req *subreq)
7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926Jakub Hrozek struct tevent_req *req = tevent_req_callback_data(subreq,
7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926Jakub Hrozek struct sss_parse_inp_state *state = tevent_req_data(req,
7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926Jakub Hrozek ret = sss_parse_name_for_domains(state, state->rctx->domains,
28ebfa4373d1e7ce45b5d70a3619df1c074a661ePavel Březina if (ret == EAGAIN && state->domname != NULL && state->name == NULL) {
7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926Jakub Hrozek "Invalid name received [%s]\n", state->rawinp);
7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926Jakub Hrozek /* Was able to parse the name now */
7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926Jakub Hrozekerrno_t sss_parse_inp_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926Jakub Hrozek struct sss_parse_inp_state *state = tevent_req_data(req,