summaryrefslogtreecommitdiffstats
path: root/server/providers/ldap
diff options
context:
space:
mode:
Diffstat (limited to 'server/providers/ldap')
-rw-r--r--server/providers/ldap/ldap_auth.c1055
-rw-r--r--server/providers/ldap/ldap_child.c429
-rw-r--r--server/providers/ldap/ldap_common.c589
-rw-r--r--server/providers/ldap/ldap_common.h115
-rw-r--r--server/providers/ldap/ldap_id.c795
-rw-r--r--server/providers/ldap/ldap_id_cleanup.c555
-rw-r--r--server/providers/ldap/ldap_id_enum.c608
-rw-r--r--server/providers/ldap/ldap_init.c179
-rw-r--r--server/providers/ldap/sdap.c388
-rw-r--r--server/providers/ldap/sdap.h258
-rw-r--r--server/providers/ldap/sdap_async.c1018
-rw-r--r--server/providers/ldap/sdap_async.h126
-rw-r--r--server/providers/ldap/sdap_async_accounts.c2065
-rw-r--r--server/providers/ldap/sdap_async_connection.c1141
-rw-r--r--server/providers/ldap/sdap_async_private.h68
-rw-r--r--server/providers/ldap/sdap_child_helpers.c462
16 files changed, 0 insertions, 9851 deletions
diff --git a/server/providers/ldap/ldap_auth.c b/server/providers/ldap/ldap_auth.c
deleted file mode 100644
index cfe8adb97..000000000
--- a/server/providers/ldap/ldap_auth.c
+++ /dev/null
@@ -1,1055 +0,0 @@
-/*
- SSSD
-
- LDAP Backend Module
-
- Authors:
- Sumit Bose <sbose@redhat.com>
-
- Copyright (C) 2008 Red Hat
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifdef WITH_MOZLDAP
-#define LDAP_OPT_SUCCESS LDAP_SUCCESS
-#define LDAP_TAG_EXOP_MODIFY_PASSWD_ID ((ber_tag_t) 0x80U)
-#define LDAP_TAG_EXOP_MODIFY_PASSWD_OLD ((ber_tag_t) 0x81U)
-#define LDAP_TAG_EXOP_MODIFY_PASSWD_NEW ((ber_tag_t) 0x82U)
-#endif
-
-#define _XOPEN_SOURCE 500 /* for strptime() */
-#include <time.h>
-#undef _XOPEN_SOURCE
-#include <errno.h>
-#include <sys/time.h>
-#include <strings.h>
-
-#include <shadow.h>
-#include <security/pam_modules.h>
-
-#include "util/util.h"
-#include "util/user_info_msg.h"
-#include "db/sysdb.h"
-#include "providers/ldap/ldap_common.h"
-#include "providers/ldap/sdap_async.h"
-
-enum pwexpire {
- PWEXPIRE_NONE = 0,
- PWEXPIRE_LDAP_PASSWORD_POLICY,
- PWEXPIRE_KERBEROS,
- PWEXPIRE_SHADOW
-};
-
-static errno_t check_pwexpire_kerberos(const char *expire_date, time_t now,
- enum sdap_result *result)
-{
- char *end;
- struct tm tm = {0, 0, 0, 0, 0, 0, 0, 0, 0};
- time_t expire_time;
-
- *result = SDAP_AUTH_FAILED;
-
- end = strptime(expire_date, "%Y%m%d%H%M%SZ", &tm);
- if (end == NULL) {
- DEBUG(1, ("Kerberos expire date [%s] invalid.\n", expire_date));
- return EINVAL;
- }
- if (*end != '\0') {
- DEBUG(1, ("Kerberos expire date [%s] contains extra characters.\n",
- expire_date));
- return EINVAL;
- }
-
- expire_time = mktime(&tm);
- if (expire_time == -1) {
- DEBUG(1, ("mktime failed to convert [%s].\n", expire_date));
- return EINVAL;
- }
-
- tzset();
- expire_time -= timezone;
- DEBUG(9, ("Time info: tzname[0] [%s] tzname[1] [%s] timezone [%d] "
- "daylight [%d] now [%d] expire_time [%d].\n", tzname[0],
- tzname[1], timezone, daylight, now, expire_time));
-
- if (difftime(now, expire_time) > 0.0) {
- DEBUG(4, ("Kerberos password expired.\n"));
- *result = SDAP_AUTH_PW_EXPIRED;
- } else {
- *result = SDAP_AUTH_SUCCESS;
- }
-
- return EOK;
-}
-
-static errno_t check_pwexpire_shadow(struct spwd *spwd, time_t now,
- enum sdap_result *result)
-{
- long today;
- long password_age;
-
- if (spwd->sp_lstchg <= 0) {
- DEBUG(4, ("Last change day is not set, new password needed.\n"));
- *result = SDAP_AUTH_PW_EXPIRED;
- return EOK;
- }
-
- today = (long) (now / (60 * 60 *24));
- password_age = today - spwd->sp_lstchg;
- if (password_age < 0) {
- DEBUG(2, ("The last password change time is in the future!.\n"));
- *result = SDAP_AUTH_SUCCESS;
- return EOK;
- }
-
- if ((spwd->sp_expire != -1 && today > spwd->sp_expire) ||
- (spwd->sp_max != -1 && spwd->sp_inact != -1 &&
- password_age > spwd->sp_max + spwd->sp_inact))
- {
- DEBUG(4, ("Account expired.\n"));
- *result = SDAP_ACCT_EXPIRED;
- return EOK;
- }
-
- if (spwd->sp_max != -1 && password_age > spwd->sp_max) {
- DEBUG(4, ("Password expired.\n"));
- *result = SDAP_AUTH_PW_EXPIRED;
- return EOK;
- }
-
-/* TODO: evaluate spwd->min and spwd->warn */
-
- *result = SDAP_AUTH_SUCCESS;
- return EOK;
-}
-
-static errno_t string_to_shadowpw_days(const char *s, long *d)
-{
- long l;
- char *endptr;
-
- if (s == NULL || *s == '\0') {
- *d = -1;
- return EOK;
- }
-
- errno = 0;
- l = strtol(s, &endptr, 10);
- if (errno != 0) {
- DEBUG(1, ("strtol failed [%d][%s].\n", errno, strerror(errno)));
- return errno;
- }
-
- if (*endptr != '\0') {
- DEBUG(1, ("Input string [%s] is invalid.\n", s));
- return EINVAL;
- }
-
- if (*d < -1) {
- DEBUG(1, ("Input string contains not allowed negative value [%d].\n",
- *d));
- return EINVAL;
- }
-
- *d = l;
-
- return EOK;
-}
-
-static errno_t find_password_expiration_attributes(TALLOC_CTX *mem_ctx,
- const struct ldb_message *msg,
- struct dp_option *opts,
- enum pwexpire *type, void **data)
-{
- const char *mark;
- const char *val;
- struct spwd *spwd;
- const char *pwd_policy;
- int ret;
-
- *type = PWEXPIRE_NONE;
- *data = NULL;
-
- pwd_policy = dp_opt_get_string(opts, SDAP_PWD_POLICY);
- if (pwd_policy == NULL) {
- DEBUG(1, ("Missing password policy.\n"));
- return EINVAL;
- }
-
- mark = ldb_msg_find_attr_as_string(msg, SYSDB_PWD_ATTRIBUTE, NULL);
- if (mark != NULL) {
- DEBUG(9, ("Found pwdAttribute, "
- "assuming LDAP password policies are active.\n"));
-
- *type = PWEXPIRE_LDAP_PASSWORD_POLICY;
- return EOK;
- }
-
- if (strcasecmp(pwd_policy, PWD_POL_OPT_NONE) == 0) {
- DEBUG(9, ("No password policy requested.\n"));
- return EOK;
- } else if (strcasecmp(pwd_policy, PWD_POL_OPT_MIT) == 0) {
- mark = ldb_msg_find_attr_as_string(msg, SYSDB_KRBPW_LASTCHANGE, NULL);
- if (mark != NULL) {
- DEBUG(9, ("Found Kerberos password expiration attributes.\n"))
- val = ldb_msg_find_attr_as_string(msg, SYSDB_KRBPW_EXPIRATION,
- NULL);
- if (val != NULL) {
- *data = talloc_strdup(mem_ctx, val);
- if (*data == NULL) {
- DEBUG(1, ("talloc_strdup failed.\n"));
- return ENOMEM;
- }
- *type = PWEXPIRE_KERBEROS;
-
- return EOK;
- }
- } else {
- DEBUG(1, ("No Kerberos password expiration attributes found, "
- "but MIT Kerberos password policy was requested.\n"));
- return EINVAL;
- }
- } else if (strcasecmp(pwd_policy, PWD_POL_OPT_SHADOW) == 0) {
- mark = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_LASTCHANGE, NULL);
- if (mark != NULL) {
- DEBUG(9, ("Found shadow password expiration attributes.\n"))
- spwd = talloc_zero(mem_ctx, struct spwd);
- if (spwd == NULL) {
- DEBUG(1, ("talloc failed.\n"));
- return ENOMEM;
- }
-
- val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_LASTCHANGE, NULL);
- ret = string_to_shadowpw_days(val, &spwd->sp_lstchg);
- if (ret != EOK) goto shadow_fail;
-
- val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_MIN, NULL);
- ret = string_to_shadowpw_days(val, &spwd->sp_min);
- if (ret != EOK) goto shadow_fail;
-
- val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_MAX, NULL);
- ret = string_to_shadowpw_days(val, &spwd->sp_max);
- if (ret != EOK) goto shadow_fail;
-
- val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_WARNING, NULL);
- ret = string_to_shadowpw_days(val, &spwd->sp_warn);
- if (ret != EOK) goto shadow_fail;
-
- val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_INACTIVE, NULL);
- ret = string_to_shadowpw_days(val, &spwd->sp_inact);
- if (ret != EOK) goto shadow_fail;
-
- val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_EXPIRE, NULL);
- ret = string_to_shadowpw_days(val, &spwd->sp_expire);
- if (ret != EOK) goto shadow_fail;
-
- *data = spwd;
- *type = PWEXPIRE_SHADOW;
-
- return EOK;
- } else {
- DEBUG(1, ("No shadow password attributes found, "
- "but shadow password policy was requested.\n"));
- return EINVAL;
- }
- }
-
- DEBUG(9, ("No password expiration attributes found.\n"));
- return EOK;
-
-shadow_fail:
- talloc_free(spwd);
- return ret;
-}
-
-/* ==Get-User-DN========================================================== */
-
-struct get_user_dn_state {
- struct tevent_context *ev;
- struct sdap_auth_ctx *ctx;
- struct sdap_handle *sh;
-
- const char **attrs;
- const char *name;
-
- char *dn;
- enum pwexpire pw_expire_type;
- void *pw_expire_data;
-};
-
-static void get_user_dn_done(void *pvt, int err, struct ldb_result *res);
-
-struct tevent_req *get_user_dn_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_auth_ctx *ctx,
- struct sdap_handle *sh,
- const char *username)
-{
- struct tevent_req *req;
- struct get_user_dn_state *state;
- int ret;
-
- req = tevent_req_create(memctx, &state, struct get_user_dn_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->ctx = ctx;
- state->sh = sh;
- state->name = username;
-
- state->attrs = talloc_array(state, const char *, 11);
- if (!state->attrs) {
- talloc_zfree(req);
- return NULL;
- }
- state->attrs[0] = SYSDB_ORIG_DN;
- state->attrs[1] = SYSDB_SHADOWPW_LASTCHANGE;
- state->attrs[2] = SYSDB_SHADOWPW_MIN;
- state->attrs[3] = SYSDB_SHADOWPW_MAX;
- state->attrs[4] = SYSDB_SHADOWPW_WARNING;
- state->attrs[5] = SYSDB_SHADOWPW_INACTIVE;
- state->attrs[6] = SYSDB_SHADOWPW_EXPIRE;
- state->attrs[7] = SYSDB_KRBPW_LASTCHANGE;
- state->attrs[8] = SYSDB_KRBPW_EXPIRATION;
- state->attrs[9] = SYSDB_PWD_ATTRIBUTE;
- state->attrs[10] = NULL;
-
- /* this sysdb call uses a sysdn operation, which means it will be
- * schedule only after we return, no timer hack needed */
- ret = sysdb_get_user_attr(state, state->ctx->be->sysdb,
- state->ctx->be->domain, state->name,
- state->attrs, get_user_dn_done, req);
- if (ret) {
- tevent_req_error(req, ret);
- tevent_req_post(req, ev);
- }
-
- return req;
-}
-
-static void get_user_dn_done(void *pvt, int err, struct ldb_result *res)
-{
- struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
- struct get_user_dn_state *state = tevent_req_data(req,
- struct get_user_dn_state);
- const char *dn;
- int ret;
-
- if (err != LDB_SUCCESS) {
- tevent_req_error(req, EIO);
- return;
- }
-
- switch (res->count) {
- case 0:
- /* FIXME: not in cache, needs a true search */
- tevent_req_error(req, ENOENT);
- break;
-
- case 1:
- dn = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_ORIG_DN, NULL);
- if (!dn) {
- /* TODO: try to search ldap server ? */
-
- /* FIXME: remove once we store originalDN on every call
- * NOTE: this is wrong, works only with some DITs */
- dn = talloc_asprintf(state, "%s=%s,%s",
- state->ctx->opts->user_map[SDAP_AT_USER_NAME].name,
- state->name,
- dp_opt_get_string(state->ctx->opts->basic,
- SDAP_USER_SEARCH_BASE));
- if (!dn) {
- tevent_req_error(req, ENOMEM);
- break;
- }
- }
-
- state->dn = talloc_strdup(state, dn);
- if (!state->dn) {
- tevent_req_error(req, ENOMEM);
- break;
- }
-
- ret = find_password_expiration_attributes(state, res->msgs[0],
- state->ctx->opts->basic,
- &state->pw_expire_type,
- &state->pw_expire_data);
- if (ret != EOK) {
- DEBUG(1, ("find_password_expiration_attributes failed.\n"));
- tevent_req_error(req, ENOMEM);
- break;
- }
-
- tevent_req_done(req);
- break;
-
- default:
- DEBUG(1, ("A user search by name (%s) returned > 1 results!\n",
- state->name));
- tevent_req_error(req, EFAULT);
- break;
- }
-}
-
-static int get_user_dn_recv(struct tevent_req *req,
- TALLOC_CTX *memctx, char **dn,
- enum pwexpire *pw_expire_type,
- void **pw_expire_data)
-{
- struct get_user_dn_state *state = tevent_req_data(req,
- struct get_user_dn_state);
-
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- *dn = talloc_steal(memctx, state->dn);
- if (!*dn) return ENOMEM;
-
- /* state->pw_expire_data may be NULL */
- *pw_expire_data = talloc_steal(memctx, state->pw_expire_data);
-
- *pw_expire_type = state->pw_expire_type;
-
- return EOK;
-}
-
-/* ==Authenticate-User==================================================== */
-
-struct auth_state {
- struct tevent_context *ev;
- struct sdap_auth_ctx *ctx;
- const char *username;
- struct dp_opt_blob password;
-
- struct sdap_handle *sh;
-
- enum sdap_result result;
- char *dn;
- enum pwexpire pw_expire_type;
- void *pw_expire_data;
-
- struct fo_server *srv;
-};
-
-static void auth_resolve_done(struct tevent_req *subreq);
-static void auth_connect_done(struct tevent_req *subreq);
-static void auth_get_user_dn_done(struct tevent_req *subreq);
-static void auth_bind_user_done(struct tevent_req *subreq);
-
-static struct tevent_req *auth_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_auth_ctx *ctx,
- const char *username,
- struct dp_opt_blob password)
-{
- struct tevent_req *req, *subreq;
- struct auth_state *state;
-
- req = tevent_req_create(memctx, &state, struct auth_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->ctx = ctx;
- state->username = username;
- state->password = password;
- state->srv = NULL;
-
- subreq = be_resolve_server_send(state, ev, ctx->be, ctx->service->name);
- if (!subreq) goto fail;
-
- tevent_req_set_callback(subreq, auth_resolve_done, req);
-
- return req;
-
-fail:
- talloc_zfree(req);
- return NULL;
-}
-
-static void auth_resolve_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct auth_state *state = tevent_req_data(req,
- struct auth_state);
- int ret;
-
- ret = be_resolve_server_recv(subreq, &state->srv);
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- subreq = sdap_connect_send(state, state->ev, state->ctx->opts,
- state->ctx->service->uri, true);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
-
- tevent_req_set_callback(subreq, auth_connect_done, req);
-}
-
-static void auth_connect_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct auth_state *state = tevent_req_data(req,
- struct auth_state);
- int ret;
-
- ret = sdap_connect_recv(subreq, state, &state->sh);
- talloc_zfree(subreq);
- if (ret) {
- if (state->srv) {
- /* mark this server as bad if connection failed */
- fo_set_port_status(state->srv, PORT_NOT_WORKING);
- }
-
- tevent_req_error(req, ret);
- return;
- } else if (state->srv) {
- fo_set_port_status(state->srv, PORT_WORKING);
- }
-
- subreq = get_user_dn_send(state, state->ev,
- state->ctx, state->sh,
- state->username);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
-
- tevent_req_set_callback(subreq, auth_get_user_dn_done, req);
-}
-
-static void auth_get_user_dn_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct auth_state *state = tevent_req_data(req,
- struct auth_state);
- int ret;
-
- ret = get_user_dn_recv(subreq, state, &state->dn, &state->pw_expire_type,
- &state->pw_expire_data);
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- subreq = sdap_auth_send(state, state->ev, state->sh,
- NULL, NULL, state->dn,
- "password", state->password);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
-
- tevent_req_set_callback(subreq, auth_bind_user_done, req);
-}
-
-static void auth_bind_user_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct auth_state *state = tevent_req_data(req,
- struct auth_state);
- int ret;
-
- ret = sdap_auth_recv(subreq, &state->result);
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- tevent_req_done(req);
-}
-
-int auth_recv(struct tevent_req *req,
- TALLOC_CTX *memctx,
- struct sdap_handle **sh,
- enum sdap_result *result, char **dn,
- enum pwexpire *pw_expire_type, void **pw_expire_data)
-{
- struct auth_state *state = tevent_req_data(req, struct auth_state);
- enum tevent_req_state tstate;
- uint64_t err;
-
- if (tevent_req_is_error(req, &tstate, &err)) {
- switch (tstate) {
- case TEVENT_REQ_USER_ERROR:
- if (err == ETIMEDOUT) *result = SDAP_UNAVAIL;
- else *result = SDAP_ERROR;
- return err;
- default:
- *result = SDAP_ERROR;
- return EIO;
- }
- }
-
- if (sh != NULL) {
- *sh = talloc_steal(memctx, state->sh);
- if (*sh == NULL) return ENOMEM;
- }
-
- if (dn != NULL) {
- *dn = talloc_steal(memctx, state->dn);
- if (*dn == NULL) return ENOMEM;
- }
-
- if (pw_expire_data != NULL) {
- *pw_expire_data = talloc_steal(memctx, state->pw_expire_data);
- }
-
- *pw_expire_type = state->pw_expire_type;
-
- *result = state->result;
- return EOK;
-}
-
-/* ==Perform-Password-Change===================== */
-
-struct sdap_pam_chpass_state {
- struct be_req *breq;
- struct pam_data *pd;
- const char *username;
- char *dn;
- char *password;
- char *new_password;
- struct sdap_handle *sh;
-};
-
-static void sdap_auth4chpass_done(struct tevent_req *req);
-static void sdap_pam_chpass_done(struct tevent_req *req);
-static void sdap_pam_auth_reply(struct be_req *breq, int dp_err, int result);
-
-void sdap_pam_chpass_handler(struct be_req *breq)
-{
- struct sdap_pam_chpass_state *state;
- struct sdap_auth_ctx *ctx;
- struct tevent_req *subreq;
- struct pam_data *pd;
- struct dp_opt_blob authtok;
- int dp_err = DP_ERR_FATAL;
-
- ctx = talloc_get_type(breq->be_ctx->bet_info[BET_CHPASS].pvt_bet_data,
- struct sdap_auth_ctx);
- pd = talloc_get_type(breq->req_data, struct pam_data);
-
- if (be_is_offline(ctx->be)) {
- DEBUG(4, ("Backend is marked offline, retry later!\n"));
- pd->pam_status = PAM_AUTHINFO_UNAVAIL;
- dp_err = DP_ERR_OFFLINE;
- goto done;
- }
-
- DEBUG(2, ("starting password change request for user [%s].\n", pd->user));
-
- pd->pam_status = PAM_SYSTEM_ERR;
-
- if (pd->cmd != SSS_PAM_CHAUTHTOK && pd->cmd != SSS_PAM_CHAUTHTOK_PRELIM) {
- DEBUG(2, ("chpass target was called by wrong pam command.\n"));
- goto done;
- }
-
- state = talloc_zero(breq, struct sdap_pam_chpass_state);
- if (!state) goto done;
-
- state->breq = breq;
- state->pd = pd;
- state->username = pd->user;
- state->password = talloc_strndup(state,
- (char *)pd->authtok, pd->authtok_size);
- if (!state->password) goto done;
- talloc_set_destructor((TALLOC_CTX *)state->password,
- password_destructor);
-
- if (pd->cmd == SSS_PAM_CHAUTHTOK) {
- state->new_password = talloc_strndup(state,
- (char *)pd->newauthtok,
- pd->newauthtok_size);
- if (!state->new_password) goto done;
- talloc_set_destructor((TALLOC_CTX *)state->new_password,
- password_destructor);
- }
-
- authtok.data = (uint8_t *)state->password;
- authtok.length = strlen(state->password);
- subreq = auth_send(breq, breq->be_ctx->ev,
- ctx, state->username, authtok);
- if (!subreq) goto done;
-
- tevent_req_set_callback(subreq, sdap_auth4chpass_done, state);
- return;
-
-done:
- sdap_pam_auth_reply(breq, dp_err, pd->pam_status);
-}
-
-static void sdap_auth4chpass_done(struct tevent_req *req)
-{
- struct sdap_pam_chpass_state *state =
- tevent_req_callback_data(req, struct sdap_pam_chpass_state);
- struct tevent_req *subreq;
- enum sdap_result result;
- enum pwexpire pw_expire_type;
- void *pw_expire_data;
- int dp_err = DP_ERR_FATAL;
- int ret;
-
- ret = auth_recv(req, state, &state->sh,
- &result, &state->dn,
- &pw_expire_type, &pw_expire_data);
- talloc_zfree(req);
- if (ret) {
- state->pd->pam_status = PAM_SYSTEM_ERR;
- goto done;
- }
-
- if (result == SDAP_AUTH_SUCCESS &&
- state->pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM) {
- DEBUG(9, ("Initial authentication for change password operation "
- "successful.\n"));
- state->pd->pam_status = PAM_SUCCESS;
- goto done;
- }
-
- if (result == SDAP_AUTH_SUCCESS) {
- switch (pw_expire_type) {
- case PWEXPIRE_SHADOW:
- ret = check_pwexpire_shadow(pw_expire_data, time(NULL),
- &result);
- if (ret != EOK) {
- DEBUG(1, ("check_pwexpire_shadow failed.\n"));
- state->pd->pam_status = PAM_SYSTEM_ERR;
- goto done;
- }
- break;
- case PWEXPIRE_KERBEROS:
- ret = check_pwexpire_kerberos(pw_expire_data, time(NULL),
- &result);
- if (ret != EOK) {
- DEBUG(1, ("check_pwexpire_kerberos failed.\n"));
- state->pd->pam_status = PAM_SYSTEM_ERR;
- goto done;
- }
-
- if (result == SDAP_AUTH_PW_EXPIRED) {
- DEBUG(1, ("LDAP provider cannot change kerberos "
- "passwords.\n"));
- state->pd->pam_status = PAM_SYSTEM_ERR;
- goto done;
- }
- break;
- case PWEXPIRE_LDAP_PASSWORD_POLICY:
- case PWEXPIRE_NONE:
- break;
- default:
- DEBUG(1, ("Unknow pasword expiration type.\n"));
- state->pd->pam_status = PAM_SYSTEM_ERR;
- goto done;
- }
- }
-
- switch (result) {
- case SDAP_AUTH_SUCCESS:
- case SDAP_AUTH_PW_EXPIRED:
- DEBUG(7, ("user [%s] successfully authenticated.\n", state->dn));
- if (pw_expire_type == PWEXPIRE_SHADOW) {
-/* TODO: implement async ldap modify request */
- DEBUG(1, ("Changing shadow password attributes not implemented.\n"));
- state->pd->pam_status = PAM_MODULE_UNKNOWN;
- goto done;
- } else {
- subreq = sdap_exop_modify_passwd_send(state,
- state->breq->be_ctx->ev,
- state->sh,
- state->dn,
- state->password,
- state->new_password);
-
- if (!subreq) {
- DEBUG(2, ("Failed to change password for %s\n", state->username));
- goto done;
- }
-
- tevent_req_set_callback(subreq, sdap_pam_chpass_done, state);
- return;
- }
- break;
- case SDAP_AUTH_FAILED:
- state->pd->pam_status = PAM_AUTH_ERR;
- break;
- default:
- state->pd->pam_status = PAM_SYSTEM_ERR;
- }
-
-done:
- sdap_pam_auth_reply(state->breq, dp_err, state->pd->pam_status);
-}
-
-static void sdap_pam_chpass_done(struct tevent_req *req)
-{
- struct sdap_pam_chpass_state *state =
- tevent_req_callback_data(req, struct sdap_pam_chpass_state);
- enum sdap_result result;
- int dp_err = DP_ERR_FATAL;
- int ret;
- char *user_error_message = NULL;
- size_t msg_len;
- uint8_t *msg;
-
- ret = sdap_exop_modify_passwd_recv(req, state, &result, &user_error_message);
- talloc_zfree(req);
- if (ret) {
- state->pd->pam_status = PAM_SYSTEM_ERR;
- goto done;
- }
-
- switch (result) {
- case SDAP_SUCCESS:
- state->pd->pam_status = PAM_SUCCESS;
- dp_err = DP_ERR_OK;
- break;
- default:
- state->pd->pam_status = PAM_AUTHTOK_ERR;
- if (user_error_message != NULL) {
- ret = pack_user_info_chpass_error(state->pd, user_error_message,
- &msg_len, &msg);
- if (ret != EOK) {
- DEBUG(1, ("pack_user_info_chpass_error failed.\n"));
- } else {
- ret = pam_add_response(state->pd, SSS_PAM_USER_INFO, msg_len,
- msg);
- if (ret != EOK) {
- DEBUG(1, ("pam_add_response failed.\n"));
- }
- }
- }
- }
-
-done:
- sdap_pam_auth_reply(state->breq, dp_err, state->pd->pam_status);
-}
-/* ==Perform-User-Authentication-and-Password-Caching===================== */
-
-struct sdap_pam_auth_state {
- struct be_req *breq;
- struct pam_data *pd;
- const char *username;
- struct dp_opt_blob password;
-};
-
-static void sdap_pam_auth_done(struct tevent_req *req);
-static void sdap_password_cache_done(struct tevent_req *req);
-
-void sdap_pam_auth_handler(struct be_req *breq)
-{
- struct sdap_pam_auth_state *state;
- struct sdap_auth_ctx *ctx;
- struct tevent_req *subreq;
- struct pam_data *pd;
- int dp_err = DP_ERR_FATAL;
-
- ctx = talloc_get_type(breq->be_ctx->bet_info[BET_AUTH].pvt_bet_data,
- struct sdap_auth_ctx);
- pd = talloc_get_type(breq->req_data, struct pam_data);
-
- if (be_is_offline(ctx->be)) {
- DEBUG(4, ("Backend is marked offline, retry later!\n"));
- pd->pam_status = PAM_AUTHINFO_UNAVAIL;
- dp_err = DP_ERR_OFFLINE;
- goto done;
- }
-
- pd->pam_status = PAM_SYSTEM_ERR;
-
- switch (pd->cmd) {
- case SSS_PAM_AUTHENTICATE:
- case SSS_PAM_CHAUTHTOK_PRELIM:
-
- state = talloc_zero(breq, struct sdap_pam_auth_state);
- if (!state) goto done;
-
- state->breq = breq;
- state->pd = pd;
- state->username = pd->user;
- state->password.data = pd->authtok;
- state->password.length = pd->authtok_size;
-
- subreq = auth_send(breq, breq->be_ctx->ev, ctx,
- state->username, state->password);
- if (!subreq) goto done;
-
- tevent_req_set_callback(subreq, sdap_pam_auth_done, state);
- return;
-
- case SSS_PAM_CHAUTHTOK:
- break;
-
- case SSS_PAM_ACCT_MGMT:
- case SSS_PAM_SETCRED:
- case SSS_PAM_OPEN_SESSION:
- case SSS_PAM_CLOSE_SESSION:
- pd->pam_status = PAM_SUCCESS;
- dp_err = DP_ERR_OK;
- break;
- default:
- pd->pam_status = PAM_MODULE_UNKNOWN;
- dp_err = DP_ERR_OK;
- }
-
-done:
- sdap_pam_auth_reply(breq, dp_err, pd->pam_status);
-}
-
-static void sdap_pam_auth_done(struct tevent_req *req)
-{
- struct sdap_pam_auth_state *state =
- tevent_req_callback_data(req, struct sdap_pam_auth_state);
- struct tevent_req *subreq;
- enum sdap_result result;
- enum pwexpire pw_expire_type;
- void *pw_expire_data;
- int dp_err = DP_ERR_OK;
- int ret;
-
- ret = auth_recv(req, state, NULL,
- &result, NULL,
- &pw_expire_type, &pw_expire_data);
- talloc_zfree(req);
- if (ret) {
- state->pd->pam_status = PAM_SYSTEM_ERR;
- dp_err = DP_ERR_FATAL;
- goto done;
- }
-
- if (result == SDAP_AUTH_SUCCESS) {
- switch (pw_expire_type) {
- case PWEXPIRE_SHADOW:
- ret = check_pwexpire_shadow(pw_expire_data, time(NULL),
- &result);
- if (ret != EOK) {
- DEBUG(1, ("check_pwexpire_shadow failed.\n"));
- state->pd->pam_status = PAM_SYSTEM_ERR;
- goto done;
- }
- break;
- case PWEXPIRE_KERBEROS:
- ret = check_pwexpire_kerberos(pw_expire_data, time(NULL),
- &result);
- if (ret != EOK) {
- DEBUG(1, ("check_pwexpire_kerberos failed.\n"));
- state->pd->pam_status = PAM_SYSTEM_ERR;
- goto done;
- }
- break;
- case PWEXPIRE_LDAP_PASSWORD_POLICY:
- case PWEXPIRE_NONE:
- break;
- default:
- DEBUG(1, ("Unknow pasword expiration type.\n"));
- state->pd->pam_status = PAM_SYSTEM_ERR;
- goto done;
- }
- }
-
- switch (result) {
- case SDAP_AUTH_SUCCESS:
- state->pd->pam_status = PAM_SUCCESS;
- break;
- case SDAP_AUTH_FAILED:
- state->pd->pam_status = PAM_PERM_DENIED;
- break;
- case SDAP_UNAVAIL:
- state->pd->pam_status = PAM_AUTHINFO_UNAVAIL;
- break;
- case SDAP_ACCT_EXPIRED:
- state->pd->pam_status = PAM_ACCT_EXPIRED;
- break;
- case SDAP_AUTH_PW_EXPIRED:
- state->pd->pam_status = PAM_AUTHTOK_EXPIRED;
- break;
- default:
- state->pd->pam_status = PAM_SYSTEM_ERR;
- dp_err = DP_ERR_FATAL;
- }
-
- if (result == SDAP_UNAVAIL) {
- be_mark_offline(state->breq->be_ctx);
- dp_err = DP_ERR_OFFLINE;
- goto done;
- }
-
- if (result == SDAP_AUTH_SUCCESS &&
- state->breq->be_ctx->domain->cache_credentials) {
-
- char *password = talloc_strndup(state, (char *)
- state->password.data,
- state->password.length);
- /* password caching failures are not fatal errors */
- if (!password) {
- DEBUG(2, ("Failed to cache password for %s\n", state->username));
- goto done;
- }
- talloc_set_destructor((TALLOC_CTX *)password, password_destructor);
-
- subreq = sysdb_cache_password_send(state,
- state->breq->be_ctx->ev,
- state->breq->be_ctx->sysdb,
- NULL,
- state->breq->be_ctx->domain,
- state->username, password);
-
- /* password caching failures are not fatal errors */
- if (!subreq) {
- DEBUG(2, ("Failed to cache password for %s\n", state->username));
- goto done;
- }
-
- tevent_req_set_callback(subreq, sdap_password_cache_done, state);
- return;
- }
-
-done:
- sdap_pam_auth_reply(state->breq, dp_err, state->pd->pam_status);
-}
-
-static void sdap_password_cache_done(struct tevent_req *subreq)
-{
- struct sdap_pam_auth_state *state = tevent_req_callback_data(subreq,
- struct sdap_pam_auth_state);
- int ret;
-
- ret = sysdb_cache_password_recv(subreq);
- talloc_zfree(subreq);
- if (ret) {
- /* password caching failures are not fatal errors */
- DEBUG(2, ("Failed to cache password for %s\n", state->username));
- } else {
- DEBUG(4, ("Password successfully cached for %s\n", state->username));
- }
-
- sdap_pam_auth_reply(state->breq, DP_ERR_OK, state->pd->pam_status);
-}
-
-static void sdap_pam_auth_reply(struct be_req *req, int dp_err, int result)
-{
- req->fn(req, dp_err, result, NULL);
-}
-
diff --git a/server/providers/ldap/ldap_child.c b/server/providers/ldap/ldap_child.c
deleted file mode 100644
index 0d34be2ca..000000000
--- a/server/providers/ldap/ldap_child.c
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
- SSSD
-
- LDAP Backend Module -- prime ccache with TGT in a child process
-
- Authors:
- Jakub Hrozek <jhrozek@redhat.com>
-
- Copyright (C) 2009 Red Hat
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <sys/types.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <popt.h>
-
-#include <security/pam_modules.h>
-
-#include "util/util.h"
-#include "util/sss_krb5.h"
-#include "providers/child_common.h"
-#include "providers/dp_backend.h"
-
-static krb5_context krb5_error_ctx;
-
-struct input_buffer {
- const char *realm_str;
- const char *princ_str;
- const char *keytab_name;
-};
-
-static errno_t unpack_buffer(uint8_t *buf, size_t size,
- struct input_buffer *ibuf)
-{
- size_t p = 0;
- uint32_t len;
-
- DEBUG(7, ("total buffer size: %d\n", size));
-
- /* realm_str size and length */
- COPY_UINT32_CHECK(&len, buf + p, p, size);
-
- DEBUG(7, ("realm_str size: %d\n", len));
- if (len) {
- if ((p + len ) > size) return EINVAL;
- ibuf->realm_str = talloc_strndup(ibuf, (char *)(buf + p), len);
- DEBUG(7, ("got realm_str: %s\n", ibuf->realm_str));
- if (ibuf->realm_str == NULL) return ENOMEM;
- p += len;
- }
-
- /* princ_str size and length */
- COPY_UINT32_CHECK(&len, buf + p, p, size);
-
- DEBUG(7, ("princ_str size: %d\n", len));
- if (len) {
- if ((p + len ) > size) return EINVAL;
- ibuf->princ_str = talloc_strndup(ibuf, (char *)(buf + p), len);
- DEBUG(7, ("got princ_str: %s\n", ibuf->princ_str));
- if (ibuf->princ_str == NULL) return ENOMEM;
- p += len;
- }
-
- /* keytab_name size and length */
- COPY_UINT32_CHECK(&len, buf + p, p, size);
-
- DEBUG(7, ("keytab_name size: %d\n", len));
- if (len) {
- if ((p + len ) > size) return EINVAL;
- ibuf->keytab_name = talloc_strndup(ibuf, (char *)(buf + p), len);
- DEBUG(7, ("got keytab_name: %s\n", ibuf->keytab_name));
- if (ibuf->keytab_name == NULL) return ENOMEM;
- p += len;
- }
-
- return EOK;
-}
-
-static int pack_buffer(struct response *r, int result, const char *msg)
-{
- int len;
- int p = 0;
-
- len = strlen(msg);
- r->size = 2 * sizeof(uint32_t) + len;
-
- /* result */
- COPY_UINT32_VALUE(&r->buf[p], result, p);
-
- /* message size */
- COPY_UINT32_VALUE(&r->buf[p], len, p);
-
- /* message itself */
- COPY_MEM(&r->buf[p], msg, p, len);
-
- return EOK;
-}
-
-static int ldap_child_get_tgt_sync(TALLOC_CTX *memctx,
- const char *realm_str,
- const char *princ_str,
- const char *keytab_name,
- const char **ccname_out)
-{
- char *ccname;
- char *realm_name = NULL;
- char *full_princ = NULL;
- krb5_context context = NULL;
- krb5_keytab keytab = NULL;
- krb5_ccache ccache = NULL;
- krb5_principal kprinc;
- krb5_creds my_creds;
- krb5_get_init_creds_opt options;
- krb5_error_code krberr;
- int ret;
-
- krberr = krb5_init_context(&context);
- if (krberr) {
- DEBUG(2, ("Failed to init kerberos context\n"));
- return EFAULT;
- }
-
- if (!realm_str) {
- krberr = krb5_get_default_realm(context, &realm_name);
- if (krberr) {
- DEBUG(2, ("Failed to get default realm name: %s\n",
- sss_krb5_get_error_message(context, krberr)));
- ret = EFAULT;
- goto done;
- }
- } else {
- realm_name = talloc_strdup(memctx, realm_str);
- if (!realm_name) {
- ret = ENOMEM;
- goto done;
- }
- }
-
- if (princ_str) {
- if (!strchr(princ_str, '@')) {
- full_princ = talloc_asprintf(memctx, "%s@%s",
- princ_str, realm_name);
- } else {
- full_princ = talloc_strdup(memctx, princ_str);
- }
- } else {
- char hostname[512];
-
- ret = gethostname(hostname, 511);
- if (ret == -1) {
- ret = errno;
- goto done;
- }
- hostname[511] = '\0';
-
- full_princ = talloc_asprintf(memctx, "host/%s@%s",
- hostname, realm_name);
- }
- if (!full_princ) {
- ret = ENOMEM;
- goto done;
- }
- DEBUG(4, ("Principal name is: [%s]\n", full_princ));
-
- krberr = krb5_parse_name(context, full_princ, &kprinc);
- if (krberr) {
- DEBUG(2, ("Unable to build principal: %s\n",
- sss_krb5_get_error_message(context, krberr)));
- ret = EFAULT;
- goto done;
- }
-
- if (keytab_name) {
- krberr = krb5_kt_resolve(context, keytab_name, &keytab);
- } else {
- krberr = krb5_kt_default(context, &keytab);
- }
- if (krberr) {
- DEBUG(2, ("Failed to read keytab file: %s\n",
- sss_krb5_get_error_message(context, krberr)));
- ret = EFAULT;
- goto done;
- }
-
- ccname = talloc_asprintf(memctx, "FILE:%s/ccache_%s", DB_PATH, realm_name);
- if (!ccname) {
- ret = ENOMEM;
- goto done;
- }
-
- krberr = krb5_cc_resolve(context, ccname, &ccache);
- if (krberr) {
- DEBUG(2, ("Failed to set cache name: %s\n",
- sss_krb5_get_error_message(context, krberr)));
- ret = EFAULT;
- goto done;
- }
-
- memset(&my_creds, 0, sizeof(my_creds));
- memset(&options, 0, sizeof(options));
-
- krb5_get_init_creds_opt_set_address_list(&options, NULL);
- krb5_get_init_creds_opt_set_forwardable(&options, 0);
- krb5_get_init_creds_opt_set_proxiable(&options, 0);
- /* set a very short lifetime, we don't keep the ticket around */
- krb5_get_init_creds_opt_set_tkt_life(&options, 300);
-
- krberr = krb5_get_init_creds_keytab(context, &my_creds, kprinc,
- keytab, 0, NULL, &options);
-
- if (krberr) {
- DEBUG(2, ("Failed to init credentials: %s\n",
- sss_krb5_get_error_message(context, krberr)));
- ret = EFAULT;
- goto done;
- }
-
- krberr = krb5_cc_initialize(context, ccache, kprinc);
- if (krberr) {
- DEBUG(2, ("Failed to init ccache: %s\n",
- sss_krb5_get_error_message(context, krberr)));
- ret = EFAULT;
- goto done;
- }
-
- krberr = krb5_cc_store_cred(context, ccache, &my_creds);
- if (krberr) {
- DEBUG(2, ("Failed to store creds: %s\n",
- sss_krb5_get_error_message(context, krberr)));
- ret = EFAULT;
- goto done;
- }
-
- ret = EOK;
- *ccname_out = ccname;
-
-done:
- if (keytab) krb5_kt_close(context, keytab);
- if (context) krb5_free_context(context);
- return ret;
-}
-
-static int prepare_response(TALLOC_CTX *mem_ctx,
- const char *ccname,
- krb5_error_code kerr,
- struct response **rsp)
-{
- int ret;
- struct response *r = NULL;
- const char *krb5_msg = NULL;
-
- r = talloc_zero(mem_ctx, struct response);
- if (!r) return ENOMEM;
-
- r->buf = talloc_size(mem_ctx, MAX_CHILD_MSG_SIZE);
- if (r->buf == NULL) {
- DEBUG(1, ("talloc_size failed.\n"));
- return ENOMEM;
- }
- r->max_size = MAX_CHILD_MSG_SIZE;
- r->size = 0;
-
- if (kerr == 0) {
- ret = pack_buffer(r, EOK, ccname);
- } else {
- krb5_msg = sss_krb5_get_error_message(krb5_error_ctx, kerr);
- if (krb5_msg == NULL) {
- DEBUG(1, ("sss_krb5_get_error_message failed.\n"));
- return ENOMEM;
- }
-
- ret = pack_buffer(r, EFAULT, krb5_msg);
- sss_krb5_free_error_message(krb5_error_ctx, krb5_msg);
- }
-
- if (ret != EOK) {
- DEBUG(1, ("pack_buffer failed\n"));
- return ret;
- }
-
- *rsp = r;
- return EOK;
-}
-
-int main(int argc, const char *argv[])
-{
- int ret;
- int kerr;
- int opt;
- int debug_fd = -1;
- poptContext pc;
- TALLOC_CTX *main_ctx;
- uint8_t *buf = NULL;
- ssize_t len = 0;
- const char *ccname = NULL;
- struct input_buffer *ibuf = NULL;
- struct response *resp = NULL;
- size_t written;
-
- struct poptOption long_options[] = {
- POPT_AUTOHELP
- {"debug-level", 'd', POPT_ARG_INT, &debug_level, 0,
- _("Debug level"), NULL},
- {"debug-timestamps", 0, POPT_ARG_INT, &debug_timestamps, 0,
- _("Add debug timestamps"), NULL},
- {"debug-fd", 0, POPT_ARG_INT, &debug_fd, 0,
- _("An open file descriptor for the debug logs"), NULL},
- POPT_TABLEEND
- };
-
- pc = poptGetContext(argv[0], argc, argv, long_options, 0);
- while((opt = poptGetNextOpt(pc)) != -1) {
- switch(opt) {
- default:
- fprintf(stderr, "\nInvalid option %s: %s\n\n",
- poptBadOption(pc, 0), poptStrerror(opt));
- poptPrintUsage(pc, stderr, 0);
- _exit(-1);
- }
- }
-
- poptFreeContext(pc);
-
- DEBUG(7, ("ldap_child started.\n"));
-
- main_ctx = talloc_new(NULL);
- if (main_ctx == NULL) {
- DEBUG(1, ("talloc_new failed.\n"));
- _exit(-1);
- }
-
- debug_prg_name = talloc_asprintf(main_ctx, "[sssd[ldap_child[%d]]]", getpid());
-
- if (debug_fd != -1) {
- ret = set_debug_file_from_fd(debug_fd);
- if (ret != EOK) {
- DEBUG(1, ("set_debug_file_from_fd failed.\n"));
- }
- }
-
- buf = talloc_size(main_ctx, sizeof(uint8_t)*IN_BUF_SIZE);
- if (buf == NULL) {
- DEBUG(1, ("talloc_size failed.\n"));
- goto fail;
- }
-
- ibuf = talloc_zero(main_ctx, struct input_buffer);
- if (ibuf == NULL) {
- DEBUG(1, ("talloc_size failed.\n"));
- goto fail;
- }
-
- while ((ret = read(STDIN_FILENO, buf + len, IN_BUF_SIZE - len)) != 0) {
- if (ret == -1) {
- if (errno == EINTR || errno == EAGAIN) {
- continue;
- }
- DEBUG(1, ("read failed [%d][%s].\n", errno, strerror(errno)));
- goto fail;
- } else if (ret > 0) {
- len += ret;
- if (len > IN_BUF_SIZE) {
- DEBUG(1, ("read too much, this should never happen.\n"));
- goto fail;
- }
- continue;
- } else {
- DEBUG(1, ("unexpected return code of read [%d].\n", ret));
- goto fail;
- }
- }
- close(STDIN_FILENO);
-
- ret = unpack_buffer(buf, len, ibuf);
- if (ret != EOK) {
- DEBUG(1, ("unpack_buffer failed.[%d][%s].\n", ret, strerror(ret)));
- goto fail;
- }
-
- kerr = ldap_child_get_tgt_sync(main_ctx,
- ibuf->realm_str, ibuf->princ_str,
- ibuf->keytab_name, &ccname);
- if (kerr != EOK) {
- DEBUG(1, ("ldap_child_get_tgt_sync failed.\n"));
- /* Do not return, must report failure */
- }
-
- ret = prepare_response(main_ctx, ccname, kerr, &resp);
- if (ret != EOK) {
- DEBUG(1, ("prepare_response failed. [%d][%s].\n", ret, strerror(ret)));
- return ENOMEM;
- }
-
- written = 0;
- while (written < resp->size) {
- ret = write(STDOUT_FILENO, resp->buf + written, resp->size - written);
- if (ret == -1) {
- if (errno == EAGAIN || errno == EINTR) {
- continue;
- }
- ret = errno;
- DEBUG(1, ("write failed [%d][%s].\n", ret, strerror(ret)));
- return ret;
- }
- written += ret;
- }
-
- close(STDOUT_FILENO);
- talloc_free(main_ctx);
- _exit(0);
-
-fail:
- close(STDOUT_FILENO);
- talloc_free(main_ctx);
- _exit(-1);
-}
diff --git a/server/providers/ldap/ldap_common.c b/server/providers/ldap/ldap_common.c
deleted file mode 100644
index bd4294f83..000000000
--- a/server/providers/ldap/ldap_common.c
+++ /dev/null
@@ -1,589 +0,0 @@
-/*
- SSSD
-
- LDAP Provider Common Functions
-
- Authors:
- Simo Sorce <ssorce@redhat.com>
-
- Copyright (C) 2008-2009 Red Hat
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "providers/ldap/ldap_common.h"
-#include "providers/fail_over.h"
-
-#include "util/sss_krb5.h"
-
-/* a fd the child process would log into */
-int ldap_child_debug_fd = -1;
-
-struct dp_option default_basic_opts[] = {
- { "ldap_uri", DP_OPT_STRING, { "ldap://localhost" }, NULL_STRING },
- { "ldap_search_base", DP_OPT_STRING, { "dc=example,dc=com" }, NULL_STRING },
- { "ldap_default_bind_dn", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "ldap_default_authtok_type", DP_OPT_STRING, NULL_STRING, NULL_STRING},
- { "ldap_default_authtok", DP_OPT_BLOB, NULL_BLOB, NULL_BLOB },
- { "ldap_search_timeout", DP_OPT_NUMBER, { .number = 60 }, NULL_NUMBER },
- { "ldap_network_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER },
- { "ldap_opt_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER },
- { "ldap_tls_reqcert", DP_OPT_STRING, { "hard" }, NULL_STRING },
- { "ldap_user_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "ldap_user_search_scope", DP_OPT_STRING, { "sub" }, NULL_STRING },
- { "ldap_user_search_filter", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "ldap_group_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "ldap_group_search_scope", DP_OPT_STRING, { "sub" }, NULL_STRING },
- { "ldap_group_search_filter", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "ldap_schema", DP_OPT_STRING, { "rfc2307" }, NULL_STRING },
- { "ldap_offline_timeout", DP_OPT_NUMBER, { .number = 60 }, NULL_NUMBER },
- { "ldap_force_upper_case_realm", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
- { "ldap_enumeration_refresh_timeout", DP_OPT_NUMBER, { .number = 300 }, NULL_NUMBER },
- { "ldap_purge_cache_timeout", DP_OPT_NUMBER, { .number = 3600 }, NULL_NUMBER },
- { "entry_cache_timoeut", DP_OPT_NUMBER, { .number = 1800 }, NULL_NUMBER },
- { "ldap_tls_cacert", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "ldap_tls_cacertdir", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "ldap_id_use_start_tls", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
- { "ldap_sasl_mech", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "ldap_sasl_authid", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "ldap_krb5_keytab", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "ldap_krb5_init_creds", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE },
- /* use the same parm name as the krb5 module so we set it only once */
- { "krb5_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "ldap_pwd_policy", DP_OPT_STRING, { "none" } , NULL_STRING },
- { "ldap_referrals", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }
-};
-
-struct sdap_attr_map generic_attr_map[] = {
- { "ldap_entry_usn", NULL, SYSDB_USN, NULL },
- { "ldap_rootdse_last_usn", NULL, SYSDB_USN, NULL }
-};
-
-struct sdap_attr_map gen_ipa_attr_map[] = {
- { "ldap_entry_usn", "entryUSN", SYSDB_USN, NULL },
- { "ldap_rootdse_last_usn", "lastUSN", SYSDB_HIGH_USN, NULL }
-};
-
-struct sdap_attr_map gen_ad_attr_map[] = {
- { "ldap_entry_usn", "uSNChanged", SYSDB_USN, NULL },
- { "ldap_rootdse_last_usn", "highestCommittedUSN", SYSDB_HIGH_USN, NULL }
-};
-
-struct sdap_attr_map rfc2307_user_map[] = {
- { "ldap_user_object_class", "posixAccount", SYSDB_USER_CLASS, NULL },
- { "ldap_user_name", "uid", SYSDB_NAME, NULL },
- { "ldap_user_pwd", "userPassword", SYSDB_PWD, NULL },
- { "ldap_user_uid_number", "uidNumber", SYSDB_UIDNUM, NULL },
- { "ldap_user_gid_number", "gidNumber", SYSDB_GIDNUM, NULL },
- { "ldap_user_gecos", "gecos", SYSDB_GECOS, NULL },
- { "ldap_user_home_directory", "homeDirectory", SYSDB_HOMEDIR, NULL },
- { "ldap_user_shell", "loginShell", SYSDB_SHELL, NULL },
- { "ldap_user_principal", "krbPrincipalName", SYSDB_UPN, NULL },
- { "ldap_user_fullname", "cn", SYSDB_FULLNAME, NULL },
- { "ldap_user_member_of", NULL, SYSDB_MEMBEROF, NULL },
- { "ldap_user_uuid", NULL, SYSDB_UUID, NULL },
- { "ldap_user_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL },
- { "ldap_user_shadow_last_change", "shadowLastChange", SYSDB_SHADOWPW_LASTCHANGE, NULL },
- { "ldap_user_shadow_min", "shadowMin", SYSDB_SHADOWPW_MIN, NULL },
- { "ldap_user_shadow_max", "shadowMax", SYSDB_SHADOWPW_MAX, NULL },
- { "ldap_user_shadow_warning", "shadowWarning", SYSDB_SHADOWPW_WARNING, NULL },
- { "ldap_user_shadow_inactive", "shadowInactive", SYSDB_SHADOWPW_INACTIVE, NULL },
- { "ldap_user_shadow_expire", "shadowExpire", SYSDB_SHADOWPW_EXPIRE, NULL },
- { "ldap_user_shadow_flag", "shadowFlag", SYSDB_SHADOWPW_FLAG, NULL },
- { "ldap_user_krb_last_pwd_change", "krbLastPwdChange", SYSDB_KRBPW_LASTCHANGE, NULL },
- { "ldap_user_krb_password_expiration", "krbPasswordExpiration", SYSDB_KRBPW_EXPIRATION, NULL },
- { "ldap_pwd_attribute", "pwdAttribute", SYSDB_PWD_ATTRIBUTE, NULL }
-};
-
-struct sdap_attr_map rfc2307_group_map[] = {
- { "ldap_group_object_class", "posixGroup", SYSDB_GROUP_CLASS, NULL },
- { "ldap_group_name", "cn", SYSDB_NAME, NULL },
- { "ldap_group_pwd", "userPassword", SYSDB_PWD, NULL },
- { "ldap_group_gid_number", "gidNumber", SYSDB_GIDNUM, NULL },
- { "ldap_group_member", "memberuid", SYSDB_MEMBER, NULL },
- { "ldap_group_uuid", NULL, SYSDB_UUID, NULL },
- { "ldap_group_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL }
-};
-
-struct sdap_attr_map rfc2307bis_user_map[] = {
- { "ldap_user_object_class", "posixAccount", SYSDB_USER_CLASS, NULL },
- { "ldap_user_name", "uid", SYSDB_NAME, NULL },
- { "ldap_user_pwd", "userPassword", SYSDB_PWD, NULL },
- { "ldap_user_uid_number", "uidNumber", SYSDB_UIDNUM, NULL },
- { "ldap_user_gid_number", "gidNumber", SYSDB_GIDNUM, NULL },
- { "ldap_user_gecos", "gecos", SYSDB_GECOS, NULL },
- { "ldap_user_home_directory", "homeDirectory", SYSDB_HOMEDIR, NULL },
- { "ldap_user_shell", "loginShell", SYSDB_SHELL, NULL },
- { "ldap_user_principal", "krbPrincipalName", SYSDB_UPN, NULL },
- { "ldap_user_fullname", "cn", SYSDB_FULLNAME, NULL },
- { "ldap_user_member_of", "memberOf", SYSDB_MEMBEROF, NULL },
- /* FIXME: this is 389ds specific */
- { "ldap_user_uuid", "nsUniqueId", SYSDB_UUID, NULL },
- { "ldap_user_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL },
- { "ldap_user_shadow_last_change", "shadowLastChange", SYSDB_SHADOWPW_LASTCHANGE, NULL },
- { "ldap_user_shadow_min", "shadowMin", SYSDB_SHADOWPW_MIN, NULL },
- { "ldap_user_shadow_max", "shadowMax", SYSDB_SHADOWPW_MAX, NULL },
- { "ldap_user_shadow_warning", "shadowWarning", SYSDB_SHADOWPW_WARNING, NULL },
- { "ldap_user_shadow_inactive", "shadowInactive", SYSDB_SHADOWPW_INACTIVE, NULL },
- { "ldap_user_shadow_expire", "shadowExpire", SYSDB_SHADOWPW_EXPIRE, NULL },
- { "ldap_user_shadow_flag", "shadowFlag", SYSDB_SHADOWPW_FLAG, NULL },
- { "ldap_user_krb_last_pwd_change", "krbLastPwdChange", SYSDB_KRBPW_LASTCHANGE, NULL },
- { "ldap_user_krb_password_expiration", "krbPasswordExpiration", SYSDB_KRBPW_EXPIRATION, NULL },
- { "ldap_pwd_attribute", "pwdAttribute", SYSDB_PWD_ATTRIBUTE, NULL }
-};
-
-struct sdap_attr_map rfc2307bis_group_map[] = {
- { "ldap_group_object_class", "posixGroup", SYSDB_GROUP_CLASS, NULL },
- { "ldap_group_name", "cn", SYSDB_NAME, NULL },
- { "ldap_group_pwd", "userPassword", SYSDB_PWD, NULL },
- { "ldap_group_gid_number", "gidNumber", SYSDB_GIDNUM, NULL },
- { "ldap_group_member", "member", SYSDB_MEMBER, NULL },
- /* FIXME: this is 389ds specific */
- { "ldap_group_uuid", "nsUniqueId", SYSDB_UUID, NULL },
- { "ldap_group_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL }
-};
-
-int ldap_get_options(TALLOC_CTX *memctx,
- struct confdb_ctx *cdb,
- const char *conf_path,
- struct sdap_options **_opts)
-{
- struct sdap_attr_map *default_attr_map;
- struct sdap_attr_map *default_user_map;
- struct sdap_attr_map *default_group_map;
- struct sdap_options *opts;
- char *schema;
- const char *pwd_policy;
- int ret;
-
- opts = talloc_zero(memctx, struct sdap_options);
- if (!opts) return ENOMEM;
-
- ret = dp_get_options(opts, cdb, conf_path,
- default_basic_opts,
- SDAP_OPTS_BASIC,
- &opts->basic);
- if (ret != EOK) {
- goto done;
- }
-
- /* set user/group search bases if they are not */
- if (NULL == dp_opt_get_string(opts->basic, SDAP_USER_SEARCH_BASE)) {
- ret = dp_opt_set_string(opts->basic, SDAP_USER_SEARCH_BASE,
- dp_opt_get_string(opts->basic,
- SDAP_SEARCH_BASE));
- if (ret != EOK) {
- goto done;
- }
- DEBUG(6, ("Option %s set to %s\n",
- opts->basic[SDAP_USER_SEARCH_BASE].opt_name,
- dp_opt_get_string(opts->basic, SDAP_USER_SEARCH_BASE)));
- }
-
- if (NULL == dp_opt_get_string(opts->basic, SDAP_GROUP_SEARCH_BASE)) {
- ret = dp_opt_set_string(opts->basic, SDAP_GROUP_SEARCH_BASE,
- dp_opt_get_string(opts->basic,
- SDAP_SEARCH_BASE));
- if (ret != EOK) {
- goto done;
- }
- DEBUG(6, ("Option %s set to %s\n",
- opts->basic[SDAP_GROUP_SEARCH_BASE].opt_name,
- dp_opt_get_string(opts->basic, SDAP_GROUP_SEARCH_BASE)));
- }
-
- pwd_policy = dp_opt_get_string(opts->basic, SDAP_PWD_POLICY);
- if (pwd_policy == NULL) {
- DEBUG(1, ("Missing password policy, this may not happen.\n"));
- ret = EINVAL;
- goto done;
- }
- if (strcasecmp(pwd_policy, PWD_POL_OPT_NONE) != 0 &&
- strcasecmp(pwd_policy, PWD_POL_OPT_SHADOW) != 0 &&
- strcasecmp(pwd_policy, PWD_POL_OPT_MIT) != 0) {
- DEBUG(1, ("Unsupported password policy [%s].\n", pwd_policy));
- ret = EINVAL;
- goto done;
- }
-
-
-#ifndef HAVE_LDAP_CONNCB
- bool ldap_referrals;
-
- ldap_referrals = dp_opt_get_bool(opts->basic, SDAP_REFERRALS);
- if (ldap_referrals) {
- DEBUG(1, ("LDAP referrals are not supported, because the LDAP library "
- "is too old, see sssd-ldap(5) for details.\n"));
- ret = dp_opt_set_bool(opts->basic, SDAP_REFERRALS, false);
- }
-#endif
-
- /* schema type */
- schema = dp_opt_get_string(opts->basic, SDAP_SCHEMA);
- if (strcasecmp(schema, "rfc2307") == 0) {
- opts->schema_type = SDAP_SCHEMA_RFC2307;
- default_attr_map = generic_attr_map;
- default_user_map = rfc2307_user_map;
- default_group_map = rfc2307_group_map;
- } else
- if (strcasecmp(schema, "rfc2307bis") == 0) {
- opts->schema_type = SDAP_SCHEMA_RFC2307BIS;
- default_attr_map = generic_attr_map;
- default_user_map = rfc2307bis_user_map;
- default_group_map = rfc2307bis_group_map;
- } else
- if (strcasecmp(schema, "IPA") == 0) {
- opts->schema_type = SDAP_SCHEMA_IPA_V1;
- default_attr_map = gen_ipa_attr_map;
- default_user_map = rfc2307bis_user_map;
- default_group_map = rfc2307bis_group_map;
- } else
- if (strcasecmp(schema, "AD") == 0) {
- opts->schema_type = SDAP_SCHEMA_AD;
- default_attr_map = gen_ad_attr_map;
- default_user_map = rfc2307bis_user_map;
- default_group_map = rfc2307bis_group_map;
- } else {
- DEBUG(0, ("Unrecognized schema type: %s\n", schema));
- ret = EINVAL;
- goto done;
- }
-
- ret = sdap_get_map(opts, cdb, conf_path,
- default_attr_map,
- SDAP_AT_GENERAL,
- &opts->gen_map);
- if (ret != EOK) {
- goto done;
- }
-
- ret = sdap_get_map(opts, cdb, conf_path,
- default_user_map,
- SDAP_OPTS_USER,
- &opts->user_map);
- if (ret != EOK) {
- goto done;
- }
-
- ret = sdap_get_map(opts, cdb, conf_path,
- default_group_map,
- SDAP_OPTS_GROUP,
- &opts->group_map);
- if (ret != EOK) {
- goto done;
- }
-
- ret = EOK;
- *_opts = opts;
-
-done:
- if (ret != EOK) {
- talloc_zfree(opts);
- }
- return ret;
-}
-
-void sdap_handler_done(struct be_req *req, int dp_err,
- int error, const char *errstr)
-{
- return req->fn(req, dp_err, error, errstr);
-}
-
-bool sdap_connected(struct sdap_id_ctx *ctx)
-{
- if (ctx->gsh) {
- return ctx->gsh->connected;
- }
-
- return false;
-}
-
-void sdap_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);
-}
-
-bool sdap_check_gssapi_reconnect(struct sdap_id_ctx *ctx)
-{
- int ret;
- bool result = false;
- const char *mech;
- const char *realm;
- char *ccname = NULL;
- krb5_context context = NULL;
- krb5_ccache ccache = NULL;
- krb5_error_code krberr;
- TALLOC_CTX *tmp_ctx = NULL;
- krb5_creds mcred;
- krb5_creds cred;
- char *server_name = NULL;
- char *client_princ_str = NULL;
- char *full_princ = NULL;
- krb5_principal client_principal = NULL;
- krb5_principal server_principal = NULL;
- char hostname[512];
- int l_errno;
-
-
- mech = dp_opt_get_string(ctx->opts->basic, SDAP_SASL_MECH);
- if (mech == NULL || strcasecmp(mech, "GSSAPI") != 0) {
- return false;
- }
-
- realm = dp_opt_get_string(ctx->opts->basic, SDAP_KRB5_REALM);
- if (realm == NULL) {
- DEBUG(3, ("Kerberos realm not available.\n"));
- return false;
- }
-
- tmp_ctx = talloc_new(NULL);
- if (tmp_ctx == NULL) {
- DEBUG(1, ("talloc_new failed.\n"));
- return false;
- }
-
- ccname = talloc_asprintf(tmp_ctx, "FILE:%s/ccache_%s", DB_PATH, realm);
- if (ccname == NULL) {
- DEBUG(1, ("talloc_asprintf failed.\n"));
- goto done;
- }
-
- krberr = krb5_init_context(&context);
- if (krberr) {
- DEBUG(1, ("Failed to init kerberos context\n"));
- goto done;
- }
-
- krberr = krb5_cc_resolve(context, ccname, &ccache);
- if (krberr != 0) {
- DEBUG(1, ("krb5_cc_resolve failed.\n"));
- goto done;
- }
-
- server_name = talloc_asprintf(tmp_ctx, "krbtgt/%s@%s", realm, realm);
- if (server_name == NULL) {
- DEBUG(1, ("talloc_asprintf failed.\n"));
- goto done;
- }
-
- krberr = krb5_parse_name(context, server_name, &server_principal);
- if (krberr != 0) {
- DEBUG(1, ("krb5_parse_name failed.\n"));
- goto done;
- }
-
- client_princ_str = dp_opt_get_string(ctx->opts->basic, SDAP_SASL_AUTHID);
- if (client_princ_str) {
- if (!strchr(client_princ_str, '@')) {
- full_princ = talloc_asprintf(tmp_ctx, "%s@%s", client_princ_str,
- realm);
- } else {
- full_princ = talloc_strdup(tmp_ctx, client_princ_str);
- }
- } else {
- ret = gethostname(hostname, sizeof(hostname)-1);
- if (ret == -1) {
- l_errno = errno;
- DEBUG(1, ("gethostname failed [%d][%s].\n", l_errno,
- strerror(l_errno)));
- goto done;
- }
- hostname[sizeof(hostname)-1] = '\0';
-
- full_princ = talloc_asprintf(tmp_ctx, "host/%s@%s", hostname, realm);
- }
- if (!full_princ) {
- DEBUG(1, ("Client principal not available.\n"));
- goto done;
- }
- DEBUG(7, ("Client principal name is: [%s]\n", full_princ));
- krberr = krb5_parse_name(context, full_princ, &client_principal);
- if (krberr != 0) {
- DEBUG(1, ("krb5_parse_name failed.\n"));
- goto done;
- }
-
- memset(&mcred, 0, sizeof(mcred));
- memset(&cred, 0, sizeof(mcred));
- mcred.client = client_principal;
- mcred.server = server_principal;
-
- krberr = krb5_cc_retrieve_cred(context, ccache, 0, &mcred, &cred);
- if (krberr != 0) {
- DEBUG(1, ("krb5_cc_retrieve_cred failed.\n"));
- goto done;
- }
-
- DEBUG(7, ("TGT end time [%d].\n", cred.times.endtime));
-
- if (cred.times.endtime <= time(NULL)) {
- DEBUG(3, ("TGT is expired.\n"));
- result = true;
- }
- krb5_free_cred_contents(context, &cred);
-
-done:
- if (client_principal != NULL) {
- krb5_free_principal(context, client_principal);
- }
- if (server_principal != NULL) {
- krb5_free_principal(context, server_principal);
- }
- if (ccache != NULL) {
- if (result) {
- krb5_cc_destroy(context, ccache);
- } else {
- krb5_cc_close(context, ccache);
- }
- }
- if (context != NULL) krb5_free_context(context);
- talloc_free(tmp_ctx);
- return result;
-}
-
-int sdap_id_setup_tasks(struct sdap_id_ctx *ctx)
-{
- struct timeval tv;
- 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*/
- tv = tevent_timeval_current_ofs(10, 0);
- ret = ldap_id_enumerate_set_timer(ctx, tv);
- } else {
- /* the enumeration task, runs the cleanup process by itself,
- * but if enumeration is not runnig we need to schedule it */
-
- /* run the first one in a couple of seconds so that we have time to
- * finish initializations first*/
- tv = tevent_timeval_current_ofs(10, 0);
- ret = ldap_id_cleanup_set_timer(ctx, tv);
- }
-
- return ret;
-}
-
-static void sdap_uri_callback(void *private_data, struct fo_server *server)
-{
- struct sdap_service *service;
- const char *tmp;
- char *new_uri;
-
- service = talloc_get_type(private_data, struct sdap_service);
- if (!service) return;
-
- tmp = (const char *)fo_get_server_user_data(server);
- if (tmp && ldap_is_ldap_url(tmp)) {
- new_uri = talloc_strdup(service, tmp);
- } else {
- new_uri = talloc_asprintf(service, "ldap://%s",
- fo_get_server_name(server));
- }
- if (!new_uri) {
- DEBUG(2, ("Failed to copy URI ...\n"));
- return;
- }
-
- /* free old one and replace with new one */
- talloc_zfree(service->uri);
- service->uri = new_uri;
-}
-
-int sdap_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
- const char *service_name, const char *urls,
- struct sdap_service **_service)
-{
- TALLOC_CTX *tmp_ctx;
- struct sdap_service *service;
- LDAPURLDesc *lud;
- char **list = NULL;
- int ret;
- int i;
-
- tmp_ctx = talloc_new(memctx);
- if (!tmp_ctx) {
- return ENOMEM;
- }
-
- service = talloc_zero(tmp_ctx, struct sdap_service);
- if (!service) {
- ret = ENOMEM;
- goto done;
- }
-
- ret = be_fo_add_service(ctx, service_name);
- if (ret != EOK) {
- DEBUG(1, ("Failed to create failover service!\n"));
- goto done;
- }
-
- service->name = talloc_strdup(service, service_name);
- if (!service->name) {
- ret = ENOMEM;
- goto done;
- }
-
- /* split server parm into a list */
- ret = split_on_separator(tmp_ctx, urls, ',', true, &list, NULL);
- if (ret != EOK) {
- DEBUG(1, ("Failed to parse server list!\n"));
- goto done;
- }
-
- /* now for each URI add a new server to the failover service */
- for (i = 0; list[i]; i++) {
- ret = ldap_url_parse(list[i], &lud);
- if (ret != LDAP_SUCCESS) {
- DEBUG(0, ("Failed to parse ldap URI (%s)!\n", list[i]));
- ret = EINVAL;
- goto done;
- }
-
- DEBUG(6, ("Added URI %s\n", list[i]));
-
- talloc_steal(service, list[i]);
-
- ret = be_fo_add_server(ctx, service->name,
- lud->lud_host, lud->lud_port, list[i]);
- if (ret) {
- goto done;
- }
- ldap_free_urldesc(lud);
- }
-
- ret = be_fo_service_add_callback(memctx, ctx, service->name,
- sdap_uri_callback, service);
- if (ret != EOK) {
- DEBUG(1, ("Failed to add failover callback!\n"));
- goto done;
- }
-
- ret = EOK;
-
-done:
- if (ret == EOK) {
- *_service = talloc_steal(memctx, service);
- }
- talloc_zfree(tmp_ctx);
- return ret;
-}
-
diff --git a/server/providers/ldap/ldap_common.h b/server/providers/ldap/ldap_common.h
deleted file mode 100644
index ff1ffb725..000000000
--- a/server/providers/ldap/ldap_common.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- SSSD
-
- LDAP Common utility code
-
- Copyright (C) Simo Sorce <ssorce@redhat.com> 2009
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _LDAP_COMMON_H_
-#define _LDAP_COMMON_H_
-
-#include "providers/dp_backend.h"
-#include "providers/ldap/sdap.h"
-#include "providers/fail_over.h"
-
-#define PWD_POL_OPT_NONE "none"
-#define PWD_POL_OPT_SHADOW "shadow"
-#define PWD_POL_OPT_MIT "mit_kerberos"
-
-/* a fd the child process would log into */
-extern int ldap_child_debug_fd;
-
-struct sdap_id_ctx {
- struct be_ctx *be;
- struct sdap_options *opts;
- struct fo_service *fo_service;
- struct sdap_service *service;
-
- /* what rootDSE returns */
- struct sysdb_attrs *rootDSE;
-
- /* global sdap handler */
- struct sdap_handle *gsh;
-
- /* enumeration loop timer */
- struct timeval last_enum;
- /* cleanup loop timer */
- struct timeval last_purge;
-
- char *max_user_timestamp;
- char *max_group_timestamp;
-};
-
-struct sdap_auth_ctx {
- struct be_ctx *be;
- struct sdap_options *opts;
- struct fo_service *fo_service;
- struct sdap_service *service;
-};
-
-/* id */
-void sdap_account_info_handler(struct be_req *breq);
-int sdap_id_setup_tasks(struct sdap_id_ctx *ctx);
-
-/* auth */
-void sdap_pam_auth_handler(struct be_req *breq);
-
-/* chpass */
-void sdap_pam_chpass_handler(struct be_req *breq);
-
-
-
-void sdap_handler_done(struct be_req *req, int dp_err,
- int error, const char *errstr);
-
-int sdap_service_init(TALLOC_CTX *mmectx, struct be_ctx *ctx,
- const char *service_name, const char *urls,
- struct sdap_service **service);
-
-/* options parser */
-int ldap_get_options(TALLOC_CTX *memctx,
- struct confdb_ctx *cdb,
- const char *conf_path,
- struct sdap_options **_opts);
-
-int ldap_id_enumerate_set_timer(struct sdap_id_ctx *ctx, struct timeval tv);
-int ldap_id_cleanup_set_timer(struct sdap_id_ctx *ctx, struct timeval tv);
-
-bool sdap_connected(struct sdap_id_ctx *ctx);
-void sdap_mark_offline(struct sdap_id_ctx *ctx);
-bool sdap_check_gssapi_reconnect(struct sdap_id_ctx *ctx);
-
-struct tevent_req *users_get_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_id_ctx *ctx,
- const char *name,
- int filter_type,
- int attrs_type);
-int users_get_recv(struct tevent_req *req);
-
-struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_id_ctx *ctx,
- const char *name,
- int filter_type,
- int attrs_type);
-int groups_get_recv(struct tevent_req *req);
-
-/* setup child logging */
-int setup_child(struct sdap_id_ctx *ctx);
-
-#endif /* _LDAP_COMMON_H_ */
diff --git a/server/providers/ldap/ldap_id.c b/server/providers/ldap/ldap_id.c
deleted file mode 100644
index 4bbc07a68..000000000
--- a/server/providers/ldap/ldap_id.c
+++ /dev/null
@@ -1,795 +0,0 @@
-/*
- SSSD
-
- LDAP Identity Backend Module
-
- Authors:
- Simo Sorce <ssorce@redhat.com>
-
- Copyright (C) 2008 Red Hat
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <errno.h>
-#include <time.h>
-#include <sys/time.h>
-
-#include "util/util.h"
-#include "db/sysdb.h"
-#include "providers/ldap/ldap_common.h"
-#include "providers/ldap/sdap_async.h"
-
-/* =Users-Related-Functions-(by-name,by-uid)============================== */
-
-struct users_get_state {
- struct tevent_context *ev;
- struct sdap_id_ctx *ctx;
- struct sysdb_ctx *sysdb;
- struct sss_domain_info *domain;
-
- const char *name;
- int filter_type;
-
- char *filter;
- const char **attrs;
-};
-
-static void users_get_connect_done(struct tevent_req *subreq);
-static void users_get_done(struct tevent_req *subreq);
-static void users_get_delete(struct tevent_req *subreq);
-
-struct tevent_req *users_get_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_id_ctx *ctx,
- const char *name,
- int filter_type,
- int attrs_type)
-{
- struct tevent_req *req, *subreq;
- struct users_get_state *state;
- const char *attr_name;
- int ret;
-
- req = tevent_req_create(memctx, &state, struct users_get_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->ctx = ctx;
- state->sysdb = ctx->be->sysdb;
- state->domain = state->ctx->be->domain;
- state->name = name;
- state->filter_type = filter_type;
-
- switch (filter_type) {
- case BE_FILTER_NAME:
- attr_name = ctx->opts->user_map[SDAP_AT_USER_NAME].name;
- break;
- case BE_FILTER_IDNUM:
- attr_name = ctx->opts->user_map[SDAP_AT_USER_UID].name;
- break;
- default:
- ret = EINVAL;
- goto fail;
- }
-
- state->filter = talloc_asprintf(state, "(&(%s=%s)(objectclass=%s))",
- attr_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 (!sdap_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->be, ctx->service,
- &ctx->rootDSE);
- if (!subreq) {
- ret = ENOMEM;
- goto fail;
- }
-
- tevent_req_set_callback(subreq, users_get_connect_done, req);
-
- return req;
- }
-
- subreq = sdap_get_users_send(state, state->ev,
- state->domain, state->sysdb,
- state->ctx->opts, state->ctx->gsh,
- state->attrs, state->filter);
- if (!subreq) {
- ret = ENOMEM;
- goto fail;
- }
- tevent_req_set_callback(subreq, users_get_done, req);
-
- return req;
-
-fail:
- tevent_req_error(req, ret);
- tevent_req_post(req, ev);
- return req;
-}
-
-static void users_get_connect_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct users_get_state *state = tevent_req_data(req,
- struct users_get_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->domain, state->sysdb,
- state->ctx->opts, state->ctx->gsh,
- state->attrs, state->filter);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, users_get_done, req);
-}
-
-static void users_get_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct users_get_state *state = tevent_req_data(req,
- struct users_get_state);
- char *endptr;
- uid_t uid;
- int ret;
-
- ret = sdap_get_users_recv(subreq, NULL, NULL);
- talloc_zfree(subreq);
- if (ret && ret != ENOENT) {
- tevent_req_error(req, ret);
- return;
- }
-
- if (ret == ENOENT) {
- if (strchr(state->name, '*')) {
- /* it was an enumeration */
- tevent_req_error(req, ret);
- return;
- }
-
- switch (state->filter_type) {
- case BE_FILTER_NAME:
- subreq = sysdb_delete_user_send(state, state->ev,
- state->sysdb, NULL,
- state->domain, state->name, 0);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, users_get_delete, req);
- return;
-
- case BE_FILTER_IDNUM:
- errno = 0;
- uid = (uid_t)strtol(state->name, &endptr, 0);
- if (errno || *endptr || (state->name == endptr)) {
- tevent_req_error(req, errno);
- return;
- }
-
- subreq = sysdb_delete_user_send(state, state->ev,
- state->sysdb, NULL,
- state->domain, NULL, uid);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, users_get_delete, req);
- return;
-
- default:
- tevent_req_error(req, EINVAL);
- return;
- }
- }
-
- tevent_req_done(req);
-}
-
-static void users_get_delete(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct users_get_state *state = tevent_req_data(req,
- struct users_get_state);
- int ret;
-
- ret = sysdb_delete_user_recv(subreq);
- talloc_zfree(subreq);
- if (ret) {
- DEBUG(2, ("User (%s) delete returned %d (%s)\n",
- state->name, ret, strerror(ret)));
- }
-
- tevent_req_done(req);
-}
-
-int users_get_recv(struct tevent_req *req)
-{
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- return EOK;
-}
-
-
-/* =Groups-Related-Functions-(by-name,by-uid)============================= */
-
-struct groups_get_state {
- struct tevent_context *ev;
- struct sdap_id_ctx *ctx;
- struct sysdb_ctx *sysdb;
- struct sss_domain_info *domain;
-
- const char *name;
- int filter_type;
-
- char *filter;
- const char **attrs;
-};
-
-static void groups_get_connect_done(struct tevent_req *subreq);
-static void groups_get_done(struct tevent_req *subreq);
-static void groups_get_delete(struct tevent_req *subreq);
-
-struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_id_ctx *ctx,
- const char *name,
- int filter_type,
- int attrs_type)
-{
- struct tevent_req *req, *subreq;
- struct groups_get_state *state;
- const char *attr_name;
- int ret;
-
- req = tevent_req_create(memctx, &state, struct groups_get_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->ctx = ctx;
- state->sysdb = ctx->be->sysdb;
- state->domain = state->ctx->be->domain;
- state->name = name;
- state->filter_type = filter_type;
-
- switch(filter_type) {
- case BE_FILTER_NAME:
- attr_name = ctx->opts->group_map[SDAP_AT_GROUP_NAME].name;
- break;
- case BE_FILTER_IDNUM:
- attr_name = ctx->opts->group_map[SDAP_AT_GROUP_GID].name;
- break;
- default:
- ret = EINVAL;
- goto fail;
- }
-
- state->filter = talloc_asprintf(state, "(&(%s=%s)(objectclass=%s))",
- attr_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 (!sdap_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->be, ctx->service,
- &ctx->rootDSE);
- if (!subreq) {
- ret = ENOMEM;
- goto fail;
- }
-
- tevent_req_set_callback(subreq, groups_get_connect_done, req);
-
- return req;
- }
-
- subreq = sdap_get_groups_send(state, state->ev,
- state->domain, state->sysdb,
- state->ctx->opts, state->ctx->gsh,
- state->attrs, state->filter);
- if (!subreq) {
- ret = ENOMEM;
- goto fail;
- }
- tevent_req_set_callback(subreq, groups_get_done, req);
-
- return req;
-
-fail:
- tevent_req_error(req, ret);
- tevent_req_post(req, ev);
- return req;
-}
-
-static void groups_get_connect_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct groups_get_state *state = tevent_req_data(req,
- struct groups_get_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->domain, state->sysdb,
- state->ctx->opts, state->ctx->gsh,
- state->attrs, state->filter);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, groups_get_done, req);
-}
-
-static void groups_get_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct groups_get_state *state = tevent_req_data(req,
- struct groups_get_state);
- char *endptr;
- gid_t gid;
- int ret;
-
- ret = sdap_get_groups_recv(subreq, NULL, NULL);
- talloc_zfree(subreq);
- if (ret && ret != ENOENT) {
- tevent_req_error(req, ret);
- return;
- }
-
- if (ret == ENOENT) {
- if (strchr(state->name, '*')) {
- /* it was an enumeration */
- tevent_req_error(req, ret);
- return;
- }
-
- switch (state->filter_type) {
- case BE_FILTER_NAME:
- subreq = sysdb_delete_group_send(state, state->ev,
- state->sysdb, NULL,
- state->domain, state->name, 0);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, groups_get_delete, req);
- return;
-
- case BE_FILTER_IDNUM:
- errno = 0;
- gid = (gid_t)strtol(state->name, &endptr, 0);
- if (errno || *endptr || (state->name == endptr)) {
- tevent_req_error(req, errno);
- return;
- }
-
- subreq = sysdb_delete_group_send(state, state->ev,
- state->sysdb, NULL,
- state->domain, NULL, gid);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, groups_get_delete, req);
- return;
-
- default:
- tevent_req_error(req, EINVAL);
- return;
- }
- }
-
- tevent_req_done(req);
-}
-
-static void groups_get_delete(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct groups_get_state *state = tevent_req_data(req,
- struct groups_get_state);
- int ret;
-
- ret = sysdb_delete_group_recv(subreq);
- talloc_zfree(subreq);
- if (ret) {
- DEBUG(2, ("Group (%s) delete returned %d (%s)\n",
- state->name, ret, strerror(ret)));
- }
-
- tevent_req_done(req);
-}
-
-int groups_get_recv(struct tevent_req *req)
-{
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- return EOK;
-}
-
-
-/* =Get-Groups-for-User================================================== */
-
-struct groups_by_user_state {
- struct tevent_context *ev;
- struct sdap_id_ctx *ctx;
- const char *name;
- const char **attrs;
-};
-
-static void groups_by_user_connect_done(struct tevent_req *subreq);
-static void groups_by_user_done(struct tevent_req *subreq);
-
-static struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_id_ctx *ctx,
- const char *name)
-{
- struct tevent_req *req, *subreq;
- struct groups_by_user_state *state;
- int ret;
-
- req = tevent_req_create(memctx, &state, struct groups_by_user_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->ctx = ctx;
- state->name = name;
-
- ret = build_attrs_from_map(state, ctx->opts->group_map,
- SDAP_OPTS_GROUP, &state->attrs);
- if (ret != EOK) goto fail;
-
- if (!sdap_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->be, ctx->service,
- &ctx->rootDSE);
- if (!subreq) {
- ret = ENOMEM;
- goto fail;
- }
-
- tevent_req_set_callback(subreq, groups_by_user_connect_done, req);
-
- return req;
- }
-
- subreq = sdap_get_initgr_send(state, state->ev,
- state->ctx->be->domain,
- state->ctx->be->sysdb,
- state->ctx->opts, state->ctx->gsh,
- state->name, state->attrs);
- if (!subreq) {
- ret = ENOMEM;
- goto fail;
- }
- tevent_req_set_callback(subreq, groups_by_user_done, req);
-
- return req;
-
-fail:
- tevent_req_error(req, ret);
- tevent_req_post(req, ev);
- return req;
-}
-
-static void groups_by_user_connect_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct groups_by_user_state *state = tevent_req_data(req,
- struct groups_by_user_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_initgr_send(state, state->ev,
- state->ctx->be->domain,
- state->ctx->be->sysdb,
- state->ctx->opts, state->ctx->gsh,
- state->name, state->attrs);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, groups_by_user_done, req);
-}
-
-static void groups_by_user_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- int ret;
-
- ret = sdap_get_initgr_recv(subreq);
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- tevent_req_done(req);
-}
-
-int groups_by_user_recv(struct tevent_req *req)
-{
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- return EOK;
-}
-
-
-
-/* =Get-Account-Info-Call================================================= */
-
-/* FIXME: embed this function in sssd_be and only call out
- * specific functions from modules ? */
-
-static void sdap_account_info_users_done(struct tevent_req *req);
-static void sdap_account_info_groups_done(struct tevent_req *req);
-static void sdap_account_info_initgr_done(struct tevent_req *req);
-
-void sdap_account_info_handler(struct be_req *breq)
-{
- struct sdap_id_ctx *ctx;
- struct be_acct_req *ar;
- struct tevent_req *req;
- const char *err = "Unknown Error";
- int ret = EOK;
-
- ctx = talloc_get_type(breq->be_ctx->bet_info[BET_ID].pvt_bet_data, struct sdap_id_ctx);
-
- if (be_is_offline(ctx->be)) {
- return sdap_handler_done(breq, DP_ERR_OFFLINE, EAGAIN, "Offline");
- }
-
- ar = talloc_get_type(breq->req_data, struct be_acct_req);
-
- switch (ar->entry_type & 0xFFF) {
- case BE_REQ_USER: /* user */
-
- /* skip enumerations on demand */
- if (strcmp(ar->filter_value, "*") == 0) {
- return sdap_handler_done(breq, DP_ERR_OK, EOK, "Success");
- }
-
- req = users_get_send(breq, breq->be_ctx->ev, ctx,
- ar->filter_value,
- ar->filter_type,
- ar->attr_type);
- if (!req) {
- return sdap_handler_done(breq, DP_ERR_FATAL, ENOMEM, "Out of memory");
- }
-
- tevent_req_set_callback(req, sdap_account_info_users_done, breq);
-
- break;
-
- case BE_REQ_GROUP: /* group */
-
- if (strcmp(ar->filter_value, "*") == 0) {
- return sdap_handler_done(breq, DP_ERR_OK, EOK, "Success");
- }
-
- /* skip enumerations on demand */
- req = groups_get_send(breq, breq->be_ctx->ev, ctx,
- ar->filter_value,
- ar->filter_type,
- ar->attr_type);
- if (!req) {
- return sdap_handler_done(breq, DP_ERR_FATAL, ENOMEM, "Out of memory");
- }
-
- tevent_req_set_callback(req, sdap_account_info_groups_done, breq);
-
- break;
-
- case BE_REQ_INITGROUPS: /* init groups for user */
- if (ar->filter_type != BE_FILTER_NAME) {
- ret = EINVAL;
- err = "Invalid filter type";
- break;
- }
- if (ar->attr_type != BE_ATTR_CORE) {
- ret = EINVAL;
- err = "Invalid attr type";
- break;
- }
- if (strchr(ar->filter_value, '*')) {
- ret = EINVAL;
- err = "Invalid filter value";
- break;
- }
- req = groups_by_user_send(breq, breq->be_ctx->ev, ctx,
- ar->filter_value);
- if (!req) ret = ENOMEM;
- /* tevent_req_set_callback(req, groups_by_user_done, breq); */
-
- tevent_req_set_callback(req, sdap_account_info_initgr_done, breq);
-
- break;
-
- default: /*fail*/
- ret = EINVAL;
- err = "Invalid request type";
- }
-
- if (ret != EOK) return sdap_handler_done(breq, DP_ERR_FATAL, ret, err);
-}
-
-static void sdap_account_info_users_done(struct tevent_req *req)
-{
- struct be_req *breq = tevent_req_callback_data(req, struct be_req);
- struct sdap_id_ctx *ctx;
- int dp_err = DP_ERR_OK;
- const char *error = NULL;
- int ret;
-
- ret = users_get_recv(req);
- talloc_zfree(req);
-
- if (ret) {
- dp_err = DP_ERR_FATAL;
- error = "Enum Users Failed";
-
- if (ret == ETIMEDOUT || ret == EFAULT || ret == EIO) {
- dp_err = DP_ERR_OFFLINE;
- ctx = talloc_get_type(breq->be_ctx->bet_info[BET_ID].pvt_bet_data,
- struct sdap_id_ctx);
- if (sdap_check_gssapi_reconnect(ctx)) {
- talloc_zfree(ctx->gsh);
- sdap_account_info_handler(breq);
- return;
- }
- sdap_mark_offline(ctx);
- }
- }
-
- sdap_handler_done(breq, dp_err, ret, error);
-}
-
-static void sdap_account_info_groups_done(struct tevent_req *req)
-{
- struct be_req *breq = tevent_req_callback_data(req, struct be_req);
- struct sdap_id_ctx *ctx;
- int dp_err = DP_ERR_OK;
- const char *error = NULL;
- int ret;
-
- ret = groups_get_recv(req);
- talloc_zfree(req);
-
- if (ret) {
- dp_err = DP_ERR_FATAL;
- error = "Enum Groups Failed";
-
- if (ret == ETIMEDOUT || ret == EFAULT || ret == EIO) {
- dp_err = DP_ERR_OFFLINE;
- ctx = talloc_get_type(breq->be_ctx->bet_info[BET_ID].pvt_bet_data,
- struct sdap_id_ctx);
- if (sdap_check_gssapi_reconnect(ctx)) {
- talloc_zfree(ctx->gsh);
- sdap_account_info_handler(breq);
- return;
- }
- sdap_mark_offline(ctx);
- }
- }
-
- return sdap_handler_done(breq, dp_err, ret, error);
-}
-
-static void sdap_account_info_initgr_done(struct tevent_req *req)
-{
- struct be_req *breq = tevent_req_callback_data(req, struct be_req);
- struct sdap_id_ctx *ctx;
- int dp_err = DP_ERR_OK;
- const char *error = NULL;
- int ret;
-
- ret = groups_by_user_recv(req);
- talloc_zfree(req);
-
- if (ret) {
- dp_err = DP_ERR_FATAL;
- error = "Init Groups Failed";
-
- if (ret == ETIMEDOUT || ret == EFAULT || ret == EIO) {
- dp_err = DP_ERR_OFFLINE;
- ctx = talloc_get_type(breq->be_ctx->bet_info[BET_ID].pvt_bet_data,
- struct sdap_id_ctx);
- if (sdap_check_gssapi_reconnect(ctx)) {
- talloc_zfree(ctx->gsh);
- sdap_account_info_handler(breq);
- return;
- }
- sdap_mark_offline(ctx);
- }
- }
-
- return sdap_handler_done(breq, dp_err, ret, error);
-}
-
diff --git a/server/providers/ldap/ldap_id_cleanup.c b/server/providers/ldap/ldap_id_cleanup.c
deleted file mode 100644
index f3fb4443c..000000000
--- a/server/providers/ldap/ldap_id_cleanup.c
+++ /dev/null
@@ -1,555 +0,0 @@
-/*
- SSSD
-
- LDAP Identity Cleanup Functions
-
- Authors:
- Simo Sorce <ssorce@redhat.com>
-
- Copyright (C) 2009 Red Hat
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <errno.h>
-#include <time.h>
-#include <sys/time.h>
-
-#include "util/util.h"
-#include "db/sysdb.h"
-#include "providers/ldap/ldap_common.h"
-#include "providers/ldap/sdap_async.h"
-
-/* ==Cleanup-Task========================================================= */
-
-struct tevent_req *ldap_id_cleanup_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_id_ctx *ctx);
-static void ldap_id_cleanup_reschedule(struct tevent_req *req);
-
-static void ldap_id_cleanup_timeout(struct tevent_context *ev,
- struct tevent_timer *te,
- struct timeval tv, void *pvt);
-
-static void ldap_id_cleanup_timer(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 delay;
-
- if (be_is_offline(ctx->be)) {
- DEBUG(4, ("Backend is marked offline, retry later!\n"));
- /* schedule starting from now, not the last run */
- delay = dp_opt_get_int(ctx->opts->basic, SDAP_CACHE_PURGE_TIMEOUT);
- tv = tevent_timeval_current_ofs(delay, 0);
- ldap_id_cleanup_set_timer(ctx, tv);
- return;
- }
-
- req = ldap_id_cleanup_send(ctx, ev, ctx);
- if (!req) {
- DEBUG(1, ("Failed to schedule cleanup, retrying later!\n"));
- /* schedule starting from now, not the last run */
- delay = dp_opt_get_int(ctx->opts->basic, SDAP_CACHE_PURGE_TIMEOUT);
- tv = tevent_timeval_current_ofs(delay, 0);
- ldap_id_cleanup_set_timer(ctx, tv);
- return;
- }
- tevent_req_set_callback(req, ldap_id_cleanup_reschedule, ctx);
-
- /* if cleanup takes so long, either we try to cleanup too
- * frequently, or something went seriously wrong */
- delay = dp_opt_get_int(ctx->opts->basic, SDAP_CACHE_PURGE_TIMEOUT);
- tv = tevent_timeval_current_ofs(delay, 0);
- timeout = tevent_add_timer(ctx->be->ev, req, tv,
- ldap_id_cleanup_timeout, req);
- return;
-}
-
-static void ldap_id_cleanup_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 delay;
-
- delay = dp_opt_get_int(ctx->opts->basic, SDAP_CACHE_PURGE_TIMEOUT);
- DEBUG(1, ("Cleanup timed out! Timeout too small? (%ds)!\n", delay));
-
- tv = tevent_timeval_current_ofs(delay, 0);
- ldap_id_enumerate_set_timer(ctx, tv);
-
- talloc_zfree(req);
-}
-
-static void ldap_id_cleanup_reschedule(struct tevent_req *req)
-{
- struct sdap_id_ctx *ctx = tevent_req_callback_data(req,
- struct sdap_id_ctx);
- enum tevent_req_state tstate;
- uint64_t err;
- struct timeval tv;
- int delay;
-
- 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_purge;
- }
- talloc_zfree(req);
-
- delay = dp_opt_get_int(ctx->opts->basic, SDAP_CACHE_PURGE_TIMEOUT);
- tv = tevent_timeval_add(&tv, delay, 0);
- ldap_id_enumerate_set_timer(ctx, tv);
-}
-
-
-
-int ldap_id_cleanup_set_timer(struct sdap_id_ctx *ctx, struct timeval tv)
-{
- struct tevent_timer *cleanup_task;
-
- DEBUG(6, ("Scheduling next cleanup at %ld.%ld\n",
- (long)tv.tv_sec, (long)tv.tv_usec));
-
- cleanup_task = tevent_add_timer(ctx->be->ev, ctx,
- tv, ldap_id_cleanup_timer, ctx);
- if (!cleanup_task) {
- DEBUG(0, ("FATAL: failed to setup cleanup task!\n"));
- return EFAULT;
- }
-
- return EOK;
-}
-
-
-
-struct global_cleanup_state {
- struct tevent_context *ev;
- struct sdap_id_ctx *ctx;
-};
-
-static struct tevent_req *cleanup_users_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_id_ctx *ctx);
-static void ldap_id_cleanup_users_done(struct tevent_req *subreq);
-static struct tevent_req *cleanup_groups_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_id_ctx *ctx);
-static void ldap_id_cleanup_groups_done(struct tevent_req *subreq);
-
-struct tevent_req *ldap_id_cleanup_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_id_ctx *ctx)
-{
- struct global_cleanup_state *state;
- struct tevent_req *req, *subreq;
-
- req = tevent_req_create(memctx, &state, struct global_cleanup_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->ctx = ctx;
-
- subreq = cleanup_users_send(state, ev, ctx);
- if (!subreq) {
- talloc_zfree(req);
- return NULL;
- }
- tevent_req_set_callback(subreq, ldap_id_cleanup_users_done, req);
-
- ctx->last_purge = tevent_timeval_current();
-
- return req;
-}
-
-static void ldap_id_cleanup_users_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct global_cleanup_state *state = tevent_req_data(req,
- struct global_cleanup_state);
- enum tevent_req_state tstate;
- uint64_t err = 0;
-
- if (tevent_req_is_error(subreq, &tstate, &err)) {
- if (tstate != TEVENT_REQ_USER_ERROR) {
- err = EIO;
- }
- if (err != ENOENT) {
- goto fail;
- }
- }
- talloc_zfree(subreq);
-
- subreq = cleanup_groups_send(state, state->ev, state->ctx);
- if (!subreq) {
- goto fail;
- }
- tevent_req_set_callback(subreq, ldap_id_cleanup_groups_done, req);
-
- return;
-
-fail:
- if (err) {
- DEBUG(9, ("User cleanup failed with: (%d)[%s]\n",
- (int)err, strerror(err)));
-
- if (sdap_check_gssapi_reconnect(state->ctx)) {
- talloc_zfree(state->ctx->gsh);
- subreq = cleanup_users_send(state, state->ev, state->ctx);
- if (subreq != NULL) {
- tevent_req_set_callback(subreq, ldap_id_cleanup_users_done, req);
- return;
- }
- }
- sdap_mark_offline(state->ctx);
- }
-
- DEBUG(1, ("Failed to cleanup users, retrying later!\n"));
- tevent_req_done(req);
-}
-
-static void ldap_id_cleanup_groups_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct global_cleanup_state *state = tevent_req_data(req,
- struct global_cleanup_state);
- enum tevent_req_state tstate;
- uint64_t err;
-
- if (tevent_req_is_error(subreq, &tstate, &err)) {
- if (tstate != TEVENT_REQ_USER_ERROR) {
- err = EIO;
- }
- if (err != ENOENT) {
- goto fail;
- }
- }
- talloc_zfree(subreq);
-
- tevent_req_done(req);
- return;
-
-fail:
- /* check if credentials are expired otherwise go offline on failures */
- if (sdap_check_gssapi_reconnect(state->ctx)) {
- talloc_zfree(state->ctx->gsh);
- subreq = cleanup_groups_send(state, state->ev, state->ctx);
- if (subreq != NULL) {
- tevent_req_set_callback(subreq, ldap_id_cleanup_groups_done, req);
- return;
- }
- }
- sdap_mark_offline(state->ctx);
- DEBUG(1, ("Failed to cleanup groups (%d [%s]), retrying later!\n",
- (int)err, strerror(err)));
- tevent_req_done(req);
-}
-
-
-/* ==User-Cleanup-Process================================================= */
-
-struct cleanup_users_state {
- struct tevent_context *ev;
- struct sdap_id_ctx *ctx;
- struct sysdb_ctx *sysdb;
- struct sss_domain_info *domain;
-
- struct sysdb_handle *handle;
-
- struct ldb_message **msgs;
- size_t count;
- int cur;
-};
-
-static void cleanup_users_process(struct tevent_req *subreq);
-static void cleanup_users_update(struct tevent_req *req);
-static void cleanup_users_up_done(struct tevent_req *subreq);
-
-static struct tevent_req *cleanup_users_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_id_ctx *ctx)
-{
- struct tevent_req *req, *subreq;
- struct cleanup_users_state *state;
- static const char *attrs[] = { SYSDB_NAME, NULL };
- time_t now = time(NULL);
- char *subfilter;
-
- req = tevent_req_create(memctx, &state, struct cleanup_users_state);
- if (!req) {
- return NULL;
- }
-
- state->ev = ev;
- state->ctx = ctx;
- state->sysdb = ctx->be->sysdb;
- state->domain = ctx->be->domain;
- state->msgs = NULL;
- state->count = 0;
- state->cur = 0;
-
- subfilter = talloc_asprintf(state, "(&(!(%s=0))(%s<=%ld))",
- SYSDB_CACHE_EXPIRE,
- SYSDB_CACHE_EXPIRE, (long)now);
- if (!subfilter) {
- DEBUG(2, ("Failed to build filter\n"));
- talloc_zfree(req);
- return NULL;
- }
-
- subreq = sysdb_search_users_send(state, state->ev,
- state->sysdb, NULL,
- state->domain, subfilter, attrs);
- if (!subreq) {
- DEBUG(2, ("Failed to send entry search\n"));
- talloc_zfree(req);
- return NULL;
- }
- tevent_req_set_callback(subreq, cleanup_users_process, req);
-
- return req;
-}
-
-static void cleanup_users_process(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct cleanup_users_state *state = tevent_req_data(req,
- struct cleanup_users_state);
- int ret;
-
- ret = sysdb_search_users_recv(subreq, state, &state->count, &state->msgs);
- talloc_zfree(subreq);
- if (ret) {
- if (ret == ENOENT) {
- tevent_req_done(req);
- return;
- }
- tevent_req_error(req, ret);
- return;
- }
-
- DEBUG(4, ("Found %d expired user entries!\n", state->count));
-
- if (state->count == 0) {
- tevent_req_done(req);
- }
-
- cleanup_users_update(req);
-}
-
-static void cleanup_users_update(struct tevent_req *req)
-{
- struct tevent_req *subreq;
- struct cleanup_users_state *state = tevent_req_data(req,
- struct cleanup_users_state);
- const char *str;
-
- str = ldb_msg_find_attr_as_string(state->msgs[state->cur],
- SYSDB_NAME, NULL);
- if (!str) {
- DEBUG(2, ("Entry %s has no Name Attribute ?!?\n",
- ldb_dn_get_linearized(state->msgs[state->cur]->dn)));
- tevent_req_error(req, EFAULT);
- return;
- }
-
- subreq = users_get_send(state, state->ev, state->ctx,
- str, BE_FILTER_NAME, BE_ATTR_CORE);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, cleanup_users_up_done, req);
-}
-
-static void cleanup_users_up_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct cleanup_users_state *state = tevent_req_data(req,
- struct cleanup_users_state);
- int ret;
-
- ret = users_get_recv(subreq);
- talloc_zfree(subreq);
- if (ret) {
- DEBUG(2, ("User check returned: %d(%s)\n",
- ret, strerror(ret)));
- }
-
- /* if the entry doesn't need to be purged, remove it from the list */
- if (ret != ENOENT) {
- talloc_zfree(state->msgs[state->cur]);
- }
-
- state->cur++;
- if (state->cur < state->count) {
- cleanup_users_update(req);
- return;
- }
-
- tevent_req_done(req);
-}
-
-/* ==Group-Cleanup-Process================================================ */
-
-struct cleanup_groups_state {
- struct tevent_context *ev;
- struct sdap_id_ctx *ctx;
- struct sysdb_ctx *sysdb;
- struct sss_domain_info *domain;
-
- struct sysdb_handle *handle;
-
- struct ldb_message **msgs;
- size_t count;
- int cur;
-};
-
-static void cleanup_groups_process(struct tevent_req *subreq);
-static void cleanup_groups_update(struct tevent_req *req);
-static void cleanup_groups_up_done(struct tevent_req *subreq);
-
-static struct tevent_req *cleanup_groups_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_id_ctx *ctx)
-{
- struct tevent_req *req, *subreq;
- struct cleanup_groups_state *state;
- static const char *attrs[] = { SYSDB_NAME, NULL };
- time_t now = time(NULL);
- char *subfilter;
-
- req = tevent_req_create(memctx, &state, struct cleanup_groups_state);
- if (!req) {
- return NULL;
- }
-
- state->ev = ev;
- state->ctx = ctx;
- state->sysdb = ctx->be->sysdb;
- state->domain = ctx->be->domain;
- state->msgs = NULL;
- state->count = 0;
- state->cur = 0;
-
- subfilter = talloc_asprintf(state, "(&(!(%s=0))(%s<=%ld))",
- SYSDB_CACHE_EXPIRE,
- SYSDB_CACHE_EXPIRE, (long)now);
- if (!subfilter) {
- DEBUG(2, ("Failed to build filter\n"));
- talloc_zfree(req);
- return NULL;
- }
-
- subreq = sysdb_search_groups_send(state, state->ev,
- state->sysdb, NULL,
- state->domain, subfilter, attrs);
- if (!subreq) {
- DEBUG(2, ("Failed to send entry search\n"));
- talloc_zfree(req);
- return NULL;
- }
- tevent_req_set_callback(subreq, cleanup_groups_process, req);
-
- return req;
-}
-
-static void cleanup_groups_process(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct cleanup_groups_state *state = tevent_req_data(req,
- struct cleanup_groups_state);
- int ret;
-
- ret = sysdb_search_groups_recv(subreq, state, &state->count, &state->msgs);
- talloc_zfree(subreq);
- if (ret) {
- if (ret == ENOENT) {
- tevent_req_done(req);
- return;
- }
- tevent_req_error(req, ret);
- return;
- }
-
- DEBUG(4, ("Found %d expired group entries!\n", state->count));
-
- if (state->count == 0) {
- tevent_req_done(req);
- }
-
- cleanup_groups_update(req);
-}
-
-static void cleanup_groups_update(struct tevent_req *req)
-{
- struct tevent_req *subreq;
- struct cleanup_groups_state *state = tevent_req_data(req,
- struct cleanup_groups_state);
- const char *str;
-
- str = ldb_msg_find_attr_as_string(state->msgs[state->cur],
- SYSDB_NAME, NULL);
- if (!str) {
- DEBUG(2, ("Entry %s has no Name Attribute ?!?\n",
- ldb_dn_get_linearized(state->msgs[state->cur]->dn)));
- tevent_req_error(req, EFAULT);
- return;
- }
-
- subreq = groups_get_send(state, state->ev, state->ctx,
- str, BE_FILTER_NAME, BE_ATTR_CORE);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, cleanup_groups_up_done, req);
-}
-
-static void cleanup_groups_up_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct cleanup_groups_state *state = tevent_req_data(req,
- struct cleanup_groups_state);
- int ret;
-
- ret = groups_get_recv(subreq);
- talloc_zfree(subreq);
- if (ret) {
- DEBUG(2, ("User check returned: %d(%s)\n",
- ret, strerror(ret)));
- }
-
- state->cur++;
- if (state->cur < state->count) {
- cleanup_groups_update(req);
- return;
- }
-
- tevent_req_done(req);
-}
-
diff --git a/server/providers/ldap/ldap_id_enum.c b/server/providers/ldap/ldap_id_enum.c
deleted file mode 100644
index bc06e8bdc..000000000
--- a/server/providers/ldap/ldap_id_enum.c
+++ /dev/null
@@ -1,608 +0,0 @@
-/*
- SSSD
-
- LDAP Identity Enumeration
-
- Authors:
- Simo Sorce <ssorce@redhat.com>
-
- Copyright (C) 2009 Red Hat
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <errno.h>
-#include <time.h>
-#include <sys/time.h>
-
-#include "util/util.h"
-#include "db/sysdb.h"
-#include "providers/ldap/ldap_common.h"
-#include "providers/ldap/sdap_async.h"
-
-extern struct tevent_req *ldap_id_cleanup_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_id_ctx *ctx);
-
-/* ==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_timeout(struct tevent_context *ev,
- struct tevent_timer *te,
- struct timeval tv, void *pvt);
-
-static void ldap_id_enumerate_timer(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 delay;
-
- if (be_is_offline(ctx->be)) {
- DEBUG(4, ("Backend is marked offline, retry later!\n"));
- /* schedule starting from now, not the last run */
- delay = dp_opt_get_int(ctx->opts->basic, SDAP_ENUM_REFRESH_TIMEOUT);
- tv = tevent_timeval_current_ofs(delay, 0);
- ldap_id_enumerate_set_timer(ctx, tv);
- return;
- }
-
- 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 */
- delay = dp_opt_get_int(ctx->opts->basic, SDAP_ENUM_REFRESH_TIMEOUT);
- tv = tevent_timeval_current_ofs(delay, 0);
- ldap_id_enumerate_set_timer(ctx, tv);
- 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 */
- delay = dp_opt_get_int(ctx->opts->basic, SDAP_ENUM_REFRESH_TIMEOUT);
- tv = tevent_timeval_current_ofs(delay, 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 delay;
-
- delay = dp_opt_get_int(ctx->opts->basic, SDAP_ENUM_REFRESH_TIMEOUT);
- DEBUG(1, ("Enumeration timed out! Timeout too small? (%ds)!\n", delay));
-
- tv = tevent_timeval_current_ofs(delay, 0);
- ldap_id_enumerate_set_timer(ctx, tv);
-
- 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);
- enum tevent_req_state tstate;
- uint64_t err;
- struct timeval tv;
- int delay;
-
- 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_enum;
- }
- talloc_zfree(req);
-
- delay = dp_opt_get_int(ctx->opts->basic, SDAP_ENUM_REFRESH_TIMEOUT);
- tv = tevent_timeval_add(&tv, delay, 0);
- ldap_id_enumerate_set_timer(ctx, tv);
-}
-
-
-
-int ldap_id_enumerate_set_timer(struct sdap_id_ctx *ctx, struct timeval tv)
-{
- struct tevent_timer *enum_task;
-
- DEBUG(6, ("Scheduling next enumeration at %ld.%ld\n",
- (long)tv.tv_sec, (long)tv.tv_usec));
-
- enum_task = tevent_add_timer(ctx->be->ev, ctx,
- tv, ldap_id_enumerate_timer, ctx);
- if (!enum_task) {
- DEBUG(0, ("FATAL: failed to setup enumeration task!\n"));
- return EFAULT;
- }
-
- return EOK;
-}
-
-
-struct global_enum_state {
- struct tevent_context *ev;
- struct sdap_id_ctx *ctx;
-
- bool purge;
-};
-
-static struct tevent_req *enum_users_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_id_ctx *ctx,
- bool purge);
-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,
- bool purge);
-static void ldap_id_enum_groups_done(struct tevent_req *subreq);
-static void ldap_id_enum_cleanup_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;
- int t;
-
- req = tevent_req_create(ctx, &state, struct global_enum_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->ctx = ctx;
-
- ctx->last_enum = tevent_timeval_current();
-
- t = dp_opt_get_int(ctx->opts->basic, SDAP_CACHE_PURGE_TIMEOUT);
- if ((ctx->last_purge.tv_sec + t) < ctx->last_enum.tv_sec) {
- state->purge = true;
- } else {
- state->purge = false;
- }
-
- subreq = enum_users_send(state, ev, ctx, state->purge);
- 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)) {
- if (tstate != TEVENT_REQ_USER_ERROR) {
- err = EIO;
- }
- if (err != ENOENT) {
- goto fail;
- }
- }
- talloc_zfree(subreq);
-
- subreq = enum_groups_send(state, state->ev, state->ctx, state->purge);
- 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)));
-
- if (sdap_check_gssapi_reconnect(state->ctx)) {
- talloc_zfree(state->ctx->gsh);
- subreq = enum_users_send(state, state->ev, state->ctx, state->purge);
- if (subreq != NULL) {
- tevent_req_set_callback(subreq, ldap_id_enum_users_done, req);
- return;
- }
- }
- sdap_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 = 0;
-
- if (tevent_req_is_error(subreq, &tstate, &err)) {
- if (tstate != TEVENT_REQ_USER_ERROR) {
- err = EIO;
- }
- if (err != ENOENT) {
- goto fail;
- }
- }
- talloc_zfree(subreq);
-
- if (state->purge) {
-
- subreq = ldap_id_cleanup_send(state, state->ev, state->ctx);
- if (!subreq) {
- goto fail;
- }
- tevent_req_set_callback(subreq, ldap_id_enum_cleanup_done, req);
-
- return;
- }
-
- tevent_req_done(req);
- return;
-
-fail:
- /* check if credentials are expired otherwise go offline on failures */
- if (sdap_check_gssapi_reconnect(state->ctx)) {
- talloc_zfree(state->ctx->gsh);
- subreq = enum_groups_send(state, state->ev, state->ctx, state->purge);
- if (subreq != NULL) {
- tevent_req_set_callback(subreq, ldap_id_enum_groups_done, req);
- return;
- }
- }
- sdap_mark_offline(state->ctx);
- DEBUG(1, ("Failed to enumerate groups (%d [%s]), retrying later!\n",
- (int)err, strerror(err)));
- tevent_req_done(req);
-}
-
-static void ldap_id_enum_cleanup_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- talloc_zfree(subreq);
- 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,
- bool purge)
-{
- 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 && !purge) {
-
- 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 (!sdap_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->be, ctx->service,
- &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,
- bool purge)
-{
- 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 && !purge) {
-
- 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 (!sdap_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->be, ctx->service,
- &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);
-}
-
diff --git a/server/providers/ldap/ldap_init.c b/server/providers/ldap/ldap_init.c
deleted file mode 100644
index b1f053fbc..000000000
--- a/server/providers/ldap/ldap_init.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- SSSD
-
- LDAP Provider Initialization functions
-
- Authors:
- Simo Sorce <ssorce@redhat.com>
-
- Copyright (C) 2009 Red Hat
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "providers/child_common.h"
-#include "providers/ldap/ldap_common.h"
-#include "providers/ldap/sdap_async_private.h"
-
-static void sdap_shutdown(struct be_req *req);
-
-/* Id Handler */
-struct bet_ops sdap_id_ops = {
- .handler = sdap_account_info_handler,
- .finalize = sdap_shutdown
-};
-
-/* Auth Handler */
-struct bet_ops sdap_auth_ops = {
- .handler = sdap_pam_auth_handler,
- .finalize = sdap_shutdown
-};
-
-/* Chpass Handler */
-struct bet_ops sdap_chpass_ops = {
- .handler = sdap_pam_chpass_handler,
- .finalize = sdap_shutdown
-};
-
-int sssm_ldap_init(struct be_ctx *bectx,
- struct bet_ops **ops,
- void **pvt_data)
-{
- struct sdap_id_ctx *ctx;
- const char *urls;
- int ret;
-
- ctx = talloc_zero(bectx, struct sdap_id_ctx);
- if (!ctx) return ENOMEM;
-
- ctx->be = bectx;
-
- ret = ldap_get_options(ctx, bectx->cdb,
- bectx->conf_path, &ctx->opts);
- if (ret != EOK) {
- goto done;
- }
-
- urls = dp_opt_get_string(ctx->opts->basic, SDAP_URI);
- if (!urls) {
- DEBUG(0, ("Missing ldap_uri\n"));
- ret = EINVAL;
- goto done;
- }
-
- ret = sdap_service_init(ctx, ctx->be, "LDAP", urls, &ctx->service);
- if (ret != EOK) {
- DEBUG(1, ("Failed to initialize failover service!\n"));
- goto done;
- }
-
- ret = setup_tls_config(ctx->opts->basic);
- if (ret != EOK) {
- DEBUG(1, ("setup_tls_config failed [%d][%s].\n",
- ret, strerror(ret)));
- goto done;
- }
-
- ret = sdap_id_setup_tasks(ctx);
- if (ret != EOK) {
- goto done;
- }
-
- ret = setup_child(ctx);
- if (ret != EOK) {
- DEBUG(1, ("setup_child failed [%d][%s].\n",
- ret, strerror(ret)));
- goto done;
- }
-
- *ops = &sdap_id_ops;
- *pvt_data = ctx;
- ret = EOK;
-
-done:
- if (ret != EOK) {
- talloc_free(ctx);
- }
- return ret;
-}
-
-int sssm_ldap_auth_init(struct be_ctx *bectx,
- struct bet_ops **ops,
- void **pvt_data)
-{
- struct sdap_auth_ctx *ctx;
- const char *urls;
- int ret;
-
- ctx = talloc(bectx, struct sdap_auth_ctx);
- if (!ctx) return ENOMEM;
-
- ctx->be = bectx;
-
- ret = ldap_get_options(ctx, bectx->cdb,
- bectx->conf_path, &ctx->opts);
- if (ret != EOK) {
- goto done;
- }
-
- urls = dp_opt_get_string(ctx->opts->basic, SDAP_URI);
- if (!urls) {
- DEBUG(0, ("Missing ldap_uri\n"));
- ret = EINVAL;
- goto done;
- }
-
- ret = sdap_service_init(ctx, ctx->be, "LDAP", urls, &ctx->service);
- if (ret != EOK) {
- DEBUG(1, ("Failed to initialize failover service!\n"));
- goto done;
- }
-
- ret = setup_tls_config(ctx->opts->basic);
- if (ret != EOK) {
- DEBUG(1, ("setup_tls_config failed [%d][%s].\n",
- ret, strerror(ret)));
- goto done;
- }
-
- *ops = &sdap_auth_ops;
- *pvt_data = ctx;
- ret = EOK;
-
-done:
- if (ret != EOK) {
- talloc_free(ctx);
- }
- return ret;
-}
-
-int sssm_ldap_chpass_init(struct be_ctx *bectx,
- struct bet_ops **ops,
- void **pvt_data)
-{
- int ret;
-
- ret = sssm_ldap_auth_init(bectx, ops, pvt_data);
-
- *ops = &sdap_chpass_ops;
-
- return ret;
-}
-
-static void sdap_shutdown(struct be_req *req)
-{
- /* TODO: Clean up any internal data */
- sdap_handler_done(req, DP_ERR_OK, EOK, NULL);
-}
-
diff --git a/server/providers/ldap/sdap.c b/server/providers/ldap/sdap.c
deleted file mode 100644
index 39c67cc92..000000000
--- a/server/providers/ldap/sdap.c
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
- SSSD
-
- LDAP Helper routines
-
- Copyright (C) Simo Sorce <ssorce@redhat.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#define LDAP_DEPRECATED 1
-#include "util/util.h"
-#include "confdb/confdb.h"
-#include "providers/ldap/sdap.h"
-
-/* =Retrieve-Options====================================================== */
-
-int sdap_get_map(TALLOC_CTX *memctx,
- struct confdb_ctx *cdb,
- const char *conf_path,
- struct sdap_attr_map *def_map,
- int num_entries,
- struct sdap_attr_map **_map)
-{
- struct sdap_attr_map *map;
- int i, ret;
-
- map = talloc_array(memctx, struct sdap_attr_map, num_entries);
- if (!map) {
- return ENOMEM;
- }
-
- for (i = 0; i < num_entries; i++) {
-
- map[i].opt_name = def_map[i].opt_name;
- map[i].def_name = def_map[i].def_name;
- map[i].sys_name = def_map[i].sys_name;
-
- ret = confdb_get_string(cdb, map, conf_path,
- map[i].opt_name,
- map[i].def_name,
- &map[i].name);
- if ((ret != EOK) || (map[i].def_name && !map[i].name)) {
- DEBUG(0, ("Failed to retrieve value for %s\n", map[i].opt_name));
- if (ret != EOK) {
- talloc_zfree(map);
- return EINVAL;
- }
- }
-
- DEBUG(5, ("Option %s has value %s\n", map[i].opt_name, map[i].name));
- }
-
- *_map = map;
- return EOK;
-}
-
-/* =Parse-msg============================================================= */
-
-int sdap_parse_entry(TALLOC_CTX *memctx,
- struct sdap_handle *sh, struct sdap_msg *sm,
- struct sdap_attr_map *map, int attrs_num,
- struct sysdb_attrs **_attrs, char **_dn)
-{
- struct sysdb_attrs *attrs;
- BerElement *ber = NULL;
- struct berval **vals;
- struct ldb_val v;
- char *str;
- int lerrno;
- int a, i, ret;
- const char *name;
- bool store;
-
- lerrno = 0;
- ldap_set_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno);
-
- attrs = sysdb_new_attrs(memctx);
- if (!attrs) return ENOMEM;
-
- str = ldap_get_dn(sh->ldap, sm->msg);
- if (!str) {
- ldap_get_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno);
- DEBUG(1, ("ldap_get_dn failed: %d(%s)\n",
- lerrno, ldap_err2string(lerrno)));
- ret = EIO;
- goto fail;
- }
-
- DEBUG(9, ("OriginalDN: [%s].\n", str));
- ret = sysdb_attrs_add_string(attrs, SYSDB_ORIG_DN, str);
- if (ret) goto fail;
- if (_dn) {
- *_dn = talloc_strdup(memctx, str);
- if (!*_dn) {
- ret = ENOMEM;
- ldap_memfree(str);
- goto fail;
- }
- }
- ldap_memfree(str);
-
- if (map) {
- vals = ldap_get_values_len(sh->ldap, sm->msg, "objectClass");
- if (!vals) {
- DEBUG(1, ("Unknown entry type, no objectClasses found!\n"));
- ret = EINVAL;
- goto fail;
- }
-
- for (i = 0; vals[i]; i++) {
- /* the objectclass is always the first name in the map */
- if (strncasecmp(map[0].name,
- vals[i]->bv_val, vals[i]->bv_len) == 0) {
- /* ok it's an entry of the right type */
- break;
- }
- }
- if (!vals[i]) {
- DEBUG(1, ("objectClass not matching: %s\n",
- map[0].name));
- ldap_value_free_len(vals);
- ret = EINVAL;
- goto fail;
- }
- ldap_value_free_len(vals);
- }
-
- str = ldap_first_attribute(sh->ldap, sm->msg, &ber);
- if (!str) {
- ldap_get_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno);
- DEBUG(1, ("Entry has no attributes [%d(%s)]!?\n",
- lerrno, ldap_err2string(lerrno)));
- if (map) {
- ret = EINVAL;
- goto fail;
- }
- }
- while (str) {
- if (map) {
- for (a = 1; a < attrs_num; a++) {
- /* check if this attr is valid with the chosen schema */
- if (!map[a].name) continue;
- /* check if it is an attr we are interested in */
- if (strcasecmp(str, map[a].name) == 0) break;
- }
- /* interesting attr */
- if (a < attrs_num) {
- store = true;
- name = map[a].sys_name;
- } else {
- store = false;
- }
- } else {
- name = str;
- store = true;
- }
-
- if (store) {
- vals = ldap_get_values_len(sh->ldap, sm->msg, str);
- if (!vals) {
- ldap_get_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno);
- DEBUG(1, ("LDAP Library error: %d(%s)",
- lerrno, ldap_err2string(lerrno)));
- ret = EIO;
- goto fail;
- }
- if (!vals[0]) {
- DEBUG(1, ("Missing value after ldap_get_values() ??\n"));
- ret = EINVAL;
- goto fail;
- }
- for (i = 0; vals[i]; i++) {
- v.data = (uint8_t *)vals[i]->bv_val;
- v.length = vals[i]->bv_len;
-
- ret = sysdb_attrs_add_val(attrs, name, &v);
- if (ret) goto fail;
- }
- ldap_value_free_len(vals);
- }
-
- ldap_memfree(str);
- str = ldap_next_attribute(sh->ldap, sm->msg, ber);
- }
- ber_free(ber, 0);
-
- ldap_get_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno);
- if (lerrno) {
- DEBUG(1, ("LDAP Library error: %d(%s)",
- lerrno, ldap_err2string(lerrno)));
- ret = EIO;
- goto fail;
- }
-
- *_attrs = attrs;
- return EOK;
-
-fail:
- if (ber) ber_free(ber, 0);
- talloc_free(attrs);
- return ret;
-}
-
-/* This function converts an ldap message into a sysdb_attrs structure.
- * It converts only known user attributes, the rest are ignored.
- * If the entry is not that of an user an error is returned.
- * The original DN is stored as an attribute named originalDN */
-
-int sdap_parse_user(TALLOC_CTX *memctx, struct sdap_options *opts,
- struct sdap_handle *sh, struct sdap_msg *sm,
- struct sysdb_attrs **_attrs, char **_dn)
-{
-
- return sdap_parse_entry(memctx, sh, sm, opts->user_map,
- SDAP_OPTS_USER, _attrs, _dn);
-}
-
-/* This function converts an ldap message into a sysdb_attrs structure.
- * It converts only known group attributes, the rest are ignored.
- * If the entry is not that of an user an error is returned.
- * The original DN is stored as an attribute named originalDN */
-
-int sdap_parse_group(TALLOC_CTX *memctx, struct sdap_options *opts,
- struct sdap_handle *sh, struct sdap_msg *sm,
- struct sysdb_attrs **_attrs, char **_dn)
-{
-
- return sdap_parse_entry(memctx, sh, sm, opts->group_map,
- SDAP_OPTS_GROUP, _attrs, _dn);
-}
-
-/* =Get-DN-from-message=================================================== */
-
-int sdap_get_msg_dn(TALLOC_CTX *memctx, struct sdap_handle *sh,
- struct sdap_msg *sm, char **_dn)
-{
- char *str;
- int lerrno;
-
- lerrno = 0;
- ldap_set_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno);
-
- str = ldap_get_dn(sh->ldap, sm->msg);
- if (!str) {
- ldap_get_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno);
- DEBUG(1, ("ldap_get_dn failed: %d(%s)\n",
- lerrno, ldap_err2string(lerrno)));
- return EIO;
- }
-
- *_dn = talloc_strdup(memctx, str);
- ldap_memfree(str);
- if (!*_dn) return ENOMEM;
-
- return EOK;
-}
-
-errno_t setup_tls_config(struct dp_option *basic_opts)
-{
- int ret;
- int ldap_opt_x_tls_require_cert;
- const char *tls_opt;
- tls_opt = dp_opt_get_string(basic_opts, SDAP_TLS_REQCERT);
- if (tls_opt) {
- if (strcasecmp(tls_opt, "never") == 0) {
- ldap_opt_x_tls_require_cert = LDAP_OPT_X_TLS_NEVER;
- }
- else if (strcasecmp(tls_opt, "allow") == 0) {
- ldap_opt_x_tls_require_cert = LDAP_OPT_X_TLS_ALLOW;
- }
- else if (strcasecmp(tls_opt, "try") == 0) {
- ldap_opt_x_tls_require_cert = LDAP_OPT_X_TLS_TRY;
- }
- else if (strcasecmp(tls_opt, "demand") == 0) {
- ldap_opt_x_tls_require_cert = LDAP_OPT_X_TLS_DEMAND;
- }
- else if (strcasecmp(tls_opt, "hard") == 0) {
- ldap_opt_x_tls_require_cert = LDAP_OPT_X_TLS_HARD;
- }
- else {
- DEBUG(1, ("Unknown value for tls_reqcert.\n"));
- return EINVAL;
- }
- /* LDAP_OPT_X_TLS_REQUIRE_CERT has to be set as a global option,
- * because the SSL/TLS context is initialized from this value. */
- ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT,
- &ldap_opt_x_tls_require_cert);
- if (ret != LDAP_OPT_SUCCESS) {
- DEBUG(1, ("ldap_set_option failed: %s\n", ldap_err2string(ret)));
- return EIO;
- }
- }
-
- tls_opt = dp_opt_get_string(basic_opts, SDAP_TLS_CACERT);
- if (tls_opt) {
- ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, tls_opt);
- if (ret != LDAP_OPT_SUCCESS) {
- DEBUG(1, ("ldap_set_option failed: %s\n", ldap_err2string(ret)));
- return EIO;
- }
- }
-
- tls_opt = dp_opt_get_string(basic_opts, SDAP_TLS_CACERTDIR);
- if (tls_opt) {
- ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTDIR, tls_opt);
- if (ret != LDAP_OPT_SUCCESS) {
- DEBUG(1, ("ldap_set_option failed: %s\n", ldap_err2string(ret)));
- return EIO;
- }
- }
-
- return EOK;
-}
-
-
-bool sdap_rootdse_sasl_mech_is_supported(struct sysdb_attrs *rootdse,
- const char *sasl_mech)
-{
- struct ldb_message_element *el = NULL;
- struct ldb_val *val;
- int i;
-
- if (!sasl_mech) return false;
-
- for (i = 0; i < rootdse->num; i++) {
- if (strcasecmp(rootdse->a[i].name, "supportedSASLMechanisms")) {
- continue;
- }
- el = &rootdse->a[i];
- break;
- }
-
- if (!el) {
- /* no supported SASL Mechanism at all ? */
- return false;
- }
-
- for (i = 0; i < el->num_values; i++) {
- val = &el->values[i];
- if (strncasecmp(sasl_mech, (const char *)val->data, val->length)) {
- continue;
- }
- return true;
- }
-
- return false;
-}
-
-int build_attrs_from_map(TALLOC_CTX *memctx,
- struct sdap_attr_map *map,
- size_t size, const char ***_attrs)
-{
- char **attrs;
- int i, j;
-
- attrs = talloc_array(memctx, char *, size + 1);
- if (!attrs) return ENOMEM;
-
- /* first attribute is "objectclass" not the specifc one */
- attrs[0] = talloc_strdup(memctx, "objectClass");
- if (!attrs[0]) return ENOMEM;
-
- /* add the others */
- for (i = j = 1; i < size; i++) {
- if (map[i].name) {
- attrs[j] = map[i].name;
- j++;
- }
- }
- attrs[j] = NULL;
-
- *_attrs = (const char **)attrs;
-
- return EOK;
-}
-
diff --git a/server/providers/ldap/sdap.h b/server/providers/ldap/sdap.h
deleted file mode 100644
index 16dbb7843..000000000
--- a/server/providers/ldap/sdap.h
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- SSSD
-
- LDAP Helper routines
-
- Copyright (C) Simo Sorce <ssorce@redhat.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _SDAP_H_
-#define _SDAP_H_
-
-#include "providers/dp_backend.h"
-#include <ldap.h>
-#include "util/sss_ldap.h"
-
-struct sdap_msg {
- struct sdap_msg *next;
- LDAPMessage *msg;
-};
-
-struct sdap_op;
-
-typedef void (sdap_op_callback_t)(struct sdap_op *op,
- struct sdap_msg *, int, void *);
-
-struct sdap_handle;
-
-struct sdap_op {
- struct sdap_op *prev, *next;
- struct sdap_handle *sh;
-
- int msgid;
- bool done;
-
- sdap_op_callback_t *callback;
- void *data;
-
- struct tevent_context *ev;
- struct sdap_msg *list;
- struct sdap_msg *last;
-};
-
-struct fd_event_item {
- struct fd_event_item *prev;
- struct fd_event_item *next;
-
- int fd;
- struct tevent_fd *fde;
-};
-
-struct ldap_cb_data {
- struct sdap_handle *sh;
- struct tevent_context *ev;
- struct fd_event_item *fd_list;
-};
-
-struct sdap_handle {
- LDAP *ldap;
- bool connected;
-
-#ifdef HAVE_LDAP_CONNCB
- struct ldap_conncb *conncb;
-#else
- struct tevent_fd *fde;
-#endif
-
- struct sdap_op *ops;
-};
-
-struct sdap_service {
- char *name;
- char *uri;
-};
-
-#define SYSDB_SHADOWPW_LASTCHANGE "shadowLastChange"
-#define SYSDB_SHADOWPW_MIN "shadowMin"
-#define SYSDB_SHADOWPW_MAX "shadowMax"
-#define SYSDB_SHADOWPW_WARNING "shadowWarning"
-#define SYSDB_SHADOWPW_INACTIVE "shadowInactive"
-#define SYSDB_SHADOWPW_EXPIRE "shadowExpire"
-#define SYSDB_SHADOWPW_FLAG "shadowFlag"
-
-#define SYSDB_KRBPW_LASTCHANGE "krbLastPwdChange"
-#define SYSDB_KRBPW_EXPIRATION "krbPasswordExpiration"
-
-#define SYSDB_PWD_ATTRIBUTE "pwdAttribute"
-
-enum sdap_result {
- SDAP_SUCCESS,
- SDAP_NOT_FOUND,
- SDAP_UNAVAIL,
- SDAP_RETRY,
- SDAP_ERROR,
- SDAP_AUTH_SUCCESS,
- SDAP_AUTH_FAILED,
- SDAP_AUTH_PW_EXPIRED,
- SDAP_ACCT_EXPIRED
-};
-
-enum sdap_basic_opt {
- SDAP_URI = 0,
- SDAP_SEARCH_BASE,
- SDAP_DEFAULT_BIND_DN,
- SDAP_DEFAULT_AUTHTOK_TYPE,
- SDAP_DEFAULT_AUTHTOK,
- SDAP_SEARCH_TIMEOUT,
- SDAP_NETWORK_TIMEOUT,
- SDAP_OPT_TIMEOUT,
- SDAP_TLS_REQCERT,
- SDAP_USER_SEARCH_BASE,
- SDAP_USER_SEARCH_SCOPE,
- SDAP_USER_SEARCH_FILTER,
- SDAP_GROUP_SEARCH_BASE,
- SDAP_GROUP_SEARCH_SCOPE,
- SDAP_GROUP_SEARCH_FILTER,
- SDAP_SCHEMA,
- SDAP_OFFLINE_TIMEOUT,
- SDAP_FORCE_UPPER_CASE_REALM,
- SDAP_ENUM_REFRESH_TIMEOUT,
- SDAP_CACHE_PURGE_TIMEOUT,
- SDAP_ENTRY_CACHE_TIMEOUT,
- SDAP_TLS_CACERT,
- SDAP_TLS_CACERTDIR,
- SDAP_ID_TLS,
- SDAP_SASL_MECH,
- SDAP_SASL_AUTHID,
- SDAP_KRB5_KEYTAB,
- SDAP_KRB5_KINIT,
- SDAP_KRB5_REALM,
- SDAP_PWD_POLICY,
- SDAP_REFERRALS,
-
- SDAP_OPTS_BASIC /* opts counter */
-};
-
-enum sdap_gen_attrs {
- SDAP_AT_ENTRY_USN = 0,
- SDAP_AT_LAST_USN,
-
- SDAP_AT_GENERAL /* attrs counter */
-};
-
-/* the objectclass must be the first attribute.
- * Functions depend on this */
-enum sdap_user_attrs {
- SDAP_OC_USER = 0,
- SDAP_AT_USER_NAME,
- SDAP_AT_USER_PWD,
- SDAP_AT_USER_UID,
- SDAP_AT_USER_GID,
- SDAP_AT_USER_GECOS,
- SDAP_AT_USER_HOME,
- SDAP_AT_USER_SHELL,
- SDAP_AT_USER_PRINC,
- SDAP_AT_USER_FULLNAME,
- SDAP_AT_USER_MEMBEROF,
- SDAP_AT_USER_UUID,
- SDAP_AT_USER_MODSTAMP,
- SDAP_AT_SP_LSTCHG,
- SDAP_AT_SP_MIN,
- SDAP_AT_SP_MAX,
- SDAP_AT_SP_WARN,
- SDAP_AT_SP_INACT,
- SDAP_AT_SP_EXPIRE,
- SDAP_AT_SP_FLAG,
- SDAP_AT_KP_LASTCHANGE,
- SDAP_AT_KP_EXPIRATION,
- SDAP_AT_PWD_ATTRIBUTE,
-
- SDAP_OPTS_USER /* attrs counter */
-};
-
-#define SDAP_FIRST_EXTRA_USER_AT SDAP_AT_SP_LSTCHG
-
-/* the objectclass must be the first attribute.
- * Functions depend on this */
-enum sdap_group_attrs {
- SDAP_OC_GROUP = 0,
- SDAP_AT_GROUP_NAME,
- SDAP_AT_GROUP_PWD,
- SDAP_AT_GROUP_GID,
- SDAP_AT_GROUP_MEMBER,
- SDAP_AT_GROUP_UUID,
- SDAP_AT_GROUP_MODSTAMP,
-
- SDAP_OPTS_GROUP /* attrs counter */
-};
-
-struct sdap_attr_map {
- const char *opt_name;
- const char *def_name;
- const char *sys_name;
- char *name;
-};
-
-struct sdap_options {
- struct dp_option *basic;
- struct sdap_attr_map *gen_map;
- struct sdap_attr_map *user_map;
- struct sdap_attr_map *group_map;
-
- /* supported schema types */
- enum schema_type {
- SDAP_SCHEMA_RFC2307 = 1, /* memberUid = uid */
- SDAP_SCHEMA_RFC2307BIS = 2, /* member = dn */
- SDAP_SCHEMA_IPA_V1 = 3, /* member/memberof */
- SDAP_SCHEMA_AD = 4 /* AD's member/memberof */
- } schema_type;
-
- struct ldb_dn *users_base;
- struct ldb_dn *groups_base;
-};
-
-int sdap_get_map(TALLOC_CTX *memctx,
- struct confdb_ctx *cdb,
- const char *conf_path,
- struct sdap_attr_map *def_map,
- int num_entries,
- struct sdap_attr_map **_map);
-
-int sdap_parse_entry(TALLOC_CTX *memctx,
- struct sdap_handle *sh, struct sdap_msg *sm,
- struct sdap_attr_map *map, int attrs_num,
- struct sysdb_attrs **_attrs, char **_dn);
-
-int sdap_parse_user(TALLOC_CTX *memctx, struct sdap_options *opts,
- struct sdap_handle *sh, struct sdap_msg *sm,
- struct sysdb_attrs **_attrs, char **_dn);
-
-int sdap_parse_group(TALLOC_CTX *memctx, struct sdap_options *opts,
- struct sdap_handle *sh, struct sdap_msg *sm,
- struct sysdb_attrs **_attrs, char **_dn);
-
-int sdap_get_msg_dn(TALLOC_CTX *memctx, struct sdap_handle *sh,
- struct sdap_msg *sm, char **_dn);
-
-errno_t setup_tls_config(struct dp_option *basic_opts);
-
-bool sdap_rootdse_sasl_mech_is_supported(struct sysdb_attrs *rootdse,
- const char *sasl_mech);
-
-int build_attrs_from_map(TALLOC_CTX *memctx,
- struct sdap_attr_map *map,
- size_t size, const char ***_attrs);
-#endif /* _SDAP_H_ */
diff --git a/server/providers/ldap/sdap_async.c b/server/providers/ldap/sdap_async.c
deleted file mode 100644
index 959c08a65..000000000
--- a/server/providers/ldap/sdap_async.c
+++ /dev/null
@@ -1,1018 +0,0 @@
-/*
- SSSD
-
- Async LDAP Helper routines
-
- Copyright (C) Simo Sorce <ssorce@redhat.com> - 2009
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <ctype.h>
-#include "util/util.h"
-#include "providers/ldap/sdap_async_private.h"
-
-#define REALM_SEPARATOR '@'
-#define REPLY_REALLOC_INCREMENT 10
-
-void make_realm_upper_case(const char *upn)
-{
- char *c;
-
- c = strchr(upn, REALM_SEPARATOR);
- if (c == NULL) {
- DEBUG(9, ("No realm delimiter found in upn [%s].\n", upn));
- return;
- }
-
- while(*(++c) != '\0') {
- c[0] = toupper(*c);
- }
-
- return;
-}
-
-/* ==LDAP-Memory-Handling================================================= */
-
-static int lmsg_destructor(void *mem)
-{
- ldap_msgfree((LDAPMessage *)mem);
- return 0;
-}
-
-static int sdap_msg_attach(TALLOC_CTX *memctx, LDAPMessage *msg)
-{
- void *h;
-
- if (!msg) return EINVAL;
-
- h = sss_mem_attach(memctx, msg, lmsg_destructor);
- if (!h) return ENOMEM;
-
- return EOK;
-}
-
-/* ==sdap-hanlde-utility-functions======================================== */
-
-static inline void sdap_handle_release(struct sdap_handle *sh);
-static int sdap_handle_destructor(void *mem);
-
-struct sdap_handle *sdap_handle_create(TALLOC_CTX *memctx)
-{
- struct sdap_handle *sh;
-
- sh = talloc_zero(memctx, struct sdap_handle);
- if (!sh) return NULL;
-
- talloc_set_destructor((TALLOC_CTX *)sh, sdap_handle_destructor);
-
- return sh;
-}
-
-static int sdap_handle_destructor(void *mem)
-{
- struct sdap_handle *sh = talloc_get_type(mem, struct sdap_handle);
-
- sdap_handle_release(sh);
-
- return 0;
-}
-
-static void sdap_handle_release(struct sdap_handle *sh)
-{
- DEBUG(8, ("Trace: sh[%p], connected[%d], ops[%p], ldap[%p]\n",
- sh, (int)sh->connected, sh->ops, sh->ldap));
-
- if (sh->connected) {
- struct sdap_op *op;
-
-#ifdef HAVE_LDAP_CONNCB
- /* remove all related fd events from the event loop */
- talloc_zfree(sh->conncb->lc_arg);
-#else
- talloc_zfree(sh->fde);
-#endif
-
- while (sh->ops) {
- op = sh->ops;
- op->callback(op, NULL, EIO, op->data);
- /* calling the callback may result in freeing the op */
- /* check if it is still the same or avoid freeing */
- if (op == sh->ops) talloc_free(op);
- }
-
- if (sh->ldap) {
- ldap_unbind_ext(sh->ldap, NULL, NULL);
- }
-#ifdef HAVE_LDAP_CONNCB
- talloc_zfree(sh->conncb);
-#endif
- sh->connected = false;
- sh->ldap = NULL;
- sh->ops = NULL;
- }
-}
-
-/* ==Parse-Results-And-Handle-Disconnections============================== */
-static void sdap_process_message(struct tevent_context *ev,
- struct sdap_handle *sh, LDAPMessage *msg);
-static void sdap_process_result(struct tevent_context *ev, void *pvt);
-static void sdap_process_next_reply(struct tevent_context *ev,
- struct tevent_timer *te,
- struct timeval tv, void *pvt);
-
-static void sdap_ldap_result(struct tevent_context *ev,
- struct tevent_fd *fde,
- uint16_t flags, void *pvt)
-{
- sdap_process_result(ev, pvt);
-}
-
-static void sdap_ldap_next_result(struct tevent_context *ev,
- struct tevent_timer *te,
- struct timeval tv, void *pvt)
-{
- sdap_process_result(ev, pvt);
-}
-
-static void sdap_process_result(struct tevent_context *ev, void *pvt)
-{
- struct sdap_handle *sh = talloc_get_type(pvt, struct sdap_handle);
- struct timeval no_timeout = {0, 0};
- struct tevent_timer *te;
- LDAPMessage *msg;
- int ret;
-
- DEBUG(8, ("Trace: sh[%p], connected[%d], ops[%p], ldap[%p]\n",
- sh, (int)sh->connected, sh->ops, sh->ldap));
-
- if (!sh->connected || !sh->ldap) {
- DEBUG(2, ("ERROR: LDAP connection is not connected!\n"));
- return;
- }
-
- ret = ldap_result(sh->ldap, LDAP_RES_ANY, 0, &no_timeout, &msg);
- if (ret == 0) {
- /* this almost always means we have reached the end of
- * the list of received messages */
- DEBUG(8, ("Trace: ldap_result found nothing!\n"));
- return;
- }
-
- if (ret == -1) {
- DEBUG(4, ("ldap_result gave -1, something bad happend!\n"));
- sdap_handle_release(sh);
- return;
- }
-
- /* We don't know if this will be the last result.
- *
- * important: we must do this before actually processing the message
- * because the message processing might even free the sdap_handler
- * so it must be the last operation.
- * FIXME: use tevent_immediate/tevent_queues, when avilable */
- memset(&no_timeout, 0, sizeof(struct timeval));
-
- te = tevent_add_timer(ev, sh, no_timeout, sdap_ldap_next_result, sh);
- if (!te) {
- DEBUG(1, ("Failed to add critical timer to fetch next result!\n"));
- }
-
- /* now process this message */
- sdap_process_message(ev, sh, msg);
-}
-
-/* process a messgae calling the right operation callback.
- * msg is completely taken care of (including freeeing it)
- * NOTE: this function may even end up freeing the sdap_handle
- * so sdap_hanbdle must not be used after this function is called
- */
-static void sdap_process_message(struct tevent_context *ev,
- struct sdap_handle *sh, LDAPMessage *msg)
-{
- struct sdap_msg *reply;
- struct sdap_op *op;
- int msgid;
- int msgtype;
- int ret;
-
- msgid = ldap_msgid(msg);
- if (msgid == -1) {
- DEBUG(2, ("can't fire callback, message id invalid!\n"));
- ldap_msgfree(msg);
- return;
- }
-
- msgtype = ldap_msgtype(msg);
-
- for (op = sh->ops; op; op = op->next) {
- if (op->msgid == msgid) break;
- }
-
- if (op == NULL) {
- DEBUG(2, ("Unmatched msgid, discarding message (type: %0x)\n",
- msgtype));
- ldap_msgfree(msg);
- return;
- }
-
- /* shouldn't happen */
- if (op->done) {
- DEBUG(2, ("Operation [%p] already handled (type: %0x)\n", op, msgtype));
- ldap_msgfree(msg);
- return;
- }
-
- switch (msgtype) {
- case LDAP_RES_SEARCH_ENTRY:
- /* go and process entry */
- break;
-
- case LDAP_RES_SEARCH_REFERENCE:
- /* more ops to come with this msgid */
- /* just ignore */
- ldap_msgfree(msg);
- return;
-
- case LDAP_RES_BIND:
- case LDAP_RES_SEARCH_RESULT:
- case LDAP_RES_MODIFY:
- case LDAP_RES_ADD:
- case LDAP_RES_DELETE:
- case LDAP_RES_MODDN:
- case LDAP_RES_COMPARE:
- case LDAP_RES_EXTENDED:
- case LDAP_RES_INTERMEDIATE:
- /* no more results expected with this msgid */
- op->done = true;
- break;
-
- default:
- /* unkwon msg type ?? */
- DEBUG(1, ("Couldn't figure out the msg type! [%0x]\n", msgtype));
- ldap_msgfree(msg);
- return;
- }
-
- reply = talloc_zero(op, struct sdap_msg);
- if (!reply) {
- ldap_msgfree(msg);
- ret = ENOMEM;
- } else {
- reply->msg = msg;
- ret = sdap_msg_attach(reply, msg);
- if (ret != EOK) {
- ldap_msgfree(msg);
- talloc_zfree(reply);
- }
- }
-
- if (op->list) {
- /* list exist, queue it */
-
- op->last->next = reply;
- op->last = reply;
-
- } else {
- /* create list, then call callback */
- op->list = op->last = reply;
-
- /* must be the last operation as it may end up freeing all memory
- * including all ops handlers */
- op->callback(op, reply, ret, op->data);
- }
-}
-
-static void sdap_unlock_next_reply(struct sdap_op *op)
-{
- struct timeval tv;
- struct tevent_timer *te;
- struct sdap_msg *next_reply;
-
- if (op->list) {
- next_reply = op->list->next;
- /* get rid of the previous reply, it has been processed already */
- talloc_zfree(op->list);
- op->list = next_reply;
- }
-
- /* if there are still replies to parse, queue a new operation */
- if (op->list) {
- /* use a very small timeout, so that fd operations have a chance to be
- * served while processing a long reply */
- tv = tevent_timeval_current();
-
- /* wait 5 microsecond */
- tv.tv_usec += 5;
- tv.tv_sec += tv.tv_usec / 1000000;
- tv.tv_usec = tv.tv_usec % 1000000;
-
- te = tevent_add_timer(op->ev, op, tv,
- sdap_process_next_reply, op);
- if (!te) {
- DEBUG(1, ("Failed to add critical timer for next reply!\n"));
- op->callback(op, NULL, EFAULT, op->data);
- }
- }
-}
-
-static void sdap_process_next_reply(struct tevent_context *ev,
- struct tevent_timer *te,
- struct timeval tv, void *pvt)
-{
- struct sdap_op *op = talloc_get_type(pvt, struct sdap_op);
-
- op->callback(op, op->list, EOK, op->data);
-}
-
-#ifdef HAVE_LDAP_CONNCB
-int sdap_ldap_connect_callback_add(LDAP *ld, Sockbuf *sb, LDAPURLDesc *srv,
- struct sockaddr *addr, struct ldap_conncb *ctx)
-{
- int ret;
- ber_socket_t ber_fd;
- struct fd_event_item *fd_event_item;
- struct ldap_cb_data *cb_data = talloc_get_type(ctx->lc_arg,
- struct ldap_cb_data);
-
- ret = ber_sockbuf_ctrl(sb, LBER_SB_OPT_GET_FD, &ber_fd);
- if (ret == -1) {
- DEBUG(1, ("ber_sockbuf_ctrl failed.\n"));
- return EINVAL;
- }
- DEBUG(9, ("New LDAP connection to [%s] with fd [%d].\n",
- ldap_url_desc2str(srv), ber_fd));
-
- fd_event_item = talloc_zero(cb_data, struct fd_event_item);
- if (fd_event_item == NULL) {
- DEBUG(1, ("talloc failed.\n"));
- return ENOMEM;
- }
-
- fd_event_item->fde = tevent_add_fd(cb_data->ev, fd_event_item, ber_fd,
- TEVENT_FD_READ, sdap_ldap_result,
- cb_data->sh);
- if (fd_event_item->fde == NULL) {
- DEBUG(1, ("tevent_add_fd failed.\n"));
- talloc_free(fd_event_item);
- return ENOMEM;
- }
- fd_event_item->fd = ber_fd;
-
- DLIST_ADD(cb_data->fd_list, fd_event_item);
-
- return LDAP_SUCCESS;
-}
-
-void sdap_ldap_connect_callback_del(LDAP *ld, Sockbuf *sb,
- struct ldap_conncb *ctx)
-{
- int ret;
- ber_socket_t ber_fd;
- struct fd_event_item *fd_event_item;
- struct ldap_cb_data *cb_data = talloc_get_type(ctx->lc_arg,
- struct ldap_cb_data);
-
- if (sb == NULL || cb_data == NULL) {
- return;
- }
-
- ret = ber_sockbuf_ctrl(sb, LBER_SB_OPT_GET_FD, &ber_fd);
- if (ret == -1) {
- DEBUG(1, ("ber_sockbuf_ctrl failed.\n"));
- return;
- }
- DEBUG(9, ("Closing LDAP connection with fd [%d].\n", ber_fd));
-
- DLIST_FOR_EACH(fd_event_item, cb_data->fd_list) {
- if (fd_event_item->fd == ber_fd) {
- break;
- }
- }
- if (fd_event_item == NULL) {
- DEBUG(1, ("No event for fd [%d] found.\n", ber_fd));
- return;
- }
-
- DLIST_REMOVE(cb_data->fd_list, fd_event_item);
- talloc_zfree(fd_event_item);
-
- return;
-}
-
-#else
-
-static int get_fd_from_ldap(LDAP *ldap, int *fd)
-{
- int ret;
-
- ret = ldap_get_option(ldap, LDAP_OPT_DESC, fd);
- if (ret != LDAP_OPT_SUCCESS) {
- DEBUG(1, ("Failed to get fd from ldap!!\n"));
- *fd = -1;
- return EIO;
- }
-
- return EOK;
-}
-
-int sdap_install_ldap_callbacks(struct sdap_handle *sh,
- struct tevent_context *ev)
-{
- int fd;
- int ret;
-
- ret = get_fd_from_ldap(sh->ldap, &fd);
- if (ret) return ret;
-
- sh->fde = tevent_add_fd(ev, sh, fd, TEVENT_FD_READ, sdap_ldap_result, sh);
- if (!sh->fde) return ENOMEM;
-
- DEBUG(8, ("Trace: sh[%p], connected[%d], ops[%p], fde[%p], ldap[%p]\n",
- sh, (int)sh->connected, sh->ops, sh->fde, sh->ldap));
-
- return EOK;
-}
-
-#endif
-
-
-/* ==LDAP-Operations-Helpers============================================== */
-
-static int sdap_op_destructor(void *mem)
-{
- struct sdap_op *op = (struct sdap_op *)mem;
-
- DLIST_REMOVE(op->sh->ops, op);
-
- if (op->done) return 0;
-
- /* we don't check the result here, if a message was really abandoned,
- * hopefully the server will get an abandon.
- * If the operation was already fully completed, this is going to be
- * just a noop */
- ldap_abandon_ext(op->sh->ldap, op->msgid, NULL, NULL);
-
- return 0;
-}
-
-static void sdap_op_timeout(struct tevent_req *req)
-{
- struct sdap_op *op = tevent_req_callback_data(req, struct sdap_op);
-
- /* should never happen, but just in case */
- if (op->done) {
- DEBUG(2, ("Timeout happened after op was finished !?\n"));
- return;
- }
-
- /* signal the caller that we have a timeout */
- op->callback(op, NULL, ETIMEDOUT, op->data);
-}
-
-int sdap_op_add(TALLOC_CTX *memctx, struct tevent_context *ev,
- struct sdap_handle *sh, int msgid,
- sdap_op_callback_t *callback, void *data,
- int timeout, struct sdap_op **_op)
-{
- struct sdap_op *op;
-
- op = talloc_zero(memctx, struct sdap_op);
- if (!op) return ENOMEM;
-
- op->sh = sh;
- op->msgid = msgid;
- op->callback = callback;
- op->data = data;
- op->ev = ev;
-
- /* check if we need to set a timeout */
- if (timeout) {
- struct tevent_req *req;
- struct timeval tv;
-
- tv = tevent_timeval_current();
- tv = tevent_timeval_add(&tv, timeout, 0);
-
- /* allocate on op, so when it get freed the timeout is removed */
- req = tevent_wakeup_send(op, ev, tv);
- if (!req) {
- talloc_zfree(op);
- return ENOMEM;
- }
- tevent_req_set_callback(req, sdap_op_timeout, op);
- }
-
- DLIST_ADD(sh->ops, op);
-
- talloc_set_destructor((TALLOC_CTX *)op, sdap_op_destructor);
-
- *_op = op;
- return EOK;
-}
-
-/* ==Modify-Password====================================================== */
-
-struct sdap_exop_modify_passwd_state {
- struct sdap_handle *sh;
-
- struct sdap_op *op;
-
- int result;
- char *user_error_message;
-};
-
-static void sdap_exop_modify_passwd_done(struct sdap_op *op,
- struct sdap_msg *reply,
- int error, void *pvt);
-
-struct tevent_req *sdap_exop_modify_passwd_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_handle *sh,
- char *user_dn,
- char *password,
- char *new_password)
-{
- struct tevent_req *req = NULL;
- struct sdap_exop_modify_passwd_state *state;
- int ret;
- BerElement *ber = NULL;
- struct berval *bv = NULL;
- int msgid;
- LDAPControl *request_controls[2];
-
- req = tevent_req_create(memctx, &state,
- struct sdap_exop_modify_passwd_state);
- if (!req) return NULL;
-
- state->sh = sh;
- state->user_error_message = NULL;
-
- ber = ber_alloc_t( LBER_USE_DER );
- if (ber == NULL) {
- DEBUG(7, ("ber_alloc_t failed.\n"));
- talloc_zfree(req);
- return NULL;
- }
-
- ret = ber_printf( ber, "{tststs}", LDAP_TAG_EXOP_MODIFY_PASSWD_ID,
- user_dn,
- LDAP_TAG_EXOP_MODIFY_PASSWD_OLD, password,
- LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, new_password);
- if (ret == -1) {
- DEBUG(1, ("ber_printf failed.\n"));
- ber_free(ber, 1);
- talloc_zfree(req);
- return NULL;
- }
-
- ret = ber_flatten(ber, &bv);
- ber_free(ber, 1);
- if (ret == -1) {
- DEBUG(1, ("ber_flatten failed.\n"));
- talloc_zfree(req);
- return NULL;
- }
-
- ret = sss_ldap_control_create(LDAP_CONTROL_PASSWORDPOLICYREQUEST,
- 0, NULL, 0, &request_controls[0]);
- if (ret != LDAP_SUCCESS) {
- DEBUG(1, ("sss_ldap_control_create failed.\n"));
- goto fail;
- }
- request_controls[1] = NULL;
-
- DEBUG(4, ("Executing extended operation\n"));
-
- ret = ldap_extended_operation(state->sh->ldap, LDAP_EXOP_MODIFY_PASSWD,
- bv, request_controls, NULL, &msgid);
- ber_bvfree(bv);
- ldap_control_free(request_controls[0]);
- if (ret == -1 || msgid == -1) {
- DEBUG(1, ("ldap_extended_operation failed\n"));
- goto fail;
- }
- DEBUG(8, ("ldap_extended_operation sent, msgid = %d\n", msgid));
-
- /* FIXME: get timeouts from configuration, for now 5 secs. */
- ret = sdap_op_add(state, ev, state->sh, msgid,
- sdap_exop_modify_passwd_done, req, 5, &state->op);
- if (ret) {
- DEBUG(1, ("Failed to set up operation!\n"));
- goto fail;
- }
-
- return req;
-
-fail:
- tevent_req_error(req, EIO);
- tevent_req_post(req, ev);
- return req;
-}
-
-static void sdap_exop_modify_passwd_done(struct sdap_op *op,
- struct sdap_msg *reply,
- int error, void *pvt)
-{
- struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
- struct sdap_exop_modify_passwd_state *state = tevent_req_data(req,
- struct sdap_exop_modify_passwd_state);
- char *errmsg = NULL;
- int ret;
- LDAPControl **response_controls = NULL;
- int c;
- ber_int_t pp_grace;
- ber_int_t pp_expire;
- LDAPPasswordPolicyError pp_error;
-
- if (error) {
- tevent_req_error(req, error);
- return;
- }
-
- ret = ldap_parse_result(state->sh->ldap, reply->msg,
- &state->result, NULL, &errmsg, NULL,
- &response_controls, 0);
- if (ret != LDAP_SUCCESS) {
- DEBUG(2, ("ldap_parse_result failed (%d)\n", state->op->msgid));
- ret = EIO;
- goto done;
- }
-
- if (response_controls == NULL) {
- DEBUG(5, ("Server returned no controls.\n"));
- } else {
- for (c = 0; response_controls[c] != NULL; c++) {
- DEBUG(9, ("Server returned control [%s].\n",
- response_controls[c]->ldctl_oid));
- if (strcmp(response_controls[c]->ldctl_oid,
- LDAP_CONTROL_PASSWORDPOLICYRESPONSE) == 0) {
- ret = ldap_parse_passwordpolicy_control(state->sh->ldap,
- response_controls[c],
- &pp_expire, &pp_grace,
- &pp_error);
- if (ret != LDAP_SUCCESS) {
- DEBUG(1, ("ldap_parse_passwordpolicy_control failed.\n"));
- ret = EIO;
- goto done;
- }
-
- DEBUG(7, ("Password Policy Response: expire [%d] grace [%d] "
- "error [%s].\n", pp_expire, pp_grace,
- ldap_passwordpolicy_err2txt(pp_error)));
- }
- }
- }
-
- if (state->result != LDAP_SUCCESS) {
- state->user_error_message = talloc_strdup(state, errmsg);
- if (state->user_error_message == NULL) {
- DEBUG(1, ("talloc_strdup failed.\n"));
- }
- }
-
- DEBUG(3, ("ldap_extended_operation result: %s(%d), %s\n",
- ldap_err2string(state->result), state->result, errmsg));
-
- ret = LDAP_SUCCESS;
-done:
- ldap_controls_free(response_controls);
- ldap_memfree(errmsg);
-
- if (ret == LDAP_SUCCESS) {
- tevent_req_done(req);
- } else {
- tevent_req_error(req, ret);
- }
-}
-
-int sdap_exop_modify_passwd_recv(struct tevent_req *req,
- TALLOC_CTX * mem_ctx,
- enum sdap_result *result,
- char **user_error_message)
-{
- struct sdap_exop_modify_passwd_state *state = tevent_req_data(req,
- struct sdap_exop_modify_passwd_state);
-
- *result = SDAP_ERROR;
- *user_error_message = talloc_steal(mem_ctx, state->user_error_message);
-
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- if (state->result == LDAP_SUCCESS) {
- *result = SDAP_SUCCESS;
- }
-
- return EOK;
-}
-
-/* ==Fetch-RootDSE============================================= */
-
-struct sdap_get_rootdse_state {
- struct tevent_context *ev;
- struct sdap_options *opts;
- struct sdap_handle *sh;
-
- struct sysdb_attrs *rootdse;
-};
-
-static void sdap_get_rootdse_done(struct tevent_req *subreq);
-
-struct tevent_req *sdap_get_rootdse_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_options *opts,
- struct sdap_handle *sh)
-{
- struct tevent_req *req, *subreq;
- struct sdap_get_rootdse_state *state;
-
- DEBUG(9, ("Getting rootdse\n"));
-
- req = tevent_req_create(memctx, &state, struct sdap_get_rootdse_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->opts = opts;
- state->sh = sh;
- state->rootdse = NULL;
-
- subreq = sdap_get_generic_send(state, ev, opts, sh,
- "", LDAP_SCOPE_BASE,
- "(objectclass=*)", NULL, NULL, 0);
- if (!subreq) {
- talloc_zfree(req);
- return NULL;
- }
- tevent_req_set_callback(subreq, sdap_get_rootdse_done, req);
-
- return req;
-}
-
-static void sdap_get_rootdse_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct sdap_get_rootdse_state *state = tevent_req_data(req,
- struct sdap_get_rootdse_state);
- struct sysdb_attrs **results;
- size_t num_results;
- int ret;
-
- ret = sdap_get_generic_recv(subreq, state, &num_results, &results);
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- if (num_results == 0 || !results) {
- DEBUG(2, ("No RootDSE for server ?!\n"));
- tevent_req_error(req, ENOENT);
- return;
- }
-
- if (num_results > 1) {
- DEBUG(2, ("Multiple replies when searching for RootDSE ??\n"));
- tevent_req_error(req, EIO);
- return;
- }
-
- state->rootdse = talloc_steal(state, results[0]);
- talloc_zfree(results);
-
- DEBUG(9, ("Got rootdse\n"));
-
- tevent_req_done(req);
-}
-
-int sdap_get_rootdse_recv(struct tevent_req *req,
- TALLOC_CTX *memctx,
- struct sysdb_attrs **rootdse)
-{
- struct sdap_get_rootdse_state *state = tevent_req_data(req,
- struct sdap_get_rootdse_state);
-
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- *rootdse = talloc_steal(memctx, state->rootdse);
-
- return EOK;
-}
-
-/* ==Generic Search============================================ */
-
-struct sdap_get_generic_state {
- struct tevent_context *ev;
- struct sdap_options *opts;
- struct sdap_handle *sh;
- const char *search_base;
- int scope;
- const char *filter;
- const char **attrs;
- struct sdap_attr_map *map;
- int map_num_attrs;
-
- struct sdap_op *op;
-
- size_t reply_max;
- size_t reply_count;
- struct sysdb_attrs **reply;
-};
-
-static errno_t add_to_reply(struct sdap_get_generic_state *state,
- struct sysdb_attrs *msg);
-
-static void sdap_get_generic_done(struct sdap_op *op,
- struct sdap_msg *reply,
- int error, void *pvt);
-
-struct tevent_req *sdap_get_generic_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_options *opts,
- struct sdap_handle *sh,
- const char *search_base,
- int scope,
- const char *filter,
- const char **attrs,
- struct sdap_attr_map *map,
- int map_num_attrs)
-{
- struct tevent_req *req = NULL;
- struct sdap_get_generic_state *state = NULL;
- int lret;
- int ret;
- int msgid;
-
- req = tevent_req_create(memctx, &state, struct sdap_get_generic_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->opts = opts;
- state->sh = sh;
- state->search_base = search_base;
- state->scope = scope;
- state->filter = filter;
- state->attrs = attrs;
- state->map = map;
- state->map_num_attrs = map_num_attrs;
- state->op = NULL;
- state->reply_max = 0;
- state->reply_count = 0;
- state->reply = NULL;
-
- DEBUG(6, ("calling ldap_search_ext with [%s][%s].\n", state->filter,
- state->search_base));
- if (debug_level >= 7) {
- int i;
-
- if (state->attrs) {
- for (i = 0; state->attrs[i]; i++) {
- DEBUG(7, ("Requesting attrs: [%s]\n", state->attrs[i]));
- }
- }
- }
-
- lret = ldap_search_ext(state->sh->ldap, state->search_base,
- state->scope, state->filter,
- discard_const(state->attrs),
- false, NULL, NULL, NULL, 0, &msgid);
- if (lret != LDAP_SUCCESS) {
- DEBUG(3, ("ldap_search_ext failed: %s\n", ldap_err2string(lret)));
- ret = EIO;
- goto fail;
- }
- DEBUG(8, ("ldap_search_ext called, msgid = %d\n", msgid));
-
- ret = sdap_op_add(state, state->ev, state->sh, msgid,
- sdap_get_generic_done, req,
- dp_opt_get_int(state->opts->basic,
- SDAP_SEARCH_TIMEOUT),
- &state->op);
- if (ret != EOK) {
- DEBUG(1, ("Failed to set up operation!\n"));
- goto fail;
- }
-
- return req;
-
-fail:
- tevent_req_error(req, ret);
- tevent_req_post(req, ev);
- return req;
-}
-
-
-static void sdap_get_generic_done(struct sdap_op *op,
- struct sdap_msg *reply,
- int error, void *pvt)
-{
- struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
- struct sdap_get_generic_state *state = tevent_req_data(req,
- struct sdap_get_generic_state);
- struct sysdb_attrs *attrs;
- char *errmsg;
- int result;
- int ret;
-
- if (error) {
- tevent_req_error(req, error);
- return;
- }
-
- switch (ldap_msgtype(reply->msg)) {
- case LDAP_RES_SEARCH_REFERENCE:
- /* ignore references for now */
- talloc_free(reply);
-
- /* unlock the operation so that we can proceed with the next result */
- sdap_unlock_next_reply(state->op);
- break;
-
- case LDAP_RES_SEARCH_ENTRY:
- ret = sdap_parse_entry(state, state->sh, reply,
- state->map, state->map_num_attrs,
- &attrs, NULL);
- if (ret != EOK) {
- DEBUG(1, ("sdap_parse_generic_entry failed.\n"));
- tevent_req_error(req, ENOMEM);
- return;
- }
-
- ret = add_to_reply(state, attrs);
- if (ret != EOK) {
- DEBUG(1, ("add_to_reply failed.\n"));
- tevent_req_error(req, ret);
- return;
- }
-
- sdap_unlock_next_reply(state->op);
- break;
-
- case LDAP_RES_SEARCH_RESULT:
- ret = ldap_parse_result(state->sh->ldap, reply->msg,
- &result, NULL, &errmsg, NULL, NULL, 0);
- if (ret != LDAP_SUCCESS) {
- DEBUG(2, ("ldap_parse_result failed (%d)\n", state->op->msgid));
- tevent_req_error(req, EIO);
- return;
- }
-
- DEBUG(6, ("Search result: %s(%d), %s\n",
- ldap_err2string(result), result, errmsg));
-
- tevent_req_done(req);
- return;
-
- default:
- /* what is going on here !? */
- tevent_req_error(req, EIO);
- return;
- }
-}
-
-static errno_t add_to_reply(struct sdap_get_generic_state *state,
- struct sysdb_attrs *msg)
-{
- if (state->reply == NULL || state->reply_max == state->reply_count) {
- state->reply_max += REPLY_REALLOC_INCREMENT;
- state->reply = talloc_realloc(state, state->reply,
- struct sysdb_attrs *,
- state->reply_max);
- if (state->reply == NULL) {
- DEBUG(1, ("talloc_realloc failed.\n"));
- return ENOMEM;
- }
- }
-
- state->reply[state->reply_count++] = talloc_steal(state->reply, msg);
-
- return EOK;
-}
-
-int sdap_get_generic_recv(struct tevent_req *req,
- TALLOC_CTX *mem_ctx,
- size_t *reply_count,
- struct sysdb_attrs ***reply)
-{
- struct sdap_get_generic_state *state = tevent_req_data(req,
- struct sdap_get_generic_state);
-
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- *reply_count = state->reply_count;
- *reply = talloc_steal(mem_ctx, state->reply);
-
- return EOK;
-}
-
diff --git a/server/providers/ldap/sdap_async.h b/server/providers/ldap/sdap_async.h
deleted file mode 100644
index 3c52d236b..000000000
--- a/server/providers/ldap/sdap_async.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- SSSD
-
- Async LDAP Helper routines
-
- Copyright (C) Simo Sorce <ssorce@redhat.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _SDAP_ASYNC_H_
-#define _SDAP_ASYNC_H_
-
-#include <talloc.h>
-#include <tevent.h>
-#include "providers/dp_backend.h"
-#include "providers/ldap/sdap.h"
-#include "providers/fail_over.h"
-
-struct tevent_req *sdap_connect_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_options *opts,
- const char *uri,
- bool use_start_tls);
-int sdap_connect_recv(struct tevent_req *req,
- TALLOC_CTX *memctx,
- struct sdap_handle **sh);
-
-struct tevent_req *sdap_get_users_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sss_domain_info *dom,
- struct sysdb_ctx *sysdb,
- struct sdap_options *opts,
- struct sdap_handle *sh,
- const char **attrs,
- const char *wildcard);
-int sdap_get_users_recv(struct tevent_req *req,
- TALLOC_CTX *mem_ctx, char **timestamp);
-
-struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sss_domain_info *dom,
- struct sysdb_ctx *sysdb,
- struct sdap_options *opts,
- struct sdap_handle *sh,
- const char **attrs,
- const char *wildcard);
-int sdap_get_groups_recv(struct tevent_req *req,
- TALLOC_CTX *mem_ctx, char **timestamp);
-
-struct tevent_req *sdap_kinit_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_handle *sh,
- int timeout,
- const char *keytab,
- const char *principal,
- const char *realm);
-int sdap_kinit_recv(struct tevent_req *req, enum sdap_result *result);
-
-struct tevent_req *sdap_auth_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_handle *sh,
- const char *sasl_mech,
- const char *sasl_user,
- const char *user_dn,
- const char *authtok_type,
- struct dp_opt_blob authtok);
-int sdap_auth_recv(struct tevent_req *req, enum sdap_result *result);
-
-struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sss_domain_info *dom,
- struct sysdb_ctx *sysdb,
- struct sdap_options *opts,
- struct sdap_handle *sh,
- const char *name,
- const char **grp_attrs);
-int sdap_get_initgr_recv(struct tevent_req *req);
-
-struct tevent_req *sdap_exop_modify_passwd_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_handle *sh,
- char *user_dn,
- char *password,
- char *new_password);
-int sdap_exop_modify_passwd_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
- enum sdap_result *result,
- char **user_error_msg);
-
-struct tevent_req *sdap_cli_connect_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_options *opts,
- struct be_ctx *be,
- struct sdap_service *service,
- struct sysdb_attrs **rootdse);
-int sdap_cli_connect_recv(struct tevent_req *req,
- TALLOC_CTX *memctx,
- struct sdap_handle **gsh,
- struct sysdb_attrs **rootdse);
-
-struct tevent_req *sdap_get_generic_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_options *opts,
- struct sdap_handle *sh,
- const char *search_base,
- int scope,
- const char *filter,
- const char **attrs,
- struct sdap_attr_map *map,
- int map_num_attrs);
-int sdap_get_generic_recv(struct tevent_req *req,
- TALLOC_CTX *mem_ctx, size_t *reply_count,
- struct sysdb_attrs ***reply_list);
-
-#endif /* _SDAP_ASYNC_H_ */
diff --git a/server/providers/ldap/sdap_async_accounts.c b/server/providers/ldap/sdap_async_accounts.c
deleted file mode 100644
index abebe2883..000000000
--- a/server/providers/ldap/sdap_async_accounts.c
+++ /dev/null
@@ -1,2065 +0,0 @@
-/*
- SSSD
-
- Async LDAP Helper routines
-
- Copyright (C) Simo Sorce <ssorce@redhat.com> - 2009
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "util/util.h"
-#include "db/sysdb.h"
-#include "providers/ldap/sdap_async_private.h"
-
-/* ==Save-User-Entry====================================================== */
-
-struct sdap_save_user_state {
- struct tevent_context *ev;
- struct sysdb_handle *handle;
- struct sdap_options *opts;
-
- struct sss_domain_info *dom;
-
- const char *name;
- struct sysdb_attrs *attrs;
- char *timestamp;
-};
-
-static void sdap_save_user_done(struct tevent_req *subreq);
-
- /* FIXME: support storing additional attributes */
-
-static struct tevent_req *sdap_save_user_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sysdb_handle *handle,
- struct sdap_options *opts,
- struct sss_domain_info *dom,
- struct sysdb_attrs *attrs,
- bool is_initgr)
-{
- struct tevent_req *req, *subreq;
- struct sdap_save_user_state *state;
- struct ldb_message_element *el;
- int ret;
- const char *pwd;
- const char *gecos;
- const char *homedir;
- const char *shell;
- long int l;
- uid_t uid;
- gid_t gid;
- struct sysdb_attrs *user_attrs;
- char *upn = NULL;
- int i;
- char *val = NULL;
- int cache_timeout;
-
- DEBUG(9, ("Save user\n"));
-
- req = tevent_req_create(memctx, &state, struct sdap_save_user_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->handle = handle;
- state->dom = dom;
- state->opts = opts;
- state->attrs = attrs;
- state->timestamp = NULL;
-
- ret = sysdb_attrs_get_el(state->attrs,
- opts->user_map[SDAP_AT_USER_NAME].sys_name, &el);
- if (ret) goto fail;
- if (el->num_values == 0) {
- ret = EINVAL;
- goto fail;
- }
- state->name = (const char *)el->values[0].data;
-
- ret = sysdb_attrs_get_el(state->attrs,
- opts->user_map[SDAP_AT_USER_PWD].sys_name, &el);
- if (ret) goto fail;
- if (el->num_values == 0) pwd = NULL;
- else pwd = (const char *)el->values[0].data;
-
- ret = sysdb_attrs_get_el(state->attrs,
- opts->user_map[SDAP_AT_USER_GECOS].sys_name, &el);
- if (ret) goto fail;
- if (el->num_values == 0) gecos = NULL;
- else gecos = (const char *)el->values[0].data;
-
- ret = sysdb_attrs_get_el(state->attrs,
- opts->user_map[SDAP_AT_USER_HOME].sys_name, &el);
- if (ret) goto fail;
- if (el->num_values == 0) homedir = NULL;
- else homedir = (const char *)el->values[0].data;
-
- ret = sysdb_attrs_get_el(state->attrs,
- opts->user_map[SDAP_AT_USER_SHELL].sys_name, &el);
- if (ret) goto fail;
- if (el->num_values == 0) shell = NULL;
- else shell = (const char *)el->values[0].data;
-
- ret = sysdb_attrs_get_el(state->attrs,
- opts->user_map[SDAP_AT_USER_UID].sys_name, &el);
- if (ret) goto fail;
- if (el->num_values == 0) {
- DEBUG(1, ("no uid provided for [%s] in domain [%s].\n",
- state->name, dom->name));
- ret = EINVAL;
- goto fail;
- }
- errno = 0;
- l = strtol((const char *)el->values[0].data, NULL, 0);
- if (errno) {
- ret = EINVAL;
- goto fail;
- }
- uid = l;
-
- /* check that the uid is valid for this domain */
- if (OUT_OF_ID_RANGE(uid, dom->id_min, dom->id_max)) {
- DEBUG(2, ("User [%s] filtered out! (id out of range)\n",
- state->name));
- ret = EINVAL;
- goto fail;
- }
-
- ret = sysdb_attrs_get_el(state->attrs,
- opts->user_map[SDAP_AT_USER_GID].sys_name, &el);
- if (ret) goto fail;
- if (el->num_values == 0) {
- DEBUG(1, ("no gid provided for [%s] in domain [%s].\n",
- state->name, dom->name));
- ret = EINVAL;
- goto fail;
- }
- errno = 0;
- l = strtol((const char *)el->values[0].data, NULL, 0);
- if (errno) {
- ret = EINVAL;
- goto fail;
- }
- gid = l;
-
- /* check that the gid is valid for this domain */
- if (OUT_OF_ID_RANGE(gid, dom->id_min, dom->id_max)) {
- DEBUG(2, ("User [%s] filtered out! (id out of range)\n",
- state->name));
- ret = EINVAL;
- goto fail;
- }
-
- user_attrs = sysdb_new_attrs(state);
- if (user_attrs == NULL) {
- ret = ENOMEM;
- goto fail;
- }
-
- ret = sysdb_attrs_get_el(state->attrs, SYSDB_ORIG_DN, &el);
- if (ret) {
- goto fail;
- }
- if (el->num_values == 0) {
- DEBUG(7, ("Original DN is not available for [%s].\n", state->name));
- } else {
- DEBUG(7, ("Adding original DN [%s] to attributes of [%s].\n",
- el->values[0].data, state->name));
- ret = sysdb_attrs_add_string(user_attrs, SYSDB_ORIG_DN,
- (const char *) el->values[0].data);
- if (ret) {
- goto fail;
- }
- }
-
- ret = sysdb_attrs_get_el(state->attrs, SYSDB_MEMBEROF, &el);
- if (ret) {
- goto fail;
- }
- if (el->num_values == 0) {
- DEBUG(7, ("Original memberOf is not available for [%s].\n",
- state->name));
- } else {
- DEBUG(7, ("Adding original memberOf attributes to [%s].\n",
- state->name));
- for (i = 0; i < el->num_values; i++) {
- ret = sysdb_attrs_add_string(user_attrs, SYSDB_ORIG_MEMBEROF,
- (const char *) el->values[i].data);
- if (ret) {
- goto fail;
- }
- }
- }
-
- ret = sysdb_attrs_get_el(state->attrs,
- opts->user_map[SDAP_AT_USER_MODSTAMP].sys_name, &el);
- if (ret) {
- goto fail;
- }
- if (el->num_values == 0) {
- DEBUG(7, ("Original mod-Timestamp is not available for [%s].\n",
- state->name));
- } else {
- ret = sysdb_attrs_add_string(user_attrs,
- opts->user_map[SDAP_AT_USER_MODSTAMP].sys_name,
- (const char*)el->values[0].data);
- if (ret) {
- goto fail;
- }
- state->timestamp = talloc_strdup(state,
- (const char*)el->values[0].data);
- if (!state->timestamp) {
- ret = ENOMEM;
- goto fail;
- }
- }
-
- ret = sysdb_attrs_get_el(state->attrs,
- opts->user_map[SDAP_AT_USER_PRINC].sys_name, &el);
- if (ret) {
- goto fail;
- }
- if (el->num_values == 0) {
- DEBUG(7, ("User principle is not available for [%s].\n", state->name));
- } else {
- upn = talloc_strdup(user_attrs, (const char*) el->values[0].data);
- if (!upn) {
- ret = ENOMEM;
- goto fail;
- }
- if (dp_opt_get_bool(opts->basic, SDAP_FORCE_UPPER_CASE_REALM)) {
- make_realm_upper_case(upn);
- }
- DEBUG(7, ("Adding user principle [%s] to attributes of [%s].\n",
- upn, state->name));
- ret = sysdb_attrs_add_string(user_attrs, SYSDB_UPN, upn);
- if (ret) {
- goto fail;
- }
- }
-
- for (i = SDAP_FIRST_EXTRA_USER_AT; i < SDAP_OPTS_USER; i++) {
- ret = sysdb_attrs_get_el(state->attrs, opts->user_map[i].sys_name, &el);
- if (ret) {
- goto fail;
- }
- if (el->num_values > 0) {
- DEBUG(9, ("Adding [%s]=[%s] to user attributes.\n",
- opts->user_map[i].sys_name,
- (const char*) el->values[0].data));
- val = talloc_strdup(user_attrs, (const char*) el->values[0].data);
- if (val == NULL) {
- ret = ENOMEM;
- goto fail;
- }
- ret = sysdb_attrs_add_string(user_attrs,
- opts->user_map[i].sys_name, val);
- if (ret) {
- goto fail;
- }
- }
- }
-
- cache_timeout = dp_opt_get_int(opts->basic, SDAP_ENTRY_CACHE_TIMEOUT);
-
- if (is_initgr) {
- ret = sysdb_attrs_add_time_t(user_attrs, SYSDB_INITGR_EXPIRE,
- (cache_timeout ?
- (time(NULL) + cache_timeout) : 0));
- if (ret) {
- goto fail;
- }
- }
-
- DEBUG(6, ("Storing info for user %s\n", state->name));
-
- subreq = sysdb_store_user_send(state, state->ev, state->handle,
- state->dom, state->name, pwd,
- uid, gid, gecos, homedir, shell,
- user_attrs, cache_timeout);
- if (!subreq) {
- ret = ENOMEM;
- goto fail;
- }
- tevent_req_set_callback(subreq, sdap_save_user_done, req);
-
- return req;
-
-fail:
- tevent_req_error(req, ret);
- tevent_req_post(req, ev);
- return req;
-}
-
-static void sdap_save_user_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct sdap_save_user_state *state = tevent_req_data(req,
- struct sdap_save_user_state);
- int ret;
-
- ret = sysdb_store_user_recv(subreq);
- talloc_zfree(subreq);
- if (ret) {
- DEBUG(2, ("Failed to save user %s\n", state->name));
- tevent_req_error(req, ret);
- return;
- }
-
- tevent_req_done(req);
-}
-
-static int sdap_save_user_recv(struct tevent_req *req,
- TALLOC_CTX *mem_ctx, char **timestamp)
-{
- struct sdap_save_user_state *state = tevent_req_data(req,
- struct sdap_save_user_state);
-
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- if (timestamp) {
- *timestamp = talloc_steal(mem_ctx, state->timestamp);
- }
-
- return EOK;
-}
-
-
-/* ==Generic-Function-to-save-multiple-users============================= */
-
-struct sdap_save_users_state {
- struct tevent_context *ev;
- struct sysdb_ctx *sysdb;
- struct sdap_options *opts;
- struct sss_domain_info *dom;
-
- struct sysdb_attrs **users;
- int count;
- int cur;
-
- struct sysdb_handle *handle;
-
- char *higher_timestamp;
-};
-
-static void sdap_save_users_trans(struct tevent_req *subreq);
-static void sdap_save_users_store(struct tevent_req *req);
-static void sdap_save_users_process(struct tevent_req *subreq);
-struct tevent_req *sdap_save_users_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sss_domain_info *dom,
- struct sysdb_ctx *sysdb,
- struct sdap_options *opts,
- struct sysdb_attrs **users,
- int num_users)
-{
- struct tevent_req *req, *subreq;
- struct sdap_save_users_state *state;
-
- req = tevent_req_create(memctx, &state, struct sdap_save_users_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->opts = opts;
- state->sysdb = sysdb;
- state->dom = dom;
- state->users = users;
- state->count = num_users;
- state->cur = 0;
- state->handle = NULL;
- state->higher_timestamp = NULL;
-
- subreq = sysdb_transaction_send(state, state->ev, state->sysdb);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- tevent_req_post(req, ev);
- return req;
- }
- tevent_req_set_callback(subreq, sdap_save_users_trans, req);
-
- return req;
-}
-
-static void sdap_save_users_trans(struct tevent_req *subreq)
-{
- struct tevent_req *req;
- struct sdap_save_users_state *state;
- int ret;
-
- req = tevent_req_callback_data(subreq, struct tevent_req);
- state = tevent_req_data(req, struct sdap_save_users_state);
-
- ret = sysdb_transaction_recv(subreq, state, &state->handle);
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- sdap_save_users_store(req);
-}
-
-static void sdap_save_users_store(struct tevent_req *req)
-{
- struct tevent_req *subreq;
- struct sdap_save_users_state *state;
-
- state = tevent_req_data(req, struct sdap_save_users_state);
-
- subreq = sdap_save_user_send(state, state->ev, state->handle,
- state->opts, state->dom,
- state->users[state->cur], false);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, sdap_save_users_process, req);
-}
-
-static void sdap_save_users_process(struct tevent_req *subreq)
-{
- struct tevent_req *req;
- struct sdap_save_users_state *state;
- char *timestamp = NULL;
- int ret;
-
- req = tevent_req_callback_data(subreq, struct tevent_req);
- state = tevent_req_data(req, struct sdap_save_users_state);
-
- ret = sdap_save_user_recv(subreq, state, &timestamp);
- talloc_zfree(subreq);
-
- /* Do not fail completely on errors.
- * Just report the failure to save and go on */
- if (ret) {
- DEBUG(2, ("Failed to store user %d. Ignoring.\n", state->cur));
- } else {
- DEBUG(9, ("User %d processed!\n", state->cur));
- }
-
- if (timestamp) {
- if (state->higher_timestamp) {
- if (strcmp(timestamp, state->higher_timestamp) > 0) {
- talloc_zfree(state->higher_timestamp);
- state->higher_timestamp = timestamp;
- } else {
- talloc_zfree(timestamp);
- }
- } else {
- state->higher_timestamp = timestamp;
- }
- }
-
- state->cur++;
- if (state->cur < state->count) {
- sdap_save_users_store(req);
- } else {
- subreq = sysdb_transaction_commit_send(state, state->ev,
- state->handle);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- /* sysdb_transaction_complete will call tevent_req_done(req) */
- tevent_req_set_callback(subreq, sysdb_transaction_complete, req);
- }
-}
-
-static int sdap_save_users_recv(struct tevent_req *req,
- TALLOC_CTX *mem_ctx, char **timestamp)
-{
- struct sdap_save_users_state *state = tevent_req_data(req,
- struct sdap_save_users_state);
-
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- if (timestamp) {
- *timestamp = talloc_steal(mem_ctx, state->higher_timestamp);
- }
-
- return EOK;
-}
-
-
-/* ==Search-Users-with-filter============================================= */
-
-struct sdap_get_users_state {
- struct tevent_context *ev;
- struct sdap_options *opts;
- struct sdap_handle *sh;
- struct sss_domain_info *dom;
- struct sysdb_ctx *sysdb;
- const char **attrs;
- const char *filter;
-
- char *higher_timestamp;
- struct sysdb_attrs **users;
- size_t count;
-};
-
-static void sdap_get_users_process(struct tevent_req *subreq);
-static void sdap_get_users_done(struct tevent_req *subreq);
-
-struct tevent_req *sdap_get_users_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sss_domain_info *dom,
- struct sysdb_ctx *sysdb,
- struct sdap_options *opts,
- struct sdap_handle *sh,
- const char **attrs,
- const char *filter)
-{
- struct tevent_req *req, *subreq;
- struct sdap_get_users_state *state;
-
- req = tevent_req_create(memctx, &state, struct sdap_get_users_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->opts = opts;
- state->dom = dom;
- state->sh = sh;
- state->sysdb = sysdb;
- state->filter = filter;
- state->attrs = attrs;
- state->higher_timestamp = NULL;
- state->users = NULL;
- state->count = 0;
-
- subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh,
- dp_opt_get_string(state->opts->basic,
- SDAP_USER_SEARCH_BASE),
- LDAP_SCOPE_SUBTREE,
- state->filter, state->attrs,
- state->opts->user_map, SDAP_OPTS_USER);
- if (!subreq) {
- talloc_zfree(req);
- return NULL;
- }
- tevent_req_set_callback(subreq, sdap_get_users_process, req);
-
- return req;
-}
-
-static void sdap_get_users_process(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct sdap_get_users_state *state = tevent_req_data(req,
- struct sdap_get_users_state);
- int ret;
-
- ret = sdap_get_generic_recv(subreq, state,
- &state->count, &state->users);
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- DEBUG(6, ("Search for users, returned %d results.\n", state->count));
-
- if (state->count == 0) {
- tevent_req_error(req, ENOENT);
- return;
- }
-
- subreq = sdap_save_users_send(state, state->ev, state->dom,
- state->sysdb, state->opts,
- state->users, state->count);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, sdap_get_users_done, req);
-}
-
-static void sdap_get_users_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct sdap_get_users_state *state = tevent_req_data(req,
- struct sdap_get_users_state);
- int ret;
-
- DEBUG(9, ("Saving %d Users - Done\n", state->count));
-
- ret = sdap_save_users_recv(subreq, state, &state->higher_timestamp);
- talloc_zfree(subreq);
- if (ret) {
- DEBUG(2, ("Failed to store users.\n"));
- tevent_req_error(req, ret);
- return;
- }
-
- tevent_req_done(req);
-}
-
-int sdap_get_users_recv(struct tevent_req *req,
- TALLOC_CTX *mem_ctx, char **timestamp)
-{
- struct sdap_get_users_state *state = tevent_req_data(req,
- struct sdap_get_users_state);
-
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- if (timestamp) {
- *timestamp = talloc_steal(mem_ctx, state->higher_timestamp);
- }
-
- return EOK;
-}
-
-/* ==Group-Parsing Routines=============================================== */
-
-struct sdap_orig_entry_state {
- int done;
-};
-
-static void sdap_find_entry_by_origDN_done(struct tevent_req *req)
-{
- struct sdap_orig_entry_state *state = tevent_req_callback_data(req,
- struct sdap_orig_entry_state);
- state->done = 1;
-}
-
-/* WARNING: this is a sync routine for now */
-static int sdap_find_entry_by_origDN(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sysdb_handle *handle,
- struct sss_domain_info *domain,
- const char *orig_dn,
- char **localdn)
-{
- struct tevent_req *req;
- struct sdap_orig_entry_state *state;
- static const char *attrs[] = { NULL };
- struct ldb_dn *base_dn;
- char *filter;
- struct ldb_message **msgs;
- size_t num_msgs;
- int ret;
-
- state = talloc_zero(memctx, struct sdap_orig_entry_state);
- if (!state) {
- ret = ENOMEM;
- goto done;
- }
-
- filter = talloc_asprintf(state, "%s=%s", SYSDB_ORIG_DN, orig_dn);
- if (!filter) {
- ret = ENOMEM;
- goto done;
- }
-
- base_dn = sysdb_domain_dn(sysdb_handle_get_ctx(handle),
- state, domain->name);
- if (!base_dn) {
- ret = ENOMEM;
- goto done;
- }
-
- req = sysdb_search_entry_send(state, ev, handle, base_dn,
- LDB_SCOPE_SUBTREE, filter, attrs);
- if (!req) {
- ret = ENOMEM;
- goto done;
- }
- tevent_req_set_callback(req, sdap_find_entry_by_origDN_done, state);
-
- /* WARNING: SYNC LOOP HERE */
- tevent_loop_allow_nesting(ev);
- while (state->done == 0) {
- tevent_loop_once(ev);
- }
-
- ret = sysdb_search_entry_recv(req, state, &num_msgs, &msgs);
- if (ret) {
- goto done;
- }
- if (num_msgs != 1) {
- ret = ENOENT;
- goto done;
- }
-
- *localdn = talloc_strdup(memctx, ldb_dn_get_linearized(msgs[0]->dn));
- if (!*localdn) {
- ret = ENOENT;
- goto done;
- }
-
- ret = EOK;
-
-done:
- talloc_zfree(state);
- return ret;
-}
-
-static int sdap_fill_memberships(struct sysdb_attrs *group_attrs,
- struct tevent_context *ev,
- struct sysdb_handle *handle,
- struct sdap_options *opts,
- struct sss_domain_info *domain,
- struct ldb_val *values,
- int num_values)
-{
- struct ldb_message_element *el;
- int i, j;
- int ret;
-
- switch (opts->schema_type) {
- case SDAP_SCHEMA_RFC2307:
- DEBUG(9, ("[RFC2307 Schema]\n"));
-
- ret = sysdb_attrs_users_from_ldb_vals(group_attrs, SYSDB_MEMBER,
- domain->name,
- values, num_values);
- if (ret) {
- goto done;
- }
-
- break;
-
- case SDAP_SCHEMA_RFC2307BIS:
- case SDAP_SCHEMA_IPA_V1:
- case SDAP_SCHEMA_AD:
- DEBUG(9, ("[IPA or AD Schema]\n"));
-
- ret = sysdb_attrs_get_el(group_attrs, SYSDB_MEMBER, &el);
- if (ret) {
- goto done;
- }
-
- /* Just allocate both big enough to contain all members for now */
- el->values = talloc_realloc(el, el->values, struct ldb_val,
- el->num_values + num_values);
- if (!el->values) {
- ret = ENOMEM;
- goto done;
- }
-
- for (i = 0, j = el->num_values; i < num_values; i++) {
-
- /* sync search entry with this as origDN */
- ret = sdap_find_entry_by_origDN(el->values, ev,
- handle, domain,
- (char *)values[i].data,
- (char **)&el->values[j].data);
- if (ret != EOK) {
- if (ret != ENOENT) {
- goto done;
- }
-
- DEBUG(7, (" member #%d (%s): not found!\n",
- i, (char *)values[i].data));
- } else {
- DEBUG(7, (" member #%d (%s): [%s]\n",
- i, (char *)values[i].data,
- (char *)el->values[j].data));
-
- el->values[j].length = strlen((char *)el->values[j].data);
- j++;
- }
- }
- el->num_values = j;
-
- break;
-
- default:
- DEBUG(0, ("FATAL ERROR: Unhandled schema type! (%d)\n",
- opts->schema_type));
- ret = EFAULT;
- goto done;
- }
-
- ret = EOK;
-
-done:
- return ret;
-}
-
-/* ==Save-Group-Entry===================================================== */
-
-struct sdap_save_group_state {
- struct tevent_context *ev;
- struct sysdb_handle *handle;
- struct sdap_options *opts;
-
- struct sss_domain_info *dom;
-
- const char *name;
- char *timestamp;
-};
-
-static void sdap_save_group_done(struct tevent_req *subreq);
-
- /* FIXME: support non legacy */
- /* FIXME: support storing additional attributes */
-
-static struct tevent_req *sdap_save_group_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sysdb_handle *handle,
- struct sdap_options *opts,
- struct sss_domain_info *dom,
- struct sysdb_attrs *attrs,
- bool store_members)
-{
- struct tevent_req *req, *subreq;
- struct sdap_save_group_state *state;
- struct ldb_message_element *el;
- struct sysdb_attrs *group_attrs;
- long int l;
- gid_t gid;
- int ret;
-
- req = tevent_req_create(memctx, &state, struct sdap_save_group_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->handle = handle;
- state->dom = dom;
- state->opts = opts;
- state->timestamp = NULL;
-
- ret = sysdb_attrs_get_el(attrs,
- opts->group_map[SDAP_AT_GROUP_NAME].sys_name, &el);
- if (ret) goto fail;
- if (el->num_values == 0) {
- ret = EINVAL;
- goto fail;
- }
- state->name = (const char *)el->values[0].data;
-
- ret = sysdb_attrs_get_el(attrs,
- opts->group_map[SDAP_AT_GROUP_GID].sys_name, &el);
- if (ret) goto fail;
- if (el->num_values == 0) {
- DEBUG(1, ("no gid provided for [%s] in domain [%s].\n",
- state->name, dom->name));
- ret = EINVAL;
- goto fail;
- }
- errno = 0;
- l = strtol((const char *)el->values[0].data, NULL, 0);
- if (errno) {
- ret = EINVAL;
- goto fail;
- }
- gid = l;
-
- /* check that the gid is valid for this domain */
- if (OUT_OF_ID_RANGE(gid, dom->id_min, dom->id_max)) {
- DEBUG(2, ("Group [%s] filtered out! (id out of range)\n",
- state->name));
- ret = EINVAL;
- goto fail;
- }
-
- group_attrs = sysdb_new_attrs(state);
- if (!group_attrs) {
- ret = ENOMEM;
- goto fail;
- }
-
- ret = sysdb_attrs_get_el(attrs, SYSDB_ORIG_DN, &el);
- if (ret) {
- goto fail;
- }
- if (el->num_values == 0) {
- DEBUG(7, ("Original DN is not available for [%s].\n", state->name));
- } else {
- DEBUG(7, ("Adding original DN [%s] to attributes of [%s].\n",
- el->values[0].data, state->name));
- ret = sysdb_attrs_add_string(group_attrs, SYSDB_ORIG_DN,
- (const char *)el->values[0].data);
- if (ret) {
- goto fail;
- }
- }
-
- ret = sysdb_attrs_get_el(attrs,
- opts->group_map[SDAP_AT_GROUP_MODSTAMP].sys_name, &el);
- if (ret) {
- goto fail;
- }
- if (el->num_values == 0) {
- DEBUG(7, ("Original mod-Timestamp is not available for [%s].\n",
- state->name));
- } else {
- ret = sysdb_attrs_add_string(group_attrs,
- opts->group_map[SDAP_AT_GROUP_MODSTAMP].sys_name,
- (const char*)el->values[0].data);
- if (ret) {
- goto fail;
- }
- state->timestamp = talloc_strdup(state,
- (const char*)el->values[0].data);
- if (!state->timestamp) {
- ret = ENOMEM;
- goto fail;
- }
- }
-
- if (store_members) {
- ret = sysdb_attrs_get_el(attrs,
- opts->group_map[SDAP_AT_GROUP_MEMBER].sys_name, &el);
- if (ret != EOK) {
- goto fail;
- }
- if (el->num_values == 0) {
- DEBUG(7, ("No members for group [%s]\n", state->name));
-
- } else {
- DEBUG(7, ("Adding member users to group [%s]\n", state->name));
-
- ret = sdap_fill_memberships(group_attrs, ev, handle, opts, dom,
- el->values, el->num_values);
- if (ret) {
- goto fail;
- }
- }
- }
-
- DEBUG(6, ("Storing info for group %s\n", state->name));
-
- subreq = sysdb_store_group_send(state, state->ev,
- state->handle, state->dom,
- state->name, gid,
- group_attrs,
- dp_opt_get_int(opts->basic,
- SDAP_ENTRY_CACHE_TIMEOUT));
- if (!subreq) {
- ret = ENOMEM;
- goto fail;
- }
- tevent_req_set_callback(subreq, sdap_save_group_done, req);
-
- return req;
-
-fail:
- tevent_req_error(req, ret);
- tevent_req_post(req, ev);
- return req;
-}
-
-static void sdap_save_group_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct sdap_save_group_state *state = tevent_req_data(req,
- struct sdap_save_group_state);
- int ret;
-
- ret = sysdb_store_group_recv(subreq);
- talloc_zfree(subreq);
- if (ret) {
- DEBUG(2, ("Failed to save group %s [%d]\n", state->name, ret));
- tevent_req_error(req, ret);
- return;
- }
-
- tevent_req_done(req);
-}
-
-static int sdap_save_group_recv(struct tevent_req *req,
- TALLOC_CTX *mem_ctx, char **timestamp)
-{
- struct sdap_save_group_state *state = tevent_req_data(req,
- struct sdap_save_group_state);
-
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- if ( timestamp ) {
- *timestamp = talloc_steal(mem_ctx, state->timestamp);
- }
-
- return EOK;
-}
-
-
-/* ==Save-Group-Memebrs=================================================== */
-
-struct sdap_save_grpmem_state {
- struct tevent_context *ev;
- struct sysdb_handle *handle;
- struct sdap_options *opts;
-
- struct sss_domain_info *dom;
-
- const char *name;
-};
-
-static void sdap_save_grpmem_done(struct tevent_req *subreq);
-
- /* FIXME: support non legacy */
- /* FIXME: support storing additional attributes */
-
-static struct tevent_req *sdap_save_grpmem_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sysdb_handle *handle,
- struct sdap_options *opts,
- struct sss_domain_info *dom,
- struct sysdb_attrs *attrs)
-{
- struct tevent_req *req, *subreq;
- struct sdap_save_grpmem_state *state;
- struct ldb_message_element *el;
- struct sysdb_attrs *group_attrs = NULL;
- int ret;
-
- req = tevent_req_create(memctx, &state, struct sdap_save_grpmem_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->handle = handle;
- state->dom = dom;
- state->opts = opts;
-
- ret = sysdb_attrs_get_string(attrs,
- opts->group_map[SDAP_AT_GROUP_NAME].sys_name,
- &state->name);
- if (ret != EOK) {
- goto fail;
- }
-
- ret = sysdb_attrs_get_el(attrs,
- opts->group_map[SDAP_AT_GROUP_MEMBER].sys_name, &el);
- if (ret != EOK) {
- goto fail;
- }
- if (el->num_values == 0) {
- DEBUG(7, ("No members for group [%s]\n", state->name));
-
- } else {
- DEBUG(7, ("Adding member users to group [%s]\n", state->name));
-
- group_attrs = sysdb_new_attrs(state);
- if (!group_attrs) {
- ret = ENOMEM;
- goto fail;
- }
-
- ret = sdap_fill_memberships(group_attrs, ev, handle, opts, dom,
- el->values, el->num_values);
- if (ret) {
- goto fail;
- }
- }
-
- DEBUG(6, ("Storing members for group %s\n", state->name));
-
- subreq = sysdb_store_group_send(state, state->ev,
- state->handle, state->dom,
- state->name, 0,
- group_attrs,
- dp_opt_get_int(opts->basic,
- SDAP_ENTRY_CACHE_TIMEOUT));
- if (!subreq) {
- ret = ENOMEM;
- goto fail;
- }
- tevent_req_set_callback(subreq, sdap_save_grpmem_done, req);
-
- return req;
-
-fail:
- tevent_req_error(req, ret);
- tevent_req_post(req, ev);
- return req;
-}
-
-static void sdap_save_grpmem_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct sdap_save_grpmem_state *state = tevent_req_data(req,
- struct sdap_save_grpmem_state);
- int ret;
-
- ret = sysdb_store_group_recv(subreq);
- talloc_zfree(subreq);
- if (ret) {
- DEBUG(2, ("Failed to save group members for %s [%d]\n",
- state->name, ret));
- tevent_req_error(req, ret);
- return;
- }
-
- tevent_req_done(req);
-}
-
-static int sdap_save_grpmem_recv(struct tevent_req *req)
-{
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- return EOK;
-}
-
-
-/* ==Generic-Function-to-save-multiple-groups============================= */
-
-struct sdap_save_groups_state {
- struct tevent_context *ev;
- struct sysdb_ctx *sysdb;
- struct sdap_options *opts;
- struct sss_domain_info *dom;
-
- struct sysdb_attrs **groups;
- int count;
- int cur;
- bool twopass;
-
- struct sysdb_handle *handle;
-
- char *higher_timestamp;
-};
-
-static void sdap_save_groups_trans(struct tevent_req *subreq);
-static void sdap_save_groups_save(struct tevent_req *req);
-static void sdap_save_groups_loop(struct tevent_req *subreq);
-static void sdap_save_groups_mem_save(struct tevent_req *req);
-static void sdap_save_groups_mem_loop(struct tevent_req *subreq);
-struct tevent_req *sdap_save_groups_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sss_domain_info *dom,
- struct sysdb_ctx *sysdb,
- struct sdap_options *opts,
- struct sysdb_attrs **groups,
- int num_groups)
-{
- struct tevent_req *req, *subreq;
- struct sdap_save_groups_state *state;
-
- req = tevent_req_create(memctx, &state, struct sdap_save_groups_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->opts = opts;
- state->sysdb = sysdb;
- state->dom = dom;
- state->groups = groups;
- state->count = num_groups;
- state->cur = 0;
- state->handle = NULL;
- state->higher_timestamp = NULL;
-
- switch (opts->schema_type) {
- case SDAP_SCHEMA_RFC2307:
- state->twopass = false;
- break;
-
- case SDAP_SCHEMA_RFC2307BIS:
- case SDAP_SCHEMA_IPA_V1:
- case SDAP_SCHEMA_AD:
- state->twopass = true;
- break;
-
- default:
- tevent_req_error(req, EINVAL);
- tevent_req_post(req, ev);
- return req;
- }
-
- subreq = sysdb_transaction_send(state, state->ev, state->sysdb);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- tevent_req_post(req, ev);
- return req;
- }
- tevent_req_set_callback(subreq, sdap_save_groups_trans, req);
-
- return req;
-}
-
-static void sdap_save_groups_trans(struct tevent_req *subreq)
-{
- struct tevent_req *req;
- struct sdap_save_groups_state *state;
- int ret;
-
- req = tevent_req_callback_data(subreq, struct tevent_req);
- state = tevent_req_data(req, struct sdap_save_groups_state);
-
- ret = sysdb_transaction_recv(subreq, state, &state->handle);
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- sdap_save_groups_save(req);
-}
-
-static void sdap_save_groups_save(struct tevent_req *req)
-{
- struct tevent_req *subreq;
- struct sdap_save_groups_state *state;
-
- state = tevent_req_data(req, struct sdap_save_groups_state);
-
- /* if 2 pass savemembers = false */
- subreq = sdap_save_group_send(state, state->ev, state->handle,
- state->opts, state->dom,
- state->groups[state->cur],
- (!state->twopass));
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, sdap_save_groups_loop, req);
-}
-
-static void sdap_save_groups_loop(struct tevent_req *subreq)
-{
- struct tevent_req *req;
- struct sdap_save_groups_state *state;
- char *timestamp = NULL;
- int ret;
-
- req = tevent_req_callback_data(subreq, struct tevent_req);
- state = tevent_req_data(req, struct sdap_save_groups_state);
-
- ret = sdap_save_group_recv(subreq, state, &timestamp);
- talloc_zfree(subreq);
-
- /* Do not fail completely on errors.
- * Just report the failure to save and go on */
- if (ret) {
- DEBUG(2, ("Failed to store group %d. Ignoring.\n", state->cur));
- } else {
- DEBUG(9, ("Group %d processed!\n", state->cur));
- }
-
- if (timestamp) {
- if (state->higher_timestamp) {
- if (strcmp(timestamp, state->higher_timestamp) > 0) {
- talloc_zfree(state->higher_timestamp);
- state->higher_timestamp = timestamp;
- } else {
- talloc_zfree(timestamp);
- }
- } else {
- state->higher_timestamp = timestamp;
- }
- }
-
- state->cur++;
- if (state->cur < state->count) {
-
- sdap_save_groups_save(req);
-
- } else if (state->twopass) {
-
- state->cur = 0;
- sdap_save_groups_mem_save(req);
-
- } else {
-
- subreq = sysdb_transaction_commit_send(state, state->ev,
- state->handle);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- /* sysdb_transaction_complete will call tevent_req_done(req) */
- tevent_req_set_callback(subreq, sysdb_transaction_complete, req);
- }
-}
-
-static void sdap_save_groups_mem_save(struct tevent_req *req)
-{
- struct tevent_req *subreq;
- struct sdap_save_groups_state *state;
-
- state = tevent_req_data(req, struct sdap_save_groups_state);
-
- subreq = sdap_save_grpmem_send(state, state->ev, state->handle,
- state->opts, state->dom,
- state->groups[state->cur]);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, sdap_save_groups_mem_loop, req);
-}
-
-static void sdap_save_groups_mem_loop(struct tevent_req *subreq)
-{
- struct tevent_req *req;
- struct sdap_save_groups_state *state;
- int ret;
-
- req = tevent_req_callback_data(subreq, struct tevent_req);
- state = tevent_req_data(req, struct sdap_save_groups_state);
-
- ret = sdap_save_grpmem_recv(subreq);
- talloc_zfree(subreq);
-
- /* Do not fail completely on errors.
- * Just report the failure to save and go on */
- if (ret) {
- DEBUG(2, ("Failed to store group %d. Ignoring.\n", state->cur));
- }
-
- state->cur++;
- if (state->cur < state->count) {
-
- sdap_save_groups_mem_save(req);
-
- } else {
-
- subreq = sysdb_transaction_commit_send(state, state->ev,
- state->handle);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- /* sysdb_transaction_complete will call tevent_req_done(req) */
- tevent_req_set_callback(subreq, sysdb_transaction_complete, req);
- }
-}
-
-static int sdap_save_groups_recv(struct tevent_req *req,
- TALLOC_CTX *mem_ctx, char **timestamp)
-{
- struct sdap_save_groups_state *state = tevent_req_data(req,
- struct sdap_save_groups_state);
-
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- if (timestamp) {
- *timestamp = talloc_steal(mem_ctx, state->higher_timestamp);
- }
-
- return EOK;
-}
-
-
-/* ==Search-Groups-with-filter============================================ */
-
-struct sdap_get_groups_state {
- struct tevent_context *ev;
- struct sdap_options *opts;
- struct sdap_handle *sh;
- struct sss_domain_info *dom;
- struct sysdb_ctx *sysdb;
- const char **attrs;
- const char *filter;
-
- char *higher_timestamp;
- struct sysdb_attrs **groups;
- size_t count;
-};
-
-static void sdap_get_groups_process(struct tevent_req *subreq);
-static void sdap_get_groups_done(struct tevent_req *subreq);
-
-struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sss_domain_info *dom,
- struct sysdb_ctx *sysdb,
- struct sdap_options *opts,
- struct sdap_handle *sh,
- const char **attrs,
- const char *filter)
-{
- struct tevent_req *req, *subreq;
- struct sdap_get_groups_state *state;
-
- req = tevent_req_create(memctx, &state, struct sdap_get_groups_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->opts = opts;
- state->dom = dom;
- state->sh = sh;
- state->sysdb = sysdb;
- state->filter = filter;
- state->attrs = attrs;
- state->higher_timestamp = NULL;
- state->groups = NULL;
- state->count = 0;
-
- subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh,
- dp_opt_get_string(state->opts->basic,
- SDAP_GROUP_SEARCH_BASE),
- LDAP_SCOPE_SUBTREE,
- state->filter, state->attrs,
- state->opts->group_map, SDAP_OPTS_GROUP);
- if (!subreq) {
- talloc_zfree(req);
- return NULL;
- }
- tevent_req_set_callback(subreq, sdap_get_groups_process, req);
-
- return req;
-}
-
-static void sdap_get_groups_process(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct sdap_get_groups_state *state = tevent_req_data(req,
- struct sdap_get_groups_state);
- int ret;
-
- ret = sdap_get_generic_recv(subreq, state,
- &state->count, &state->groups);
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- DEBUG(6, ("Search for groups, returned %d results.\n", state->count));
-
- if (state->count == 0) {
- tevent_req_error(req, ENOENT);
- return;
- }
-
- subreq = sdap_save_groups_send(state, state->ev, state->dom,
- state->sysdb, state->opts,
- state->groups, state->count);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, sdap_get_groups_done, req);
-}
-
-static void sdap_get_groups_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct sdap_get_groups_state *state = tevent_req_data(req,
- struct sdap_get_groups_state);
- int ret;
-
- DEBUG(9, ("Saving %d Groups - Done\n", state->count));
-
- ret = sdap_save_groups_recv(subreq, state, &state->higher_timestamp);
- talloc_zfree(subreq);
- if (ret) {
- DEBUG(2, ("Failed to store groups.\n"));
- tevent_req_error(req, ret);
- return;
- }
-
- tevent_req_done(req);
-}
-
-int sdap_get_groups_recv(struct tevent_req *req,
- TALLOC_CTX *mem_ctx, char **timestamp)
-{
- struct sdap_get_groups_state *state = tevent_req_data(req,
- struct sdap_get_groups_state);
-
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- if (timestamp) {
- *timestamp = talloc_steal(mem_ctx, state->higher_timestamp);
- }
-
- return EOK;
-}
-
-
-/* ==Initgr-call-(groups-a-user-is-member-of)-RFC2307-Classic/BIS========= */
-
-struct sdap_initgr_rfc2307_state {
- struct tevent_context *ev;
- struct sysdb_ctx *sysdb;
- struct sdap_options *opts;
- struct sss_domain_info *dom;
- struct sdap_handle *sh;
-
- struct sdap_op *op;
-};
-
-static void sdap_initgr_rfc2307_process(struct tevent_req *subreq);
-static void sdap_initgr_rfc2307_done(struct tevent_req *subreq);
-struct tevent_req *sdap_initgr_rfc2307_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_options *opts,
- struct sysdb_ctx *sysdb,
- struct sss_domain_info *dom,
- struct sdap_handle *sh,
- const char *base_dn,
- const char *name,
- const char **grp_attrs)
-{
- struct tevent_req *req, *subreq;
- struct sdap_initgr_rfc2307_state *state;
- const char *filter;
-
- req = tevent_req_create(memctx, &state, struct sdap_initgr_rfc2307_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->opts = opts;
- state->sysdb = sysdb;
- state->dom = dom;
- state->sh = sh;
- state->op = NULL;
-
- filter = talloc_asprintf(state, "(&(%s=%s)(objectclass=%s))",
- opts->group_map[SDAP_AT_GROUP_MEMBER].name,
- name, opts->group_map[SDAP_OC_GROUP].name);
- if (!filter) {
- talloc_zfree(req);
- return NULL;
- }
-
- subreq = sdap_get_generic_send(state, state->ev, state->opts,
- state->sh, base_dn, LDAP_SCOPE_SUBTREE,
- filter, grp_attrs,
- state->opts->group_map, SDAP_OPTS_GROUP);
- if (!subreq) {
- talloc_zfree(req);
- return NULL;
- }
- tevent_req_set_callback(subreq, sdap_initgr_rfc2307_process, req);
-
- return req;
-}
-
-static void sdap_initgr_rfc2307_process(struct tevent_req *subreq)
-{
- struct tevent_req *req;
- struct sdap_initgr_rfc2307_state *state;
- struct sysdb_attrs **groups;
- size_t count;
- int ret;
-
- req = tevent_req_callback_data(subreq, struct tevent_req);
- state = tevent_req_data(req, struct sdap_initgr_rfc2307_state);
-
- ret = sdap_get_generic_recv(subreq, state, &count, &groups);
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- if (count == 0) {
- tevent_req_done(req);
- return;
- }
-
- subreq = sdap_save_groups_send(state, state->ev, state->dom,
- state->sysdb, state->opts,
- groups, count);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, sdap_initgr_rfc2307_done, req);
-}
-
-static void sdap_initgr_rfc2307_done(struct tevent_req *subreq)
-{
- struct tevent_req *req;
- int ret;
-
- req = tevent_req_callback_data(subreq, struct tevent_req);
-
- ret = sdap_save_groups_recv(subreq, NULL, NULL);
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- tevent_req_done(req);
-}
-
-static int sdap_initgr_rfc2307_recv(struct tevent_req *req)
-{
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- return EOK;
-}
-
-
-/* ==Initgr-call-(groups-a-user-is-member-of)-nested-groups=============== */
-
-struct sdap_initgr_nested_state {
- struct tevent_context *ev;
- struct sysdb_ctx *sysdb;
- struct sdap_options *opts;
- struct sss_domain_info *dom;
- struct sdap_handle *sh;
-
- const char **grp_attrs;
-
- char *filter;
- char **group_dns;
- int count;
- int cur;
-
- struct sdap_op *op;
-
- struct sysdb_attrs **groups;
- int groups_cur;
-};
-
-static void sdap_initgr_nested_search(struct tevent_req *subreq);
-static void sdap_initgr_nested_store(struct tevent_req *req);
-static void sdap_initgr_nested_done(struct tevent_req *subreq);
-static struct tevent_req *sdap_initgr_nested_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_options *opts,
- struct sysdb_ctx *sysdb,
- struct sss_domain_info *dom,
- struct sdap_handle *sh,
- struct sysdb_attrs *user,
- const char **grp_attrs)
-{
- struct tevent_req *req, *subreq;
- struct sdap_initgr_nested_state *state;
- struct ldb_message_element *el;
- int i, ret;
-
- req = tevent_req_create(memctx, &state, struct sdap_initgr_nested_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->opts = opts;
- state->sysdb = sysdb;
- state->dom = dom;
- state->sh = sh;
- state->grp_attrs = grp_attrs;
- state->op = NULL;
-
- state->filter = talloc_asprintf(state, "(objectclass=%s)",
- opts->group_map[SDAP_OC_GROUP].name);
- if (!state->filter) {
- talloc_zfree(req);
- return NULL;
- }
-
- /* TODO: test rootDSE for deref support and use it if available */
- /* TODO: or test rootDSE for ASQ support and use it if available */
-
- ret = sysdb_attrs_get_el(user, SYSDB_MEMBEROF, &el);
- if (ret || !el || el->num_values == 0) {
- DEBUG(4, ("User entry lacks original memberof ?\n"));
- /* user with no groups ? */
- tevent_req_error(req, ENOENT);
- tevent_req_post(req, ev);
- }
- state->count = el->num_values;
-
- state->groups = talloc_zero_array(state, struct sysdb_attrs *,
- state->count + 1);;
- if (!state->groups) {
- talloc_zfree(req);
- return NULL;
- }
- state->groups_cur = 0;
-
- state->group_dns = talloc_array(state, char *, state->count + 1);
- if (!state->group_dns) {
- talloc_zfree(req);
- return NULL;
- }
- for (i = 0; i < state->count; i++) {
- state->group_dns[i] = talloc_strdup(state->group_dns,
- (char *)el->values[i].data);
- if (!state->group_dns[i]) {
- talloc_zfree(req);
- return NULL;
- }
- }
- state->group_dns[i] = NULL; /* terminate */
- state->cur = 0;
-
- subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh,
- state->group_dns[state->cur],
- LDAP_SCOPE_BASE,
- state->filter, state->grp_attrs,
- state->opts->group_map, SDAP_OPTS_GROUP);
- if (!subreq) {
- talloc_zfree(req);
- return NULL;
- }
- tevent_req_set_callback(subreq, sdap_initgr_nested_search, req);
-
- return req;
-}
-
-static void sdap_initgr_nested_search(struct tevent_req *subreq)
-{
- struct tevent_req *req;
- struct sdap_initgr_nested_state *state;
- struct sysdb_attrs **groups;
- size_t count;
- int ret;
-
- req = tevent_req_callback_data(subreq, struct tevent_req);
- state = tevent_req_data(req, struct sdap_initgr_nested_state);
-
- ret = sdap_get_generic_recv(subreq, state, &count, &groups);
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- if (count == 1) {
- state->groups[state->groups_cur] = groups[0];
- state->groups_cur++;
- } else {
- DEBUG(2, ("Search for group %s, returned %d results. Skipping\n",
- state->group_dns[state->cur], count));
- }
-
- state->cur++;
- if (state->cur < state->count) {
- subreq = sdap_get_generic_send(state, state->ev,
- state->opts, state->sh,
- state->group_dns[state->cur],
- LDAP_SCOPE_BASE,
- state->filter, state->grp_attrs,
- state->opts->group_map,
- SDAP_OPTS_GROUP);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, sdap_initgr_nested_search, req);
- } else {
- sdap_initgr_nested_store(req);
- }
-}
-
-static void sdap_initgr_nested_store(struct tevent_req *req)
-{
- struct tevent_req *subreq;
- struct sdap_initgr_nested_state *state;
-
- state = tevent_req_data(req, struct sdap_initgr_nested_state);
-
- subreq = sdap_save_groups_send(state, state->ev, state->dom,
- state->sysdb, state->opts,
- state->groups, state->groups_cur);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, sdap_initgr_nested_done, req);
-}
-
-static void sdap_initgr_nested_done(struct tevent_req *subreq)
-{
- struct tevent_req *req;
- int ret;
-
- req = tevent_req_callback_data(subreq, struct tevent_req);
-
- ret = sdap_save_groups_recv(subreq, NULL, NULL);
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- tevent_req_done(req);
-}
-
-static int sdap_initgr_nested_recv(struct tevent_req *req)
-{
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- return EOK;
-}
-
-
-/* ==Initgr-call-(groups-a-user-is-member-of)============================= */
-
-struct sdap_get_initgr_state {
- struct tevent_context *ev;
- struct sysdb_ctx *sysdb;
- struct sdap_options *opts;
- struct sss_domain_info *dom;
- struct sdap_handle *sh;
- const char *name;
- const char **grp_attrs;
-
- struct sysdb_attrs *orig_user;
-
- struct sysdb_handle *handle;
-};
-
-static void sdap_get_initgr_user(struct tevent_req *subreq);
-static void sdap_get_initgr_store(struct tevent_req *subreq);
-static void sdap_get_initgr_commit(struct tevent_req *subreq);
-static void sdap_get_initgr_process(struct tevent_req *subreq);
-static void sdap_get_initgr_done(struct tevent_req *subreq);
-
-struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sss_domain_info *dom,
- struct sysdb_ctx *sysdb,
- struct sdap_options *opts,
- struct sdap_handle *sh,
- const char *name,
- const char **grp_attrs)
-{
- struct tevent_req *req, *subreq;
- struct sdap_get_initgr_state *state;
- const char *base_dn;
- char *filter;
- const char **attrs;
- int ret;
-
- DEBUG(9, ("Retrieving info for initgroups call\n"));
-
- req = tevent_req_create(memctx, &state, struct sdap_get_initgr_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->opts = opts;
- state->sysdb = sysdb;
- state->dom = dom;
- state->sh = sh;
- state->name = name;
- state->grp_attrs = grp_attrs;
- state->orig_user = NULL;
-
- filter = talloc_asprintf(state, "(&(%s=%s)(objectclass=%s))",
- state->opts->user_map[SDAP_AT_USER_NAME].name,
- state->name,
- state->opts->user_map[SDAP_OC_USER].name);
- if (!filter) {
- talloc_zfree(req);
- return NULL;
- }
-
- base_dn = dp_opt_get_string(state->opts->basic,
- SDAP_USER_SEARCH_BASE);
- if (!base_dn) {
- talloc_zfree(req);
- return NULL;
- }
-
- ret = build_attrs_from_map(state, state->opts->user_map,
- SDAP_OPTS_USER, &attrs);
- if (ret) {
- talloc_zfree(req);
- return NULL;
- }
-
- subreq = sdap_get_generic_send(state, state->ev,
- state->opts, state->sh,
- base_dn, LDAP_SCOPE_SUBTREE,
- filter, attrs,
- state->opts->user_map, SDAP_OPTS_USER);
- if (!subreq) {
- talloc_zfree(req);
- return NULL;
- }
- tevent_req_set_callback(subreq, sdap_get_initgr_user, req);
-
- return req;
-}
-
-static void sdap_get_initgr_user(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct sdap_get_initgr_state *state = tevent_req_data(req,
- struct sdap_get_initgr_state);
- struct sysdb_attrs **usr_attrs;
- size_t count;
- int ret;
-
- DEBUG(9, ("Receiving info for the user\n"));
-
- ret = sdap_get_generic_recv(subreq, state, &count, &usr_attrs);
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- if (count != 1) {
- DEBUG(2, ("Expected one user entry and got %d\n", count));
- tevent_req_error(req, ENOENT);
- return;
- }
-
- state->orig_user = usr_attrs[0];
-
- subreq = sysdb_transaction_send(state, state->ev, state->sysdb);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, sdap_get_initgr_store, req);
-}
-
-static void sdap_get_initgr_store(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct sdap_get_initgr_state *state = tevent_req_data(req,
- struct sdap_get_initgr_state);
- int ret;
-
- DEBUG(9, ("Storing the user\n"));
-
- ret = sysdb_transaction_recv(subreq, state, &state->handle);
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- subreq = sdap_save_user_send(state, state->ev, state->handle,
- state->opts, state->dom,
- state->orig_user, true);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, sdap_get_initgr_commit, req);
-}
-
-static void sdap_get_initgr_commit(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct sdap_get_initgr_state *state = tevent_req_data(req,
- struct sdap_get_initgr_state);
- int ret;
-
- DEBUG(9, ("Commit change\n"));
-
- ret = sdap_save_user_recv(subreq, NULL, NULL);
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- subreq = sysdb_transaction_commit_send(state, state->ev, state->handle);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, sdap_get_initgr_process, req);
-}
-
-static void sdap_get_initgr_process(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct sdap_get_initgr_state *state = tevent_req_data(req,
- struct sdap_get_initgr_state);
- int ret;
-
- DEBUG(9, ("Process user's groups\n"));
-
- ret = sysdb_transaction_commit_recv(subreq);
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- switch (state->opts->schema_type) {
- case SDAP_SCHEMA_RFC2307:
- subreq = sdap_initgr_rfc2307_send(state, state->ev, state->opts,
- state->sysdb, state->dom, state->sh,
- dp_opt_get_string(state->opts->basic,
- SDAP_GROUP_SEARCH_BASE),
- state->name, state->grp_attrs);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, sdap_get_initgr_done, req);
- break;
-
- case SDAP_SCHEMA_RFC2307BIS:
- case SDAP_SCHEMA_IPA_V1:
- case SDAP_SCHEMA_AD:
- /* TODO: AD uses a different member/memberof schema
- * We need an AD specific call that is able to unroll
- * nested groups by doing extensive recursive searches */
-
- subreq = sdap_initgr_nested_send(state, state->ev, state->opts,
- state->sysdb, state->dom, state->sh,
- state->orig_user, state->grp_attrs);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, sdap_get_initgr_done, req);
- return;
-
- default:
- tevent_req_error(req, EINVAL);
- return;
- }
-}
-
-static void sdap_get_initgr_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct sdap_get_initgr_state *state = tevent_req_data(req,
- struct sdap_get_initgr_state);
- int ret;
-
- DEBUG(9, ("Initgroups done\n"));
-
- switch (state->opts->schema_type) {
- case SDAP_SCHEMA_RFC2307:
-
- ret = sdap_initgr_rfc2307_recv(subreq);
- break;
-
- case SDAP_SCHEMA_RFC2307BIS:
- case SDAP_SCHEMA_IPA_V1:
- case SDAP_SCHEMA_AD:
-
- ret = sdap_initgr_nested_recv(subreq);
- break;
-
- default:
-
- ret = EINVAL;
- break;
- }
-
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- tevent_req_done(req);
-}
-
-int sdap_get_initgr_recv(struct tevent_req *req)
-{
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- return EOK;
-}
-
diff --git a/server/providers/ldap/sdap_async_connection.c b/server/providers/ldap/sdap_async_connection.c
deleted file mode 100644
index 18e47d3b7..000000000
--- a/server/providers/ldap/sdap_async_connection.c
+++ /dev/null
@@ -1,1141 +0,0 @@
-/*
- SSSD
-
- Async LDAP Helper routines
-
- Copyright (C) Simo Sorce <ssorce@redhat.com> - 2009
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <sasl/sasl.h>
-#include "util/util.h"
-#include "util/sss_krb5.h"
-#include "providers/ldap/sdap_async_private.h"
-
-#define LDAP_X_SSSD_PASSWORD_EXPIRED 0x555D
-
-/* ==Connect-to-LDAP-Server=============================================== */
-
-struct sdap_connect_state {
- struct tevent_context *ev;
- struct sdap_options *opts;
- struct sdap_handle *sh;
-
- struct sdap_op *op;
-
- struct sdap_msg *reply;
- int result;
-};
-
-static void sdap_connect_done(struct sdap_op *op,
- struct sdap_msg *reply,
- int error, void *pvt);
-
-struct tevent_req *sdap_connect_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_options *opts,
- const char *uri,
- bool use_start_tls)
-{
- struct tevent_req *req;
- struct sdap_connect_state *state;
- struct timeval tv;
- int ver;
- int lret;
- int ret = EOK;
- int msgid;
- bool ldap_referrals;
-
- req = tevent_req_create(memctx, &state, struct sdap_connect_state);
- if (!req) return NULL;
-
- state->reply = talloc(state, struct sdap_msg);
- if (!state->reply) {
- talloc_zfree(req);
- return NULL;
- }
-
- state->ev = ev;
- state->opts = opts;
- state->sh = sdap_handle_create(state);
- if (!state->sh) {
- talloc_zfree(req);
- return NULL;
- }
- /* Initialize LDAP handler */
- lret = ldap_initialize(&state->sh->ldap, uri);
- if (lret != LDAP_SUCCESS) {
- DEBUG(1, ("ldap_initialize failed: %s\n", ldap_err2string(lret)));
- goto fail;
- }
-
- /* Force ldap version to 3 */
- ver = LDAP_VERSION3;
- lret = ldap_set_option(state->sh->ldap, LDAP_OPT_PROTOCOL_VERSION, &ver);
- if (lret != LDAP_OPT_SUCCESS) {
- DEBUG(1, ("Failed to set ldap version to 3\n"));
- goto fail;
- }
-
- /* Set Network Timeout */
- tv.tv_sec = dp_opt_get_int(opts->basic, SDAP_NETWORK_TIMEOUT);
- tv.tv_usec = 0;
- lret = ldap_set_option(state->sh->ldap, LDAP_OPT_NETWORK_TIMEOUT, &tv);
- if (lret != LDAP_OPT_SUCCESS) {
- DEBUG(1, ("Failed to set network timeout to %d\n",
- dp_opt_get_int(opts->basic, SDAP_NETWORK_TIMEOUT)));
- goto fail;
- }
-
- /* Set Default Timeout */
- tv.tv_sec = dp_opt_get_int(opts->basic, SDAP_OPT_TIMEOUT);
- tv.tv_usec = 0;
- lret = ldap_set_option(state->sh->ldap, LDAP_OPT_TIMEOUT, &tv);
- if (lret != LDAP_OPT_SUCCESS) {
- DEBUG(1, ("Failed to set default timeout to %d\n",
- dp_opt_get_int(opts->basic, SDAP_OPT_TIMEOUT)));
- goto fail;
- }
-
- /* Set Referral chasing */
- ldap_referrals = dp_opt_get_bool(opts->basic, SDAP_REFERRALS);
- lret = ldap_set_option(state->sh->ldap, LDAP_OPT_REFERRALS,
- (ldap_referrals ? LDAP_OPT_ON : LDAP_OPT_OFF));
- if (lret != LDAP_OPT_SUCCESS) {
- DEBUG(1, ("Failed to set referral chasing to %s\n",
- (ldap_referrals ? "LDAP_OPT_ON" : "LDAP_OPT_OFF")));
- goto fail;
- }
-
-#ifdef HAVE_LDAP_CONNCB
- struct ldap_cb_data *cb_data;
-
- /* add connection callback */
- state->sh->conncb = talloc_zero(state->sh, struct ldap_conncb);
- if (state->sh->conncb == NULL) {
- DEBUG(1, ("talloc_zero failed.\n"));
- ret = ENOMEM;
- goto fail;
- }
-
- cb_data = talloc_zero(state->sh->conncb, struct ldap_cb_data);
- if (cb_data == NULL) {
- DEBUG(1, ("talloc_zero failed.\n"));
- ret = ENOMEM;
- goto fail;
- }
- cb_data->sh = state->sh;
- cb_data->ev = state->ev;
-
- state->sh->conncb->lc_add = sdap_ldap_connect_callback_add;
- state->sh->conncb->lc_del = sdap_ldap_connect_callback_del;
- state->sh->conncb->lc_arg = cb_data;
-
- lret = ldap_set_option(state->sh->ldap, LDAP_OPT_CONNECT_CB,
- state->sh->conncb);
- if (lret != LDAP_OPT_SUCCESS) {
- DEBUG(1, ("Failed to set connection callback\n"));
- goto fail;
- }
-#endif
-
- /* if we do not use start_tls the connection is not really connected yet
- * just fake an async procedure and leave connection to the bind call */
- if (!use_start_tls) {
- tevent_req_post(req, ev);
- return req;
- }
-
- DEBUG(4, ("Executing START TLS\n"));
-
- lret = ldap_start_tls(state->sh->ldap, NULL, NULL, &msgid);
- if (lret != LDAP_SUCCESS) {
- DEBUG(3, ("ldap_start_tls failed: [%s]", ldap_err2string(ret)));
- goto fail;
- }
-
- state->sh->connected = true;
-#ifndef HAVE_LDAP_CONNCB
- ret = sdap_install_ldap_callbacks(state->sh, state->ev);
- if (ret) goto fail;
-#endif
-
- /* FIXME: get timeouts from configuration, for now 5 secs. */
- ret = sdap_op_add(state, ev, state->sh, msgid,
- sdap_connect_done, req, 5, &state->op);
- if (ret) {
- DEBUG(1, ("Failed to set up operation!\n"));
- goto fail;
- }
-
- return req;
-
-fail:
- if (ret) {
- tevent_req_error(req, ret);
- } else {
- if (lret == LDAP_SERVER_DOWN) {
- tevent_req_error(req, ETIMEDOUT);
- } else {
- tevent_req_error(req, EIO);
- }
- }
- tevent_req_post(req, ev);
- return req;
-}
-
-static void sdap_connect_done(struct sdap_op *op,
- struct sdap_msg *reply,
- int error, void *pvt)
-{
- struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
- struct sdap_connect_state *state = tevent_req_data(req,
- struct sdap_connect_state);
- char *errmsg;
- int ret;
-
- if (error) {
- tevent_req_error(req, error);
- return;
- }
-
- state->reply = talloc_steal(state, reply);
-
- ret = ldap_parse_result(state->sh->ldap, state->reply->msg,
- &state->result, NULL, &errmsg, NULL, NULL, 0);
- if (ret != LDAP_SUCCESS) {
- DEBUG(2, ("ldap_parse_result failed (%d)\n", state->op->msgid));
- tevent_req_error(req, EIO);
- return;
- }
-
- DEBUG(3, ("START TLS result: %s(%d), %s\n",
- ldap_err2string(state->result), state->result, errmsg));
-
- if (ldap_tls_inplace(state->sh->ldap)) {
- DEBUG(9, ("SSL/TLS handler already in place.\n"));
- tevent_req_done(req);
- return;
- }
-
-/* FIXME: take care that ldap_install_tls might block */
- ret = ldap_install_tls(state->sh->ldap);
- if (ret != LDAP_SUCCESS) {
- DEBUG(1, ("ldap_install_tls failed: [%d][%s]\n", ret,
- ldap_err2string(ret)));
- state->result = ret;
- tevent_req_error(req, EIO);
- return;
- }
-
- tevent_req_done(req);
-}
-
-int sdap_connect_recv(struct tevent_req *req,
- TALLOC_CTX *memctx,
- struct sdap_handle **sh)
-{
- struct sdap_connect_state *state = tevent_req_data(req,
- struct sdap_connect_state);
- enum tevent_req_state tstate;
- uint64_t err = EIO;
-
- if (tevent_req_is_error(req, &tstate, &err)) {
- /* if tstate shows in progress, it is because
- * we did not ask to perform tls, just pretend all is fine */
- if (tstate != TEVENT_REQ_IN_PROGRESS) {
- return err;
- }
- }
-
- *sh = talloc_steal(memctx, state->sh);
- if (!*sh) {
- return ENOMEM;
- }
- return EOK;
-}
-
-/* ==Simple-Bind========================================================== */
-
-struct simple_bind_state {
- struct tevent_context *ev;
- struct sdap_handle *sh;
- const char *user_dn;
- struct berval *pw;
-
- struct sdap_op *op;
-
- struct sdap_msg *reply;
- int result;
-};
-
-static void simple_bind_done(struct sdap_op *op,
- struct sdap_msg *reply,
- int error, void *pvt);
-
-static struct tevent_req *simple_bind_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_handle *sh,
- const char *user_dn,
- struct berval *pw)
-{
- struct tevent_req *req;
- struct simple_bind_state *state;
- int ret = EOK;
- int msgid;
- int ldap_err;
- LDAPControl *request_controls[2];
-
- req = tevent_req_create(memctx, &state, struct simple_bind_state);
- if (!req) return NULL;
-
- state->reply = talloc(state, struct sdap_msg);
- if (!state->reply) {
- talloc_zfree(req);
- return NULL;
- }
-
- state->ev = ev;
- state->sh = sh;
- state->user_dn = user_dn;
- state->pw = pw;
-
- ret = sss_ldap_control_create(LDAP_CONTROL_PASSWORDPOLICYREQUEST,
- 0, NULL, 0, &request_controls[0]);
- if (ret != LDAP_SUCCESS) {
- DEBUG(1, ("sss_ldap_control_create failed.\n"));
- goto fail;
- }
- request_controls[1] = NULL;
-
- DEBUG(4, ("Executing simple bind as: %s\n", state->user_dn));
-
- ret = ldap_sasl_bind(state->sh->ldap, state->user_dn, LDAP_SASL_SIMPLE,
- state->pw, request_controls, NULL, &msgid);
- ldap_control_free(request_controls[0]);
- if (ret == -1 || msgid == -1) {
- ret = ldap_get_option(state->sh->ldap,
- LDAP_OPT_RESULT_CODE, &ldap_err);
- if (ret != LDAP_OPT_SUCCESS) {
- DEBUG(1, ("ldap_bind failed (couldn't get ldap error)\n"));
- ret = LDAP_LOCAL_ERROR;
- } else {
- DEBUG(1, ("ldap_bind failed (%d)[%s]\n",
- ldap_err, ldap_err2string(ldap_err)));
- ret = ldap_err;
- }
- goto fail;
- }
- DEBUG(8, ("ldap simple bind sent, msgid = %d\n", msgid));
-
- if (!sh->connected) {
- sh->connected = true;
-#ifndef HAVE_LDAP_CONNCB
- ret = sdap_install_ldap_callbacks(sh, ev);
- if (ret) goto fail;
-#endif
- }
-
- /* FIXME: get timeouts from configuration, for now 5 secs. */
- ret = sdap_op_add(state, ev, sh, msgid,
- simple_bind_done, req, 5, &state->op);
- if (ret) {
- DEBUG(1, ("Failed to set up operation!\n"));
- goto fail;
- }
-
- return req;
-
-fail:
- if (ret == LDAP_SERVER_DOWN) {
- tevent_req_error(req, ETIMEDOUT);
- } else {
- tevent_req_error(req, EIO);
- }
- tevent_req_post(req, ev);
- return req;
-}
-
-static void simple_bind_done(struct sdap_op *op,
- struct sdap_msg *reply,
- int error, void *pvt)
-{
- struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
- struct simple_bind_state *state = tevent_req_data(req,
- struct simple_bind_state);
- char *errmsg;
- int ret;
- LDAPControl **response_controls;
- int c;
- ber_int_t pp_grace;
- ber_int_t pp_expire;
- LDAPPasswordPolicyError pp_error;
-
- if (error) {
- tevent_req_error(req, error);
- return;
- }
-
- state->reply = talloc_steal(state, reply);
-
- ret = ldap_parse_result(state->sh->ldap, state->reply->msg,
- &state->result, NULL, &errmsg, NULL,
- &response_controls, 0);
- if (ret != LDAP_SUCCESS) {
- DEBUG(2, ("ldap_parse_result failed (%d)\n", state->op->msgid));
- ret = EIO;
- goto done;
- }
-
- if (response_controls == NULL) {
- DEBUG(5, ("Server returned no controls.\n"));
- } else {
- for (c = 0; response_controls[c] != NULL; c++) {
- DEBUG(9, ("Server returned control [%s].\n",
- response_controls[c]->ldctl_oid));
- if (strcmp(response_controls[c]->ldctl_oid,
- LDAP_CONTROL_PASSWORDPOLICYRESPONSE) == 0) {
- ret = ldap_parse_passwordpolicy_control(state->sh->ldap,
- response_controls[c],
- &pp_expire, &pp_grace,
- &pp_error);
- if (ret != LDAP_SUCCESS) {
- DEBUG(1, ("ldap_parse_passwordpolicy_control failed.\n"));
- ret = EIO;
- goto done;
- }
-
- DEBUG(7, ("Password Policy Response: expire [%d] grace [%d] "
- "error [%s].\n", pp_expire, pp_grace,
- ldap_passwordpolicy_err2txt(pp_error)));
-
- if (state->result == LDAP_SUCCESS &&
- (pp_error == PP_changeAfterReset || pp_grace > 0)) {
- DEBUG(4, ("User must set a new password.\n"));
- state->result = LDAP_X_SSSD_PASSWORD_EXPIRED;
- }
- }
- }
- }
-
- DEBUG(3, ("Bind result: %s(%d), %s\n",
- ldap_err2string(state->result), state->result, errmsg));
-
- ret = LDAP_SUCCESS;
-done:
- ldap_controls_free(response_controls);
-
- if (ret == LDAP_SUCCESS) {
- tevent_req_done(req);
- } else {
- tevent_req_error(req, ret);
- }
-}
-
-static int simple_bind_recv(struct tevent_req *req, int *ldaperr)
-{
- struct simple_bind_state *state = tevent_req_data(req,
- struct simple_bind_state);
-
- *ldaperr = LDAP_OTHER;
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- *ldaperr = state->result;
- return EOK;
-}
-
-/* ==SASL-Bind============================================================ */
-
-struct sasl_bind_state {
- struct tevent_context *ev;
- struct sdap_handle *sh;
-
- const char *sasl_mech;
- const char *sasl_user;
- struct berval *sasl_cred;
-
- int result;
-};
-
-static int sdap_sasl_interact(LDAP *ld, unsigned flags,
- void *defaults, void *interact);
-
-static struct tevent_req *sasl_bind_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_handle *sh,
- const char *sasl_mech,
- const char *sasl_user,
- struct berval *sasl_cred)
-{
- struct tevent_req *req;
- struct sasl_bind_state *state;
- int ret = EOK;
-
- req = tevent_req_create(memctx, &state, struct sasl_bind_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->sh = sh;
- state->sasl_mech = sasl_mech;
- state->sasl_user = sasl_user;
- state->sasl_cred = sasl_cred;
-
- DEBUG(4, ("Executing sasl bind mech: %s, user: %s\n",
- sasl_mech, sasl_user));
-
- /* FIXME: Warning, this is a sync call!
- * No async variant exist in openldap libraries yet */
-
- ret = ldap_sasl_interactive_bind_s(state->sh->ldap, NULL,
- sasl_mech, NULL, NULL,
- LDAP_SASL_QUIET,
- (*sdap_sasl_interact), state);
- state->result = ret;
- if (ret != LDAP_SUCCESS) {
- DEBUG(1, ("ldap_sasl_bind failed (%d)[%s]\n",
- ret, ldap_err2string(ret)));
- goto fail;
- }
-
- if (!sh->connected) {
- sh->connected = true;
-#ifndef HAVE_LDAP_CONNCB
- ret = sdap_install_ldap_callbacks(sh, ev);
- if (ret) goto fail;
-#endif
- }
-
- tevent_req_post(req, ev);
- return req;
-
-fail:
- if (ret == LDAP_SERVER_DOWN) {
- tevent_req_error(req, ETIMEDOUT);
- } else {
- tevent_req_error(req, EIO);
- }
- tevent_req_post(req, ev);
- return req;
-}
-
-static int sdap_sasl_interact(LDAP *ld, unsigned flags,
- void *defaults, void *interact)
-{
- struct sasl_bind_state *state = talloc_get_type(defaults,
- struct sasl_bind_state);
- sasl_interact_t *in = (sasl_interact_t *)interact;
-
- if (!ld) return LDAP_PARAM_ERROR;
-
- while (in->id != SASL_CB_LIST_END) {
-
- switch (in->id) {
- case SASL_CB_GETREALM:
- case SASL_CB_AUTHNAME:
- case SASL_CB_PASS:
- if (in->defresult) {
- in->result = in->defresult;
- } else {
- in->result = "";
- }
- in->len = strlen(in->result);
- break;
- case SASL_CB_USER:
- if (state->sasl_user) {
- in->result = state->sasl_user;
- } else if (in->defresult) {
- in->result = in->defresult;
- } else {
- in->result = "";
- }
- in->len = strlen(in->result);
- break;
- case SASL_CB_NOECHOPROMPT:
- case SASL_CB_ECHOPROMPT:
- goto fail;
- }
-
- in++;
- }
-
- return LDAP_SUCCESS;
-
-fail:
- return LDAP_UNAVAILABLE;
-}
-
-static int sasl_bind_recv(struct tevent_req *req, int *ldaperr)
-{
- struct sasl_bind_state *state = tevent_req_data(req,
- struct sasl_bind_state);
- enum tevent_req_state tstate;
- uint64_t err = EIO;
-
- if (tevent_req_is_error(req, &tstate, &err)) {
- if (tstate != TEVENT_REQ_IN_PROGRESS) {
- *ldaperr = LDAP_OTHER;
- return err;
- }
- }
-
- *ldaperr = state->result;
- return EOK;
-}
-
-/* ==Perform-Kinit-given-keytab-and-principal============================= */
-
-struct sdap_kinit_state {
- int result;
-};
-
-static void sdap_kinit_done(struct tevent_req *subreq);
-
-struct tevent_req *sdap_kinit_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_handle *sh,
- int timeout,
- const char *keytab,
- const char *principal,
- const char *realm)
-{
- struct tevent_req *req;
- struct tevent_req *subreq;
- struct sdap_kinit_state *state;
- int ret;
-
- DEBUG(6, ("Attempting kinit (%s, %s, %s)\n", keytab, principal, realm));
-
- req = tevent_req_create(memctx, &state, struct sdap_kinit_state);
- if (!req) return NULL;
-
- state->result = SDAP_AUTH_FAILED;
-
- if (keytab) {
- ret = setenv("KRB5_KTNAME", keytab, 1);
- if (ret == -1) {
- DEBUG(2, ("Failed to set KRB5_KTNAME to %s\n", keytab));
- return NULL;
- }
- }
-
- subreq = sdap_get_tgt_send(state, ev, realm, principal, keytab, timeout);
- if (!subreq) {
- talloc_zfree(req);
- return NULL;
- }
- tevent_req_set_callback(subreq, sdap_kinit_done, req);
-
- return req;
-}
-
-static void sdap_kinit_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct sdap_kinit_state *state = tevent_req_data(req,
- struct sdap_kinit_state);
-
- int ret;
- int result;
- char *ccname = NULL;
-
- ret = sdap_get_tgt_recv(subreq, state, &result, &ccname);
- talloc_zfree(subreq);
- if (ret != EOK) {
- state->result = SDAP_AUTH_FAILED;
- DEBUG(1, ("child failed (%d [%s])\n", ret, strerror(ret)));
- tevent_req_error(req, ret);
- return;
- }
-
- if (result == EOK) {
- ret = setenv("KRB5CCNAME", ccname, 1);
- if (ret == -1) {
- DEBUG(2, ("Unable to set env. variable KRB5CCNAME!\n"));
- state->result = SDAP_AUTH_FAILED;
- tevent_req_error(req, EFAULT);
- }
-
- state->result = SDAP_AUTH_SUCCESS;
- tevent_req_done(req);
- return;
- }
-
- DEBUG(4, ("Could not get TGT: %d [%s]\n", result, strerror(result)));
- state->result = SDAP_AUTH_FAILED;
- tevent_req_error(req, EIO);
-}
-
-int sdap_kinit_recv(struct tevent_req *req, enum sdap_result *result)
-{
- struct sdap_kinit_state *state = tevent_req_data(req,
- struct sdap_kinit_state);
- enum tevent_req_state tstate;
- uint64_t err = EIO;
-
- if (tevent_req_is_error(req, &tstate, &err)) {
- if (tstate != TEVENT_REQ_IN_PROGRESS) {
- *result = SDAP_ERROR;
- return err;
- }
- }
-
- *result = state->result;
- return EOK;
-}
-
-
-/* ==Authenticaticate-User-by-DN========================================== */
-
-struct sdap_auth_state {
- const char *user_dn;
- struct berval pw;
-
- int result;
- bool is_sasl;
-};
-
-static void sdap_auth_done(struct tevent_req *subreq);
-
-/* TODO: handle sasl_cred */
-struct tevent_req *sdap_auth_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_handle *sh,
- const char *sasl_mech,
- const char *sasl_user,
- const char *user_dn,
- const char *authtok_type,
- struct dp_opt_blob authtok)
-{
- struct tevent_req *req, *subreq;
- struct sdap_auth_state *state;
-
- if (authtok_type != NULL && strcasecmp(authtok_type,"password") != 0) {
- DEBUG(1,("Authentication token type [%s] is not supported"));
- return NULL;
- }
-
- req = tevent_req_create(memctx, &state, struct sdap_auth_state);
- if (!req) return NULL;
-
- state->user_dn = user_dn;
- state->pw.bv_val = (char *)authtok.data;
- state->pw.bv_len = authtok.length;
-
- if (sasl_mech) {
- state->is_sasl = true;
- subreq = sasl_bind_send(state, ev, sh, sasl_mech, sasl_user, NULL);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return tevent_req_post(req, ev);
- }
- } else {
- state->is_sasl = false;
- subreq = simple_bind_send(state, ev, sh, user_dn, &state->pw);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return tevent_req_post(req, ev);
- }
- }
-
- tevent_req_set_callback(subreq, sdap_auth_done, req);
- return req;
-}
-
-static void sdap_auth_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct sdap_auth_state *state = tevent_req_data(req,
- struct sdap_auth_state);
- int ret;
-
- if (state->is_sasl) {
- ret = sasl_bind_recv(subreq, &state->result);
- } else {
- ret = simple_bind_recv(subreq, &state->result);
- }
- if (ret != EOK) {
- tevent_req_error(req, ret);
- return;
- }
-
- tevent_req_done(req);
-}
-
-int sdap_auth_recv(struct tevent_req *req, enum sdap_result *result)
-{
- struct sdap_auth_state *state = tevent_req_data(req,
- struct sdap_auth_state);
-
- *result = SDAP_ERROR;
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- switch (state->result) {
- case LDAP_SUCCESS:
- *result = SDAP_AUTH_SUCCESS;
- break;
- case LDAP_INVALID_CREDENTIALS:
- *result = SDAP_AUTH_FAILED;
- break;
- case LDAP_X_SSSD_PASSWORD_EXPIRED:
- *result = SDAP_AUTH_PW_EXPIRED;
- break;
- default:
- break;
- }
-
- return EOK;
-}
-
-/* ==Client connect============================================ */
-
-struct sdap_cli_connect_state {
- struct tevent_context *ev;
- struct sdap_options *opts;
- struct sdap_service *service;
-
- bool use_rootdse;
- struct sysdb_attrs *rootdse;
-
- struct sdap_handle *sh;
-
- struct fo_server *srv;
-};
-
-static void sdap_cli_resolve_done(struct tevent_req *subreq);
-static void sdap_cli_connect_done(struct tevent_req *subreq);
-static void sdap_cli_rootdse_step(struct tevent_req *req);
-static void sdap_cli_rootdse_done(struct tevent_req *subreq);
-static void sdap_cli_kinit_step(struct tevent_req *req);
-static void sdap_cli_kinit_done(struct tevent_req *subreq);
-static void sdap_cli_auth_step(struct tevent_req *req);
-static void sdap_cli_auth_done(struct tevent_req *subreq);
-
-struct tevent_req *sdap_cli_connect_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_options *opts,
- struct be_ctx *be,
- struct sdap_service *service,
- struct sysdb_attrs **rootdse)
-{
- struct tevent_req *req, *subreq;
- struct sdap_cli_connect_state *state;
-
- req = tevent_req_create(memctx, &state, struct sdap_cli_connect_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->opts = opts;
- state->service = service;
- state->srv = NULL;
-
- if (rootdse) {
- state->use_rootdse = true;
- state->rootdse = *rootdse;
- } else {
- state->use_rootdse = false;
- state->rootdse = NULL;
- }
-
- /* NOTE: this call may cause service->uri to be refreshed
- * with a new valid server. Do not use service->uri before */
- subreq = be_resolve_server_send(state, ev, be, service->name);
- if (!subreq) {
- talloc_zfree(req);
- return NULL;
- }
- tevent_req_set_callback(subreq, sdap_cli_resolve_done, req);
-
- return req;
-}
-
-static void sdap_cli_resolve_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct sdap_cli_connect_state *state = tevent_req_data(req,
- struct sdap_cli_connect_state);
- int ret;
-
- ret = be_resolve_server_recv(subreq, &state->srv);
- talloc_zfree(subreq);
- if (ret) {
- /* all servers have been tried and none
- * was found good, go offline */
- tevent_req_error(req, EIO);
- return;
- }
-
- subreq = sdap_connect_send(state, state->ev, state->opts,
- state->service->uri,
- dp_opt_get_bool(state->opts->basic,
- SDAP_ID_TLS));
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, sdap_cli_connect_done, req);
-}
-
-static void sdap_cli_connect_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct sdap_cli_connect_state *state = tevent_req_data(req,
- struct sdap_cli_connect_state);
- const char *sasl_mech;
- int ret;
-
- ret = sdap_connect_recv(subreq, state, &state->sh);
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- if (state->use_rootdse && !state->rootdse) {
- /* fetch the rootDSE this time */
- sdap_cli_rootdse_step(req);
- return;
- }
-
- sasl_mech = dp_opt_get_string(state->opts->basic, SDAP_SASL_MECH);
-
- if (sasl_mech && state->use_rootdse) {
- /* check if server claims to support GSSAPI */
- if (!sdap_rootdse_sasl_mech_is_supported(state->rootdse,
- sasl_mech)) {
- tevent_req_error(req, ENOTSUP);
- return;
- }
- }
-
- if (sasl_mech && (strcasecmp(sasl_mech, "GSSAPI") == 0)) {
- if (dp_opt_get_bool(state->opts->basic, SDAP_KRB5_KINIT)) {
- sdap_cli_kinit_step(req);
- return;
- }
- }
-
- sdap_cli_auth_step(req);
-}
-
-static void sdap_cli_rootdse_step(struct tevent_req *req)
-{
- struct sdap_cli_connect_state *state = tevent_req_data(req,
- struct sdap_cli_connect_state);
- struct tevent_req *subreq;
-
- subreq = sdap_get_rootdse_send(state, state->ev, state->opts, state->sh);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, sdap_cli_rootdse_done, req);
-
- if (!state->sh->connected) {
- /* this rootdse search is performed before we actually do a bind,
- * so we need to set up the callbacks or we will never get notified
- * of a reply */
- state->sh->connected = true;
-#ifndef HAVE_LDAP_CONNCB
- int ret;
-
- ret = sdap_install_ldap_callbacks(state->sh, state->ev);
- if (ret) {
- tevent_req_error(req, ret);
- }
-#endif
- }
-}
-
-static void sdap_cli_rootdse_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct sdap_cli_connect_state *state = tevent_req_data(req,
- struct sdap_cli_connect_state);
- const char *sasl_mech;
- int ret;
-
- ret = sdap_get_rootdse_recv(subreq, state, &state->rootdse);
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- sasl_mech = dp_opt_get_string(state->opts->basic, SDAP_SASL_MECH);
-
- if (sasl_mech && state->use_rootdse) {
- /* check if server claims to support GSSAPI */
- if (!sdap_rootdse_sasl_mech_is_supported(state->rootdse,
- sasl_mech)) {
- tevent_req_error(req, ENOTSUP);
- return;
- }
- }
-
- if (sasl_mech && (strcasecmp(sasl_mech, "GSSAPI") == 0)) {
- if (dp_opt_get_bool(state->opts->basic, SDAP_KRB5_KINIT)) {
- sdap_cli_kinit_step(req);
- return;
- }
- }
-
- sdap_cli_auth_step(req);
-}
-
-static void sdap_cli_kinit_step(struct tevent_req *req)
-{
- struct sdap_cli_connect_state *state = tevent_req_data(req,
- struct sdap_cli_connect_state);
- struct tevent_req *subreq;
-
- subreq = sdap_kinit_send(state, state->ev,
- state->sh,
- dp_opt_get_int(state->opts->basic,
- SDAP_OPT_TIMEOUT),
- dp_opt_get_string(state->opts->basic,
- SDAP_KRB5_KEYTAB),
- dp_opt_get_string(state->opts->basic,
- SDAP_SASL_AUTHID),
- dp_opt_get_string(state->opts->basic,
- SDAP_KRB5_REALM));
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, sdap_cli_kinit_done, req);
-}
-
-static void sdap_cli_kinit_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- enum sdap_result result;
- int ret;
-
- ret = sdap_kinit_recv(subreq, &result);
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
- if (result != SDAP_AUTH_SUCCESS) {
- tevent_req_error(req, EACCES);
- return;
- }
-
- sdap_cli_auth_step(req);
-}
-
-static void sdap_cli_auth_step(struct tevent_req *req)
-{
- struct sdap_cli_connect_state *state = tevent_req_data(req,
- struct sdap_cli_connect_state);
- struct tevent_req *subreq;
-
- subreq = sdap_auth_send(state,
- state->ev,
- state->sh,
- dp_opt_get_string(state->opts->basic,
- SDAP_SASL_MECH),
- dp_opt_get_string(state->opts->basic,
- SDAP_SASL_AUTHID),
- dp_opt_get_string(state->opts->basic,
- SDAP_DEFAULT_BIND_DN),
- dp_opt_get_string(state->opts->basic,
- SDAP_DEFAULT_AUTHTOK_TYPE),
- dp_opt_get_blob(state->opts->basic,
- SDAP_DEFAULT_AUTHTOK));
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, sdap_cli_auth_done, req);
-}
-
-static void sdap_cli_auth_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- enum sdap_result result;
- int ret;
-
- ret = sdap_auth_recv(subreq, &result);
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
- if (result != SDAP_AUTH_SUCCESS) {
- tevent_req_error(req, EACCES);
- return;
- }
-
- tevent_req_done(req);
-}
-
-int sdap_cli_connect_recv(struct tevent_req *req,
- TALLOC_CTX *memctx,
- struct sdap_handle **gsh,
- struct sysdb_attrs **rootdse)
-{
- struct sdap_cli_connect_state *state = tevent_req_data(req,
- struct sdap_cli_connect_state);
- enum tevent_req_state tstate;
- uint64_t err;
-
- if (tevent_req_is_error(req, &tstate, &err)) {
- /* mark the server as bad if connection failed */
- if (state->srv) {
- fo_set_port_status(state->srv, PORT_NOT_WORKING);
- }
-
- if (tstate == TEVENT_REQ_USER_ERROR) {
- return err;
- }
- return EIO;
- } else if (state->srv) {
- fo_set_port_status(state->srv, PORT_WORKING);
- }
-
- if (gsh) {
- *gsh = talloc_steal(memctx, state->sh);
- if (!*gsh) {
- return ENOMEM;
- }
- } else {
- talloc_zfree(state->sh);
- }
-
- if (rootdse) {
- if (state->use_rootdse) {
- *rootdse = talloc_steal(memctx, state->rootdse);
- if (!*rootdse) {
- return ENOMEM;
- }
- } else {
- *rootdse = NULL;
- }
- } else {
- talloc_zfree(rootdse);
- }
-
- return EOK;
-}
-
diff --git a/server/providers/ldap/sdap_async_private.h b/server/providers/ldap/sdap_async_private.h
deleted file mode 100644
index 55f76ed70..000000000
--- a/server/providers/ldap/sdap_async_private.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- SSSD
-
- Async LDAP Helper routines
-
- Copyright (C) Simo Sorce <ssorce@redhat.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _SDAP_ASYNC_PRIVATE_H_
-#define _SDAP_ASYNC_PRIVATE_H_
-
-#include "config.h"
-#include "providers/ldap/sdap_async.h"
-
-void make_realm_upper_case(const char *upn);
-struct sdap_handle *sdap_handle_create(TALLOC_CTX *memctx);
-
-#ifdef HAVE_LDAP_CONNCB
-int sdap_ldap_connect_callback_add(LDAP *ld, Sockbuf *sb, LDAPURLDesc *srv,
- struct sockaddr *addr, struct ldap_conncb *ctx);
-void sdap_ldap_connect_callback_del(LDAP *ld, Sockbuf *sb,
- struct ldap_conncb *ctx);
-#else
-int sdap_install_ldap_callbacks(struct sdap_handle *sh,
- struct tevent_context *ev);
-#endif
-
-int sdap_op_add(TALLOC_CTX *memctx, struct tevent_context *ev,
- struct sdap_handle *sh, int msgid,
- sdap_op_callback_t *callback, void *data,
- int timeout, struct sdap_op **_op);
-
-struct tevent_req *sdap_get_rootdse_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_options *opts,
- struct sdap_handle *sh);
-int sdap_get_rootdse_recv(struct tevent_req *req,
- TALLOC_CTX *memctx,
- struct sysdb_attrs **rootdse);
-
-/* from sdap_child_helpers.c */
-
-struct tevent_req *sdap_get_tgt_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- const char *realm_str,
- const char *princ_str,
- const char *keytab_name,
- int timeout);
-
-int sdap_get_tgt_recv(struct tevent_req *req,
- TALLOC_CTX *mem_ctx,
- int *result,
- char **ccname);
-
-#endif /* _SDAP_ASYNC_PRIVATE_H_ */
diff --git a/server/providers/ldap/sdap_child_helpers.c b/server/providers/ldap/sdap_child_helpers.c
deleted file mode 100644
index 0a95c8a0d..000000000
--- a/server/providers/ldap/sdap_child_helpers.c
+++ /dev/null
@@ -1,462 +0,0 @@
-/*
- SSSD
-
- LDAP Backend Module -- child helpers
-
- Authors:
- Jakub Hrozek <jhrozek@redhat.com>
-
- Copyright (C) 2009 Red Hat
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <pwd.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include "util/util.h"
-#include "providers/ldap/ldap_common.h"
-#include "providers/child_common.h"
-
-#ifndef SSSD_LIBEXEC_PATH
-#error "SSSD_LIBEXEC_PATH not defined"
-#else
-#define LDAP_CHILD SSSD_LIBEXEC_PATH"/ldap_child"
-#endif
-
-#ifndef LDAP_CHILD_USER
-#define LDAP_CHILD_USER "nobody"
-#endif
-
-struct sdap_child {
- /* child info */
- pid_t pid;
- int read_from_child_fd;
- int write_to_child_fd;
-};
-
-static void sdap_close_fd(int *fd)
-{
- int ret;
-
- if (*fd == -1) {
- DEBUG(6, ("fd already closed\n"));
- return;
- }
-
- ret = close(*fd);
- if (ret) {
- ret = errno;
- DEBUG(2, ("Closing fd %d, return error %d (%s)\n",
- *fd, ret, strerror(ret)));
- }
-
- *fd = -1;
-}
-
-static int sdap_child_destructor(void *ptr)
-{
- struct sdap_child *child = talloc_get_type(ptr, struct sdap_child);
-
- child_cleanup(child->read_from_child_fd, child->write_to_child_fd);
-
- return 0;
-}
-
-static errno_t sdap_fork_child(struct sdap_child *child)
-{
- int pipefd_to_child[2];
- int pipefd_from_child[2];
- pid_t pid;
- int ret;
- errno_t err;
-
- ret = pipe(pipefd_from_child);
- if (ret == -1) {
- err = errno;
- DEBUG(1, ("pipe failed [%d][%s].\n", err, strerror(err)));
- return err;
- }
- ret = pipe(pipefd_to_child);
- if (ret == -1) {
- err = errno;
- DEBUG(1, ("pipe failed [%d][%s].\n", err, strerror(err)));
- return err;
- }
-
- pid = fork();
-
- if (pid == 0) { /* child */
- err = exec_child(child,
- pipefd_to_child, pipefd_from_child,
- LDAP_CHILD, ldap_child_debug_fd);
- if (err != EOK) {
- DEBUG(1, ("Could not exec LDAP child: [%d][%s].\n",
- err, strerror(err)));
- return err;
- }
- } else if (pid > 0) { /* parent */
- child->pid = pid;
- child->read_from_child_fd = pipefd_from_child[0];
- close(pipefd_from_child[1]);
- child->write_to_child_fd = pipefd_to_child[1];
- close(pipefd_to_child[0]);
- fd_nonblocking(child->read_from_child_fd);
- fd_nonblocking(child->write_to_child_fd);
-
- } else { /* error */
- err = errno;
- DEBUG(1, ("fork failed [%d][%s].\n", err, strerror(err)));
- return err;
- }
-
- return EOK;
-}
-
-static errno_t create_tgt_req_send_buffer(TALLOC_CTX *mem_ctx,
- const char *realm_str,
- const char *princ_str,
- const char *keytab_name,
- struct io_buffer **io_buf)
-{
- struct io_buffer *buf;
- size_t rp;
-
- buf = talloc(mem_ctx, struct io_buffer);
- if (buf == NULL) {
- DEBUG(1, ("talloc failed.\n"));
- return ENOMEM;
- }
-
- buf->size = 3 * sizeof(uint32_t);
- if (realm_str) {
- buf->size += strlen(realm_str);
- }
- if (princ_str) {
- buf->size += strlen(princ_str);
- }
- if (keytab_name) {
- buf->size += strlen(keytab_name);
- }
-
- DEBUG(7, ("buffer size: %d\n", buf->size));
-
- buf->data = talloc_size(buf, buf->size);
- if (buf->data == NULL) {
- DEBUG(1, ("talloc_size failed.\n"));
- talloc_free(buf);
- return ENOMEM;
- }
-
- rp = 0;
-
- /* realm */
- if (realm_str) {
- COPY_UINT32_VALUE(&buf->data[rp], strlen(realm_str), rp);
- COPY_MEM(&buf->data[rp], realm_str, rp, strlen(realm_str));
- } else {
- COPY_UINT32_VALUE(&buf->data[rp], 0, rp);
- }
-
- /* principal */
- if (princ_str) {
- COPY_UINT32_VALUE(&buf->data[rp], strlen(princ_str), rp);
- COPY_MEM(&buf->data[rp], princ_str, rp, strlen(princ_str));
- } else {
- COPY_UINT32_VALUE(&buf->data[rp], 0, rp);
- }
-
- /* keytab */
- if (keytab_name) {
- COPY_UINT32_VALUE(&buf->data[rp], strlen(keytab_name), rp);
- COPY_MEM(&buf->data[rp], keytab_name, rp, strlen(realm_str));
- } else {
- COPY_UINT32_VALUE(&buf->data[rp], 0, rp);
- }
-
- *io_buf = buf;
- return EOK;
-}
-
-static int parse_child_response(TALLOC_CTX *mem_ctx,
- uint8_t *buf, ssize_t size,
- int *result, char **ccache)
-{
- size_t p = 0;
- uint32_t len;
- uint32_t res;
- char *ccn;
-
- /* operation result code */
- COPY_UINT32_CHECK(&res, buf + p, p, size);
-
- /* ccache name size */
- COPY_UINT32_CHECK(&len, buf + p, p, size);
-
- if ((p + len ) > size) return EINVAL;
-
- ccn = talloc_size(mem_ctx, sizeof(char) * (len + 1));
- if (ccn == NULL) {
- DEBUG(1, ("talloc_size failed.\n"));
- return ENOMEM;
- }
- memcpy(ccn, buf+p, sizeof(char) * (len + 1));
- ccn[len] = '\0';
-
- *result = res;
- *ccache = ccn;
- return EOK;
-}
-
-/* ==The-public-async-interface============================================*/
-
-struct sdap_get_tgt_state {
- struct tevent_context *ev;
- struct sdap_child *child;
- ssize_t len;
- uint8_t *buf;
-};
-
-static errno_t set_tgt_child_timeout(struct tevent_req *req,
- struct tevent_context *ev,
- int timeout);
-static void sdap_get_tgt_step(struct tevent_req *subreq);
-static void sdap_get_tgt_done(struct tevent_req *subreq);
-
-struct tevent_req *sdap_get_tgt_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- const char *realm_str,
- const char *princ_str,
- const char *keytab_name,
- int timeout)
-{
- struct tevent_req *req, *subreq;
- struct sdap_get_tgt_state *state;
- struct io_buffer *buf;
- int ret;
-
- req = tevent_req_create(mem_ctx, &state, struct sdap_get_tgt_state);
- if (!req) {
- return NULL;
- }
-
- state->ev = ev;
-
- state->child = talloc_zero(state, struct sdap_child);
- if (!state->child) {
- ret = ENOMEM;
- goto fail;
- }
-
- state->child->read_from_child_fd = -1;
- state->child->write_to_child_fd = -1;
- talloc_set_destructor((TALLOC_CTX *)state->child, sdap_child_destructor);
-
- /* prepare the data to pass to child */
- ret = create_tgt_req_send_buffer(state,
- realm_str, princ_str, keytab_name,
- &buf);
- if (ret != EOK) {
- DEBUG(1, ("create_tgt_req_send_buffer failed.\n"));
- goto fail;
- }
-
- ret = sdap_fork_child(state->child);
- if (ret != EOK) {
- DEBUG(1, ("sdap_fork_child failed.\n"));
- goto fail;
- }
-
- ret = set_tgt_child_timeout(req, ev, timeout);
- if (ret != EOK) {
- DEBUG(1, ("activate_child_timeout_handler failed.\n"));
- goto fail;
- }
-
- subreq = write_pipe_send(state, ev, buf->data, buf->size,
- state->child->write_to_child_fd);
- if (!subreq) {
- ret = ENOMEM;
- goto fail;
- }
- tevent_req_set_callback(subreq, sdap_get_tgt_step, req);
-
- return req;
-
-fail:
- tevent_req_error(req, ret);
- tevent_req_post(req, ev);
- return req;
-}
-
-static void sdap_get_tgt_step(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct sdap_get_tgt_state *state = tevent_req_data(req,
- struct sdap_get_tgt_state);
- int ret;
-
- ret = write_pipe_recv(subreq);
- talloc_zfree(subreq);
- if (ret != EOK) {
- tevent_req_error(req, ret);
- return;
- }
-
- sdap_close_fd(&state->child->write_to_child_fd);
-
- subreq = read_pipe_send(state, state->ev,
- state->child->read_from_child_fd);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, sdap_get_tgt_done, req);
-}
-
-static void sdap_get_tgt_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct sdap_get_tgt_state *state = tevent_req_data(req,
- struct sdap_get_tgt_state);
- int ret;
-
- ret = read_pipe_recv(subreq, state, &state->buf, &state->len);
- talloc_zfree(subreq);
- if (ret != EOK) {
- tevent_req_error(req, ret);
- return;
- }
-
- sdap_close_fd(&state->child->read_from_child_fd);
-
- tevent_req_done(req);
-}
-
-int sdap_get_tgt_recv(struct tevent_req *req,
- TALLOC_CTX *mem_ctx,
- int *result,
- char **ccname)
-{
- struct sdap_get_tgt_state *state = tevent_req_data(req,
- struct sdap_get_tgt_state);
- char *ccn;
- int res;
- int ret;
-
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- ret = parse_child_response(mem_ctx, state->buf, state->len, &res, &ccn);
- if (ret != EOK) {
- DEBUG(1, ("Cannot parse child response: [%d][%s]\n", ret, strerror(ret)));
- return ret;
- }
-
- DEBUG(6, ("Child responded: %d [%s]\n", res, ccn));
- *result = res;
- *ccname = ccn;
- return EOK;
-}
-
-
-
-static void get_tgt_timeout_handler(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_get_tgt_state *state = tevent_req_data(req,
- struct sdap_get_tgt_state);
- int ret;
-
- DEBUG(9, ("timeout for tgt child [%d] reached.\n", state->child->pid));
-
- ret = kill(state->child->pid, SIGKILL);
- if (ret == -1) {
- DEBUG(1, ("kill failed [%d][%s].\n", errno, strerror(errno)));
- }
-
- tevent_req_error(req, ETIMEDOUT);
-}
-
-static errno_t set_tgt_child_timeout(struct tevent_req *req,
- struct tevent_context *ev,
- int timeout)
-{
- struct tevent_timer *te;
- struct timeval tv;
-
- DEBUG(6, ("Setting %d seconds timeout for tgt child\n", timeout));
-
- tv = tevent_timeval_current_ofs(timeout, 0);
-
- te = tevent_add_timer(ev, req, tv, get_tgt_timeout_handler, req);
- if (te == NULL) {
- DEBUG(1, ("tevent_add_timer failed.\n"));
- return ENOMEM;
- }
-
- return EOK;
-}
-
-
-
-/* Setup child logging */
-int setup_child(struct sdap_id_ctx *ctx)
-{
- int ret;
- const char *mech;
- struct tevent_signal *sige;
- unsigned v;
- FILE *debug_filep;
-
- mech = dp_opt_get_string(ctx->opts->basic,
- SDAP_SASL_MECH);
- if (!mech) {
- return EOK;
- }
-
- sige = tevent_add_signal(ctx->be->ev, ctx, SIGCHLD, SA_SIGINFO,
- child_sig_handler, NULL);
- if (sige == NULL) {
- DEBUG(1, ("tevent_add_signal failed.\n"));
- return ENOMEM;
- }
-
- if (debug_to_file != 0 && ldap_child_debug_fd == -1) {
- ret = open_debug_file_ex("ldap_child", &debug_filep);
- if (ret != EOK) {
- DEBUG(0, ("Error setting up logging (%d) [%s]\n",
- ret, strerror(ret)));
- return ret;
- }
-
- ldap_child_debug_fd = fileno(debug_filep);
- if (ldap_child_debug_fd == -1) {
- DEBUG(0, ("fileno failed [%d][%s]\n", errno, strerror(errno)));
- ret = errno;
- return ret;
- }
-
- v = fcntl(ldap_child_debug_fd, F_GETFD, 0);
- fcntl(ldap_child_debug_fd, F_SETFD, v & ~FD_CLOEXEC);
- }
-
- return EOK;
-}