diff options
author | Pavel Březina <pbrezina@redhat.com> | 2013-06-18 12:28:36 +0200 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2013-06-21 10:00:28 +0200 |
commit | e5f455afbc2d149527bfd08f4e89903a3a8da17a (patch) | |
tree | 4dfbd9044175db000ff6bbcb4ae8f39ebaa23f46 | |
parent | b509de2164be8fa9a8d52d70883f4ec70b4bddf8 (diff) | |
download | sssd-e5f455afbc2d149527bfd08f4e89903a3a8da17a.tar.gz sssd-e5f455afbc2d149527bfd08f4e89903a3a8da17a.tar.xz sssd-e5f455afbc2d149527bfd08f4e89903a3a8da17a.zip |
failover: return error when SRV lookup returned only duplicates
https://fedorahosted.org/sssd/ticket/1947
Otherwise we risk that the meta server is removed from the server list,
but without a chance to return, because there may be no fo_server with
srv_data = meta.
Also if state->meta->next is NULL (it is still orphaned because we try
to errornously expand it without invoking collapse first), state->out
will be NULL and SSSD will crash.
New error code: ERR_SRV_DUPLICATES
-rw-r--r-- | src/providers/fail_over.c | 23 | ||||
-rw-r--r-- | src/util/util_errors.c | 1 | ||||
-rw-r--r-- | src/util/util_errors.h | 1 |
3 files changed, 23 insertions, 2 deletions
diff --git a/src/providers/fail_over.c b/src/providers/fail_over.c index c4dd1ea01..c5db70242 100644 --- a/src/providers/fail_over.c +++ b/src/providers/fail_over.c @@ -1288,21 +1288,40 @@ resolve_srv_done(struct tevent_req *subreq) backup_servers, num_backup_servers, state->meta->srv_data, state->meta->user_data, - false, NULL); + false, &last_server); if (ret != EOK) { goto done; } } + if (last_server == state->meta) { + /* SRV lookup returned only those servers + * that are already present. */ + DEBUG(SSSDBG_TRACE_FUNC, ("SRV lookup did not return " + "any new server.\n")); + ret = ERR_SRV_DUPLICATES; + goto done; + } + + /* At least one new server was inserted. + * We will return the first new server. */ + if (state->meta->next == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + ("BUG: state->meta->next is NULL\n")); + ret = ERR_INTERNAL; + goto done; + } + state->out = state->meta->next; + /* And remove meta server from the server list. It will be + * inserted again during srv collapse. */ DLIST_REMOVE(state->service->server_list, state->meta); if (state->service->last_tried_server == state->meta) { state->service->last_tried_server = state->out; } set_srv_data_status(state->meta->srv_data, SRV_RESOLVED); - ret = EOK; break; case ERR_SRV_NOT_FOUND: diff --git a/src/util/util_errors.c b/src/util/util_errors.c index 22a3045a6..015c5acaf 100644 --- a/src/util/util_errors.c +++ b/src/util/util_errors.c @@ -44,6 +44,7 @@ struct err_string error_to_str[] = { { "Host Access Denied" }, /* ERR_ACCESS_DENIED */ { "SRV record not found" }, /* ERR_SRV_NOT_FOUND */ { "SRV lookup error" }, /* ERR_SRV_LOOKUP_ERROR */ + { "SRV lookup did not return any new server "}, /* ERR_SRV_DUPLICATES */ { "Dynamic DNS update failed" }, /* ERR_DYNDNS_FAILED */ { "Dynamic DNS update timed out" }, /* ERR_DYNDNS_TIMEOUT */ { "Dynamic DNS update not possible while offline" }, /* ERR_DYNDNS_OFFLINE */ diff --git a/src/util/util_errors.h b/src/util/util_errors.h index 65d37aedb..ca4472823 100644 --- a/src/util/util_errors.h +++ b/src/util/util_errors.h @@ -66,6 +66,7 @@ enum sssd_errors { ERR_ACCESS_DENIED, ERR_SRV_NOT_FOUND, ERR_SRV_LOOKUP_ERROR, + ERR_SRV_DUPLICATES, ERR_DYNDNS_FAILED, ERR_DYNDNS_TIMEOUT, ERR_DYNDNS_OFFLINE, |