summaryrefslogtreecommitdiffstats
path: root/src/providers/ipa/ipa_subdomains.c
diff options
context:
space:
mode:
authorJan Zeleny <jzeleny@redhat.com>2012-05-15 06:33:13 -0400
committerStephen Gallagher <sgallagh@redhat.com>2012-06-10 15:45:42 -0400
commit84c611c1b7c04cc7735ab54d4e5f48284b79e6fb (patch)
tree003902da01986b7b5464a7f279146d8995b0f340 /src/providers/ipa/ipa_subdomains.c
parentd1b9cd8de7b10f5d54501aace8731db9abbcc0b1 (diff)
downloadsssd-84c611c1b7c04cc7735ab54d4e5f48284b79e6fb.tar.gz
sssd-84c611c1b7c04cc7735ab54d4e5f48284b79e6fb.tar.xz
sssd-84c611c1b7c04cc7735ab54d4e5f48284b79e6fb.zip
IPA subdomains - ask for information about master domain
The query is performed only if there is missing information in the cache. That means this should be done only once after restart when cache doesn't exist. All subsequent requests for subdomains won't include the request for master domain.
Diffstat (limited to 'src/providers/ipa/ipa_subdomains.c')
-rw-r--r--src/providers/ipa/ipa_subdomains.c147
1 files changed, 132 insertions, 15 deletions
diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c
index da9785f2c..185b3c523 100644
--- a/src/providers/ipa/ipa_subdomains.c
+++ b/src/providers/ipa/ipa_subdomains.c
@@ -27,10 +27,24 @@
#include "providers/ipa/ipa_common.h"
#define SUBDOMAINS_FILTER "objectclass=ipaNTTrustedDomain"
+#define MASTER_DOMAIN_FILTER "objectclass=ipaNTDomainAttrs"
+
#define IPA_CN "cn"
#define IPA_FLATNAME "ipaNTFlatName"
#define IPA_SID "ipaNTTrustedDomainSID"
+enum ipa_subdomains_req_type {
+ IPA_SUBDOMAINS_MASTER,
+ IPA_SUBDOMAINS_SLAVE,
+
+ IPA_SUBDOMAINS_MAX /* Counter */
+};
+
+struct ipa_subdomains_req_params {
+ const char *filter;
+ tevent_req_fn cb;
+};
+
static void ipa_subdomains_reply(struct be_req *be_req, int dp_err, int result)
{
be_req->fn(be_req, dp_err, result, NULL);
@@ -131,8 +145,16 @@ struct ipa_subdomains_req_ctx {
};
static void ipa_subdomains_get_conn_done(struct tevent_req *req);
-static errno_t ipa_subdomains_handler_next(struct ipa_subdomains_req_ctx *ctx);
+static errno_t
+ipa_subdomains_handler_get(struct ipa_subdomains_req_ctx *ctx,
+ enum ipa_subdomains_req_type type);
static void ipa_subdomains_handler_done(struct tevent_req *req);
+static void ipa_subdomains_handler_master_done(struct tevent_req *req);
+
+static struct ipa_subdomains_req_params subdomain_requests[] = {
+ { MASTER_DOMAIN_FILTER, ipa_subdomains_handler_master_done },
+ { SUBDOMAINS_FILTER, ipa_subdomains_handler_done }
+};
void ipa_subdomains_handler(struct be_req *be_req)
{
@@ -208,7 +230,7 @@ static void ipa_subdomains_get_conn_done(struct tevent_req *req)
goto fail;
}
- ret = ipa_subdomains_handler_next(ctx);
+ ret = ipa_subdomains_handler_get(ctx, IPA_SUBDOMAINS_SLAVE);
if (ret != EOK && ret != EAGAIN) {
goto fail;
}
@@ -221,23 +243,31 @@ fail:
ipa_subdomains_reply(be_req, dp_error, ret);
}
-static errno_t ipa_subdomains_handler_next(struct ipa_subdomains_req_ctx *ctx)
+static errno_t
+ipa_subdomains_handler_get(struct ipa_subdomains_req_ctx *ctx,
+ enum ipa_subdomains_req_type type)
{
struct tevent_req *req;
struct sdap_search_base *base;
- const char *attrs[] = {"cn",
- "ipaNTFlatName",
- "ipaNTTrustedDomainSID",
+ struct ipa_subdomains_req_params *params;
+ const char *attrs[] = {IPA_CN,
+ IPA_FLATNAME,
+ IPA_SID,
NULL};
+ if (type >= IPA_SUBDOMAINS_MAX) {
+ return EINVAL;
+ }
+
+ params = &subdomain_requests[type];
+
base = ctx->search_bases[ctx->search_base_iter];
if (base == NULL) {
return EOK;
}
talloc_free(ctx->current_filter);
- ctx->current_filter = sdap_get_id_specific_filter(ctx, SUBDOMAINS_FILTER,
- base->filter);
+ ctx->current_filter = sdap_get_id_specific_filter(ctx, params->filter, base->filter);
if (ctx->current_filter == NULL) {
return ENOMEM;
}
@@ -255,7 +285,7 @@ static errno_t ipa_subdomains_handler_next(struct ipa_subdomains_req_ctx *ctx)
return ENOMEM;
}
- tevent_req_set_callback(req, ipa_subdomains_handler_done, ctx);
+ tevent_req_set_callback(req, params->cb, ctx);
return EAGAIN;
}
@@ -263,13 +293,15 @@ static errno_t ipa_subdomains_handler_next(struct ipa_subdomains_req_ctx *ctx)
static void ipa_subdomains_handler_done(struct tevent_req *req)
{
int ret;
- struct be_req *be_req;
size_t reply_count;
struct sysdb_attrs **reply = NULL;
struct ipa_subdomains_req_ctx *ctx = tevent_req_callback_data(req,
struct ipa_subdomains_req_ctx);
+ struct be_req *be_req = ctx->be_req;
+ struct sysdb_ctx *sysdb;
+ struct subdomain_info *domain_info;
- be_req = ctx->be_req;
+ sysdb = (be_req->sysdb)?be_req->sysdb:be_req->be_ctx->sysdb;
ret = sdap_get_generic_recv(req, ctx, &reply_count, &reply);
talloc_zfree(req);
@@ -291,7 +323,7 @@ static void ipa_subdomains_handler_done(struct tevent_req *req)
}
ctx->search_base_iter++;
- ret = ipa_subdomains_handler_next(ctx);
+ ret = ipa_subdomains_handler_get(ctx, IPA_SUBDOMAINS_SLAVE);
if (ret == EAGAIN) {
return;
} else if (ret != EOK) {
@@ -304,14 +336,99 @@ static void ipa_subdomains_handler_done(struct tevent_req *req)
goto done;
}
- ret = sysdb_update_subdomains(ctx->sd_ctx->sdap_id_ctx->be->sysdb,
- ctx->sd_data->domain_list);
+ ret = sysdb_update_subdomains(sysdb, ctx->sd_data->domain_list);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("sysdb_update_subdomains failed.\n"));
goto done;
}
- ret = EOK;
+ ret = sysdb_master_domain_get_info(ctx, sysdb, &domain_info);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ if (domain_info->flat_name == NULL ||
+ domain_info->id == NULL ||
+ domain_info->name == NULL) {
+
+ ctx->search_base_iter = 0;
+ ctx->search_bases = ctx->sd_ctx->master_search_bases;
+ ret = ipa_subdomains_handler_get(ctx, IPA_SUBDOMAINS_MASTER);
+ if (ret == EAGAIN) {
+ return;
+ } else if (ret != EOK) {
+ goto done;
+ }
+ } else {
+ ret = EOK;
+ }
+
+done:
+ talloc_free(ctx);
+ ipa_subdomains_reply(be_req, (ret == EOK ? DP_ERR_OK : DP_ERR_FATAL), ret);
+}
+
+static void ipa_subdomains_handler_master_done(struct tevent_req *req)
+{
+ errno_t ret;
+ size_t reply_count;
+ struct sysdb_attrs **reply = NULL;
+ struct ipa_subdomains_req_ctx *ctx = tevent_req_callback_data(req,
+ struct ipa_subdomains_req_ctx);
+ struct be_req *be_req = ctx->be_req;
+ struct subdomain_info *domain_info;
+ const char *tmp_str;
+
+ ret = sdap_get_generic_recv(req, ctx, &reply_count, &reply);
+ talloc_zfree(req);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("sdap_get_generic_send request failed.\n"));
+ goto done;
+ }
+
+ if (reply_count) {
+ domain_info = talloc_zero(ctx, struct subdomain_info);
+ if (domain_info == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = sysdb_attrs_get_string(reply[0], IPA_FLATNAME, &tmp_str);
+ if (ret != EOK) goto done;
+ domain_info->flat_name = talloc_strdup(domain_info, tmp_str);
+ if (domain_info->flat_name == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = sysdb_attrs_get_string(reply[0], IPA_SID, &tmp_str);
+ if (ret != EOK) {
+ goto done;
+ }
+ domain_info->id = talloc_strdup(domain_info, tmp_str);
+ if (domain_info->flat_name == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = sysdb_master_domain_add_info(be_req->be_ctx->sysdb, domain_info);
+ goto done;
+ } else {
+ ctx->search_base_iter++;
+ ret = ipa_subdomains_handler_get(ctx, IPA_SUBDOMAINS_MASTER);
+ if (ret == EAGAIN) {
+ return;
+ } else if (ret != EOK) {
+ goto done;
+ }
+
+ /* Right now we know there has been an error
+ * and we don't have the master domain record
+ */
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Master domain record not found!\n"));
+ ret = EIO;
+ goto done;
+ }
done:
talloc_free(ctx);