|
|
bb7cd1 |
From 54790675d0fd0627f7db8449ef97d59c0632006e Mon Sep 17 00:00:00 2001
|
|
|
bb7cd1 |
From: Jakub Hrozek <jhrozek@redhat.com>
|
|
|
bb7cd1 |
Date: Mon, 24 Apr 2017 10:13:44 +0200
|
|
|
bb7cd1 |
Subject: [PATCH 119/119] AD: Make ad_account_can_shortcut() reusable by SSSD
|
|
|
bb7cd1 |
on an IPA server
|
|
|
bb7cd1 |
MIME-Version: 1.0
|
|
|
bb7cd1 |
Content-Type: text/plain; charset=UTF-8
|
|
|
bb7cd1 |
Content-Transfer-Encoding: 8bit
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
Resolves:
|
|
|
bb7cd1 |
https://pagure.io/SSSD/sssd/issue/3318
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
The ad_account_can_shortcut() function is helpful to avoid unnecessary
|
|
|
bb7cd1 |
searches when SSSD is configured with an Active Directory domain that
|
|
|
bb7cd1 |
uses ID-mapping in the sense that if we find that an ID is outside our
|
|
|
bb7cd1 |
range, we can just abort the search in this domain and carry on.
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
This function was only used in the AD provider functions which are used
|
|
|
bb7cd1 |
when SSSD is enrolled direcly with an AD server. This patch moves the
|
|
|
bb7cd1 |
function to a codepath that is shared between directly enrolled SSSD and
|
|
|
bb7cd1 |
SSSD running on an IPA server.
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
Apart from moving the code, there are some minor changes to the function
|
|
|
bb7cd1 |
signature, namely the domain is passed as as struct (previously the
|
|
|
bb7cd1 |
domain name from the DP input was passed).
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
Reviewed-by: Michal Židek <mzidek@redhat.com>
|
|
|
bb7cd1 |
(cherry picked from commit dfe05f505dcfea16e7d66ca1a44206aa2570e861)
|
|
|
bb7cd1 |
---
|
|
|
bb7cd1 |
src/providers/ad/ad_id.c | 162 ++++++++++++++++++++++++-----------------------
|
|
|
bb7cd1 |
1 file changed, 84 insertions(+), 78 deletions(-)
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
diff --git a/src/providers/ad/ad_id.c b/src/providers/ad/ad_id.c
|
|
|
bb7cd1 |
index 8f26cb8744d2372c6180342c0d1bca025b16f52c..d1f6c444f5ddbcbbac6ff7f41fb6c8bf9ca976cb 100644
|
|
|
bb7cd1 |
--- a/src/providers/ad/ad_id.c
|
|
|
bb7cd1 |
+++ b/src/providers/ad/ad_id.c
|
|
|
bb7cd1 |
@@ -50,6 +50,77 @@ disable_gc(struct ad_options *ad_options)
|
|
|
bb7cd1 |
}
|
|
|
bb7cd1 |
}
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
+static bool ad_account_can_shortcut(struct sdap_idmap_ctx *idmap_ctx,
|
|
|
bb7cd1 |
+ struct sss_domain_info *domain,
|
|
|
bb7cd1 |
+ int filter_type,
|
|
|
bb7cd1 |
+ const char *filter_value)
|
|
|
bb7cd1 |
+{
|
|
|
bb7cd1 |
+ struct sss_domain_info *dom_head = NULL;
|
|
|
bb7cd1 |
+ struct sss_domain_info *sid_dom = NULL;
|
|
|
bb7cd1 |
+ enum idmap_error_code err;
|
|
|
bb7cd1 |
+ char *sid = NULL;
|
|
|
bb7cd1 |
+ const char *csid = NULL;
|
|
|
bb7cd1 |
+ uint32_t id;
|
|
|
bb7cd1 |
+ bool shortcut = false;
|
|
|
bb7cd1 |
+ errno_t ret;
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ if (!sdap_idmap_domain_has_algorithmic_mapping(idmap_ctx, domain->name,
|
|
|
bb7cd1 |
+ domain->domain_id)) {
|
|
|
bb7cd1 |
+ goto done;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ switch (filter_type) {
|
|
|
bb7cd1 |
+ case BE_FILTER_IDNUM:
|
|
|
bb7cd1 |
+ /* convert value to ID */
|
|
|
bb7cd1 |
+ errno = 0;
|
|
|
bb7cd1 |
+ id = strtouint32(filter_value, NULL, 10);
|
|
|
bb7cd1 |
+ if (errno != 0) {
|
|
|
bb7cd1 |
+ ret = errno;
|
|
|
bb7cd1 |
+ DEBUG(SSSDBG_MINOR_FAILURE, "Unable to convert filter value to "
|
|
|
bb7cd1 |
+ "number [%d]: %s\n", ret, strerror(ret));
|
|
|
bb7cd1 |
+ goto done;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ /* convert the ID to its SID equivalent */
|
|
|
bb7cd1 |
+ err = sss_idmap_unix_to_sid(idmap_ctx->map, id, &sid;;
|
|
|
bb7cd1 |
+ if (err != IDMAP_SUCCESS) {
|
|
|
bb7cd1 |
+ DEBUG(SSSDBG_MINOR_FAILURE, "Mapping ID [%s] to SID failed: "
|
|
|
bb7cd1 |
+ "[%s]\n", filter_value, idmap_error_string(err));
|
|
|
bb7cd1 |
+ goto done;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+ /* fall through */
|
|
|
bb7cd1 |
+ SSS_ATTRIBUTE_FALLTHROUGH;
|
|
|
bb7cd1 |
+ case BE_FILTER_SECID:
|
|
|
bb7cd1 |
+ csid = sid == NULL ? filter_value : sid;
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ dom_head = get_domains_head(domain);
|
|
|
bb7cd1 |
+ if (dom_head == NULL) {
|
|
|
bb7cd1 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find domain head\n");
|
|
|
bb7cd1 |
+ goto done;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ sid_dom = find_domain_by_sid(dom_head, csid);
|
|
|
bb7cd1 |
+ if (sid_dom == NULL) {
|
|
|
bb7cd1 |
+ DEBUG(SSSDBG_OP_FAILURE, "Invalid domain for SID:%s\n", csid);
|
|
|
bb7cd1 |
+ goto done;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ if (strcasecmp(sid_dom->name, domain->name) != 0) {
|
|
|
bb7cd1 |
+ shortcut = true;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+ break;
|
|
|
bb7cd1 |
+ default:
|
|
|
bb7cd1 |
+ break;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+done:
|
|
|
bb7cd1 |
+ if (sid != NULL) {
|
|
|
bb7cd1 |
+ sss_idmap_free_sid(idmap_ctx->map, sid);
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ return shortcut;
|
|
|
bb7cd1 |
+}
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
struct ad_handle_acct_info_state {
|
|
|
bb7cd1 |
struct dp_id_data *ar;
|
|
|
bb7cd1 |
struct sdap_id_ctx *ctx;
|
|
|
bb7cd1 |
@@ -78,6 +149,7 @@ ad_handle_acct_info_send(TALLOC_CTX *mem_ctx,
|
|
|
bb7cd1 |
struct ad_handle_acct_info_state *state;
|
|
|
bb7cd1 |
struct be_ctx *be_ctx = ctx->be;
|
|
|
bb7cd1 |
errno_t ret;
|
|
|
bb7cd1 |
+ bool shortcut;
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
req = tevent_req_create(mem_ctx, &state, struct ad_handle_acct_info_state);
|
|
|
bb7cd1 |
if (req == NULL) {
|
|
|
bb7cd1 |
@@ -90,6 +162,18 @@ ad_handle_acct_info_send(TALLOC_CTX *mem_ctx,
|
|
|
bb7cd1 |
state->ad_options = ad_options;
|
|
|
bb7cd1 |
state->cindex = 0;
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
+ /* Try to shortcut if this is ID or SID search and it belongs to
|
|
|
bb7cd1 |
+ * other domain range than is in ar->domain. */
|
|
|
bb7cd1 |
+ shortcut = ad_account_can_shortcut(ctx->opts->idmap_ctx,
|
|
|
bb7cd1 |
+ sdom->dom,
|
|
|
bb7cd1 |
+ ar->filter_type,
|
|
|
bb7cd1 |
+ ar->filter_value);
|
|
|
bb7cd1 |
+ if (shortcut) {
|
|
|
bb7cd1 |
+ DEBUG(SSSDBG_TRACE_FUNC, "This ID is from different domain\n");
|
|
|
bb7cd1 |
+ ret = EOK;
|
|
|
bb7cd1 |
+ goto immediate;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
if (sss_domain_get_state(sdom->dom) == DOM_INACTIVE) {
|
|
|
bb7cd1 |
ret = ERR_SUBDOM_INACTIVE;
|
|
|
bb7cd1 |
goto immediate;
|
|
|
bb7cd1 |
@@ -297,72 +381,6 @@ get_conn_list(TALLOC_CTX *mem_ctx, struct ad_id_ctx *ad_ctx,
|
|
|
bb7cd1 |
return clist;
|
|
|
bb7cd1 |
}
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
-static bool ad_account_can_shortcut(struct be_ctx *be_ctx,
|
|
|
bb7cd1 |
- struct sdap_idmap_ctx *idmap_ctx,
|
|
|
bb7cd1 |
- int filter_type,
|
|
|
bb7cd1 |
- const char *filter_value,
|
|
|
bb7cd1 |
- const char *filter_domain)
|
|
|
bb7cd1 |
-{
|
|
|
bb7cd1 |
- struct sss_domain_info *domain = be_ctx->domain;
|
|
|
bb7cd1 |
- struct sss_domain_info *req_dom = NULL;
|
|
|
bb7cd1 |
- enum idmap_error_code err;
|
|
|
bb7cd1 |
- char *sid = NULL;
|
|
|
bb7cd1 |
- const char *csid = NULL;
|
|
|
bb7cd1 |
- uint32_t id;
|
|
|
bb7cd1 |
- bool shortcut = false;
|
|
|
bb7cd1 |
- errno_t ret;
|
|
|
bb7cd1 |
-
|
|
|
bb7cd1 |
- if (!sdap_idmap_domain_has_algorithmic_mapping(idmap_ctx, domain->name,
|
|
|
bb7cd1 |
- domain->domain_id)) {
|
|
|
bb7cd1 |
- goto done;
|
|
|
bb7cd1 |
- }
|
|
|
bb7cd1 |
-
|
|
|
bb7cd1 |
- switch (filter_type) {
|
|
|
bb7cd1 |
- case BE_FILTER_IDNUM:
|
|
|
bb7cd1 |
- /* convert value to ID */
|
|
|
bb7cd1 |
- errno = 0;
|
|
|
bb7cd1 |
- id = strtouint32(filter_value, NULL, 10);
|
|
|
bb7cd1 |
- if (errno != 0) {
|
|
|
bb7cd1 |
- ret = errno;
|
|
|
bb7cd1 |
- DEBUG(SSSDBG_MINOR_FAILURE, "Unable to convert filter value to "
|
|
|
bb7cd1 |
- "number [%d]: %s\n", ret, strerror(ret));
|
|
|
bb7cd1 |
- goto done;
|
|
|
bb7cd1 |
- }
|
|
|
bb7cd1 |
-
|
|
|
bb7cd1 |
- /* convert the ID to its SID equivalent */
|
|
|
bb7cd1 |
- err = sss_idmap_unix_to_sid(idmap_ctx->map, id, &sid;;
|
|
|
bb7cd1 |
- if (err != IDMAP_SUCCESS) {
|
|
|
bb7cd1 |
- DEBUG(SSSDBG_MINOR_FAILURE, "Mapping ID [%s] to SID failed: "
|
|
|
bb7cd1 |
- "[%s]\n", filter_value, idmap_error_string(err));
|
|
|
bb7cd1 |
- goto done;
|
|
|
bb7cd1 |
- }
|
|
|
bb7cd1 |
- /* fall through */
|
|
|
bb7cd1 |
- SSS_ATTRIBUTE_FALLTHROUGH;
|
|
|
bb7cd1 |
- case BE_FILTER_SECID:
|
|
|
bb7cd1 |
- csid = sid == NULL ? filter_value : sid;
|
|
|
bb7cd1 |
-
|
|
|
bb7cd1 |
- req_dom = find_domain_by_sid(domain, csid);
|
|
|
bb7cd1 |
- if (req_dom == NULL) {
|
|
|
bb7cd1 |
- DEBUG(SSSDBG_OP_FAILURE, "Invalid domain for SID:%s\n", csid);
|
|
|
bb7cd1 |
- goto done;
|
|
|
bb7cd1 |
- }
|
|
|
bb7cd1 |
-
|
|
|
bb7cd1 |
- if (strcasecmp(req_dom->name, filter_domain) != 0) {
|
|
|
bb7cd1 |
- shortcut = true;
|
|
|
bb7cd1 |
- }
|
|
|
bb7cd1 |
- break;
|
|
|
bb7cd1 |
- default:
|
|
|
bb7cd1 |
- break;
|
|
|
bb7cd1 |
- }
|
|
|
bb7cd1 |
-
|
|
|
bb7cd1 |
-done:
|
|
|
bb7cd1 |
- if (sid != NULL) {
|
|
|
bb7cd1 |
- sss_idmap_free_sid(idmap_ctx->map, sid);
|
|
|
bb7cd1 |
- }
|
|
|
bb7cd1 |
-
|
|
|
bb7cd1 |
- return shortcut;
|
|
|
bb7cd1 |
-}
|
|
|
bb7cd1 |
-
|
|
|
bb7cd1 |
struct ad_account_info_handler_state {
|
|
|
bb7cd1 |
struct sss_domain_info *domain;
|
|
|
bb7cd1 |
struct dp_reply_std reply;
|
|
|
bb7cd1 |
@@ -384,7 +402,6 @@ ad_account_info_handler_send(TALLOC_CTX *mem_ctx,
|
|
|
bb7cd1 |
struct tevent_req *subreq;
|
|
|
bb7cd1 |
struct tevent_req *req;
|
|
|
bb7cd1 |
struct be_ctx *be_ctx;
|
|
|
bb7cd1 |
- bool shortcut;
|
|
|
bb7cd1 |
errno_t ret;
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
sdap_id_ctx = id_ctx->sdap_id_ctx;
|
|
|
bb7cd1 |
@@ -403,17 +420,6 @@ ad_account_info_handler_send(TALLOC_CTX *mem_ctx,
|
|
|
bb7cd1 |
goto immediately;
|
|
|
bb7cd1 |
}
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
- /* Try to shortcut if this is ID or SID search and it belongs to
|
|
|
bb7cd1 |
- * other domain range than is in ar->domain. */
|
|
|
bb7cd1 |
- shortcut = ad_account_can_shortcut(be_ctx, sdap_id_ctx->opts->idmap_ctx,
|
|
|
bb7cd1 |
- data->filter_type, data->filter_value,
|
|
|
bb7cd1 |
- data->domain);
|
|
|
bb7cd1 |
- if (shortcut) {
|
|
|
bb7cd1 |
- DEBUG(SSSDBG_TRACE_FUNC, "This ID is from different domain\n");
|
|
|
bb7cd1 |
- ret = EOK;
|
|
|
bb7cd1 |
- goto immediately;
|
|
|
bb7cd1 |
- }
|
|
|
bb7cd1 |
-
|
|
|
bb7cd1 |
domain = be_ctx->domain;
|
|
|
bb7cd1 |
if (strcasecmp(data->domain, be_ctx->domain->name) != 0) {
|
|
|
bb7cd1 |
/* Subdomain request, verify subdomain. */
|
|
|
bb7cd1 |
--
|
|
|
bb7cd1 |
2.9.3
|
|
|
bb7cd1 |
|