summaryrefslogtreecommitdiffstats
path: root/server/providers/ldap
diff options
context:
space:
mode:
authorSimo Sorce <ssorce@redhat.com>2009-10-29 15:02:41 -0400
committerStephen Gallagher <sgallagh@redhat.com>2009-10-29 16:05:13 -0400
commit44685ff64447b7ad87c75aec478e5f21bd50b4b7 (patch)
treeb0c8b4e0054de890c006b0ad2486c99adbcc7b1c /server/providers/ldap
parentb79b1228de615c860df841670c9a882ca748f63a (diff)
downloadsssd-44685ff64447b7ad87c75aec478e5f21bd50b4b7.tar.gz
sssd-44685ff64447b7ad87c75aec478e5f21bd50b4b7.tar.xz
sssd-44685ff64447b7ad87c75aec478e5f21bd50b4b7.zip
Add support to get rootDSE from the LDAP server.
Also fic sdap_get_generic_send() to be a bit more "generic" :-) Also figs bugs within it. This patch allow us 2 good things. A) we check that the server effectively supports GSSAPI auth before we try to use it. B) against IPA it substantially cuts delays when the server is offline because it uses a 5 second async timeout on the connection and doesn't try to do a slow synchronous kinit+sasl_bind if the server is not even available.
Diffstat (limited to 'server/providers/ldap')
-rw-r--r--server/providers/ldap/ldap_common.h3
-rw-r--r--server/providers/ldap/ldap_id.c40
-rw-r--r--server/providers/ldap/sdap.c40
-rw-r--r--server/providers/ldap/sdap.h3
-rw-r--r--server/providers/ldap/sdap_async.c407
-rw-r--r--server/providers/ldap/sdap_async.h26
6 files changed, 398 insertions, 121 deletions
diff --git a/server/providers/ldap/ldap_common.h b/server/providers/ldap/ldap_common.h
index a6e77e901..c9d857860 100644
--- a/server/providers/ldap/ldap_common.h
+++ b/server/providers/ldap/ldap_common.h
@@ -30,6 +30,9 @@ struct sdap_id_ctx {
struct sdap_options *opts;
+ /* what rootDSE returns */
+ struct sysdb_attrs *rootDSE;
+
/* global sdap handler */
struct sdap_handle *gsh;
diff --git a/server/providers/ldap/ldap_id.c b/server/providers/ldap/ldap_id.c
index 9fd0d4f18..7e69c3dc6 100644
--- a/server/providers/ldap/ldap_id.c
+++ b/server/providers/ldap/ldap_id.c
@@ -147,7 +147,7 @@ static struct tevent_req *users_get_send(TALLOC_CTX *memctx,
/* FIXME: add option to decide if tls should be used
* or SASL/GSSAPI, etc ... */
- subreq = sdap_cli_connect_send(state, ev, ctx->opts);
+ subreq = sdap_cli_connect_send(state, ev, ctx->opts, &ctx->rootDSE);
if (!subreq) {
ret = ENOMEM;
goto fail;
@@ -185,9 +185,13 @@ static void users_get_connect_done(struct tevent_req *subreq)
struct users_get_state);
int ret;
- ret = sdap_cli_connect_recv(subreq, state->ctx, &state->ctx->gsh);
+ 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;
}
@@ -314,7 +318,7 @@ static struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
/* FIXME: add option to decide if tls should be used
* or SASL/GSSAPI, etc ... */
- subreq = sdap_cli_connect_send(state, ev, ctx->opts);
+ subreq = sdap_cli_connect_send(state, ev, ctx->opts, &ctx->rootDSE);
if (!subreq) {
ret = ENOMEM;
goto fail;
@@ -352,9 +356,13 @@ static void groups_get_connect_done(struct tevent_req *subreq)
struct groups_get_state);
int ret;
- ret = sdap_cli_connect_recv(subreq, state->ctx, &state->ctx->gsh);
+ 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;
}
@@ -456,7 +464,7 @@ static struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx,
/* FIXME: add option to decide if tls should be used
* or SASL/GSSAPI, etc ... */
- subreq = sdap_cli_connect_send(state, ev, ctx->opts);
+ subreq = sdap_cli_connect_send(state, ev, ctx->opts, &ctx->rootDSE);
if (!subreq) {
ret = ENOMEM;
goto fail;
@@ -494,9 +502,13 @@ static void groups_by_user_connect_done(struct tevent_req *subreq)
struct groups_by_user_state);
int ret;
- ret = sdap_cli_connect_recv(subreq, state->ctx, &state->ctx->gsh);
+ 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;
}
@@ -912,7 +924,7 @@ static struct tevent_req *enum_users_send(TALLOC_CTX *memctx,
/* FIXME: add option to decide if tls should be used
* or SASL/GSSAPI, etc ... */
- subreq = sdap_cli_connect_send(state, ev, ctx->opts);
+ subreq = sdap_cli_connect_send(state, ev, ctx->opts, &ctx->rootDSE);
if (!subreq) {
ret = ENOMEM;
goto fail;
@@ -951,9 +963,13 @@ static void enum_users_connect_done(struct tevent_req *subreq)
struct enum_users_state);
int ret;
- ret = sdap_cli_connect_recv(subreq, state->ctx, &state->ctx->gsh);
+ 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;
}
@@ -1059,7 +1075,7 @@ static struct tevent_req *enum_groups_send(TALLOC_CTX *memctx,
/* FIXME: add option to decide if tls should be used
* or SASL/GSSAPI, etc ... */
- subreq = sdap_cli_connect_send(state, ev, ctx->opts);
+ subreq = sdap_cli_connect_send(state, ev, ctx->opts, &ctx->rootDSE);
if (!subreq) {
ret = ENOMEM;
goto fail;
@@ -1097,9 +1113,13 @@ static void enum_groups_connect_done(struct tevent_req *subreq)
struct enum_groups_state);
int ret;
- ret = sdap_cli_connect_recv(subreq, state->ctx, &state->ctx->gsh);
+ 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;
}
diff --git a/server/providers/ldap/sdap.c b/server/providers/ldap/sdap.c
index 926869259..d0ea9ffd9 100644
--- a/server/providers/ldap/sdap.c
+++ b/server/providers/ldap/sdap.c
@@ -192,9 +192,9 @@ fail:
}
int sdap_parse_generic_entry(TALLOC_CTX *memctx,
- struct sdap_handle *sh,
- struct sdap_msg *sm,
- struct sysdb_attrs **_attrs)
+ struct sdap_handle *sh,
+ struct sdap_msg *sm,
+ struct sysdb_attrs **_attrs)
{
struct sysdb_attrs *attrs;
BerElement *ber = NULL;
@@ -386,3 +386,37 @@ errno_t setup_tls_config(struct dp_option *basic_opts)
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;
+
+ 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;
+}
+
+
diff --git a/server/providers/ldap/sdap.h b/server/providers/ldap/sdap.h
index f4e5aac31..152d46b9f 100644
--- a/server/providers/ldap/sdap.h
+++ b/server/providers/ldap/sdap.h
@@ -215,4 +215,7 @@ int sdap_get_msg_dn(TALLOC_CTX *memctx, struct sdap_handle *sh,
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);
+
#endif /* _SDAP_H_ */
diff --git a/server/providers/ldap/sdap_async.c b/server/providers/ldap/sdap_async.c
index 28e4fa4f1..ae6806f43 100644
--- a/server/providers/ldap/sdap_async.c
+++ b/server/providers/ldap/sdap_async.c
@@ -2276,7 +2276,6 @@ static void sdap_get_users_transaction(struct tevent_req *subreq)
}
DEBUG(8, ("ldap_search_ext called, msgid = %d\n", msgid));
- /* FIXME: get timeouts from configuration, for now 10 minutes */
ret = sdap_op_add(state, state->ev, state->sh, msgid,
sdap_get_users_done, req,
dp_opt_get_int(state->opts->basic,
@@ -3233,22 +3232,127 @@ int sdap_exop_modify_passwd_recv(struct tevent_req *req,
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);
+ 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);
+}
+
+static 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);
+ enum tevent_req_state tstate;
+ uint64_t err;
+
+ if (tevent_req_is_error(req, &tstate, &err)) {
+ if (err) return err;
+ return EIO;
+ }
+
+ *rootdse = talloc_steal(memctx, state->rootdse);
+
+ return EOK;
+}
+
/* ==Client connect============================================ */
struct sdap_cli_connect_state {
struct tevent_context *ev;
struct sdap_options *opts;
+ struct sysdb_attrs *rootdse;
+ bool use_rootdse;
struct sdap_handle *sh;
};
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_bind_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 sdap_options *opts,
+ struct sysdb_attrs **rootdse)
{
struct tevent_req *req, *subreq;
struct sdap_cli_connect_state *state;
@@ -3258,6 +3362,13 @@ struct tevent_req *sdap_cli_connect_send(TALLOC_CTX *memctx,
state->ev = ev;
state->opts = opts;
+ if (rootdse) {
+ state->use_rootdse = true;
+ state->rootdse = *rootdse;
+ } else {
+ state->use_rootdse = false;
+ state->rootdse = NULL;
+ }
subreq = sdap_connect_send(state, ev, opts,
dp_opt_get_bool(opts->basic, SDAP_ID_TLS));
@@ -3275,7 +3386,7 @@ 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);
+ struct sdap_cli_connect_state);
const char *sasl_mech;
int ret;
@@ -3286,50 +3397,120 @@ static void sdap_cli_connect_done(struct tevent_req *subreq)
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 (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)) {
- subreq = sdap_kinit_send(state, state->ev, state->sh,
- 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);
+ sdap_cli_kinit_step(req);
return;
}
}
- subreq = sdap_auth_send(state,
- state->ev,
- state->sh,
- 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));
+ 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;
+ int ret;
+
+ 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_bind_done, req);
+ 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;
+ ret = sdap_install_ldap_callbacks(state->sh, state->ev);
+ if (ret) {
+ tevent_req_error(req, ret);
+ }
+ }
}
-static void sdap_cli_kinit_done(struct tevent_req *subreq)
+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);
+ 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 (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_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;
@@ -3344,6 +3525,15 @@ static void sdap_cli_kinit_done(struct tevent_req *subreq)
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,
@@ -3361,10 +3551,10 @@ static void sdap_cli_kinit_done(struct tevent_req *subreq)
tevent_req_error(req, ENOMEM);
return;
}
- tevent_req_set_callback(subreq, sdap_cli_bind_done, req);
+ tevent_req_set_callback(subreq, sdap_cli_auth_done, req);
}
-static void sdap_cli_bind_done(struct tevent_req *subreq)
+static void sdap_cli_auth_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(subreq,
struct tevent_req);
@@ -3385,11 +3575,13 @@ static void sdap_cli_bind_done(struct tevent_req *subreq)
tevent_req_done(req);
}
-int sdap_cli_connect_recv(struct tevent_req *req, TALLOC_CTX *memctx,
- struct sdap_handle **gsh)
+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);
+ struct sdap_cli_connect_state);
enum tevent_req_state tstate;
uint64_t err;
@@ -3398,10 +3590,28 @@ int sdap_cli_connect_recv(struct tevent_req *req, TALLOC_CTX *memctx,
return EIO;
}
- *gsh = talloc_steal(memctx, state->sh);
- if (!*gsh) {
- return ENOMEM;
+ 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;
}
@@ -3411,35 +3621,33 @@ struct sdap_get_generic_state {
struct tevent_context *ev;
struct sdap_options *opts;
struct sdap_handle *sh;
- struct sss_domain_info *dom;
- const char **attrs;
- const char *filter;
const char *search_base;
- struct sysdb_attrs **reply;
- size_t reply_max;
- size_t reply_count;
+ int scope;
+ const char *filter;
+ const char **attrs;
- struct sysdb_handle *handle;
struct sdap_op *op;
+
+ size_t reply_max;
+ size_t reply_count;
+ struct sysdb_attrs **reply;
};
-static errno_t add_to_reply(TALLOC_CTX *memctx,
- struct sdap_get_generic_state *state,
+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 sdap_msg *reply,
+ int error, void *pvt);
struct tevent_req *sdap_get_generic_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,
- const char *search_base)
+ 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 tevent_req *req = NULL;
struct sdap_get_generic_state *state = NULL;
@@ -3452,29 +3660,30 @@ struct tevent_req *sdap_get_generic_send(TALLOC_CTX *memctx,
state->ev = ev;
state->opts = opts;
- state->dom = dom;
state->sh = sh;
+ state->search_base = search_base;
+ state->scope = scope;
state->filter = filter;
state->attrs = attrs;
- state->search_base = search_base;
- state->reply = NULL;
+ state->op = NULL;
state->reply_max = 0;
state->reply_count = 0;
- state->op = NULL;
- state->handle = NULL;
+ state->reply = NULL;
DEBUG(7, ("calling ldap_search_ext with [%s][%s].\n", state->filter,
state->search_base));
if (debug_level >= 7) {
int i;
- for (i = 0; state->attrs[i]; i++) {
- DEBUG(7, ("Requesting attrs: [%s]\n", state->attrs[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,
- LDAP_SCOPE_SUBTREE, state->filter,
+ state->scope, state->filter,
discard_const(state->attrs),
false, NULL, NULL, NULL, 0, &msgid);
if (lret != LDAP_SUCCESS) {
@@ -3486,7 +3695,8 @@ struct tevent_req *sdap_get_generic_send(TALLOC_CTX *memctx,
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),
+ dp_opt_get_int(state->opts->basic,
+ SDAP_SEARCH_TIMEOUT),
&state->op);
if (ret != EOK) {
DEBUG(1, ("Failed to set up operation!\n"));
@@ -3509,8 +3719,10 @@ static void sdap_get_generic_done(struct sdap_op *op,
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);
- int ret;
struct sysdb_attrs *attrs;
+ char *errmsg;
+ int result;
+ int ret;
if (error) {
tevent_req_error(req, error);
@@ -3534,7 +3746,7 @@ static void sdap_get_generic_done(struct sdap_op *op,
return;
}
- ret = add_to_reply(state, state, attrs);
+ ret = add_to_reply(state, attrs);
if (ret != EOK) {
DEBUG(1, ("add_to_reply failed.\n"));
tevent_req_error(req, ret);
@@ -3543,18 +3755,46 @@ static void sdap_get_generic_done(struct sdap_op *op,
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(3, ("Search result: %s(%d), %s\n",
+ ldap_err2string(result), result, errmsg));
+
tevent_req_done(req);
return;
- break;
default:
/* what is going on here !? */
tevent_req_error(req, EIO);
return;
}
+}
- 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,
@@ -3566,7 +3806,6 @@ int sdap_get_generic_recv(struct tevent_req *req,
struct sdap_get_generic_state);
enum tevent_req_state tstate;
uint64_t err;
- int i;
if (tevent_req_is_error(req, &tstate, &err)) {
if (err) return err;
@@ -3575,31 +3814,7 @@ int sdap_get_generic_recv(struct tevent_req *req,
*reply_count = state->reply_count;
*reply = talloc_steal(mem_ctx, state->reply);
- for (i = 0; i < state->reply_count; i++) {
- talloc_steal(mem_ctx, state->reply[i]);
- }
return EOK;
}
-static errno_t add_to_reply(TALLOC_CTX *memctx,
- struct sdap_get_generic_state *state,
- struct sysdb_attrs *msg)
-{
- struct sysdb_attrs **dummy;
-
- if (state->reply == NULL || state->reply_max == state->reply_count) {
- state->reply_max += REPLY_REALLOC_INCREMENT;
- dummy = talloc_realloc(memctx, state->reply, struct sysdb_attrs *,
- state->reply_max);
- if (dummy == NULL) {
- DEBUG(1, ("talloc_realloc failed.\n"));
- return ENOMEM;
- }
- state->reply = dummy;
- }
-
- state->reply[state->reply_count++] = talloc_steal(state->reply, msg);
-
- return EOK;
-}
diff --git a/server/providers/ldap/sdap_async.h b/server/providers/ldap/sdap_async.h
index 8410f3d1a..911933a72 100644
--- a/server/providers/ldap/sdap_async.h
+++ b/server/providers/ldap/sdap_async.h
@@ -91,20 +91,22 @@ struct tevent_req *sdap_exop_modify_passwd_send(TALLOC_CTX *memctx,
int sdap_exop_modify_passwd_recv(struct tevent_req *req, enum sdap_result *result);
struct tevent_req *sdap_cli_connect_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_options *opts);
-int sdap_cli_connect_recv(struct tevent_req *req, TALLOC_CTX *memctx,
- struct sdap_handle **gsh);
+ struct tevent_context *ev,
+ struct sdap_options *opts,
+ 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 sss_domain_info *dom,
- struct sysdb_ctx *sysdb,
- struct sdap_options *opts,
- struct sdap_handle *sh,
- const char **attrs,
- const char *filter,
- const char *search_base);
+ struct tevent_context *ev,
+ struct sdap_options *opts,
+ struct sdap_handle *sh,
+ const char *search_base,
+ int scope,
+ const char *filter,
+ const char **attrs);
int sdap_get_generic_recv(struct tevent_req *req,
TALLOC_CTX *mem_ctx, size_t *reply_count,
struct sysdb_attrs ***reply_list);