On 04/10/2013 02:13 PM, Jakub Hrozek wrote:
On Tue, Apr 09, 2013 at 02:36:09PM +0200, Pavel Březina wrote:
On 04/08/2013 12:28 PM, Pavel Březina wrote:
This has to be applied atop the first way.
Feel free to ping me for testing environment.
Addressed some review issues raised in other thread.
Maybe you'd change the patch to address the compilation
issue I raised in the other thread, but the code looks good to me and
works OK.
I only have concern about the man page and the default.
<varlistentry>
+ <term>ipa_enable_dns_sites (boolean)</term>
+ <listitem>
+ <para>
+ Enables/disables DNS sites - location based
+ service discovery.
I think just enables is OK. A boolean can enable and disable by definition :)
+ </para>
+ <para>
+ If true and _srv_ is present in ipa_server,
+ SSSD will search for SRV records in
+ (1) _location.hostname.example.com, (2)
example.com.
+ If (1) exists, it is expected to contain primary
+ servers and (2) is treated as backup servers. If
(1)
+ does not exist, (2) is treated as primary servers.
Can you run this paragraph by some native speaker? Maybe we could reword it to
say something like:
"If true and service discovery (see Service Discovery paragraph at the
bottom of the man page) is enabled, then the SSSD will first attempt
location based discovery using a query that contains
"_location.hostname.example.com" and then fall back to traditional SRV
discovery. If the location based discovery succeeds, the IPA servers located
with the location based discovery are treated as primary servers and the IPA
servers located using the traditional SRV discovery are used as back up
servers".
That was just a suggestion, but the original paragraph was not clear to me.
+ </para>
+ <para>
+ Default: true
I think the default should be False until the IPA server supports this
discovery by defualt, too, otherwise there is a wasted round-trip for every IPA
client.
+ </para>
+ </listitem>
+ </varlistentry>
Thanks. Done.
From d919ffc6bb45ed3c02d79dd4f9df145167f288a4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <[email protected]>
Date: Tue, 9 Apr 2013 13:16:23 +0200
Subject: [PATCH 1/2] DNS sites support - add IPA SRV plugin
https://fedorahosted.org/sssd/ticket/1032
---
Makefile.am | 2 +
src/config/SSSDConfig/__init__.py.in | 1 +
src/config/etc/sssd.api.d/sssd-ipa.conf | 1 +
src/man/sssd-ipa.5.xml | 26 +++
src/providers/ipa/ipa_common.h | 1 +
src/providers/ipa/ipa_init.c | 29 +++-
src/providers/ipa/ipa_opts.h | 1 +
src/providers/ipa/ipa_srv.c | 296 ++++++++++++++++++++++++++++++++
src/providers/ipa/ipa_srv.h | 47 +++++
9 files changed, 399 insertions(+), 5 deletions(-)
create mode 100644 src/providers/ipa/ipa_srv.c
create mode 100644 src/providers/ipa/ipa_srv.h
diff --git a/Makefile.am b/Makefile.am
index dc9a7be59f41d4b667495d5ec89a3935e612ca33..01114aae9ff51cc041638a7b0567a39b4f07826a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -463,6 +463,7 @@ dist_noinst_HEADERS = \
src/providers/ipa/ipa_id.h \
src/providers/ipa/ipa_hostid.h \
src/providers/ipa/ipa_opts.h \
+ src/providers/ipa/ipa_srv.h \
src/providers/proxy/proxy.h \
src/tools/tools_util.h \
src/tools/sss_sync_ops.h \
@@ -1485,6 +1486,7 @@ libsss_ipa_la_SOURCES = \
src/providers/ipa/ipa_selinux.c \
src/providers/ipa/ipa_selinux_maps.c \
src/providers/ipa/ipa_selinux_common.c \
+ src/providers/ipa/ipa_srv.c \
src/util/user_info_msg.c \
src/util/find_uid.c \
src/util/sss_ldap.c \
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index a1f223956b2d1a009c57ea5834e4d53c41d8c055..1f997f23813d3e6e3f7360ae8d9e0b8aea391345 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -142,6 +142,7 @@ option_strings = {
'ipa_automount_location' : _("The automounter location this IPA client is using"),
'ipa_master_domain_search_base': _("Search base for object containing info about IPA domain"),
'ipa_ranges_search_base': _("Search base for objects containing info about ID ranges"),
+ 'ipa_enable_dns_sites': _("Enable DNS sites - location based service discovery"),
# [provider/ad]
'ad_domain' : _('Active Directory domain'),
diff --git a/src/config/etc/sssd.api.d/sssd-ipa.conf b/src/config/etc/sssd.api.d/sssd-ipa.conf
index a165bc23afdfb6e691acddbb07c74d4e4672bb14..04855d6cece3876e4fa191ae02747b6d88048f8d 100644
--- a/src/config/etc/sssd.api.d/sssd-ipa.conf
+++ b/src/config/etc/sssd.api.d/sssd-ipa.conf
@@ -10,6 +10,7 @@ ipa_hbac_search_base = str, None, false
ipa_host_search_base = str, None, false
ipa_master_domain_search_base = str, None, false
ipa_ranges_search_base = str, None, false
+ipa_enable_dns_sites = bool, None, false
ldap_uri = str, None, false
ldap_backup_uri = str, None, false
ldap_search_base = str, None, false
diff --git a/src/man/sssd-ipa.5.xml b/src/man/sssd-ipa.5.xml
index c4227da23c3c4adafc529919d930a2ea02796f82..93b30edd1f08865eb356bca8e25e14b229d0d8f6 100644
--- a/src/man/sssd-ipa.5.xml
+++ b/src/man/sssd-ipa.5.xml
@@ -158,6 +158,32 @@
</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term>ipa_enable_dns_sites (boolean)</term>
+ <listitem>
+ <para>
+ Enables DNS sites - location based
+ service discovery.
+ </para>
+ <para>
+ If true and service discovery (see Service
+ Discovery paragraph at the bottom of the man page)
+ is enabled, then the SSSD will first attempt
+ location based discovery using a query that contains
+ "_location.hostname.example.com" and then fall back
+ to traditional SRV discovery. If the location based
+ discovery succeeds, the IPA servers located with
+ the location based discovery are treated as primary
+ servers and the IPA servers located using the
+ traditional SRV discovery are used as back up
+ servers
+ </para>
+ <para>
+ Default: false
+ </para>
+ </listitem>
+ </varlistentry>
<varlistentry>
<term>ipa_hbac_search_base (string)</term>
diff --git a/src/providers/ipa/ipa_common.h b/src/providers/ipa/ipa_common.h
index e3915bebc21d88459cf5574264b901e6bd3657ff..ae1c91731e9637c06dad555d1a87ef2e0cf53184 100644
--- a/src/providers/ipa/ipa_common.h
+++ b/src/providers/ipa/ipa_common.h
@@ -52,6 +52,7 @@ enum ipa_basic_opt {
IPA_HBAC_SUPPORT_SRCHOST,
IPA_AUTOMOUNT_LOCATION,
IPA_RANGES_SEARCH_BASE,
+ IPA_ENABLE_DNS_SITES,
IPA_OPTS_BASIC /* opts counter */
};
diff --git a/src/providers/ipa/ipa_init.c b/src/providers/ipa/ipa_init.c
index cdca706da0d181bbd1bc09cc88dd619c1d814489..b65a6cea1ddd05272a8ae522be5c8b070a93ac1e 100644
--- a/src/providers/ipa/ipa_init.c
+++ b/src/providers/ipa/ipa_init.c
@@ -39,6 +39,7 @@
#include "providers/ipa/ipa_selinux.h"
#include "providers/ldap/sdap_access.h"
#include "providers/ipa/ipa_subdomains.h"
+#include "providers/ipa/ipa_srv.h"
struct ipa_options *ipa_options = NULL;
@@ -111,6 +112,8 @@ int sssm_ipa_id_init(struct be_ctx *bectx,
struct sdap_id_ctx *sdap_ctx;
struct stat stat_buf;
const char *hostname;
+ const char *ipa_domain;
+ struct ipa_srv_plugin_ctx *srv_ctx;
errno_t err;
int ret;
@@ -210,11 +213,27 @@ int sssm_ipa_id_init(struct be_ctx *bectx,
/* setup SRV lookup plugin */
hostname = dp_opt_get_string(ipa_options->basic, IPA_HOSTNAME);
- ret = be_fo_set_dns_srv_lookup_plugin(bectx, hostname);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to set SRV lookup plugin "
- "[%d]: %s\n", ret, strerror(ret)));
- goto done;
+ if (dp_opt_get_bool(ipa_options->basic, IPA_ENABLE_DNS_SITES)) {
+ /* use IPA plugin */
+ ipa_domain = dp_opt_get_string(ipa_options->basic, IPA_DOMAIN);
+ srv_ctx = ipa_srv_plugin_ctx_init(bectx, bectx->be_res->resolv,
+ hostname, ipa_domain);
+ if (srv_ctx == NULL) {
+ DEBUG(SSSDBG_FATAL_FAILURE, ("Out of memory?\n"));
+ ret = ENOMEM;
+ goto done;
+ }
+
+ be_fo_set_srv_lookup_plugin(bectx, ipa_srv_plugin_send,
+ ipa_srv_plugin_recv, srv_ctx, "IPA");
+ } else {
+ /* fall back to standard plugin */
+ ret = be_fo_set_dns_srv_lookup_plugin(bectx, hostname);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to set SRV lookup plugin "
+ "[%d]: %s\n", ret, strerror(ret)));
+ goto done;
+ }
}
*ops = &ipa_id_ops;
diff --git a/src/providers/ipa/ipa_opts.h b/src/providers/ipa/ipa_opts.h
index 970d05b3921463f33c860f70c2a5b75f6b5f4e7d..a3d0210a2dd80500ef27f78b7e85b1a5cd7cca4a 100644
--- a/src/providers/ipa/ipa_opts.h
+++ b/src/providers/ipa/ipa_opts.h
@@ -50,6 +50,7 @@ struct dp_option ipa_basic_opts[] = {
{ "ipa_hbac_support_srchost", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
{ "ipa_automount_location", DP_OPT_STRING, { "default" }, NULL_STRING },
{ "ipa_ranges_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING },
+ { "ipa_enable_dns_sites", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
DP_OPTION_TERMINATOR
};
diff --git a/src/providers/ipa/ipa_srv.c b/src/providers/ipa/ipa_srv.c
new file mode 100644
index 0000000000000000000000000000000000000000..be2583bd1f6affb13ef3a2aef29547ba19b15387
--- /dev/null
+++ b/src/providers/ipa/ipa_srv.c
@@ -0,0 +1,296 @@
+/*
+ Authors:
+ Pavel BÅezina <[email protected]>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include <string.h>
+#include <talloc.h>
+#include <tevent.h>
+
+#include "util/util.h"
+#include "resolv/async_resolv.h"
+#include "providers/fail_over_srv.h"
+
+#define IPA_DNS_LOCATION "_location"
+
+struct ipa_srv_plugin_ctx {
+ struct resolv_ctx *resolv_ctx;
+ const char *hostname;
+ const char *ipa_domain;
+};
+
+struct ipa_srv_plugin_ctx *
+ipa_srv_plugin_ctx_init(TALLOC_CTX *mem_ctx,
+ struct resolv_ctx *resolv_ctx,
+ const char *hostname,
+ const char *ipa_domain)
+{
+ struct ipa_srv_plugin_ctx *ctx = NULL;
+
+ ctx = talloc_zero(mem_ctx, struct ipa_srv_plugin_ctx);
+ if (ctx == NULL) {
+ return NULL;
+ }
+
+ ctx->resolv_ctx = resolv_ctx;
+
+ ctx->hostname = talloc_strdup(ctx, hostname);
+ if (ctx->hostname == NULL) {
+ goto fail;
+ }
+
+ ctx->ipa_domain = talloc_strdup(ctx, ipa_domain);
+ if (ctx->ipa_domain == NULL) {
+ goto fail;
+ }
+
+ return ctx;
+
+fail:
+ talloc_free(ctx);
+ return NULL;
+}
+
+struct ipa_srv_plugin_state {
+ struct tevent_context *ev;
+ struct ipa_srv_plugin_ctx *ctx;
+ const char *service;
+ const char *protocol;
+ const char *discovery_domain;
+
+ 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;
+};
+
+static void ipa_srv_plugin_primary_done(struct tevent_req *subreq);
+static void ipa_srv_plugin_backup_done(struct tevent_req *subreq);
+
+/* If IPA server supports sites, we will use
+ * _locations.hostname.discovery_domain for primary servers and
+ * discovery_domain for backup servers. If the server does not support sites or
+ * client's SRV record is not found, we will use the latter for primary
+ * servers, setting backup servers to NULL */
+struct tevent_req *ipa_srv_plugin_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ const char *service,
+ const char *protocol,
+ const char *discovery_domain,
+ void *pvt)
+{
+ struct ipa_srv_plugin_state *state = NULL;
+ struct ipa_srv_plugin_ctx *ctx = NULL;
+ struct tevent_req *req = NULL;
+ struct tevent_req *subreq = NULL;
+ const char **domains = NULL;
+ errno_t ret;
+
+ req = tevent_req_create(mem_ctx, &state,
+ struct ipa_srv_plugin_state);
+ if (req == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("tevent_req_create() failed\n"));
+ return NULL;
+ }
+
+ ctx = talloc_get_type(pvt, struct ipa_srv_plugin_ctx);
+ if (ctx == NULL) {
+ ret = EINVAL;
+ goto immediately;
+ }
+
+ state->ev = ev;
+ state->ctx = ctx;
+ state->service = service;
+ state->protocol = protocol;
+
+ if (discovery_domain != NULL) {
+ state->discovery_domain = discovery_domain;
+ } else {
+ state->discovery_domain = ctx->ipa_domain;
+ }
+ if (state->discovery_domain == NULL) {
+ ret = ENOMEM;
+ goto immediately;
+ }
+
+ DEBUG(SSSDBG_TRACE_FUNC, ("Looking up primary servers\n"));
+
+ domains = talloc_zero_array(state, const char *, 3);
+ if (domains == NULL) {
+ ret = ENOMEM;
+ goto immediately;
+ }
+
+ if (strchr(ctx->hostname, '.') == NULL) {
+ /* not FQDN, append domain name */
+ domains[0] = talloc_asprintf(domains, IPA_DNS_LOCATION ".%s.%s",
+ ctx->hostname, state->discovery_domain);
+ } else {
+ domains[0] = talloc_asprintf(domains, IPA_DNS_LOCATION ".%s",
+ ctx->hostname);
+ }
+ if (domains[0] == NULL) {
+ ret = ENOMEM;
+ goto immediately;
+ }
+ domains[1] = state->discovery_domain;
+
+ subreq = fo_discover_srv_send(state, ev, ctx->resolv_ctx,
+ state->service, state->protocol, domains);
+ if (subreq == NULL) {
+ ret = ENOMEM;
+ goto immediately;
+ }
+
+ tevent_req_set_callback(subreq, ipa_srv_plugin_primary_done, req);
+
+ return req;
+
+immediately:
+ tevent_req_error(req, ret);
+ tevent_req_post(req, ev);
+
+ return req;
+}
+
+static void ipa_srv_plugin_primary_done(struct tevent_req *subreq)
+{
+ struct ipa_srv_plugin_state *state = NULL;
+ struct tevent_req *req = NULL;
+ const char **domains = NULL;
+ errno_t ret;
+
+ req = tevent_req_callback_data(subreq, struct tevent_req);
+ state = tevent_req_data(req, struct ipa_srv_plugin_state);
+
+ ret = fo_discover_srv_recv(state, subreq,
+ &state->dns_domain,
+ &state->primary_servers,
+ &state->num_primary_servers);
+ talloc_zfree(subreq);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ if (strcmp(state->dns_domain, state->discovery_domain) == 0) {
+ /* IPA server does not support sites or this host is in default site */
+ state->backup_servers = NULL;
+ state->num_backup_servers = 0;
+
+ ret = EOK;
+ goto done;
+ }
+
+ DEBUG(SSSDBG_TRACE_FUNC, ("Looking up backup servers\n"));
+
+ domains = talloc_zero_array(state, const char *, 3);
+ if (domains == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ domains[0] = state->discovery_domain;
+
+ subreq = fo_discover_srv_send(state, state->ev, state->ctx->resolv_ctx,
+ state->service, state->protocol, domains);
+ if (subreq == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ tevent_req_set_callback(subreq, ipa_srv_plugin_backup_done, req);
+
+ ret = EAGAIN;
+
+done:
+ if (ret == EOK) {
+ tevent_req_done(req);
+ } else if (ret != EAGAIN) {
+ tevent_req_error(req, ret);
+ }
+
+ return;
+}
+
+static void ipa_srv_plugin_backup_done(struct tevent_req *subreq)
+{
+ struct ipa_srv_plugin_state *state = NULL;
+ struct tevent_req *req = NULL;
+ errno_t ret;
+
+ req = tevent_req_callback_data(subreq, struct tevent_req);
+ state = tevent_req_data(req, struct ipa_srv_plugin_state);
+
+ ret = fo_discover_srv_recv(state, subreq, NULL,
+ &state->backup_servers,
+ &state->num_backup_servers);
+ talloc_zfree(subreq);
+ if (ret == ERR_SRV_NOT_FOUND || ret == ERR_SRV_LOOKUP_ERROR) {
+ /* we have successfully fetched primary servers, so we will
+ * finish the request normally */
+ DEBUG(SSSDBG_MINOR_FAILURE, ("Unable to retrieve backup servers "
+ "[%d]: %s\n", ret, sss_strerror(ret)));
+ ret = EOK;
+ }
+
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ tevent_req_done(req);
+}
+
+errno_t ipa_srv_plugin_recv(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)
+{
+ struct ipa_srv_plugin_state *state = NULL;
+ state = tevent_req_data(req, struct ipa_srv_plugin_state);
+
+ TEVENT_REQ_RETURN_ON_ERROR(req);
+
+ if (_primary_servers) {
+ *_primary_servers = talloc_steal(mem_ctx, state->primary_servers);
+ }
+
+ if (_num_primary_servers) {
+ *_num_primary_servers = state->num_primary_servers;
+ }
+
+ if (_backup_servers) {
+ *_backup_servers = talloc_steal(mem_ctx, state->backup_servers);
+ }
+
+ if (_num_backup_servers) {
+ *_num_backup_servers = state->num_backup_servers;
+ }
+
+ if (_dns_domain) {
+ *_dns_domain = talloc_steal(mem_ctx, state->dns_domain);
+ }
+
+
+ return EOK;
+}
diff --git a/src/providers/ipa/ipa_srv.h b/src/providers/ipa/ipa_srv.h
new file mode 100644
index 0000000000000000000000000000000000000000..1bfd2eeaebec6ae9d2826aa76060746a32a634fc
--- /dev/null
+++ b/src/providers/ipa/ipa_srv.h
@@ -0,0 +1,47 @@
+/*
+ Authors:
+ Pavel BÅezina <[email protected]>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __IPA_SRV_H__
+#define __IPA_SRV_H__
+
+struct ipa_srv_plugin_ctx;
+
+struct ipa_srv_plugin_ctx *
+ipa_srv_plugin_ctx_init(TALLOC_CTX *mem_ctx,
+ struct resolv_ctx *resolv_ctx,
+ const char *hostname,
+ const char *ipa_domain);
+
+struct tevent_req *ipa_srv_plugin_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ const char *service,
+ const char *protocol,
+ const char *discovery_domain,
+ void *pvt);
+
+errno_t ipa_srv_plugin_recv(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 /* __IPA_SRV_H__ */
--
1.7.11.7
_______________________________________________
sssd-devel mailing list
[email protected]
https://lists.fedorahosted.org/mailman/listinfo/sssd-devel