From 40def28805f9df3ff640209def765723cd8e2de3 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Thu, 25 Nov 2010 11:08:37 +0100 Subject: Allow protocol fallback for SRV queries https://fedorahosted.org/sssd/ticket/691 --- src/man/include/service_discovery.xml | 7 +++++++ src/man/sssd-krb5.5.xml | 5 +++++ src/man/sssd-ldap.5.xml | 5 +++++ src/providers/data_provider_fo.c | 25 ++++++++++++++++++++++--- src/providers/dp_backend.h | 10 ++++++++-- src/providers/fail_over.c | 4 ++-- src/providers/ipa/ipa_common.c | 2 +- src/providers/krb5/krb5_common.c | 2 +- src/providers/ldap/ldap_common.c | 5 ++--- 9 files changed, 53 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/man/include/service_discovery.xml b/src/man/include/service_discovery.xml index d33b4c21..64898dbe 100644 --- a/src/man/include/service_discovery.xml +++ b/src/man/include/service_discovery.xml @@ -31,6 +31,13 @@ manual page for more defails. + + The protocol + + The queries usually specify _tcp as the protocol. Exceptions + are documented in respective option description. + + See Also diff --git a/src/man/sssd-krb5.5.xml b/src/man/sssd-krb5.5.xml index 0238af1b..f5c8ad0a 100644 --- a/src/man/sssd-krb5.5.xml +++ b/src/man/sssd-krb5.5.xml @@ -85,6 +85,11 @@ for more information, refer to the SERVICE DISCOVERY section. + + When using service discovery for KDC or kpasswd servers, + SSSD first searches for DNS entries that specify _udp as + the protocol and falls back to _tcp if none are found. + This option was named krb5_kdcip in earlier releases of SSSD. While the legacy name is recognized diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml index a30b49d1..cf6747e7 100644 --- a/src/man/sssd-ldap.5.xml +++ b/src/man/sssd-ldap.5.xml @@ -902,6 +902,11 @@ for more information, refer to the SERVICE DISCOVERY section. + + When using service discovery for KDC or kpasswd servers, + SSSD first searches for DNS entries that specify _udp as + the protocol and falls back to _tcp if none are found. + diff --git a/src/providers/data_provider_fo.c b/src/providers/data_provider_fo.c index dff0aef2..8617cd23 100644 --- a/src/providers/data_provider_fo.c +++ b/src/providers/data_provider_fo.c @@ -54,6 +54,8 @@ struct be_failover_ctx { struct be_svc_data *svcs; }; +static const char *proto_table[] = { FO_PROTO_TCP, FO_PROTO_UDP, NULL }; + int be_fo_is_srv_identifier(const char *server) { return server && strcasecmp(server, BE_SRV_IDENTIFIER) == 0; @@ -258,12 +260,13 @@ int be_fo_service_add_callback(TALLOC_CTX *memctx, } int be_fo_add_srv_server(struct be_ctx *ctx, const char *service_name, - const char *query_service, const char *proto, - void *user_data) + const char *query_service, enum be_fo_protocol proto, + bool proto_fallback, void *user_data) { struct be_svc_data *svc; char *domain; int ret; + int i; svc = be_fo_find_svc_data(ctx, service_name); if (NULL == svc) { @@ -279,13 +282,29 @@ int be_fo_add_srv_server(struct be_ctx *ctx, const char *service_name, return ret; } + /* Add the first protocol as the primary lookup */ ret = fo_add_srv_server(svc->fo_service, query_service, - domain, proto, user_data); + domain, proto_table[proto], user_data); if (ret && ret != EEXIST) { DEBUG(1, ("Failed to add SRV lookup reference to failover service\n")); return ret; } + if (proto_fallback) { + i = (proto + 1) % BE_FO_PROTO_SENTINEL; + /* All the rest as fallback */ + while (i != proto) { + ret = fo_add_srv_server(svc->fo_service, query_service, + domain, proto_table[i], user_data); + if (ret && ret != EEXIST) { + DEBUG(1, ("Failed to add SRV lookup reference to failover service\n")); + return ret; + } + + i = (i + 1) % BE_FO_PROTO_SENTINEL; + } + } + return EOK; } diff --git a/src/providers/dp_backend.h b/src/providers/dp_backend.h index a31e458f..e11b3b6c 100644 --- a/src/providers/dp_backend.h +++ b/src/providers/dp_backend.h @@ -157,6 +157,12 @@ int be_add_offline_cb(TALLOC_CTX *mem_ctx, void be_run_offline_cb(struct be_ctx *be); /* from data_provider_fo.c */ +enum be_fo_protocol { + BE_FO_PROTO_TCP, + BE_FO_PROTO_UDP, + BE_FO_PROTO_SENTINEL +}; + typedef void (be_svc_callback_fn_t)(void *, struct fo_server *); int be_init_failover(struct be_ctx *ctx); @@ -167,8 +173,8 @@ int be_fo_service_add_callback(TALLOC_CTX *memctx, be_svc_callback_fn_t *fn, void *private_data); int be_fo_get_server_count(struct be_ctx *ctx, const char *service_name); int be_fo_add_srv_server(struct be_ctx *ctx, const char *service_name, - const char *query_service, const char *proto, - void *user_data); + const char *query_service, enum be_fo_protocol proto, + bool proto_fallback, void *user_data); int be_fo_add_server(struct be_ctx *ctx, const char *service_name, const char *server, int port, void *user_data); diff --git a/src/providers/fail_over.c b/src/providers/fail_over.c index fa91aec4..9b818d0c 100644 --- a/src/providers/fail_over.c +++ b/src/providers/fail_over.c @@ -502,8 +502,8 @@ fo_add_srv_server(struct fo_service *service, const char *srv, { struct fo_server *server; - DEBUG(3, ("Adding new SRV server in domain '%s', to service '%s'\n", - dns_domain ? dns_domain : "unknown", service->name)); + DEBUG(3, ("Adding new SRV server in domain '%s', to service '%s' using %s\n", + dns_domain ? dns_domain : "unknown", service->name, proto)); DLIST_FOR_EACH(server, service->server_list) { if (server->user_data != user_data) diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c index aee8b65f..a7f4494b 100644 --- a/src/providers/ipa/ipa_common.c +++ b/src/providers/ipa/ipa_common.c @@ -625,7 +625,7 @@ int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, if (be_fo_is_srv_identifier(list[i])) { ret = be_fo_add_srv_server(ctx, "IPA", "ldap", - FO_PROTO_TCP, NULL); + BE_FO_PROTO_TCP, false, NULL); if (ret) { DEBUG(0, ("Failed to add server\n")); goto done; diff --git a/src/providers/krb5/krb5_common.c b/src/providers/krb5/krb5_common.c index 4d577257..bf47dcc4 100644 --- a/src/providers/krb5/krb5_common.c +++ b/src/providers/krb5/krb5_common.c @@ -387,7 +387,7 @@ int krb5_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, if (be_fo_is_srv_identifier(server_spec)) { ret = be_fo_add_srv_server(ctx, service_name, service_name, - FO_PROTO_TCP, NULL); + BE_FO_PROTO_UDP, true, NULL); if (ret) { DEBUG(0, ("Failed to add server\n")); goto done; diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c index 5de3d554..aa0bac64 100644 --- a/src/providers/ldap/ldap_common.c +++ b/src/providers/ldap/ldap_common.c @@ -692,9 +692,8 @@ int sdap_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, goto done; } - ret = be_fo_add_srv_server(ctx, service_name, - dns_service_name, FO_PROTO_TCP, - srv_user_data); + ret = be_fo_add_srv_server(ctx, service_name, dns_service_name, + BE_FO_PROTO_TCP, false, srv_user_data); if (ret) { DEBUG(0, ("Failed to add server\n")); goto done; -- cgit