summaryrefslogtreecommitdiffstats
path: root/server/providers/ldap/ldap_id.c
diff options
context:
space:
mode:
Diffstat (limited to 'server/providers/ldap/ldap_id.c')
-rw-r--r--server/providers/ldap/ldap_id.c553
1 files changed, 6 insertions, 547 deletions
diff --git a/server/providers/ldap/ldap_id.c b/server/providers/ldap/ldap_id.c
index ba7cdab45..307f1e701 100644
--- a/server/providers/ldap/ldap_id.c
+++ b/server/providers/ldap/ldap_id.c
@@ -28,32 +28,9 @@
#include "util/util.h"
#include "db/sysdb.h"
-#include "providers/dp_backend.h"
#include "providers/ldap/ldap_common.h"
#include "providers/ldap/sdap_async.h"
-/* =Connection-handling-functions========================================= */
-
-static bool connected(struct sdap_id_ctx *ctx)
-{
- if (ctx->gsh) {
- return ctx->gsh->connected;
- }
-
- return false;
-}
-
-static void mark_offline(struct sdap_id_ctx *ctx)
-{
- if (ctx->gsh) {
- /* make sure we mark the connection as gone when we go offline so that
- * we do not try to reuse a bad connection by mistale later */
- talloc_zfree(ctx->gsh);
- }
-
- be_mark_offline(ctx->be);
-}
-
/* =Users-Related-Functions-(by-name,by-uid)============================== */
struct users_get_state {
@@ -111,7 +88,7 @@ static struct tevent_req *users_get_send(TALLOC_CTX *memctx,
SDAP_OPTS_USER, &state->attrs);
if (ret != EOK) goto fail;
- if (!connected(ctx)) {
+ if (!sdap_connected(ctx)) {
if (ctx->gsh) talloc_zfree(ctx->gsh);
@@ -218,7 +195,7 @@ static void users_get_done(struct tevent_req *req)
if (ret == ETIMEDOUT || ret == EFAULT) {
ctx = talloc_get_type(breq->be_ctx->bet_info[BET_ID].pvt_bet_data,
struct sdap_id_ctx);
- mark_offline(ctx);
+ sdap_mark_offline(ctx);
}
}
@@ -282,7 +259,7 @@ static struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
SDAP_OPTS_GROUP, &state->attrs);
if (ret != EOK) goto fail;
- if (!connected(ctx)) {
+ if (!sdap_connected(ctx)) {
if (ctx->gsh) talloc_zfree(ctx->gsh);
@@ -389,7 +366,7 @@ static void groups_get_done(struct tevent_req *req)
if (ret == ETIMEDOUT || ret == EFAULT) {
ctx = talloc_get_type(breq->be_ctx->bet_info[BET_ID].pvt_bet_data,
struct sdap_id_ctx);
- mark_offline(ctx);
+ sdap_mark_offline(ctx);
}
}
@@ -428,7 +405,7 @@ static struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx,
SDAP_OPTS_GROUP, &state->attrs);
if (ret != EOK) goto fail;
- if (!connected(ctx)) {
+ if (!sdap_connected(ctx)) {
if (ctx->gsh) talloc_zfree(ctx->gsh);
@@ -535,7 +512,7 @@ static void groups_by_user_done(struct tevent_req *req)
if (ret == ETIMEDOUT || ret == EFAULT) {
ctx = talloc_get_type(breq->be_ctx->bet_info[BET_ID].pvt_bet_data,
struct sdap_id_ctx);
- mark_offline(ctx);
+ sdap_mark_offline(ctx);
}
}
@@ -636,521 +613,3 @@ void sdap_account_info_handler(struct be_req *breq)
if (ret != EOK) return sdap_handler_done(breq, DP_ERR_FATAL, ret, err);
}
-
-/* ==Enumeration-Task===================================================== */
-
-static struct tevent_req *ldap_id_enumerate_send(struct tevent_context *ev,
- struct sdap_id_ctx *ctx);
-static void ldap_id_enumerate_reschedule(struct tevent_req *req);
-static void ldap_id_enumerate_set_timer(struct sdap_id_ctx *ctx,
- struct timeval tv);
-
-static void ldap_id_enumerate_timeout(struct tevent_context *ev,
- struct tevent_timer *te,
- struct timeval tv, void *pvt);
-
-static void ldap_id_enumerate(struct tevent_context *ev,
- struct tevent_timer *tt,
- struct timeval tv, void *pvt)
-{
- struct sdap_id_ctx *ctx = talloc_get_type(pvt, struct sdap_id_ctx);
- struct tevent_timer *timeout;
- struct tevent_req *req;
- int ert;
-
- if (be_is_offline(ctx->be)) {
- DEBUG(4, ("Backend is marked offline, retry later!\n"));
- /* schedule starting from now, not the last run */
- ldap_id_enumerate_set_timer(ctx, tevent_timeval_current());
- return;
- }
-
- ctx->last_run = tv;
-
- req = ldap_id_enumerate_send(ev, ctx);
- if (!req) {
- DEBUG(1, ("Failed to schedule enumeration, retrying later!\n"));
- /* schedule starting from now, not the last run */
- ldap_id_enumerate_set_timer(ctx, tevent_timeval_current());
- return;
- }
- tevent_req_set_callback(req, ldap_id_enumerate_reschedule, ctx);
-
- /* if enumeration takes so long, either we try to enumerate too
- * frequently, or something went seriously wrong */
- tv = tevent_timeval_current();
- ert = dp_opt_get_int(ctx->opts->basic, SDAP_ENUM_REFRESH_TIMEOUT);
- tv = tevent_timeval_add(&tv, ert, 0);
- timeout = tevent_add_timer(ctx->be->ev, req, tv,
- ldap_id_enumerate_timeout, req);
- return;
-}
-
-static void ldap_id_enumerate_timeout(struct tevent_context *ev,
- struct tevent_timer *te,
- struct timeval tv, void *pvt)
-{
- struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
- struct sdap_id_ctx *ctx = tevent_req_callback_data(req,
- struct sdap_id_ctx);
- int ert;
-
- ert = dp_opt_get_int(ctx->opts->basic, SDAP_ENUM_REFRESH_TIMEOUT);
- DEBUG(1, ("Enumeration timed out! Timeout too small? (%ds)!\n", ert));
- ldap_id_enumerate_set_timer(ctx, tevent_timeval_current());
-
- talloc_zfree(req);
-}
-
-static void ldap_id_enumerate_reschedule(struct tevent_req *req)
-{
- struct sdap_id_ctx *ctx = tevent_req_callback_data(req,
- struct sdap_id_ctx);
- struct timeval tv;
- enum tevent_req_state tstate;
- uint64_t err;
-
- if (tevent_req_is_error(req, &tstate, &err)) {
- /* On error schedule starting from now, not the last run */
- tv = tevent_timeval_current();
- } else {
- tv = ctx->last_run;
- }
- talloc_zfree(req);
-
- ldap_id_enumerate_set_timer(ctx, ctx->last_run);
-}
-
-static void ldap_id_enumerate_set_timer(struct sdap_id_ctx *ctx,
- struct timeval tv)
-{
- struct tevent_timer *enum_task;
- int ert;
-
- ert = dp_opt_get_int(ctx->opts->basic, SDAP_ENUM_REFRESH_TIMEOUT);
- tv = tevent_timeval_add(&tv, ert, 0);
- enum_task = tevent_add_timer(ctx->be->ev, ctx, tv, ldap_id_enumerate, ctx);
- if (!enum_task) {
- DEBUG(0, ("FATAL: failed to setup enumeration task!\n"));
- /* shutdown! */
- exit(1);
- }
-}
-
-
-
-struct global_enum_state {
- struct tevent_context *ev;
- struct sdap_id_ctx *ctx;
-};
-
-static struct tevent_req *enum_users_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_id_ctx *ctx);
-static void ldap_id_enum_users_done(struct tevent_req *subreq);
-static struct tevent_req *enum_groups_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_id_ctx *ctx);
-static void ldap_id_enum_groups_done(struct tevent_req *subreq);
-
-static struct tevent_req *ldap_id_enumerate_send(struct tevent_context *ev,
- struct sdap_id_ctx *ctx)
-{
- struct global_enum_state *state;
- struct tevent_req *req, *subreq;
-
- req = tevent_req_create(ctx, &state, struct global_enum_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->ctx = ctx;
-
- subreq = enum_users_send(state, ev, ctx);
- if (!subreq) {
- talloc_zfree(req);
- return NULL;
- }
- tevent_req_set_callback(subreq, ldap_id_enum_users_done, req);
-
- return req;
-}
-
-static void ldap_id_enum_users_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct global_enum_state *state = tevent_req_data(req,
- struct global_enum_state);
- enum tevent_req_state tstate;
- uint64_t err = 0;
-
- if (tevent_req_is_error(subreq, &tstate, &err)) {
- goto fail;
- }
- talloc_zfree(subreq);
-
- subreq = enum_groups_send(state, state->ev, state->ctx);
- if (!subreq) {
- goto fail;
- }
- tevent_req_set_callback(subreq, ldap_id_enum_groups_done, req);
-
- return;
-
-fail:
- if (err) {
- DEBUG(9, ("User enumeration failed with: (%d)[%s]\n",
- (int)err, strerror(err)));
-
- mark_offline(state->ctx);
- }
-
- DEBUG(1, ("Failed to enumerate users, retrying later!\n"));
- tevent_req_done(req);
-}
-
-static void ldap_id_enum_groups_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct global_enum_state *state = tevent_req_data(req,
- struct global_enum_state);
- enum tevent_req_state tstate;
- uint64_t err;
-
- if (tevent_req_is_error(subreq, &tstate, &err)) {
- goto fail;
- }
- talloc_zfree(subreq);
-
- tevent_req_done(req);
- return;
-
-fail:
- /* always go offline on failures */
- mark_offline(state->ctx);
- DEBUG(1, ("Failed to enumerate groups (%d [%s]), retrying later!\n",
- (int)err, strerror(err)));
- tevent_req_done(req);
-}
-
-
-/* ==User-Enumeration===================================================== */
-
-struct enum_users_state {
- struct tevent_context *ev;
- struct sdap_id_ctx *ctx;
-
- char *filter;
- const char **attrs;
-};
-
-static void enum_users_connect_done(struct tevent_req *subreq);
-static void enum_users_op_done(struct tevent_req *subreq);
-
-static struct tevent_req *enum_users_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_id_ctx *ctx)
-{
- struct tevent_req *req, *subreq;
- struct enum_users_state *state;
- int ret;
-
- req = tevent_req_create(memctx, &state, struct enum_users_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->ctx = ctx;
-
- if (ctx->max_user_timestamp) {
- state->filter = talloc_asprintf(state,
- "(&(%s=*)(objectclass=%s)(%s>=%s)(!(%s=%s)))",
- ctx->opts->user_map[SDAP_AT_USER_NAME].name,
- ctx->opts->user_map[SDAP_OC_USER].name,
- ctx->opts->user_map[SDAP_AT_USER_MODSTAMP].name,
- ctx->max_user_timestamp,
- ctx->opts->user_map[SDAP_AT_USER_MODSTAMP].name,
- ctx->max_user_timestamp);
- } else {
- state->filter = talloc_asprintf(state,
- "(&(%s=*)(objectclass=%s))",
- ctx->opts->user_map[SDAP_AT_USER_NAME].name,
- ctx->opts->user_map[SDAP_OC_USER].name);
- }
- if (!state->filter) {
- DEBUG(2, ("Failed to build filter\n"));
- ret = ENOMEM;
- goto fail;
- }
-
- /* TODO: handle attrs_type */
- ret = build_attrs_from_map(state, ctx->opts->user_map,
- SDAP_OPTS_USER, &state->attrs);
- if (ret != EOK) goto fail;
-
- if (!connected(ctx)) {
-
- if (ctx->gsh) talloc_zfree(ctx->gsh);
-
- /* FIXME: add option to decide if tls should be used
- * or SASL/GSSAPI, etc ... */
- subreq = sdap_cli_connect_send(state, ev, ctx->opts, &ctx->rootDSE);
- if (!subreq) {
- ret = ENOMEM;
- goto fail;
- }
-
- tevent_req_set_callback(subreq, enum_users_connect_done, req);
-
- return req;
- }
-
- subreq = sdap_get_users_send(state, state->ev,
- state->ctx->be->domain,
- state->ctx->be->sysdb,
- state->ctx->opts,
- state->ctx->gsh,
- state->attrs, state->filter);
- if (!subreq) {
- ret = ENOMEM;
- goto fail;
- }
- tevent_req_set_callback(subreq, enum_users_op_done, req);
-
- return req;
-
-fail:
- tevent_req_error(req, ret);
- tevent_req_post(req, ev);
- return req;
-}
-
-static void enum_users_connect_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct enum_users_state *state = tevent_req_data(req,
- struct enum_users_state);
- int ret;
-
- ret = sdap_cli_connect_recv(subreq, state->ctx,
- &state->ctx->gsh, &state->ctx->rootDSE);
- talloc_zfree(subreq);
- if (ret) {
- if (ret == ENOTSUP) {
- DEBUG(0, ("Authentication mechanism not Supported by server"));
- }
- tevent_req_error(req, ret);
- return;
- }
-
- subreq = sdap_get_users_send(state, state->ev,
- state->ctx->be->domain,
- state->ctx->be->sysdb,
- state->ctx->opts, state->ctx->gsh,
- state->attrs, state->filter);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, enum_users_op_done, req);
-}
-
-static void enum_users_op_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct enum_users_state *state = tevent_req_data(req,
- struct enum_users_state);
- char *timestamp;
- int ret;
-
- ret = sdap_get_users_recv(subreq, state, &timestamp);
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- if (timestamp) {
- talloc_zfree(state->ctx->max_user_timestamp);
- state->ctx->max_user_timestamp = talloc_steal(state->ctx, timestamp);
- }
-
- DEBUG(4, ("Users higher timestamp: [%s]\n",
- state->ctx->max_user_timestamp));
-
- tevent_req_done(req);
-}
-
-/* =Group-Enumeration===================================================== */
-
-struct enum_groups_state {
- struct tevent_context *ev;
- struct sdap_id_ctx *ctx;
-
- char *filter;
- const char **attrs;
-};
-
-static void enum_groups_connect_done(struct tevent_req *subreq);
-static void enum_groups_op_done(struct tevent_req *subreq);
-
-static struct tevent_req *enum_groups_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_id_ctx *ctx)
-{
- struct tevent_req *req, *subreq;
- struct enum_groups_state *state;
- const char *attr_name;
- int ret;
-
- req = tevent_req_create(memctx, &state, struct enum_groups_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->ctx = ctx;
-
- attr_name = ctx->opts->group_map[SDAP_AT_GROUP_NAME].name;
-
- if (ctx->max_group_timestamp) {
- state->filter = talloc_asprintf(state,
- "(&(%s=*)(objectclass=%s)(%s>=%s)(!(%s=%s)))",
- ctx->opts->group_map[SDAP_AT_GROUP_NAME].name,
- ctx->opts->group_map[SDAP_OC_GROUP].name,
- ctx->opts->group_map[SDAP_AT_GROUP_MODSTAMP].name,
- ctx->max_group_timestamp,
- ctx->opts->group_map[SDAP_AT_GROUP_MODSTAMP].name,
- ctx->max_group_timestamp);
- } else {
- state->filter = talloc_asprintf(state,
- "(&(%s=*)(objectclass=%s))",
- ctx->opts->group_map[SDAP_AT_GROUP_NAME].name,
- ctx->opts->group_map[SDAP_OC_GROUP].name);
- }
- if (!state->filter) {
- DEBUG(2, ("Failed to build filter\n"));
- ret = ENOMEM;
- goto fail;
- }
-
- /* TODO: handle attrs_type */
- ret = build_attrs_from_map(state, ctx->opts->group_map,
- SDAP_OPTS_GROUP, &state->attrs);
- if (ret != EOK) goto fail;
-
- if (!connected(ctx)) {
-
- if (ctx->gsh) talloc_zfree(ctx->gsh);
-
- /* FIXME: add option to decide if tls should be used
- * or SASL/GSSAPI, etc ... */
- subreq = sdap_cli_connect_send(state, ev, ctx->opts, &ctx->rootDSE);
- if (!subreq) {
- ret = ENOMEM;
- goto fail;
- }
-
- tevent_req_set_callback(subreq, enum_groups_connect_done, req);
-
- return req;
- }
-
- subreq = sdap_get_groups_send(state, state->ev,
- state->ctx->be->domain,
- state->ctx->be->sysdb,
- state->ctx->opts, state->ctx->gsh,
- state->attrs, state->filter);
- if (!subreq) {
- ret = ENOMEM;
- goto fail;
- }
- tevent_req_set_callback(subreq, enum_groups_op_done, req);
-
- return req;
-
-fail:
- tevent_req_error(req, ret);
- tevent_req_post(req, ev);
- return req;
-}
-
-static void enum_groups_connect_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct enum_groups_state *state = tevent_req_data(req,
- struct enum_groups_state);
- int ret;
-
- ret = sdap_cli_connect_recv(subreq, state->ctx,
- &state->ctx->gsh, &state->ctx->rootDSE);
- talloc_zfree(subreq);
- if (ret) {
- if (ret == ENOTSUP) {
- DEBUG(0, ("Authentication mechanism not Supported by server"));
- }
- tevent_req_error(req, ret);
- return;
- }
-
- subreq = sdap_get_groups_send(state, state->ev,
- state->ctx->be->domain,
- state->ctx->be->sysdb,
- state->ctx->opts, state->ctx->gsh,
- state->attrs, state->filter);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, enum_groups_op_done, req);
-}
-
-static void enum_groups_op_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct enum_groups_state *state = tevent_req_data(req,
- struct enum_groups_state);
- char *timestamp;
- int ret;
-
- ret = sdap_get_groups_recv(subreq, state, &timestamp);
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- if (timestamp) {
- talloc_zfree(state->ctx->max_group_timestamp);
- state->ctx->max_group_timestamp = talloc_steal(state->ctx, timestamp);
- }
-
- DEBUG(4, ("Groups higher timestamp: [%s]\n",
- state->ctx->max_group_timestamp));
-
- tevent_req_done(req);
-}
-
-int sdap_id_setup_tasks(struct sdap_id_ctx *ctx)
-{
- struct tevent_timer *enum_task;
- int ret = EOK;
-
- /* set up enumeration task */
- if (ctx->be->domain->enumerate) {
- /* run the first one in a couple of seconds so that we have time to
- * finish initializations first*/
- ctx->last_run = tevent_timeval_current_ofs(2, 0);
- enum_task = tevent_add_timer(ctx->be->ev, ctx, ctx->last_run,
- ldap_id_enumerate, ctx);
- if (!enum_task) {
- DEBUG(0, ("FATAL: failed to setup enumeration task!\n"));
- ret = EFAULT;
- }
- }
-
- return ret;
-}
-