|
|
2fc102 |
From 3b0d429051648a1545de528ec760c4823088a1d9 Mon Sep 17 00:00:00 2001
|
|
|
2fc102 |
From: Jakub Hrozek <jhrozek@redhat.com>
|
|
|
2fc102 |
Date: Mon, 16 Dec 2013 18:36:12 +0100
|
|
|
2fc102 |
Subject: [PATCH 81/84] LDAP: Detect the presence of POSIX attributes
|
|
|
2fc102 |
MIME-Version: 1.0
|
|
|
2fc102 |
Content-Type: text/plain; charset=UTF-8
|
|
|
2fc102 |
Content-Transfer-Encoding: 8bit
|
|
|
2fc102 |
|
|
|
2fc102 |
When the schema is set to AD and ID mapping is not used, there is a one-time
|
|
|
2fc102 |
check ran when searching for users to detect the presence of POSIX
|
|
|
2fc102 |
attributes in LDAP. If this check fails, the search fails as if no entry
|
|
|
2fc102 |
was found and returns a special error code.
|
|
|
2fc102 |
|
|
|
2fc102 |
The sdap_server_opts structure is filled every time a client connects to
|
|
|
2fc102 |
a server so the posix check boolean is reset to false again on connecting
|
|
|
2fc102 |
to the server.
|
|
|
2fc102 |
|
|
|
2fc102 |
It might be better to move the check to where the rootDSE is retrieved,
|
|
|
2fc102 |
but the check depends on several features that are not known to the code
|
|
|
2fc102 |
that retrieves the rootDSE (or the connection code for example) such as what
|
|
|
2fc102 |
the attribute mappings are or the authentication method that should be used.
|
|
|
2fc102 |
|
|
|
2fc102 |
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
|
|
2fc102 |
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
|
|
2fc102 |
(cherry picked from commit e81deec535d11912b87954c81a1edd768c1386c9)
|
|
|
2fc102 |
---
|
|
|
2fc102 |
src/providers/ad/ad_id.c | 50 ++++++++-
|
|
|
2fc102 |
src/providers/ad/ad_id.h | 1 +
|
|
|
2fc102 |
src/providers/ipa/ipa_subdomains_id.c | 2 +-
|
|
|
2fc102 |
src/providers/ldap/ldap_id.c | 158 +++++++++++++++++++++++++--
|
|
|
2fc102 |
src/providers/ldap/sdap.h | 1 +
|
|
|
2fc102 |
src/providers/ldap/sdap_async.c | 200 ++++++++++++++++++++++++++++++++++
|
|
|
2fc102 |
src/providers/ldap/sdap_async.h | 9 ++
|
|
|
2fc102 |
src/providers/ldap/sdap_async_enum.c | 96 +++++++++++++++-
|
|
|
2fc102 |
src/util/util_errors.c | 1 +
|
|
|
2fc102 |
src/util/util_errors.h | 1 +
|
|
|
2fc102 |
10 files changed, 504 insertions(+), 15 deletions(-)
|
|
|
2fc102 |
|
|
|
2fc102 |
diff --git a/src/providers/ad/ad_id.c b/src/providers/ad/ad_id.c
|
|
|
2fc102 |
index e3302c15774ab1c24b16cefc274313e447b31e5c..bfae86284355b6c13547aac55b7273133bde851d 100644
|
|
|
2fc102 |
--- a/src/providers/ad/ad_id.c
|
|
|
2fc102 |
+++ b/src/providers/ad/ad_id.c
|
|
|
2fc102 |
@@ -27,6 +27,28 @@
|
|
|
2fc102 |
#include "providers/ldap/sdap_async_enum.h"
|
|
|
2fc102 |
#include "providers/ldap/sdap_idmap.h"
|
|
|
2fc102 |
|
|
|
2fc102 |
+static void
|
|
|
2fc102 |
+disable_gc(struct ad_options *ad_options)
|
|
|
2fc102 |
+{
|
|
|
2fc102 |
+ errno_t ret;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ if (dp_opt_get_bool(ad_options->basic, AD_ENABLE_GC) == false) {
|
|
|
2fc102 |
+ return;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ DEBUG(SSSDBG_IMPORTANT_INFO, ("POSIX attributes were requested "
|
|
|
2fc102 |
+ "but are not present on the server side. Global Catalog "
|
|
|
2fc102 |
+ "lookups will be disabled\n"));
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ ret = dp_opt_set_bool(ad_options->basic,
|
|
|
2fc102 |
+ AD_ENABLE_GC, false);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_MINOR_FAILURE,
|
|
|
2fc102 |
+ ("Could not turn off GC support\n"));
|
|
|
2fc102 |
+ /* Not fatal */
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+}
|
|
|
2fc102 |
+
|
|
|
2fc102 |
struct ad_handle_acct_info_state {
|
|
|
2fc102 |
struct be_req *breq;
|
|
|
2fc102 |
struct be_acct_req *ar;
|
|
|
2fc102 |
@@ -34,6 +56,7 @@ struct ad_handle_acct_info_state {
|
|
|
2fc102 |
struct sdap_id_conn_ctx **conn;
|
|
|
2fc102 |
struct sdap_domain *sdom;
|
|
|
2fc102 |
size_t cindex;
|
|
|
2fc102 |
+ struct ad_options *ad_options;
|
|
|
2fc102 |
|
|
|
2fc102 |
int dp_error;
|
|
|
2fc102 |
const char *err;
|
|
|
2fc102 |
@@ -47,6 +70,7 @@ ad_handle_acct_info_send(TALLOC_CTX *mem_ctx,
|
|
|
2fc102 |
struct be_req *breq,
|
|
|
2fc102 |
struct be_acct_req *ar,
|
|
|
2fc102 |
struct sdap_id_ctx *ctx,
|
|
|
2fc102 |
+ struct ad_options *ad_options,
|
|
|
2fc102 |
struct sdap_domain *sdom,
|
|
|
2fc102 |
struct sdap_id_conn_ctx **conn)
|
|
|
2fc102 |
{
|
|
|
2fc102 |
@@ -64,6 +88,7 @@ ad_handle_acct_info_send(TALLOC_CTX *mem_ctx,
|
|
|
2fc102 |
state->ctx = ctx;
|
|
|
2fc102 |
state->sdom = sdom;
|
|
|
2fc102 |
state->conn = conn;
|
|
|
2fc102 |
+ state->ad_options = ad_options;
|
|
|
2fc102 |
state->cindex = 0;
|
|
|
2fc102 |
|
|
|
2fc102 |
ret = ad_handle_acct_info_step(req);
|
|
|
2fc102 |
@@ -137,12 +162,14 @@ ad_handle_acct_info_done(struct tevent_req *subreq)
|
|
|
2fc102 |
if (sdap_err == EOK) {
|
|
|
2fc102 |
tevent_req_done(req);
|
|
|
2fc102 |
return;
|
|
|
2fc102 |
+ } else if (sdap_err == ERR_NO_POSIX) {
|
|
|
2fc102 |
+ disable_gc(state->ad_options);
|
|
|
2fc102 |
} else if (sdap_err != ENOENT) {
|
|
|
2fc102 |
tevent_req_error(req, EIO);
|
|
|
2fc102 |
return;
|
|
|
2fc102 |
}
|
|
|
2fc102 |
|
|
|
2fc102 |
- /* Ret is only ENOENT now. Try the next connection */
|
|
|
2fc102 |
+ /* Ret is only ENOENT or ERR_NO_POSIX now. Try the next connection */
|
|
|
2fc102 |
state->cindex++;
|
|
|
2fc102 |
ret = ad_handle_acct_info_step(req);
|
|
|
2fc102 |
if (ret != EAGAIN) {
|
|
|
2fc102 |
@@ -356,7 +383,7 @@ ad_account_info_handler(struct be_req *be_req)
|
|
|
2fc102 |
}
|
|
|
2fc102 |
|
|
|
2fc102 |
req = ad_handle_acct_info_send(be_req, be_req, ar, sdap_id_ctx,
|
|
|
2fc102 |
- sdom, clist);
|
|
|
2fc102 |
+ ad_ctx->ad_options, sdom, clist);
|
|
|
2fc102 |
if (req == NULL) {
|
|
|
2fc102 |
ret = ENOMEM;
|
|
|
2fc102 |
goto fail;
|
|
|
2fc102 |
@@ -611,9 +638,24 @@ ad_enumeration_done(struct tevent_req *subreq)
|
|
|
2fc102 |
|
|
|
2fc102 |
ret = sdap_dom_enum_ex_recv(subreq);
|
|
|
2fc102 |
talloc_zfree(subreq);
|
|
|
2fc102 |
- if (ret != EOK) {
|
|
|
2fc102 |
+ if (ret == ERR_NO_POSIX) {
|
|
|
2fc102 |
+ /* Retry enumerating the same domain again, this time w/o
|
|
|
2fc102 |
+ * connecting to GC
|
|
|
2fc102 |
+ */
|
|
|
2fc102 |
+ disable_gc(state->id_ctx->ad_options);
|
|
|
2fc102 |
+ ret = ad_enum_sdom(req, state->sditer, state->id_ctx);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
2fc102 |
+ ("Could not retry domain %s\n", state->sditer->dom->name));
|
|
|
2fc102 |
+ tevent_req_error(req, ret);
|
|
|
2fc102 |
+ return;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ /* Execution will resume in ad_enumeration_done */
|
|
|
2fc102 |
+ return;
|
|
|
2fc102 |
+ } else if (ret != EOK) {
|
|
|
2fc102 |
DEBUG(SSSDBG_OP_FAILURE,
|
|
|
2fc102 |
- ("Could not enumerate domain %s\n", state->sdom->dom->name));
|
|
|
2fc102 |
+ ("Could not enumerate domain %s\n", state->sditer->dom->name));
|
|
|
2fc102 |
tevent_req_error(req, ret);
|
|
|
2fc102 |
return;
|
|
|
2fc102 |
}
|
|
|
2fc102 |
diff --git a/src/providers/ad/ad_id.h b/src/providers/ad/ad_id.h
|
|
|
2fc102 |
index 74b85645c2d6458617a4064fe3fb3f99696c3741..9eb0ac3754be2fd687ed2257b91854f5fceb82a2 100644
|
|
|
2fc102 |
--- a/src/providers/ad/ad_id.h
|
|
|
2fc102 |
+++ b/src/providers/ad/ad_id.h
|
|
|
2fc102 |
@@ -31,6 +31,7 @@ ad_handle_acct_info_send(TALLOC_CTX *mem_ctx,
|
|
|
2fc102 |
struct be_req *breq,
|
|
|
2fc102 |
struct be_acct_req *ar,
|
|
|
2fc102 |
struct sdap_id_ctx *ctx,
|
|
|
2fc102 |
+ struct ad_options *ad_options,
|
|
|
2fc102 |
struct sdap_domain *sdom,
|
|
|
2fc102 |
struct sdap_id_conn_ctx **conn);
|
|
|
2fc102 |
errno_t
|
|
|
2fc102 |
diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c
|
|
|
2fc102 |
index fb1ad896885866dd9c34f9db960e09d92763f86d..b61c6a5f4d7605f0cdfa182bbc933d35c4613a79 100644
|
|
|
2fc102 |
--- a/src/providers/ipa/ipa_subdomains_id.c
|
|
|
2fc102 |
+++ b/src/providers/ipa/ipa_subdomains_id.c
|
|
|
2fc102 |
@@ -323,7 +323,7 @@ ipa_get_ad_acct_send(TALLOC_CTX *mem_ctx,
|
|
|
2fc102 |
}
|
|
|
2fc102 |
|
|
|
2fc102 |
subreq = ad_handle_acct_info_send(req, be_req, ar, sdap_id_ctx,
|
|
|
2fc102 |
- sdom, clist);
|
|
|
2fc102 |
+ ad_id_ctx->ad_options, sdom, clist);
|
|
|
2fc102 |
if (subreq == NULL) {
|
|
|
2fc102 |
ret = ENOMEM;
|
|
|
2fc102 |
goto fail;
|
|
|
2fc102 |
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
|
|
|
2fc102 |
index e36c1f697c18e865a47d991dad103fc440456118..b948ba9f358af994bdbbb99a468f7dbe66e65c1d 100644
|
|
|
2fc102 |
--- a/src/providers/ldap/ldap_id.c
|
|
|
2fc102 |
+++ b/src/providers/ldap/ldap_id.c
|
|
|
2fc102 |
@@ -50,6 +50,7 @@ struct users_get_state {
|
|
|
2fc102 |
|
|
|
2fc102 |
char *filter;
|
|
|
2fc102 |
const char **attrs;
|
|
|
2fc102 |
+ bool use_id_mapping;
|
|
|
2fc102 |
|
|
|
2fc102 |
int dp_error;
|
|
|
2fc102 |
int sdap_ret;
|
|
|
2fc102 |
@@ -58,6 +59,8 @@ struct users_get_state {
|
|
|
2fc102 |
|
|
|
2fc102 |
static int users_get_retry(struct tevent_req *req);
|
|
|
2fc102 |
static void users_get_connect_done(struct tevent_req *subreq);
|
|
|
2fc102 |
+static void users_get_posix_check_done(struct tevent_req *subreq);
|
|
|
2fc102 |
+static void users_get_search(struct tevent_req *req);
|
|
|
2fc102 |
static void users_get_done(struct tevent_req *subreq);
|
|
|
2fc102 |
|
|
|
2fc102 |
struct tevent_req *users_get_send(TALLOC_CTX *memctx,
|
|
|
2fc102 |
@@ -79,7 +82,6 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx,
|
|
|
2fc102 |
uid_t uid;
|
|
|
2fc102 |
enum idmap_error_code err;
|
|
|
2fc102 |
char *sid;
|
|
|
2fc102 |
- bool use_id_mapping;
|
|
|
2fc102 |
|
|
|
2fc102 |
req = tevent_req_create(memctx, &state, struct users_get_state);
|
|
|
2fc102 |
if (!req) return NULL;
|
|
|
2fc102 |
@@ -103,7 +105,7 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx,
|
|
|
2fc102 |
state->name = name;
|
|
|
2fc102 |
state->filter_type = filter_type;
|
|
|
2fc102 |
|
|
|
2fc102 |
- use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(
|
|
|
2fc102 |
+ state->use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(
|
|
|
2fc102 |
ctx->opts->idmap_ctx,
|
|
|
2fc102 |
sdom->dom->name,
|
|
|
2fc102 |
sdom->dom->domain_id);
|
|
|
2fc102 |
@@ -116,7 +118,7 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx,
|
|
|
2fc102 |
}
|
|
|
2fc102 |
break;
|
|
|
2fc102 |
case BE_FILTER_IDNUM:
|
|
|
2fc102 |
- if (use_id_mapping) {
|
|
|
2fc102 |
+ if (state->use_id_mapping) {
|
|
|
2fc102 |
/* If we're ID-mapping, we need to use the objectSID
|
|
|
2fc102 |
* in the search filter.
|
|
|
2fc102 |
*/
|
|
|
2fc102 |
@@ -184,7 +186,7 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx,
|
|
|
2fc102 |
goto fail;
|
|
|
2fc102 |
}
|
|
|
2fc102 |
|
|
|
2fc102 |
- if (use_id_mapping || filter_type == BE_FILTER_SECID) {
|
|
|
2fc102 |
+ if (state->use_id_mapping || filter_type == BE_FILTER_SECID) {
|
|
|
2fc102 |
/* When mapping IDs or looking for SIDs, we don't want to limit
|
|
|
2fc102 |
* ourselves to users with a UID value. But there must be a SID to map
|
|
|
2fc102 |
* from.
|
|
|
2fc102 |
@@ -269,6 +271,75 @@ static void users_get_connect_done(struct tevent_req *subreq)
|
|
|
2fc102 |
return;
|
|
|
2fc102 |
}
|
|
|
2fc102 |
|
|
|
2fc102 |
+ /* If POSIX attributes have been requested with an AD server and we
|
|
|
2fc102 |
+ * have no idea about POSIX attributes support, run a one-time check
|
|
|
2fc102 |
+ */
|
|
|
2fc102 |
+ if (state->use_id_mapping == false &&
|
|
|
2fc102 |
+ state->ctx->opts->schema_type == SDAP_SCHEMA_AD &&
|
|
|
2fc102 |
+ state->ctx->srv_opts &&
|
|
|
2fc102 |
+ state->ctx->srv_opts->posix_checked == false) {
|
|
|
2fc102 |
+ subreq = sdap_posix_check_send(state, state->ev, state->ctx->opts,
|
|
|
2fc102 |
+ sdap_id_op_handle(state->op),
|
|
|
2fc102 |
+ state->sdom->user_search_bases,
|
|
|
2fc102 |
+ dp_opt_get_int(state->ctx->opts->basic,
|
|
|
2fc102 |
+ SDAP_SEARCH_TIMEOUT));
|
|
|
2fc102 |
+ if (subreq == NULL) {
|
|
|
2fc102 |
+ tevent_req_error(req, ENOMEM);
|
|
|
2fc102 |
+ return;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ tevent_req_set_callback(subreq, users_get_posix_check_done, req);
|
|
|
2fc102 |
+ return;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ users_get_search(req);
|
|
|
2fc102 |
+}
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+static void users_get_posix_check_done(struct tevent_req *subreq)
|
|
|
2fc102 |
+{
|
|
|
2fc102 |
+ errno_t ret;
|
|
|
2fc102 |
+ bool has_posix;
|
|
|
2fc102 |
+ int dp_error;
|
|
|
2fc102 |
+ struct tevent_req *req = tevent_req_callback_data(subreq,
|
|
|
2fc102 |
+ struct tevent_req);
|
|
|
2fc102 |
+ struct users_get_state *state = tevent_req_data(req,
|
|
|
2fc102 |
+ struct users_get_state);
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ ret = sdap_posix_check_recv(subreq, &has_posix);
|
|
|
2fc102 |
+ talloc_zfree(subreq);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ /* We can only finish the id_op on error as the connection
|
|
|
2fc102 |
+ * is re-used by the user search
|
|
|
2fc102 |
+ */
|
|
|
2fc102 |
+ ret = sdap_id_op_done(state->op, ret, &dp_error);
|
|
|
2fc102 |
+ if (dp_error == DP_ERR_OK && ret != EOK) {
|
|
|
2fc102 |
+ /* retry */
|
|
|
2fc102 |
+ ret = users_get_retry(req);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ tevent_req_error(req, ret);
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ return;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ state->ctx->srv_opts->posix_checked = true;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ /* If the check ran to completion, we know for certain about the attributes
|
|
|
2fc102 |
+ */
|
|
|
2fc102 |
+ if (has_posix == false) {
|
|
|
2fc102 |
+ state->sdap_ret = ERR_NO_POSIX;
|
|
|
2fc102 |
+ tevent_req_done(req);
|
|
|
2fc102 |
+ return;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ users_get_search(req);
|
|
|
2fc102 |
+}
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+static void users_get_search(struct tevent_req *req)
|
|
|
2fc102 |
+{
|
|
|
2fc102 |
+ struct users_get_state *state = tevent_req_data(req,
|
|
|
2fc102 |
+ struct users_get_state);
|
|
|
2fc102 |
+ struct tevent_req *subreq;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
subreq = sdap_get_users_send(state, state->ev,
|
|
|
2fc102 |
state->domain, state->sysdb,
|
|
|
2fc102 |
state->ctx->opts,
|
|
|
2fc102 |
@@ -434,6 +505,7 @@ struct groups_get_state {
|
|
|
2fc102 |
|
|
|
2fc102 |
char *filter;
|
|
|
2fc102 |
const char **attrs;
|
|
|
2fc102 |
+ bool use_id_mapping;
|
|
|
2fc102 |
|
|
|
2fc102 |
int dp_error;
|
|
|
2fc102 |
int sdap_ret;
|
|
|
2fc102 |
@@ -442,6 +514,8 @@ struct groups_get_state {
|
|
|
2fc102 |
|
|
|
2fc102 |
static int groups_get_retry(struct tevent_req *req);
|
|
|
2fc102 |
static void groups_get_connect_done(struct tevent_req *subreq);
|
|
|
2fc102 |
+static void groups_get_posix_check_done(struct tevent_req *subreq);
|
|
|
2fc102 |
+static void groups_get_search(struct tevent_req *req);
|
|
|
2fc102 |
static void groups_get_done(struct tevent_req *subreq);
|
|
|
2fc102 |
|
|
|
2fc102 |
struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
|
|
|
2fc102 |
@@ -463,7 +537,6 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
|
|
|
2fc102 |
gid_t gid;
|
|
|
2fc102 |
enum idmap_error_code err;
|
|
|
2fc102 |
char *sid;
|
|
|
2fc102 |
- bool use_id_mapping;
|
|
|
2fc102 |
const char *member_filter[2];
|
|
|
2fc102 |
|
|
|
2fc102 |
req = tevent_req_create(memctx, &state, struct groups_get_state);
|
|
|
2fc102 |
@@ -488,7 +561,7 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
|
|
|
2fc102 |
state->name = name;
|
|
|
2fc102 |
state->filter_type = filter_type;
|
|
|
2fc102 |
|
|
|
2fc102 |
- use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(
|
|
|
2fc102 |
+ state->use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(
|
|
|
2fc102 |
ctx->opts->idmap_ctx,
|
|
|
2fc102 |
sdom->dom->name,
|
|
|
2fc102 |
sdom->dom->domain_id);
|
|
|
2fc102 |
@@ -503,7 +576,7 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
|
|
|
2fc102 |
}
|
|
|
2fc102 |
break;
|
|
|
2fc102 |
case BE_FILTER_IDNUM:
|
|
|
2fc102 |
- if (use_id_mapping) {
|
|
|
2fc102 |
+ if (state->use_id_mapping) {
|
|
|
2fc102 |
/* If we're ID-mapping, we need to use the objectSID
|
|
|
2fc102 |
* in the search filter.
|
|
|
2fc102 |
*/
|
|
|
2fc102 |
@@ -571,7 +644,7 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
|
|
|
2fc102 |
goto fail;
|
|
|
2fc102 |
}
|
|
|
2fc102 |
|
|
|
2fc102 |
- if (use_id_mapping || filter_type == BE_FILTER_SECID) {
|
|
|
2fc102 |
+ if (state->use_id_mapping || filter_type == BE_FILTER_SECID) {
|
|
|
2fc102 |
/* When mapping IDs or looking for SIDs, we don't want to limit
|
|
|
2fc102 |
* ourselves to groups with a GID value
|
|
|
2fc102 |
*/
|
|
|
2fc102 |
@@ -660,6 +733,75 @@ static void groups_get_connect_done(struct tevent_req *subreq)
|
|
|
2fc102 |
return;
|
|
|
2fc102 |
}
|
|
|
2fc102 |
|
|
|
2fc102 |
+ /* If POSIX attributes have been requested with an AD server and we
|
|
|
2fc102 |
+ * have no idea about POSIX attributes support, run a one-time check
|
|
|
2fc102 |
+ */
|
|
|
2fc102 |
+ if (state->use_id_mapping == false &&
|
|
|
2fc102 |
+ state->ctx->opts->schema_type == SDAP_SCHEMA_AD &&
|
|
|
2fc102 |
+ state->ctx->srv_opts &&
|
|
|
2fc102 |
+ state->ctx->srv_opts->posix_checked == false) {
|
|
|
2fc102 |
+ subreq = sdap_posix_check_send(state, state->ev, state->ctx->opts,
|
|
|
2fc102 |
+ sdap_id_op_handle(state->op),
|
|
|
2fc102 |
+ state->sdom->user_search_bases,
|
|
|
2fc102 |
+ dp_opt_get_int(state->ctx->opts->basic,
|
|
|
2fc102 |
+ SDAP_SEARCH_TIMEOUT));
|
|
|
2fc102 |
+ if (subreq == NULL) {
|
|
|
2fc102 |
+ tevent_req_error(req, ENOMEM);
|
|
|
2fc102 |
+ return;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ tevent_req_set_callback(subreq, groups_get_posix_check_done, req);
|
|
|
2fc102 |
+ return;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ groups_get_search(req);
|
|
|
2fc102 |
+}
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+static void groups_get_posix_check_done(struct tevent_req *subreq)
|
|
|
2fc102 |
+{
|
|
|
2fc102 |
+ errno_t ret;
|
|
|
2fc102 |
+ bool has_posix;
|
|
|
2fc102 |
+ int dp_error;
|
|
|
2fc102 |
+ struct tevent_req *req = tevent_req_callback_data(subreq,
|
|
|
2fc102 |
+ struct tevent_req);
|
|
|
2fc102 |
+ struct groups_get_state *state = tevent_req_data(req,
|
|
|
2fc102 |
+ struct groups_get_state);
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ ret = sdap_posix_check_recv(subreq, &has_posix);
|
|
|
2fc102 |
+ talloc_zfree(subreq);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ /* We can only finish the id_op on error as the connection
|
|
|
2fc102 |
+ * is re-used by the group search
|
|
|
2fc102 |
+ */
|
|
|
2fc102 |
+ ret = sdap_id_op_done(state->op, ret, &dp_error);
|
|
|
2fc102 |
+ if (dp_error == DP_ERR_OK && ret != EOK) {
|
|
|
2fc102 |
+ /* retry */
|
|
|
2fc102 |
+ ret = groups_get_retry(req);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ tevent_req_error(req, ret);
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ return;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ state->ctx->srv_opts->posix_checked = true;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ /* If the check ran to completion, we know for certain about the attributes
|
|
|
2fc102 |
+ */
|
|
|
2fc102 |
+ if (has_posix == false) {
|
|
|
2fc102 |
+ state->sdap_ret = ERR_NO_POSIX;
|
|
|
2fc102 |
+ tevent_req_done(req);
|
|
|
2fc102 |
+ return;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ groups_get_search(req);
|
|
|
2fc102 |
+}
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+static void groups_get_search(struct tevent_req *req)
|
|
|
2fc102 |
+{
|
|
|
2fc102 |
+ struct groups_get_state *state = tevent_req_data(req,
|
|
|
2fc102 |
+ struct groups_get_state);
|
|
|
2fc102 |
+ struct tevent_req *subreq;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
subreq = sdap_get_groups_send(state, state->ev,
|
|
|
2fc102 |
state->sdom,
|
|
|
2fc102 |
state->ctx->opts,
|
|
|
2fc102 |
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
|
|
|
2fc102 |
index d408be0a65cdd840d8379b7af4c0ab1e67ed3f5c..f3f13e9c72b368af0c14e2d830a89a41e8cf77e4 100644
|
|
|
2fc102 |
--- a/src/providers/ldap/sdap.h
|
|
|
2fc102 |
+++ b/src/providers/ldap/sdap.h
|
|
|
2fc102 |
@@ -446,6 +446,7 @@ struct sdap_server_opts {
|
|
|
2fc102 |
char *max_group_value;
|
|
|
2fc102 |
char *max_service_value;
|
|
|
2fc102 |
char *max_sudo_value;
|
|
|
2fc102 |
+ bool posix_checked;
|
|
|
2fc102 |
};
|
|
|
2fc102 |
|
|
|
2fc102 |
struct sdap_id_ctx;
|
|
|
2fc102 |
diff --git a/src/providers/ldap/sdap_async.c b/src/providers/ldap/sdap_async.c
|
|
|
2fc102 |
index 367007bde0011ed4de283b2a50b22538830a5275..1022a093f06ec7e9a50b13160fc9a4660a255e92 100644
|
|
|
2fc102 |
--- a/src/providers/ldap/sdap_async.c
|
|
|
2fc102 |
+++ b/src/providers/ldap/sdap_async.c
|
|
|
2fc102 |
@@ -21,6 +21,7 @@
|
|
|
2fc102 |
|
|
|
2fc102 |
#include <ctype.h>
|
|
|
2fc102 |
#include "util/util.h"
|
|
|
2fc102 |
+#include "util/strtonum.h"
|
|
|
2fc102 |
#include "providers/ldap/sdap_async_private.h"
|
|
|
2fc102 |
|
|
|
2fc102 |
#define REALM_SEPARATOR '@'
|
|
|
2fc102 |
@@ -2083,6 +2084,205 @@ int sdap_asq_search_recv(struct tevent_req *req,
|
|
|
2fc102 |
return EOK;
|
|
|
2fc102 |
}
|
|
|
2fc102 |
|
|
|
2fc102 |
+/* ==Posix attribute presence test================================= */
|
|
|
2fc102 |
+static errno_t sdap_posix_check_next(struct tevent_req *req);
|
|
|
2fc102 |
+static void sdap_posix_check_done(struct tevent_req *subreq);
|
|
|
2fc102 |
+static errno_t sdap_posix_check_parse(struct sdap_handle *sh,
|
|
|
2fc102 |
+ struct sdap_msg *msg,
|
|
|
2fc102 |
+ void *pvt);
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+struct sdap_posix_check_state {
|
|
|
2fc102 |
+ struct tevent_context *ev;
|
|
|
2fc102 |
+ struct sdap_options *opts;
|
|
|
2fc102 |
+ struct sdap_handle *sh;
|
|
|
2fc102 |
+ struct sdap_search_base **search_bases;
|
|
|
2fc102 |
+ int timeout;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ const char **attrs;
|
|
|
2fc102 |
+ const char *filter;
|
|
|
2fc102 |
+ size_t base_iter;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ bool has_posix;
|
|
|
2fc102 |
+};
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+struct tevent_req *
|
|
|
2fc102 |
+sdap_posix_check_send(TALLOC_CTX *memctx, struct tevent_context *ev,
|
|
|
2fc102 |
+ struct sdap_options *opts, struct sdap_handle *sh,
|
|
|
2fc102 |
+ struct sdap_search_base **search_bases,
|
|
|
2fc102 |
+ int timeout)
|
|
|
2fc102 |
+{
|
|
|
2fc102 |
+ struct tevent_req *req = NULL;
|
|
|
2fc102 |
+ struct sdap_posix_check_state *state;
|
|
|
2fc102 |
+ errno_t ret;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ req = tevent_req_create(memctx, &state, struct sdap_posix_check_state);
|
|
|
2fc102 |
+ if (req == NULL) {
|
|
|
2fc102 |
+ return NULL;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ state->ev = ev;
|
|
|
2fc102 |
+ state->sh = sh;
|
|
|
2fc102 |
+ state->opts = opts;
|
|
|
2fc102 |
+ state->search_bases = search_bases;
|
|
|
2fc102 |
+ state->timeout = timeout;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ state->attrs = talloc_array(state, const char *, 4);
|
|
|
2fc102 |
+ if (state->attrs == NULL) {
|
|
|
2fc102 |
+ ret = ENOMEM;
|
|
|
2fc102 |
+ goto fail;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ state->attrs[0] = "objectclass";
|
|
|
2fc102 |
+ state->attrs[1] = opts->user_map[SDAP_AT_USER_UID].name;
|
|
|
2fc102 |
+ state->attrs[2] = opts->group_map[SDAP_AT_GROUP_GID].name;
|
|
|
2fc102 |
+ state->attrs[3] = NULL;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ state->filter = talloc_asprintf(state, "(|(%s=*)(%s=*))",
|
|
|
2fc102 |
+ opts->user_map[SDAP_AT_USER_UID].name,
|
|
|
2fc102 |
+ opts->group_map[SDAP_AT_GROUP_GID].name);
|
|
|
2fc102 |
+ if (state->filter == NULL) {
|
|
|
2fc102 |
+ ret = ENOMEM;
|
|
|
2fc102 |
+ goto fail;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ ret = sdap_posix_check_next(req);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ goto fail;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ return req;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+fail:
|
|
|
2fc102 |
+ tevent_req_error(req, ret);
|
|
|
2fc102 |
+ tevent_req_post(req, ev);
|
|
|
2fc102 |
+ return req;
|
|
|
2fc102 |
+}
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+static errno_t sdap_posix_check_next(struct tevent_req *req)
|
|
|
2fc102 |
+{
|
|
|
2fc102 |
+ struct tevent_req *subreq = NULL;
|
|
|
2fc102 |
+ struct sdap_posix_check_state *state =
|
|
|
2fc102 |
+ tevent_req_data(req, struct sdap_posix_check_state);
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ DEBUG(SSSDBG_TRACE_FUNC,
|
|
|
2fc102 |
+ ("Searching for POSIX attributes with base [%s]\n",
|
|
|
2fc102 |
+ state->search_bases[state->base_iter]->basedn));
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ subreq = sdap_get_generic_ext_send(state, state->ev, state->opts,
|
|
|
2fc102 |
+ state->sh,
|
|
|
2fc102 |
+ state->search_bases[state->base_iter]->basedn,
|
|
|
2fc102 |
+ LDAP_SCOPE_SUBTREE, state->filter,
|
|
|
2fc102 |
+ state->attrs, false,
|
|
|
2fc102 |
+ NULL, NULL, 1, state->timeout,
|
|
|
2fc102 |
+ false, sdap_posix_check_parse,
|
|
|
2fc102 |
+ state);
|
|
|
2fc102 |
+ if (subreq == NULL) {
|
|
|
2fc102 |
+ return ENOMEM;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ tevent_req_set_callback(subreq, sdap_posix_check_done, req);
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ return EOK;
|
|
|
2fc102 |
+}
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+static errno_t sdap_posix_check_parse(struct sdap_handle *sh,
|
|
|
2fc102 |
+ struct sdap_msg *msg,
|
|
|
2fc102 |
+ void *pvt)
|
|
|
2fc102 |
+{
|
|
|
2fc102 |
+ struct berval **vals = NULL;
|
|
|
2fc102 |
+ struct sdap_posix_check_state *state =
|
|
|
2fc102 |
+ talloc_get_type(pvt, struct sdap_posix_check_state);
|
|
|
2fc102 |
+ char *dn;
|
|
|
2fc102 |
+ char *endptr;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ dn = ldap_get_dn(sh->ldap, msg->msg);
|
|
|
2fc102 |
+ if (dn == NULL) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_TRACE_LIBS,
|
|
|
2fc102 |
+ ("Search did not find any entry with POSIX attributes\n"));
|
|
|
2fc102 |
+ goto done;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ DEBUG(SSSDBG_TRACE_LIBS, ("Found [%s] with POSIX attributes\n", dn));
|
|
|
2fc102 |
+ ldap_memfree(dn);
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ vals = ldap_get_values_len(sh->ldap, msg->msg,
|
|
|
2fc102 |
+ state->opts->user_map[SDAP_AT_USER_UID].name);
|
|
|
2fc102 |
+ if (vals == NULL) {
|
|
|
2fc102 |
+ vals = ldap_get_values_len(sh->ldap, msg->msg,
|
|
|
2fc102 |
+ state->opts->group_map[SDAP_AT_GROUP_GID].name);
|
|
|
2fc102 |
+ if (vals == NULL) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_TRACE_LIBS, ("Entry does not have POSIX attrs?\n"));
|
|
|
2fc102 |
+ goto done;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ if (vals[0] == NULL) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_TRACE_LIBS, ("No value for POSIX attr\n"));
|
|
|
2fc102 |
+ goto done;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ errno = 0;
|
|
|
2fc102 |
+ strtouint32(vals[0]->bv_val, &endptr, 10);
|
|
|
2fc102 |
+ if (errno || *endptr || (vals[0]->bv_val == endptr)) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
2fc102 |
+ ("POSIX attribute is not a number: %s\n", vals[0]->bv_val));
|
|
|
2fc102 |
+ goto done;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ state->has_posix = true;
|
|
|
2fc102 |
+done:
|
|
|
2fc102 |
+ ldap_value_free_len(vals);
|
|
|
2fc102 |
+ return EOK;
|
|
|
2fc102 |
+}
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+static void sdap_posix_check_done(struct tevent_req *subreq)
|
|
|
2fc102 |
+{
|
|
|
2fc102 |
+ struct tevent_req *req = tevent_req_callback_data(subreq,
|
|
|
2fc102 |
+ struct tevent_req);
|
|
|
2fc102 |
+ struct sdap_posix_check_state *state =
|
|
|
2fc102 |
+ tevent_req_data(req, struct sdap_posix_check_state);
|
|
|
2fc102 |
+ errno_t ret;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ ret = sdap_get_generic_ext_recv(subreq);
|
|
|
2fc102 |
+ talloc_zfree(subreq);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
2fc102 |
+ ("sdap_get_generic_ext_recv failed [%d]: %s\n",
|
|
|
2fc102 |
+ ret, strerror(ret)));
|
|
|
2fc102 |
+ tevent_req_error(req, ret);
|
|
|
2fc102 |
+ return;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ /* Positive hit is definitve, no need to search other bases */
|
|
|
2fc102 |
+ if (state->has_posix == true) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_FUNC_DATA, ("Server has POSIX attributes\n"));
|
|
|
2fc102 |
+ tevent_req_done(req);
|
|
|
2fc102 |
+ return;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ state->base_iter++;
|
|
|
2fc102 |
+ if (state->search_bases[state->base_iter]) {
|
|
|
2fc102 |
+ /* There are more search bases to try */
|
|
|
2fc102 |
+ ret = sdap_posix_check_next(req);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ tevent_req_error(req, ret);
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ return;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ /* All bases done! */
|
|
|
2fc102 |
+ DEBUG(SSSDBG_TRACE_LIBS, ("Cycled through all bases\n"));
|
|
|
2fc102 |
+ tevent_req_done(req);
|
|
|
2fc102 |
+}
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+int sdap_posix_check_recv(struct tevent_req *req,
|
|
|
2fc102 |
+ bool *_has_posix)
|
|
|
2fc102 |
+{
|
|
|
2fc102 |
+ struct sdap_posix_check_state *state = tevent_req_data(req,
|
|
|
2fc102 |
+ struct sdap_posix_check_state);
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ *_has_posix = state->has_posix;
|
|
|
2fc102 |
+ return EOK;
|
|
|
2fc102 |
+}
|
|
|
2fc102 |
+
|
|
|
2fc102 |
/* ==Generic Deref Search============================================ */
|
|
|
2fc102 |
enum sdap_deref_type {
|
|
|
2fc102 |
SDAP_DEREF_OPENLDAP,
|
|
|
2fc102 |
diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h
|
|
|
2fc102 |
index 33e8708ab7e80ab4280df300fdc300d4ecd18305..593404af3c460f8d956b0832b8f7e398b331729b 100644
|
|
|
2fc102 |
--- a/src/providers/ldap/sdap_async.h
|
|
|
2fc102 |
+++ b/src/providers/ldap/sdap_async.h
|
|
|
2fc102 |
@@ -210,6 +210,15 @@ int sdap_deref_search_recv(struct tevent_req *req,
|
|
|
2fc102 |
size_t *reply_count,
|
|
|
2fc102 |
struct sdap_deref_attrs ***reply);
|
|
|
2fc102 |
|
|
|
2fc102 |
+struct tevent_req *
|
|
|
2fc102 |
+sdap_posix_check_send(TALLOC_CTX *memctx, struct tevent_context *ev,
|
|
|
2fc102 |
+ struct sdap_options *opts, struct sdap_handle *sh,
|
|
|
2fc102 |
+ struct sdap_search_base **search_bases,
|
|
|
2fc102 |
+ int timeout);
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+int sdap_posix_check_recv(struct tevent_req *req,
|
|
|
2fc102 |
+ bool *_has_posix);
|
|
|
2fc102 |
+
|
|
|
2fc102 |
errno_t
|
|
|
2fc102 |
sdap_attrs_add_ldap_attr(struct sysdb_attrs *ldap_attrs,
|
|
|
2fc102 |
const char *attr_name,
|
|
|
2fc102 |
diff --git a/src/providers/ldap/sdap_async_enum.c b/src/providers/ldap/sdap_async_enum.c
|
|
|
2fc102 |
index cbc56be20526e6c2323f9fd1b49038dd4bf13fe5..0c20afa9d7a1b0198bb71cffdafcb14763c1dafb 100644
|
|
|
2fc102 |
--- a/src/providers/ldap/sdap_async_enum.c
|
|
|
2fc102 |
+++ b/src/providers/ldap/sdap_async_enum.c
|
|
|
2fc102 |
@@ -68,6 +68,8 @@ static errno_t sdap_dom_enum_ex_retry(struct tevent_req *req,
|
|
|
2fc102 |
tevent_req_fn tcb);
|
|
|
2fc102 |
static bool sdap_dom_enum_ex_connected(struct tevent_req *subreq);
|
|
|
2fc102 |
static void sdap_dom_enum_ex_get_users(struct tevent_req *subreq);
|
|
|
2fc102 |
+static void sdap_dom_enum_ex_posix_check_done(struct tevent_req *subreq);
|
|
|
2fc102 |
+static errno_t sdap_dom_enum_search_users(struct tevent_req *req);
|
|
|
2fc102 |
static void sdap_dom_enum_ex_users_done(struct tevent_req *subreq);
|
|
|
2fc102 |
static void sdap_dom_enum_ex_get_groups(struct tevent_req *subreq);
|
|
|
2fc102 |
static void sdap_dom_enum_ex_groups_done(struct tevent_req *subreq);
|
|
|
2fc102 |
@@ -178,19 +180,109 @@ static void sdap_dom_enum_ex_get_users(struct tevent_req *subreq)
|
|
|
2fc102 |
struct tevent_req);
|
|
|
2fc102 |
struct sdap_dom_enum_ex_state *state = tevent_req_data(req,
|
|
|
2fc102 |
struct sdap_dom_enum_ex_state);
|
|
|
2fc102 |
+ bool use_id_mapping;
|
|
|
2fc102 |
+ errno_t ret;
|
|
|
2fc102 |
|
|
|
2fc102 |
if (sdap_dom_enum_ex_connected(subreq) == false) {
|
|
|
2fc102 |
return;
|
|
|
2fc102 |
}
|
|
|
2fc102 |
|
|
|
2fc102 |
+ use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(
|
|
|
2fc102 |
+ state->ctx->opts->idmap_ctx,
|
|
|
2fc102 |
+ state->sdom->dom->name,
|
|
|
2fc102 |
+ state->sdom->dom->domain_id);
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ /* If POSIX attributes have been requested with an AD server and we
|
|
|
2fc102 |
+ * have no idea about POSIX attributes support, run a one-time check
|
|
|
2fc102 |
+ */
|
|
|
2fc102 |
+ if (use_id_mapping == false &&
|
|
|
2fc102 |
+ state->ctx->opts->schema_type == SDAP_SCHEMA_AD &&
|
|
|
2fc102 |
+ state->ctx->srv_opts &&
|
|
|
2fc102 |
+ state->ctx->srv_opts->posix_checked == false) {
|
|
|
2fc102 |
+ subreq = sdap_posix_check_send(state, state->ev, state->ctx->opts,
|
|
|
2fc102 |
+ sdap_id_op_handle(state->user_op),
|
|
|
2fc102 |
+ state->sdom->user_search_bases,
|
|
|
2fc102 |
+ dp_opt_get_int(state->ctx->opts->basic,
|
|
|
2fc102 |
+ SDAP_SEARCH_TIMEOUT));
|
|
|
2fc102 |
+ if (subreq == NULL) {
|
|
|
2fc102 |
+ tevent_req_error(req, ENOMEM);
|
|
|
2fc102 |
+ return;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ tevent_req_set_callback(subreq,
|
|
|
2fc102 |
+ sdap_dom_enum_ex_posix_check_done, req);
|
|
|
2fc102 |
+ return;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ ret = sdap_dom_enum_search_users(req);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ tevent_req_error(req, ret);
|
|
|
2fc102 |
+ return;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ /* Execution resumes in sdap_dom_enum_ex_users_done */
|
|
|
2fc102 |
+}
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+static void sdap_dom_enum_ex_posix_check_done(struct tevent_req *subreq)
|
|
|
2fc102 |
+{
|
|
|
2fc102 |
+ errno_t ret;
|
|
|
2fc102 |
+ bool has_posix;
|
|
|
2fc102 |
+ int dp_error;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ struct tevent_req *req = tevent_req_callback_data(subreq,
|
|
|
2fc102 |
+ struct tevent_req);
|
|
|
2fc102 |
+ struct sdap_dom_enum_ex_state *state = tevent_req_data(req,
|
|
|
2fc102 |
+ struct sdap_dom_enum_ex_state);
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ ret = sdap_posix_check_recv(subreq, &has_posix);
|
|
|
2fc102 |
+ talloc_zfree(subreq);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ /* We can only finish the id_op on error as the connection
|
|
|
2fc102 |
+ * is re-used by the user search
|
|
|
2fc102 |
+ */
|
|
|
2fc102 |
+ ret = sdap_id_op_done(state->user_op, ret, &dp_error);
|
|
|
2fc102 |
+ if (dp_error == DP_ERR_OK && ret != EOK) {
|
|
|
2fc102 |
+ /* retry */
|
|
|
2fc102 |
+ ret = sdap_dom_enum_ex_retry(req, state->user_op,
|
|
|
2fc102 |
+ sdap_dom_enum_ex_get_users);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ tevent_req_error(req, ret);
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ return;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ state->ctx->srv_opts->posix_checked = true;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ /* If the check ran to completion, we know for certain about the attributes
|
|
|
2fc102 |
+ */
|
|
|
2fc102 |
+ if (has_posix == false) {
|
|
|
2fc102 |
+ tevent_req_error(req, ERR_NO_POSIX);
|
|
|
2fc102 |
+ return;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ ret = sdap_dom_enum_search_users(req);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ tevent_req_error(req, ret);
|
|
|
2fc102 |
+ return;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ /* Execution resumes in sdap_dom_enum_ex_users_done */
|
|
|
2fc102 |
+}
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+static errno_t sdap_dom_enum_search_users(struct tevent_req *req)
|
|
|
2fc102 |
+{
|
|
|
2fc102 |
+ struct sdap_dom_enum_ex_state *state = tevent_req_data(req,
|
|
|
2fc102 |
+ struct sdap_dom_enum_ex_state);
|
|
|
2fc102 |
+ struct tevent_req *subreq;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
subreq = enum_users_send(state, state->ev,
|
|
|
2fc102 |
state->ctx, state->sdom,
|
|
|
2fc102 |
state->user_op, state->purge);
|
|
|
2fc102 |
if (subreq == NULL) {
|
|
|
2fc102 |
- tevent_req_error(req, ENOMEM);
|
|
|
2fc102 |
- return;
|
|
|
2fc102 |
+ return ENOMEM;
|
|
|
2fc102 |
}
|
|
|
2fc102 |
tevent_req_set_callback(subreq, sdap_dom_enum_ex_users_done, req);
|
|
|
2fc102 |
+ return EOK;
|
|
|
2fc102 |
}
|
|
|
2fc102 |
|
|
|
2fc102 |
static void sdap_dom_enum_ex_users_done(struct tevent_req *subreq)
|
|
|
2fc102 |
diff --git a/src/util/util_errors.c b/src/util/util_errors.c
|
|
|
2fc102 |
index 633257e8da0ef039e555a07ad8b51125114ca01c..c9b507557da07555c719bb0dd18145e6799a53eb 100644
|
|
|
2fc102 |
--- a/src/util/util_errors.c
|
|
|
2fc102 |
+++ b/src/util/util_errors.c
|
|
|
2fc102 |
@@ -52,6 +52,7 @@ struct err_string error_to_str[] = {
|
|
|
2fc102 |
{ "Domain not found" }, /* ERR_DOMAIN_NOT_FOUND */
|
|
|
2fc102 |
{ "Missing configuration file" }, /* ERR_MISSING_CONF */
|
|
|
2fc102 |
{ "Malformed search filter" }, /* ERR_INVALID_FILTER, */
|
|
|
2fc102 |
+ { "No POSIX attributes detected" }, /* ERR_NO_POSIX */
|
|
|
2fc102 |
};
|
|
|
2fc102 |
|
|
|
2fc102 |
|
|
|
2fc102 |
diff --git a/src/util/util_errors.h b/src/util/util_errors.h
|
|
|
2fc102 |
index 1332085031dbe6935cbdc94543fa14b09fe81028..3dd94af1f304d65e22515c859c6f69a021fa7e92 100644
|
|
|
2fc102 |
--- a/src/util/util_errors.h
|
|
|
2fc102 |
+++ b/src/util/util_errors.h
|
|
|
2fc102 |
@@ -74,6 +74,7 @@ enum sssd_errors {
|
|
|
2fc102 |
ERR_DOMAIN_NOT_FOUND,
|
|
|
2fc102 |
ERR_MISSING_CONF,
|
|
|
2fc102 |
ERR_INVALID_FILTER,
|
|
|
2fc102 |
+ ERR_NO_POSIX,
|
|
|
2fc102 |
ERR_LAST /* ALWAYS LAST */
|
|
|
2fc102 |
};
|
|
|
2fc102 |
|
|
|
2fc102 |
--
|
|
|
2fc102 |
1.8.5.3
|
|
|
2fc102 |
|