ldap_id_enum.c revision 9e99e3c5c45b20189e76e4d2546966ff1fb3ce40
f062ed7bd262a37a909dd77ce5fc23b446818823fielding LDAP Identity Enumeration
2d2eda71267231c2526be701fe655db125852c1ffielding Simo Sorce <ssorce@redhat.com>
2d2eda71267231c2526be701fe655db125852c1ffielding Copyright (C) 2009 Red Hat
2d2eda71267231c2526be701fe655db125852c1ffielding This program is free software; you can redistribute it and/or modify
f062ed7bd262a37a909dd77ce5fc23b446818823fielding it under the terms of the GNU General Public License as published by
2d2eda71267231c2526be701fe655db125852c1ffielding the Free Software Foundation; either version 3 of the License, or
2d2eda71267231c2526be701fe655db125852c1ffielding (at your option) any later version.
2d2eda71267231c2526be701fe655db125852c1ffielding This program is distributed in the hope that it will be useful,
2d2eda71267231c2526be701fe655db125852c1ffielding but WITHOUT ANY WARRANTY; without even the implied warranty of
2d2eda71267231c2526be701fe655db125852c1ffielding MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
f062ed7bd262a37a909dd77ce5fc23b446818823fielding GNU General Public License for more details.
f062ed7bd262a37a909dd77ce5fc23b446818823fielding You should have received a copy of the GNU General Public License
f062ed7bd262a37a909dd77ce5fc23b446818823fielding along with this program. If not, see <http://www.gnu.org/licenses/>.
2d2eda71267231c2526be701fe655db125852c1ffieldingextern struct tevent_req *ldap_id_cleanup_send(TALLOC_CTX *memctx,
f062ed7bd262a37a909dd77ce5fc23b446818823fielding/* ==Enumeration-Task===================================================== */
f062ed7bd262a37a909dd77ce5fc23b446818823fieldingstatic struct tevent_req *ldap_id_enumerate_send(struct tevent_context *ev,
f062ed7bd262a37a909dd77ce5fc23b446818823fieldingstatic void ldap_id_enumerate_reschedule(struct tevent_req *req);
f062ed7bd262a37a909dd77ce5fc23b446818823fieldingstatic void ldap_id_enumerate_timeout(struct tevent_context *ev,
2d2eda71267231c2526be701fe655db125852c1ffieldingstatic void ldap_id_enumerate_timer(struct tevent_context *ev,
2d2eda71267231c2526be701fe655db125852c1ffielding struct sdap_id_ctx *ctx = talloc_get_type(pvt, struct sdap_id_ctx);
2d2eda71267231c2526be701fe655db125852c1ffielding DEBUG(4, ("Backend is marked offline, retry later!\n"));
2d2eda71267231c2526be701fe655db125852c1ffielding /* schedule starting from now, not the last run */
2d2eda71267231c2526be701fe655db125852c1ffielding delay = dp_opt_get_int(ctx->opts->basic, SDAP_ENUM_REFRESH_TIMEOUT);
2d2eda71267231c2526be701fe655db125852c1ffielding DEBUG(1, ("Failed to schedule enumeration, retrying later!\n"));
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb /* schedule starting from now, not the last run */
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb delay = dp_opt_get_int(ctx->opts->basic, SDAP_ENUM_REFRESH_TIMEOUT);
952908500d5f99f35afc5ed510391b9bdc3833farbb tevent_req_set_callback(req, ldap_id_enumerate_reschedule, ctx);
2d2eda71267231c2526be701fe655db125852c1ffielding /* if enumeration takes so long, either we try to enumerate too
30c289e6bc6d28d210b21edd800ab2cfc78a8381wrowe * frequently, or something went seriously wrong */
bd53cb2bf4d77574fd502e1c02d8c3c0d5431967stoddard delay = dp_opt_get_int(ctx->opts->basic, SDAP_ENUM_REFRESH_TIMEOUT);
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbbstatic void ldap_id_enumerate_timeout(struct tevent_context *ev,
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
2d2eda71267231c2526be701fe655db125852c1ffielding delay = dp_opt_get_int(ctx->opts->basic, SDAP_ENUM_REFRESH_TIMEOUT);
2d2eda71267231c2526be701fe655db125852c1ffielding DEBUG(1, ("Enumeration timed out! Timeout too small? (%ds)!\n", delay));
2d2eda71267231c2526be701fe655db125852c1ffieldingstatic void ldap_id_enumerate_reschedule(struct tevent_req *req)
2e123e8beedc9f921448c113e2d6823a92fd5261fielding struct sdap_id_ctx *ctx = tevent_req_callback_data(req,
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb /* On error schedule starting from now, not the last run */
2d2eda71267231c2526be701fe655db125852c1ffielding delay = dp_opt_get_int(ctx->opts->basic, SDAP_ENUM_REFRESH_TIMEOUT);
2d2eda71267231c2526be701fe655db125852c1ffieldingint ldap_id_enumerate_set_timer(struct sdap_id_ctx *ctx, struct timeval tv)
2d2eda71267231c2526be701fe655db125852c1ffielding DEBUG(6, ("Scheduling next enumeration at %ld.%ld\n",
2d2eda71267231c2526be701fe655db125852c1ffielding DEBUG(0, ("FATAL: failed to setup enumeration task!\n"));
2d2eda71267231c2526be701fe655db125852c1ffieldingstatic struct tevent_req *enum_users_send(TALLOC_CTX *memctx,
2d2eda71267231c2526be701fe655db125852c1ffieldingstatic void ldap_id_enum_users_done(struct tevent_req *subreq);
2d2eda71267231c2526be701fe655db125852c1ffieldingstatic struct tevent_req *enum_groups_send(TALLOC_CTX *memctx,
2d2eda71267231c2526be701fe655db125852c1ffieldingstatic void ldap_id_enum_groups_done(struct tevent_req *subreq);
2d2eda71267231c2526be701fe655db125852c1ffieldingstatic void ldap_id_enum_cleanup_done(struct tevent_req *subreq);
2d2eda71267231c2526be701fe655db125852c1ffieldingstatic int ldap_id_enum_users_restart(struct tevent_req *req);
2d2eda71267231c2526be701fe655db125852c1ffieldingstatic int ldap_id_enum_groups_restart(struct tevent_req *req);
2d2eda71267231c2526be701fe655db125852c1ffieldingstatic struct tevent_req *ldap_id_enumerate_send(struct tevent_context *ev,
2d2eda71267231c2526be701fe655db125852c1ffielding req = tevent_req_create(ctx, &state, struct global_enum_state);
2d2eda71267231c2526be701fe655db125852c1ffielding t = dp_opt_get_int(ctx->opts->basic, SDAP_CACHE_PURGE_TIMEOUT);
2d2eda71267231c2526be701fe655db125852c1ffielding if ((ctx->last_purge.tv_sec + t) < ctx->last_enum.tv_sec) {
2d2eda71267231c2526be701fe655db125852c1ffielding subreq = enum_users_send(state, ev, ctx, state->purge);
2d2eda71267231c2526be701fe655db125852c1ffielding tevent_req_set_callback(subreq, ldap_id_enum_users_done, req);
2d2eda71267231c2526be701fe655db125852c1ffieldingstatic void ldap_id_enum_users_done(struct tevent_req *subreq)
2d2eda71267231c2526be701fe655db125852c1ffielding struct tevent_req *req = tevent_req_callback_data(subreq,
2d2eda71267231c2526be701fe655db125852c1ffielding struct global_enum_state *state = tevent_req_data(req,
2d2eda71267231c2526be701fe655db125852c1ffielding subreq = enum_groups_send(state, state->ev, state->ctx, state->purge);
2d2eda71267231c2526be701fe655db125852c1ffielding tevent_req_set_callback(subreq, ldap_id_enum_groups_done, req);
2d2eda71267231c2526be701fe655db125852c1ffielding DEBUG(9, ("User enumeration failed with: (%d)[%s]\n",
2d2eda71267231c2526be701fe655db125852c1ffielding DEBUG(1, ("Failed to enumerate users, retrying later!\n"));
2d2eda71267231c2526be701fe655db125852c1ffieldingstatic void ldap_id_enum_groups_done(struct tevent_req *subreq)
2d2eda71267231c2526be701fe655db125852c1ffielding struct tevent_req *req = tevent_req_callback_data(subreq,
2d2eda71267231c2526be701fe655db125852c1ffielding struct global_enum_state *state = tevent_req_data(req,
2d2eda71267231c2526be701fe655db125852c1ffielding subreq = ldap_id_cleanup_send(state, state->ev, state->ctx);
2d2eda71267231c2526be701fe655db125852c1ffielding tevent_req_set_callback(subreq, ldap_id_enum_cleanup_done, req);
32644678e889a3253f71bde0b3d6daea6d9dc21awrowe /* check if credentials are expired otherwise go offline on failures */
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb DEBUG(1, ("Failed to enumerate groups (%d [%s]), retrying later!\n",
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbbstatic void ldap_id_enum_cleanup_done(struct tevent_req *subreq)
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb struct tevent_req *req = tevent_req_callback_data(subreq,
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbbstatic void ldap_id_enum_users_immediate(struct tevent_context *ctx,
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb subreq = enum_users_send(state, state->ev, state->ctx, state->purge);
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb tevent_req_set_callback(subreq, ldap_id_enum_users_done, req);
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbbstatic int ldap_id_enum_users_restart(struct tevent_req *req)
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb /* schedule a completely new event to avoid deep recursions */
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbbstatic void ldap_id_enum_groups_immediate(struct tevent_context *ctx,
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb subreq = enum_groups_send(state, state->ev, state->ctx, state->purge);
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb tevent_req_set_callback(subreq, ldap_id_enum_groups_done, req);
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbbstatic int ldap_id_enum_groups_restart(struct tevent_req *req)
2d2eda71267231c2526be701fe655db125852c1ffielding /* schedule a completely new event to avoid deep recursions */
2d2eda71267231c2526be701fe655db125852c1ffielding/* ==User-Enumeration===================================================== */
2d2eda71267231c2526be701fe655db125852c1ffielding const char **attrs;
2d2eda71267231c2526be701fe655db125852c1ffieldingstatic void enum_users_connect_done(struct tevent_req *subreq);
2d2eda71267231c2526be701fe655db125852c1ffieldingstatic void enum_users_op_done(struct tevent_req *subreq);
2d2eda71267231c2526be701fe655db125852c1ffieldingstatic struct tevent_req *enum_users_send(TALLOC_CTX *memctx,
2d2eda71267231c2526be701fe655db125852c1ffielding req = tevent_req_create(memctx, &state, struct enum_users_state);
2d2eda71267231c2526be701fe655db125852c1ffielding "(&(%s=*)(objectclass=%s)(%s>=%s)(!(%s=%s)))",
2d2eda71267231c2526be701fe655db125852c1ffielding "(&(%s=*)(objectclass=%s))",
2d2eda71267231c2526be701fe655db125852c1ffielding /* TODO: handle attrs_type */
2d2eda71267231c2526be701fe655db125852c1ffielding ret = build_attrs_from_map(state, ctx->opts->user_map,
2d2eda71267231c2526be701fe655db125852c1ffielding /* FIXME: add option to decide if tls should be used
2d2eda71267231c2526be701fe655db125852c1ffielding * or SASL/GSSAPI, etc ... */
2d2eda71267231c2526be701fe655db125852c1ffielding subreq = sdap_cli_connect_send(state, ev, ctx->opts,
2d2eda71267231c2526be701fe655db125852c1ffielding tevent_req_set_callback(subreq, enum_users_connect_done, req);
2d2eda71267231c2526be701fe655db125852c1ffielding tevent_req_set_callback(subreq, enum_users_op_done, req);
2d2eda71267231c2526be701fe655db125852c1ffieldingstatic void enum_users_connect_done(struct tevent_req *subreq)
2d2eda71267231c2526be701fe655db125852c1ffielding struct tevent_req *req = tevent_req_callback_data(subreq,
2d2eda71267231c2526be701fe655db125852c1ffielding struct enum_users_state *state = tevent_req_data(req,
91f0d8da77152d24e4bbb31ce199282b3fd6e3b2coar DEBUG(0, ("Authentication mechanism not Supported by server"));
54e94821097724bf413d2d4cc70711760f7494e1trawick tevent_req_set_callback(subreq, enum_users_op_done, req);
54e94821097724bf413d2d4cc70711760f7494e1trawickstatic void enum_users_op_done(struct tevent_req *subreq)
54e94821097724bf413d2d4cc70711760f7494e1trawick struct tevent_req *req = tevent_req_callback_data(subreq,
54e94821097724bf413d2d4cc70711760f7494e1trawick struct enum_users_state *state = tevent_req_data(req,
2d2eda71267231c2526be701fe655db125852c1ffielding ret = sdap_get_users_recv(subreq, state, ×tamp);
2d2eda71267231c2526be701fe655db125852c1ffielding state->ctx->max_user_timestamp = talloc_steal(state->ctx, timestamp);
2d2eda71267231c2526be701fe655db125852c1ffielding/* =Group-Enumeration===================================================== */
952908500d5f99f35afc5ed510391b9bdc3833farbb const char **attrs;
2d2eda71267231c2526be701fe655db125852c1ffieldingstatic void enum_groups_connect_done(struct tevent_req *subreq);
952908500d5f99f35afc5ed510391b9bdc3833farbbstatic void enum_groups_op_done(struct tevent_req *subreq);
952908500d5f99f35afc5ed510391b9bdc3833farbbstatic struct tevent_req *enum_groups_send(TALLOC_CTX *memctx,
3887202241db08986e94b252fbd06a55e55d4b2dbhyde req = tevent_req_create(memctx, &state, struct enum_groups_state);
2d2eda71267231c2526be701fe655db125852c1ffielding attr_name = ctx->opts->group_map[SDAP_AT_GROUP_NAME].name;
2d2eda71267231c2526be701fe655db125852c1ffielding "(&(%s=*)(objectclass=%s)(%s>=%s)(!(%s=%s)))",
952908500d5f99f35afc5ed510391b9bdc3833farbb "(&(%s=*)(objectclass=%s))",
952908500d5f99f35afc5ed510391b9bdc3833farbb /* TODO: handle attrs_type */
952908500d5f99f35afc5ed510391b9bdc3833farbb /* FIXME: add option to decide if tls should be used
3887202241db08986e94b252fbd06a55e55d4b2dbhyde * or SASL/GSSAPI, etc ... */
952908500d5f99f35afc5ed510391b9bdc3833farbb tevent_req_set_callback(subreq, enum_groups_connect_done, req);
2d2eda71267231c2526be701fe655db125852c1ffielding tevent_req_set_callback(subreq, enum_groups_op_done, req);
952908500d5f99f35afc5ed510391b9bdc3833farbbstatic void enum_groups_connect_done(struct tevent_req *subreq)
952908500d5f99f35afc5ed510391b9bdc3833farbb struct tevent_req *req = tevent_req_callback_data(subreq,
952908500d5f99f35afc5ed510391b9bdc3833farbb DEBUG(0, ("Authentication mechanism not Supported by server"));
952908500d5f99f35afc5ed510391b9bdc3833farbb tevent_req_set_callback(subreq, enum_groups_op_done, req);
952908500d5f99f35afc5ed510391b9bdc3833farbbstatic void enum_groups_op_done(struct tevent_req *subreq)
952908500d5f99f35afc5ed510391b9bdc3833farbb struct tevent_req *req = tevent_req_callback_data(subreq,