summaryrefslogtreecommitdiffstats
path: root/src/providers/ldap/sdap_async_enum.c
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2013-12-16 18:36:12 +0100
committerJakub Hrozek <jhrozek@redhat.com>2014-02-12 15:29:21 +0100
commit86c2e80de2243c3bd7691657086f1a182e7fc45c (patch)
tree32591bfcb63c492698d484d1ebe9102d5734a868 /src/providers/ldap/sdap_async_enum.c
parentfba393bc85e28f517aefa9c0c18608a2bf58937b (diff)
downloadsssd-86c2e80de2243c3bd7691657086f1a182e7fc45c.tar.gz
sssd-86c2e80de2243c3bd7691657086f1a182e7fc45c.tar.xz
sssd-86c2e80de2243c3bd7691657086f1a182e7fc45c.zip
LDAP: Detect the presence of POSIX attributes
When the schema is set to AD and ID mapping is not used, there is a one-time check ran when searching for users to detect the presence of POSIX attributes in LDAP. If this check fails, the search fails as if no entry was found and returns a special error code. The sdap_server_opts structure is filled every time a client connects to a server so the posix check boolean is reset to false again on connecting to the server. It might be better to move the check to where the rootDSE is retrieved, but the check depends on several features that are not known to the code that retrieves the rootDSE (or the connection code for example) such as what the attribute mappings are or the authentication method that should be used. Reviewed-by: Sumit Bose <sbose@redhat.com> Reviewed-by: Pavel Březina <pbrezina@redhat.com> (cherry picked from commit e81deec535d11912b87954c81a1edd768c1386c9)
Diffstat (limited to 'src/providers/ldap/sdap_async_enum.c')
-rw-r--r--src/providers/ldap/sdap_async_enum.c96
1 files changed, 94 insertions, 2 deletions
diff --git a/src/providers/ldap/sdap_async_enum.c b/src/providers/ldap/sdap_async_enum.c
index cbc56be20..0c20afa9d 100644
--- a/src/providers/ldap/sdap_async_enum.c
+++ b/src/providers/ldap/sdap_async_enum.c
@@ -68,6 +68,8 @@ static errno_t sdap_dom_enum_ex_retry(struct tevent_req *req,
tevent_req_fn tcb);
static bool sdap_dom_enum_ex_connected(struct tevent_req *subreq);
static void sdap_dom_enum_ex_get_users(struct tevent_req *subreq);
+static void sdap_dom_enum_ex_posix_check_done(struct tevent_req *subreq);
+static errno_t sdap_dom_enum_search_users(struct tevent_req *req);
static void sdap_dom_enum_ex_users_done(struct tevent_req *subreq);
static void sdap_dom_enum_ex_get_groups(struct tevent_req *subreq);
static void sdap_dom_enum_ex_groups_done(struct tevent_req *subreq);
@@ -178,19 +180,109 @@ static void sdap_dom_enum_ex_get_users(struct tevent_req *subreq)
struct tevent_req);
struct sdap_dom_enum_ex_state *state = tevent_req_data(req,
struct sdap_dom_enum_ex_state);
+ bool use_id_mapping;
+ errno_t ret;
if (sdap_dom_enum_ex_connected(subreq) == false) {
return;
}
+ use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(
+ state->ctx->opts->idmap_ctx,
+ state->sdom->dom->name,
+ state->sdom->dom->domain_id);
+
+ /* If POSIX attributes have been requested with an AD server and we
+ * have no idea about POSIX attributes support, run a one-time check
+ */
+ if (use_id_mapping == false &&
+ state->ctx->opts->schema_type == SDAP_SCHEMA_AD &&
+ state->ctx->srv_opts &&
+ state->ctx->srv_opts->posix_checked == false) {
+ subreq = sdap_posix_check_send(state, state->ev, state->ctx->opts,
+ sdap_id_op_handle(state->user_op),
+ state->sdom->user_search_bases,
+ dp_opt_get_int(state->ctx->opts->basic,
+ SDAP_SEARCH_TIMEOUT));
+ if (subreq == NULL) {
+ tevent_req_error(req, ENOMEM);
+ return;
+ }
+ tevent_req_set_callback(subreq,
+ sdap_dom_enum_ex_posix_check_done, req);
+ return;
+ }
+
+
+ ret = sdap_dom_enum_search_users(req);
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ return;
+ }
+ /* Execution resumes in sdap_dom_enum_ex_users_done */
+}
+
+static void sdap_dom_enum_ex_posix_check_done(struct tevent_req *subreq)
+{
+ errno_t ret;
+ bool has_posix;
+ int dp_error;
+
+ struct tevent_req *req = tevent_req_callback_data(subreq,
+ struct tevent_req);
+ struct sdap_dom_enum_ex_state *state = tevent_req_data(req,
+ struct sdap_dom_enum_ex_state);
+
+ ret = sdap_posix_check_recv(subreq, &has_posix);
+ talloc_zfree(subreq);
+ if (ret != EOK) {
+ /* We can only finish the id_op on error as the connection
+ * is re-used by the user search
+ */
+ ret = sdap_id_op_done(state->user_op, ret, &dp_error);
+ if (dp_error == DP_ERR_OK && ret != EOK) {
+ /* retry */
+ ret = sdap_dom_enum_ex_retry(req, state->user_op,
+ sdap_dom_enum_ex_get_users);
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ }
+ return;
+ }
+ }
+
+ state->ctx->srv_opts->posix_checked = true;
+
+ /* If the check ran to completion, we know for certain about the attributes
+ */
+ if (has_posix == false) {
+ tevent_req_error(req, ERR_NO_POSIX);
+ return;
+ }
+
+
+ ret = sdap_dom_enum_search_users(req);
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ return;
+ }
+ /* Execution resumes in sdap_dom_enum_ex_users_done */
+}
+
+static errno_t sdap_dom_enum_search_users(struct tevent_req *req)
+{
+ struct sdap_dom_enum_ex_state *state = tevent_req_data(req,
+ struct sdap_dom_enum_ex_state);
+ struct tevent_req *subreq;
+
subreq = enum_users_send(state, state->ev,
state->ctx, state->sdom,
state->user_op, state->purge);
if (subreq == NULL) {
- tevent_req_error(req, ENOMEM);
- return;
+ return ENOMEM;
}
tevent_req_set_callback(subreq, sdap_dom_enum_ex_users_done, req);
+ return EOK;
}
static void sdap_dom_enum_ex_users_done(struct tevent_req *subreq)