fail_over_srv.c revision 8df69bbc58c2f4d3f0b34be9756d9ddf24b1db6d
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder Pavel Březina <pbrezina@redhat.com>
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder Copyright (C) 2013 Red Hat
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder This program is free software; you can redistribute it and/or modify
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder it under the terms of the GNU General Public License as published by
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder the Free Software Foundation; either version 3 of the License, or
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder (at your option) any later version.
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder This program is distributed in the hope that it will be useful,
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder but WITHOUT ANY WARRANTY; without even the implied warranty of
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke GNU General Public License for more details.
df6ca59bbc7bd5371359e385e028f069752c54dfChristian Maeder You should have received a copy of the GNU General Public License
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke along with this program. If not, see <http://www.gnu.org/licenses/>.
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maederstatic void fo_discover_srv_done(struct tevent_req *subreq);
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maederstruct tevent_req *fo_discover_srv_send(TALLOC_CTX *mem_ctx,
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder struct fo_discover_srv_state *state = NULL;
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder req = tevent_req_create(mem_ctx, &state, struct fo_discover_srv_state);
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
9035db0b84603cb494e48ec767f138641d389ca0Christian Maeder subreq = resolv_discover_srv_send(state, ev, resolv_ctx, service,
9035db0b84603cb494e48ec767f138641d389ca0Christian Maeder tevent_req_set_callback(subreq, fo_discover_srv_done, req);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maederstatic void fo_discover_srv_done(struct tevent_req *subreq)
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder struct fo_discover_srv_state *state = NULL;
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder req = tevent_req_callback_data(subreq, struct tevent_req);
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder state = tevent_req_data(req, struct fo_discover_srv_state);
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder &reply_list, &state->ttl, &state->dns_domain);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder DEBUG(SSSDBG_TRACE_FUNC, "Got answer. Processing...\n");
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke /* sort and store the answer */
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "Could not sort the answers from DNS "
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder for (record = reply_list; record != NULL; record = record->next) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder DEBUG(SSSDBG_TRACE_FUNC, "Got %zu servers\n", state->num_servers);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->servers = talloc_array(state, struct fo_server_info,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->servers[i].host = talloc_steal(state->servers, record->host);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->servers[i].priority = record->priority;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maedererrno_t fo_discover_srv_recv(TALLOC_CTX *mem_ctx,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder struct fo_discover_srv_state *state = NULL;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state = tevent_req_data(req, struct fo_discover_srv_state);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder *_dns_domain = talloc_steal(mem_ctx, state->dns_domain);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder *_servers = talloc_steal(mem_ctx, state->servers);
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maederstatic void fo_discover_servers_primary_done(struct tevent_req *subreq);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maederstatic void fo_discover_servers_backup_done(struct tevent_req *subreq);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maederstruct tevent_req *fo_discover_servers_send(TALLOC_CTX *mem_ctx,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder struct fo_discover_servers_state *state = NULL;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->service = talloc_strdup(state, service);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->protocol = talloc_strdup(state, protocol);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->primary_domain = talloc_strdup(state, primary_domain);
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke state->backup_domain = talloc_strdup(state, backup_domain);
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke if (state->backup_domain == NULL && backup_domain != NULL) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder DEBUG(SSSDBG_TRACE_FUNC, "Looking up primary servers\n");
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke domains = talloc_zero_array(state, const char *, 3);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder subreq = fo_discover_srv_send(state, ev, resolv_ctx,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder tevent_req_set_callback(subreq, fo_discover_servers_primary_done, req);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maederstatic void fo_discover_servers_primary_done(struct tevent_req *subreq)
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder struct fo_discover_servers_state *state = NULL;
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke req = tevent_req_callback_data(subreq, struct tevent_req);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state = tevent_req_data(req, struct fo_discover_servers_state);
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke DEBUG(SSSDBG_OP_FAILURE, "Unable to retrieve primary servers "
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (ret != ERR_SRV_NOT_FOUND && ret != ERR_SRV_LOOKUP_ERROR) {
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke /* abort on system error */
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke /* if there is no backup domain, we are done */
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder DEBUG(SSSDBG_TRACE_FUNC, "No backup domain specified\n");
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder && strcasecmp(state->dns_domain, state->backup_domain) == 0) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder /* If there was no error and dns_domain is the same as backup domain,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder * it means that we were unable to resolve SRV in primary domain, but
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder * SRV from backup domain was resolved and those servers are considered
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder * to be primary. We are done. */
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder DEBUG(SSSDBG_TRACE_FUNC, "Looking up backup servers\n");
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder domains = talloc_zero_array(state, const char *, 2);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder subreq = fo_discover_srv_send(state, state->ev, state->resolv_ctx,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder tevent_req_set_callback(subreq, fo_discover_servers_backup_done, req);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maederstatic void fo_discover_servers_backup_done(struct tevent_req *subreq)
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder struct fo_discover_servers_state *state = NULL;
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder req = tevent_req_callback_data(subreq, struct tevent_req);
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke state = tevent_req_data(req, struct fo_discover_servers_state);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder ret = fo_discover_srv_recv(state, subreq, NULL,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder DEBUG(SSSDBG_MINOR_FAILURE, "Unable to retrieve backup servers "
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (ret == ERR_SRV_NOT_FOUND || ret == ERR_SRV_LOOKUP_ERROR) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder /* we have successfully fetched primary servers, so we will
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder * finish the request normally on non system error */
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maedererrno_t fo_discover_servers_recv(TALLOC_CTX *mem_ctx,
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke struct fo_discover_servers_state *state = NULL;
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke state = tevent_req_data(req, struct fo_discover_servers_state);
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke *_primary_servers = talloc_steal(mem_ctx, state->primary_servers);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder *_num_primary_servers = state->num_primary_servers;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder *_backup_servers = talloc_steal(mem_ctx, state->backup_servers);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder *_num_backup_servers = state->num_backup_servers;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder *_dns_domain = talloc_steal(mem_ctx, state->dns_domain);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maederstatic void fo_resolve_srv_dns_domain_done(struct tevent_req *subreq);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maederstatic errno_t fo_resolve_srv_dns_discover(struct tevent_req *req);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maederstatic void fo_resolve_srv_dns_done(struct tevent_req *subreq);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maederfo_resolve_srv_dns_ctx_init(TALLOC_CTX *mem_ctx,
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke ctx = talloc_zero(mem_ctx, struct fo_resolve_srv_dns_ctx);
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke ctx->sssd_domain = talloc_strdup(ctx, sssd_domain);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maederstruct tevent_req *fo_resolve_srv_dns_send(TALLOC_CTX *mem_ctx,
9035db0b84603cb494e48ec767f138641d389ca0Christian Maeder struct fo_resolve_srv_dns_state *state = NULL;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder req = tevent_req_create(mem_ctx, &state, struct fo_resolve_srv_dns_state);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder ctx = talloc_get_type(pvt, struct fo_resolve_srv_dns_ctx);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->discovery_domain = discovery_domain;
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder if (discovery_domain == NULL && ctx->detected_domain == NULL) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder /* we will try to detect proper discovery domain */
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder subreq = resolv_get_domain_send(state, state->ev, ctx->resolv_ctx,
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke tevent_req_set_callback(subreq, fo_resolve_srv_dns_domain_done, req);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder /* we will use either provided or previously detected
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder * discovery domain */
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maederstatic void fo_resolve_srv_dns_domain_done(struct tevent_req *subreq)
a6f3aafabdb36f0bb079e09de67818fde83f2c92Klaus Luettich struct fo_resolve_srv_dns_state *state = NULL;
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke req = tevent_req_callback_data(subreq, struct tevent_req);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state = tevent_req_data(req, struct fo_resolve_srv_dns_state);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder ret = resolv_get_domain_recv(state->ctx, subreq,
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maederstatic errno_t fo_resolve_srv_dns_discover(struct tevent_req *req)
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder struct fo_resolve_srv_dns_state *state = NULL;
goto done;
goto done;
goto done;
goto done;
done:
return ret;
goto done;
done:
char **_dns_domain,
if (_primary_servers) {
if (_num_primary_servers) {
if (_backup_servers) {
if (_num_backup_servers) {
*_num_backup_servers = 0;
if (_dns_domain) {
if (_ttl) {
return EOK;