summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2012-07-31 17:25:35 +0200
committerJakub Hrozek <jhrozek@redhat.com>2012-08-07 11:39:16 +0200
commit10a67601de071a664df84dd98255b629d739710f (patch)
treecc1f79a14c6e6886b40498b4c497f9716c97a8fe
parent33dd2356d5b2cadf14e912a0e9f7a8a56f6bc5f1 (diff)
downloadsssd-10a67601de071a664df84dd98255b629d739710f.tar.gz
sssd-10a67601de071a664df84dd98255b629d739710f.tar.xz
sssd-10a67601de071a664df84dd98255b629d739710f.zip
Failover: Return last tried server if it's still being tried
In the failover, we treat both KDC and LDAP on the IPA server as a single "port", numbered 0. This was done in order to make sure that the SSSD always talks to the same server for both LDAP and Kerberos. However, this clever hack breaks when the IPA provider needs to establish an GSSAPI encrypted LDAP connection because we're asking the fail over code to yield a server while no server has yet been marked as tried. This triggers a fail over for the KDC, so in effect, the TGT is received from second server. If the second server is not available for some reason, the whole provider goes offline. The fail over needs to detect that the server asked for is still being resolved and return the same pointer.
-rw-r--r--src/providers/fail_over.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/src/providers/fail_over.c b/src/providers/fail_over.c
index 002d6d578..7fed7cce1 100644
--- a/src/providers/fail_over.c
+++ b/src/providers/fail_over.c
@@ -75,7 +75,7 @@ struct fo_server {
bool primary;
void *user_data;
int port;
- int port_status;
+ enum port_status port_status;
struct srv_data *srv_data;
struct fo_service *service;
struct timeval last_status_change;
@@ -686,12 +686,16 @@ get_first_server_entity(struct fo_service *service, struct fo_server **_server)
* Otherwise iterate through the server list.
*/
-
/* First, try primary servers after the last one we tried.
* (only if the last one was primary as well)
*/
if (service->last_tried_server != NULL &&
service->last_tried_server->primary) {
+ if (service->last_tried_server->port_status == PORT_NEUTRAL) {
+ server = service->last_tried_server;
+ goto done;
+ }
+
DLIST_FOR_EACH(server, service->last_tried_server->next) {
/* Go only through primary servers */
if (!server->primary) continue;