summaryrefslogtreecommitdiffstats
path: root/src/providers
diff options
context:
space:
mode:
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"));