From f9961e5f82e0ef474d6492371bfdf9e74e208a99 Mon Sep 17 00:00:00 2001 From: Pavel Březina Date: Tue, 19 Mar 2013 15:53:44 +0100 Subject: DNS sites support - SRV lookup plugin interface https://fedorahosted.org/sssd/ticket/1032 Introduces two new error codes: - ERR_SRV_NOT_FOUND - ERR_SRV_LOOKUP_ERROR Since id_provider is authoritative in case of SRV plugin choise, ability to override the selected pluging during runtime is not desirable. We rely on the fact that id_provider is initialized before all other providers, thus the plugin is set correctly. --- Makefile.am | 1 + src/providers/data_provider_fo.c | 21 ++++++++++++ src/providers/dp_backend.h | 7 ++++ src/providers/fail_over.c | 26 +++++++++++++++ src/providers/fail_over.h | 9 +++++ src/providers/fail_over_srv.h | 72 ++++++++++++++++++++++++++++++++++++++++ src/util/util_errors.c | 2 ++ src/util/util_errors.h | 2 ++ 8 files changed, 140 insertions(+) create mode 100644 src/providers/fail_over_srv.h diff --git a/Makefile.am b/Makefile.am index 503b2b7bb..4e331098b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -431,6 +431,7 @@ dist_noinst_HEADERS = \ src/providers/data_provider.h \ src/providers/dp_backend.h \ src/providers/fail_over.h \ + src/providers/fail_over_srv.h \ src/util/child_common.h \ src/providers/simple/simple_access.h \ src/providers/krb5/krb5_auth.h \ diff --git a/src/providers/data_provider_fo.c b/src/providers/data_provider_fo.c index 04944e52a..232717e75 100644 --- a/src/providers/data_provider_fo.c +++ b/src/providers/data_provider_fo.c @@ -233,6 +233,27 @@ int be_fo_service_add_callback(TALLOC_CTX *memctx, return EOK; } +void be_fo_set_srv_lookup_plugin(struct be_ctx *ctx, + fo_srv_lookup_plugin_send_t send_fn, + fo_srv_lookup_plugin_recv_t recv_fn, + void *pvt, + const char *plugin_name) +{ + bool bret; + + DEBUG(SSSDBG_TRACE_FUNC, ("Trying to set SRV lookup plugin to %s\n", + plugin_name)); + + bret = fo_set_srv_lookup_plugin(ctx->be_fo->fo_ctx, send_fn, recv_fn, pvt); + if (bret) { + DEBUG(SSSDBG_TRACE_FUNC, ("SRV lookup plugin is now %s\n", + plugin_name)); + } else { + DEBUG(SSSDBG_MINOR_FAILURE, ("Unable to set SRV lookup plugin, " + "another plugin may be already in place\n")); + } +} + int be_fo_add_srv_server(struct be_ctx *ctx, const char *service_name, const char *query_service, diff --git a/src/providers/dp_backend.h b/src/providers/dp_backend.h index 01d1e43be..1b8a59e60 100644 --- a/src/providers/dp_backend.h +++ b/src/providers/dp_backend.h @@ -211,6 +211,13 @@ int be_fo_service_add_callback(TALLOC_CTX *memctx, struct be_ctx *ctx, const char *service_name, be_svc_callback_fn_t *fn, void *private_data); int be_fo_get_server_count(struct be_ctx *ctx, const char *service_name); + +void be_fo_set_srv_lookup_plugin(struct be_ctx *ctx, + fo_srv_lookup_plugin_send_t send_fn, + fo_srv_lookup_plugin_recv_t recv_fn, + void *pvt, + const char *plugin_name); + int be_fo_add_srv_server(struct be_ctx *ctx, const char *service_name, const char *query_service, diff --git a/src/providers/fail_over.c b/src/providers/fail_over.c index e7c44174d..900e2d6a5 100644 --- a/src/providers/fail_over.c +++ b/src/providers/fail_over.c @@ -55,6 +55,10 @@ struct fo_ctx { struct server_common *server_common_list; struct fo_options *opts; + + fo_srv_lookup_plugin_send_t srv_send_fn; + fo_srv_lookup_plugin_recv_t srv_recv_fn; + void *srv_pvt; }; struct fo_service { @@ -1591,3 +1595,25 @@ bool fo_svc_has_server(struct fo_service *service, struct fo_server *server) return false; } + +bool fo_set_srv_lookup_plugin(struct fo_ctx *ctx, + fo_srv_lookup_plugin_send_t send_fn, + fo_srv_lookup_plugin_recv_t recv_fn, + void *pvt) +{ + if (ctx == NULL || send_fn == NULL || recv_fn == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid parameters\n")); + return false; + } + + if (ctx->srv_send_fn != NULL || ctx->srv_recv_fn != NULL) { + DEBUG(SSSDBG_MINOR_FAILURE, ("SRV lookup plugin is already set\n")); + return false; + } + + ctx->srv_send_fn = send_fn; + ctx->srv_recv_fn = recv_fn; + ctx->srv_pvt = talloc_steal(ctx, pvt); + + return true; +} diff --git a/src/providers/fail_over.h b/src/providers/fail_over.h index 1ad081e78..3a0bd9b1b 100644 --- a/src/providers/fail_over.h +++ b/src/providers/fail_over.h @@ -29,6 +29,7 @@ #include #include "resolv/async_resolv.h" +#include "providers/fail_over_srv.h" #define FO_PROTO_TCP "tcp" #define FO_PROTO_UDP "udp" @@ -198,4 +199,12 @@ void fo_reset_services(struct fo_ctx *fo_ctx); bool fo_svc_has_server(struct fo_service *service, struct fo_server *server); +/* + * pvt will be talloc_stealed to ctx + */ +bool fo_set_srv_lookup_plugin(struct fo_ctx *ctx, + fo_srv_lookup_plugin_send_t send_fn, + fo_srv_lookup_plugin_recv_t recv_fn, + void *pvt); + #endif /* !__FAIL_OVER_H__ */ diff --git a/src/providers/fail_over_srv.h b/src/providers/fail_over_srv.h new file mode 100644 index 000000000..0796ad5ab --- /dev/null +++ b/src/providers/fail_over_srv.h @@ -0,0 +1,72 @@ +/* + Authors: + Pavel B??ezina + + Copyright (C) 2013 Red Hat + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef __FAIL_OVER_SRV_H__ +#define __FAIL_OVER_SRV_H__ + +#include +#include + +#include "resolv/async_resolv.h" + +/* SRV lookup plugin interface */ + +struct fo_server_info { + char *host; + int port; +}; + +/* + * If discovery_domain is NULL, it should be detected automatically. + */ +typedef struct tevent_req * +(*fo_srv_lookup_plugin_send_t)(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + const char *service, + const char *protocol, + const char *discovery_domain, + void *pvt); + +/* + * Returns: + * EOK - at least one primary or backup server was found + * ERR_SRV_NOT_FOUND - no primary nor backup server found + * ERR_SRV_LOOKUP_ERROR - error communicating with SRV database + * other code - depends on plugin + * + * If EOK is returned: + * - and no primary server is found: + * *_primary_servers = NULL + * *_num_primary_servers = 0 + * - and no backup server is found: + * *_backup_servers = NULL + * *_num_backup_servers = 0 + * - *_dns_domain = DNS domain name where the servers were found + */ +typedef errno_t +(*fo_srv_lookup_plugin_recv_t)(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + char **_dns_domain, + struct fo_server_info **_primary_servers, + size_t *_num_primary_servers, + struct fo_server_info **_backup_servers, + size_t *_num_backup_servers); + +#endif /* __FAIL_OVER_SRV_H__ */ diff --git a/src/util/util_errors.c b/src/util/util_errors.c index 475a3cbd8..b5c1928cb 100644 --- a/src/util/util_errors.c +++ b/src/util/util_errors.c @@ -41,6 +41,8 @@ struct err_string error_to_str[] = { { "Account Expired" }, /* ERR_ACCOUNT_EXPIRED */ { "Password Expired" }, /* ERR_PASSWORD_EXPIRED */ { "Host Access Denied" }, /* ERR_ACCESS_DENIED */ + { "SRV record not found" }, /* ERR_SRV_NOT_FOUND */ + { "SRV lookup error" }, /* ERR_SRV_LOOKUP_ERROR */ }; diff --git a/src/util/util_errors.h b/src/util/util_errors.h index b4dfaf85f..4f7c0086e 100644 --- a/src/util/util_errors.h +++ b/src/util/util_errors.h @@ -63,6 +63,8 @@ enum sssd_errors { ERR_ACCOUNT_EXPIRED, ERR_PASSWORD_EXPIRED, ERR_ACCESS_DENIED, + ERR_SRV_NOT_FOUND, + ERR_SRV_LOOKUP_ERROR, ERR_LAST /* ALWAYS LAST */ }; -- cgit