summaryrefslogtreecommitdiffstats
path: root/src/providers
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2010-06-01 15:36:56 +0200
committerStephen Gallagher <sgallagh@redhat.com>2010-06-30 07:35:31 -0400
commit780ffc9f6d5e1fcd4df3d390b56cb98878223cc0 (patch)
treee0d94ce0260b4435f5ea882f356adeac41c8fee7 /src/providers
parent2dd3faebcd3cfd00efda38ffd2585d675e696b12 (diff)
downloadsssd-780ffc9f6d5e1fcd4df3d390b56cb98878223cc0.tar.gz
sssd-780ffc9f6d5e1fcd4df3d390b56cb98878223cc0.tar.xz
sssd-780ffc9f6d5e1fcd4df3d390b56cb98878223cc0.zip
Add dns_discovery_domain option
The service discovery used to use the SSSD domain name to perform DNS queries. This is not an optimal solution, for example from the point of view of authconfig. This patch introduces a new option "dns_discovery_domain" that allows to set the domain part of a DNS SRV query. If this option is not set, the default behavior is to use the domain part of the machine's hostname. Fixes: #479
Diffstat (limited to 'src/providers')
-rw-r--r--src/providers/data_provider_fo.c13
-rw-r--r--src/providers/dp_backend.h3
-rw-r--r--src/providers/fail_over.c198
-rw-r--r--src/providers/ipa/ipa_common.c2
-rw-r--r--src/providers/krb5/krb5_common.c2
-rw-r--r--src/providers/ldap/ldap_common.c1
6 files changed, 192 insertions, 27 deletions
diff --git a/src/providers/data_provider_fo.c b/src/providers/data_provider_fo.c
index 56a072aee..1654e2227 100644
--- a/src/providers/data_provider_fo.c
+++ b/src/providers/data_provider_fo.c
@@ -243,9 +243,10 @@ 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,
- const char *domain, void *user_data)
+ void *user_data)
{
struct be_svc_data *svc;
+ char *domain;
int ret;
DLIST_FOR_EACH(svc, ctx->be_fo->svcs) {
@@ -257,6 +258,15 @@ int be_fo_add_srv_server(struct be_ctx *ctx, const char *service_name,
return ENOENT;
}
+ ret = confdb_get_string(ctx->cdb, svc, ctx->conf_path,
+ CONFDB_DOMAIN_DNS_DISCOVERY_NAME,
+ NULL, &domain);
+ if (ret != EOK) {
+ DEBUG(1, ("Failed reading %s from confdb\n",
+ CONFDB_DOMAIN_DNS_DISCOVERY_NAME));
+ return ret;
+ }
+
ret = fo_add_srv_server(svc->fo_service, query_service,
domain, proto, user_data);
if (ret && ret != EEXIST) {
@@ -461,3 +471,4 @@ int be_fo_run_callbacks_at_next_request(struct be_ctx *ctx,
return EOK;
}
+
diff --git a/src/providers/dp_backend.h b/src/providers/dp_backend.h
index 0668859b7..61917b99d 100644
--- a/src/providers/dp_backend.h
+++ b/src/providers/dp_backend.h
@@ -167,7 +167,7 @@ int be_fo_service_add_callback(TALLOC_CTX *memctx,
be_svc_callback_fn_t *fn, void *private_data);
int be_fo_add_srv_server(struct be_ctx *ctx, const char *service_name,
const char *query_service, const char *proto,
- const char *domain, void *user_data);
+ void *user_data);
int be_fo_add_server(struct be_ctx *ctx, const char *service_name,
const char *server, int port, void *user_data);
@@ -179,4 +179,5 @@ int be_resolve_server_recv(struct tevent_req *req, struct fo_server **srv);
int be_fo_run_callbacks_at_next_request(struct be_ctx *ctx,
const char *service_name);
+
#endif /* __DP_BACKEND_H___ */
diff --git a/src/providers/fail_over.c b/src/providers/fail_over.c
index 4fb05c1f6..c965c0e3a 100644
--- a/src/providers/fail_over.c
+++ b/src/providers/fail_over.c
@@ -97,7 +97,7 @@ struct server_common {
};
struct srv_data {
- char *domain;
+ char *dns_domain;
char *proto;
char *srv;
@@ -212,7 +212,7 @@ get_srv_query(TALLOC_CTX *mem_ctx, struct fo_server *server)
query = talloc_asprintf(mem_ctx, "_%s._%s.%s", server->srv_data->srv,
server->srv_data->proto,
- server->srv_data->domain);
+ server->srv_data->dns_domain);
return query;
}
@@ -222,7 +222,7 @@ collapse_srv_lookup(struct fo_server *server)
struct fo_server *tmp, *meta;
meta = server->srv_data->meta;
- DEBUG(4, ("Need to refresh SRV lookup for domain %s\n", meta->srv_data->domain))
+ DEBUG(4, ("Need to refresh SRV lookup for domain %s\n", meta->srv_data->dns_domain))
if (server != meta) {
while (server->prev && server->prev->srv_data == meta->srv_data) {
@@ -498,19 +498,20 @@ create_server_common(TALLOC_CTX *mem_ctx, struct fo_ctx *ctx, const char *name)
int
fo_add_srv_server(struct fo_service *service, const char *srv,
- const char *domain, const char *proto, void *user_data)
+ const char *dns_domain, const char *proto, void *user_data)
{
struct fo_server *server;
DEBUG(3, ("Adding new SRV server in domain '%s', to service '%s'\n",
- domain, service->name));
+ dns_domain ? dns_domain : "unknown", service->name));
DLIST_FOR_EACH(server, service->server_list) {
if (server->user_data != user_data)
continue;
if (fo_is_srv_lookup(server)) {
- if (strcasecmp(server->srv_data->domain, domain) == 0 &&
+ if (((dns_domain == NULL && server->srv_data->dns_domain == NULL) ||
+ strcasecmp(server->srv_data->dns_domain, dns_domain) == 0) &&
strcasecmp(server->srv_data->proto, proto) == 0) {
return EEXIST;
}
@@ -530,14 +531,18 @@ fo_add_srv_server(struct fo_service *service, const char *srv,
if (server->srv_data == NULL)
return ENOMEM;
- server->srv_data->domain = talloc_strdup(server->srv_data, domain);
server->srv_data->proto = talloc_strdup(server->srv_data, proto);
server->srv_data->srv = talloc_strdup(server->srv_data, srv);
- if (server->srv_data->domain == NULL ||
- server->srv_data->proto == NULL ||
+ if (server->srv_data->proto == NULL ||
server->srv_data->srv == NULL)
return ENOMEM;
+ if (dns_domain) {
+ server->srv_data->dns_domain = talloc_strdup(server->srv_data, dns_domain);
+ if (server->srv_data->dns_domain == NULL)
+ return ENOMEM;
+ }
+
server->srv_data->meta = server;
server->srv_data->srv_lookup_status = DEFAULT_SRV_STATUS;
server->srv_data->last_status_change.tv_sec = 0;
@@ -895,6 +900,17 @@ fo_resolve_service_recv(struct tevent_req *req, struct fo_server **server)
*******************************************************************/
static void resolve_srv_done(struct tevent_req *subreq);
+static void resolve_srv_cont(struct tevent_req *req);
+
+struct tevent_req *resolve_get_domain_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct fo_ctx *foctx,
+ struct resolv_ctx *resolv);
+
+static void resolve_getsrv_domain_done(struct tevent_req *req);
+int resolve_get_domain_recv(struct tevent_req *req,
+ TALLOC_CTX *mem_ctx,
+ char **dns_domain);
struct resolve_srv_state {
struct fo_server *meta;
@@ -913,7 +929,6 @@ resolve_srv_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
struct fo_server *server)
{
int ret;
- char *query;
struct tevent_req *req;
struct tevent_req *subreq;
struct resolve_srv_state *state;
@@ -937,19 +952,18 @@ resolve_srv_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
state->meta = collapse_srv_lookup(server);
/* FALLTHROUGH */
case SRV_NEUTRAL: /* Request SRV lookup */
- query = get_srv_query(state, state->meta);
- if (!query) {
- ret = ENOMEM;
- goto done;
- }
- DEBUG(4, ("Searching for servers via SRV query '%s'\n", query));
-
- subreq = resolv_getsrv_send(state, ev, resolv, query);
- if (subreq == NULL) {
- ret = ENOMEM;
- goto done;
+ if (server->srv_data->dns_domain == NULL) {
+ /* we need to look up our DNS domain first */
+ subreq = resolve_get_domain_send(state, ev, ctx, resolv);
+ if (subreq == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+ tevent_req_set_callback(subreq, resolve_getsrv_domain_done, req);
+ break;
}
- tevent_req_set_callback(subreq, resolve_srv_done, req);
+ /* we know the DNS domain, just do the lookup */
+ resolve_srv_cont(req);
break;
case SRV_NOT_RESOLVED: /* query could not be resolved but don't retry yet */
ret = EIO;
@@ -975,6 +989,49 @@ done:
}
static void
+resolve_getsrv_domain_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(subreq,
+ struct tevent_req);
+ struct resolve_srv_state *state = tevent_req_data(req,
+ struct resolve_srv_state);
+ int ret;
+
+ ret = resolve_get_domain_recv(subreq, state->meta->srv_data,
+ &state->meta->srv_data->dns_domain);
+ talloc_zfree(subreq);
+ if (ret) {
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ resolve_srv_cont(req);
+}
+
+static void
+resolve_srv_cont(struct tevent_req *req)
+{
+ struct resolve_srv_state *state = tevent_req_data(req,
+ struct resolve_srv_state);
+ char *query;
+ struct tevent_req *subreq;
+
+ query = get_srv_query(state, state->meta);
+ if (!query) {
+ tevent_req_error(req, ENOMEM);
+ return;
+ }
+ DEBUG(4, ("Searching for servers via SRV query '%s'\n", query));
+
+ subreq = resolv_getsrv_send(state, state->ev, state->resolv, query);
+ if (subreq == NULL) {
+ tevent_req_error(req, ENOMEM);
+ return;
+ }
+ tevent_req_set_callback(subreq, resolve_srv_done, req);
+}
+
+static void
resolve_srv_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(subreq,
@@ -1072,6 +1129,103 @@ resolve_srv_recv(struct tevent_req *req, struct fo_server **server)
return EOK;
}
+/*******************************************************************
+ * Get Fully Qualified Domain Name of the host machine *
+ *******************************************************************/
+struct resolve_get_domain_state {
+ char *fqdn;
+ char hostname[HOST_NAME_MAX];
+};
+
+static void resolve_get_domain_done(struct tevent_req *subreq);
+
+struct tevent_req *
+resolve_get_domain_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct fo_ctx *foctx,
+ struct resolv_ctx *resolv)
+{
+ int ret;
+ struct resolve_get_domain_state *state;
+ struct tevent_req *req, *subreq;
+
+ req = tevent_req_create(mem_ctx, &state, struct resolve_get_domain_state);
+ if (!req) {
+ return NULL;
+ }
+
+ ret = gethostname(state->hostname, HOST_NAME_MAX);
+ if (ret) {
+ DEBUG(2, ("gethostname() failed: [%d]: %s\n",ret, strerror(ret)));
+ return NULL;
+ }
+ state->hostname[HOST_NAME_MAX-1] = '\0';
+ DEBUG(7, ("Host name is: %s\n", state->hostname));
+
+ subreq = resolv_gethostbyname_send(mem_ctx, ev, resolv,
+ state->hostname,
+ foctx->opts->family_order);
+ if (!subreq) {
+ talloc_zfree(req);
+ return NULL;
+ }
+ tevent_req_set_callback(subreq, resolve_get_domain_done, req);
+
+ return req;
+}
+
+static void resolve_get_domain_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(subreq,
+ struct tevent_req);
+ struct resolve_get_domain_state *state = tevent_req_data(req,
+ struct resolve_get_domain_state);
+ struct hostent *hostent;
+ int ret;
+
+ ret = resolv_gethostbyname_recv(subreq, req, NULL, NULL, &hostent);
+ talloc_zfree(subreq);
+ if (ret) {
+ DEBUG(2, ("Could not get fully qualified name for host name %s "
+ "resolver returned: [%d]: %s\n",
+ state->hostname, ret, strerror(ret)));
+ /* We'll proceed with hostname in this case */
+ } else {
+ DEBUG(7, ("The full FQDN is: %s\n", hostent->h_name));
+ state->fqdn = hostent->h_name;
+ }
+ tevent_req_done(req);
+}
+
+int resolve_get_domain_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
+ char **dns_domain)
+{
+ struct resolve_get_domain_state *state = tevent_req_data(req,
+ struct resolve_get_domain_state);
+ char *fqdn;
+ char *domptr;
+
+ TEVENT_REQ_RETURN_ON_ERROR(req);
+
+ fqdn = state->fqdn ? state->fqdn : state->hostname;
+ domptr = strchr(fqdn, '.');
+
+ if (!domptr || (*(domptr+1) == '\0')) {
+ /* If the FQDN did not contain a dot or the dot was the last character
+ * (broken DNS server perhaps */
+ *dns_domain = talloc_strdup(mem_ctx, fqdn);
+ } else {
+ domptr++;
+ *dns_domain = talloc_strdup(mem_ctx, domptr);
+ }
+
+ if (*dns_domain == NULL) {
+ return ENOMEM;
+ }
+
+ return EOK;
+}
+
static void
set_server_common_status(struct server_common *common,
enum server_status status)
diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c
index 3ada423e8..99b1508f9 100644
--- a/src/providers/ipa/ipa_common.c
+++ b/src/providers/ipa/ipa_common.c
@@ -570,7 +570,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, ctx->domain->name, NULL);
+ FO_PROTO_TCP, 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 57d7b1d0c..e5471e3f1 100644
--- a/src/providers/krb5/krb5_common.c
+++ b/src/providers/krb5/krb5_common.c
@@ -338,7 +338,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, ctx->domain->name, NULL);
+ FO_PROTO_TCP, 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 4f1dc067a..978e23276 100644
--- a/src/providers/ldap/ldap_common.c
+++ b/src/providers/ldap/ldap_common.c
@@ -638,7 +638,6 @@ int sdap_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
ret = be_fo_add_srv_server(ctx, service_name,
dns_service_name, FO_PROTO_TCP,
- ctx->domain->name,
srv_user_data);
if (ret) {
DEBUG(0, ("Failed to add server\n"));