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);
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 ======= */
a63d74f65db2db7389cd373cb37adcdaaa2d56eaMichal Židekstatic 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 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 */
66c8e92eb5a4985bb7f64c349a53b08030a000cfFabiano Fidêncio ret = sss_resp_populate_cr_domains(state->rctx);
66c8e92eb5a4985bb7f64c349a53b08030a000cfFabiano Fidêncio "sss_resp_populate_cr_domains() failed [%d]: [%s]\n",
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);
749963195393efa3a4f9b168dd02fbcc68976ba3Sumit Bosestatic void sss_resp_update_certmaps(struct resp_ctx *rctx)
749963195393efa3a4f9b168dd02fbcc68976ba3Sumit Bose for (dom = rctx->domains; dom != NULL; dom = dom->next) {
749963195393efa3a4f9b168dd02fbcc68976ba3Sumit Bose ret = sysdb_get_certmap(dom, dom->sysdb, &certmaps, &user_name_hint);
749963195393efa3a4f9b168dd02fbcc68976ba3Sumit Bose "sysdb_get_certmap failed for domain [%s].\n", dom->name);
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);
a63d74f65db2db7389cd373cb37adcdaaa2d56eaMichal Židek ret = process_subdomains(state->dom, state->rctx->cdb);
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 */
66c8e92eb5a4985bb7f64c349a53b08030a000cfFabiano Fidêncio ret = sss_resp_populate_cr_domains(state->rctx);
66c8e92eb5a4985bb7f64c349a53b08030a000cfFabiano Fidêncio "sss_resp_populate_cr_domains() failed [%d]: [%s]\n",
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);
a63d74f65db2db7389cd373cb37adcdaaa2d56eaMichal Židekprocess_subdomains(struct sss_domain_info *domain, struct confdb_ctx *confdb)
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");
0c5b97812f20b57b93c10496fed34ea221fbcca8Sumit Bose if (!NEED_CHECK_PROVIDER(state->rctx->domains->provider)) {
0c5b97812f20b57b93c10496fed34ea221fbcca8Sumit Bose ret = sysdb_master_domain_update(state->rctx->domains);
0c5b97812f20b57b93c10496fed34ea221fbcca8Sumit Bose DEBUG(SSSDBG_OP_FAILURE, "sysdb_master_domain_update failed, "
0c5b97812f20b57b93c10496fed34ea221fbcca8Sumit Bose "ignored.\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,
7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926Jakub Hrozek *_domname = talloc_steal(mem_ctx, state->domname);
677a31351c80453d9ce006481364399a96312052René Genz/* ========== Get domain of an account ================= */
95fd82a4d7b50e64fed6906bc5345f271e8247d9Jakub Hrozekstatic DBusMessage *sss_dp_get_account_domain_msg(void *pvt);
95fd82a4d7b50e64fed6906bc5345f271e8247d9Jakub Hrozekstruct tevent_req *sss_dp_get_account_domain_send(TALLOC_CTX *mem_ctx,
95fd82a4d7b50e64fed6906bc5345f271e8247d9Jakub Hrozek req = tevent_req_create(mem_ctx, &state, struct sss_dp_req_state);
95fd82a4d7b50e64fed6906bc5345f271e8247d9Jakub Hrozek info = talloc_zero(state, struct sss_dp_get_account_domain_info);
95fd82a4d7b50e64fed6906bc5345f271e8247d9Jakub Hrozek key = talloc_asprintf(state, "%d: %"SPRIuid"@%s", type, opt_id, dom->name);
95fd82a4d7b50e64fed6906bc5345f271e8247d9Jakub Hrozek ret = sss_dp_issue_request(state, rctx, key, dom,
95fd82a4d7b50e64fed6906bc5345f271e8247d9Jakub Hrozek "Could not issue DP request [%d]: %s\n",
95fd82a4d7b50e64fed6906bc5345f271e8247d9Jakub Hrozek info = talloc_get_type(pvt, struct sss_dp_get_account_domain_info);
95fd82a4d7b50e64fed6906bc5345f271e8247d9Jakub Hrozek "Unsupported lookup type %X for this request\n", info->type);
95fd82a4d7b50e64fed6906bc5345f271e8247d9Jakub Hrozek filter = talloc_asprintf(info, "idnumber=%u", info->opt_id);
95fd82a4d7b50e64fed6906bc5345f271e8247d9Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n");
95fd82a4d7b50e64fed6906bc5345f271e8247d9Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n");
95fd82a4d7b50e64fed6906bc5345f271e8247d9Jakub Hrozek /* create the message */
95fd82a4d7b50e64fed6906bc5345f271e8247d9Jakub Hrozek "Creating request for [%s][%#x][%s][%s:-]\n",
95fd82a4d7b50e64fed6906bc5345f271e8247d9Jakub Hrozek info->dom->name, entry_type, be_req2str(entry_type), filter);
95fd82a4d7b50e64fed6906bc5345f271e8247d9Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "Failed to build message\n");
95fd82a4d7b50e64fed6906bc5345f271e8247d9Jakub Hrozekerrno_t sss_dp_get_account_domain_recv(TALLOC_CTX *mem_ctx,
95fd82a4d7b50e64fed6906bc5345f271e8247d9Jakub Hrozek ret = sss_dp_req_recv(mem_ctx, req, &err_maj, &err_min, &msg);
95fd82a4d7b50e64fed6906bc5345f271e8247d9Jakub Hrozek "Could not get account info [%d]: %s\n",
95fd82a4d7b50e64fed6906bc5345f271e8247d9Jakub Hrozek "Data Provider Error: %u, %u\n",