>From d8d7153c77dc0b43f5ecfd1a36f5b7e3a2e3fb0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20B=C5=99ezina?= Date: Mon, 9 Sep 2013 15:52:03 +0200 Subject: [PATCH 1/8] ad: shortcut if possible during get object by ID or SID When getByID or getBySID comes from responder, the request doesn't necessarily have to contain correct domain, since responder iterates over all domains until it finds a match. Every domain has its own ID range, so we can simply shortcut if domain does not match and avoid LDAP round trip. Responder will continue with next domain until it finds the correct one. --- src/providers/ad/ad_id.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/providers/ad/ad_id.c b/src/providers/ad/ad_id.c index 20f9c23fa8d1d272f91c0b886bd1e2e3a2522320..986639404ccc1cac09b03ac3228f3c3cc3be94ca 100644 --- a/src/providers/ad/ad_id.c +++ b/src/providers/ad/ad_id.c @@ -20,10 +20,12 @@ along with this program. If not, see . */ #include "util/util.h" +#include "util/strtonum.h" #include "providers/ad/ad_common.h" #include "providers/ad/ad_id.h" #include "providers/ad/ad_domain_info.h" #include "providers/ldap/sdap_async_enum.h" +#include "providers/ldap/sdap_idmap.h" struct ad_handle_acct_info_state { struct be_req *breq; @@ -235,17 +237,63 @@ ad_account_info_handler(struct be_req *be_req) struct sss_domain_info *dom; struct sdap_domain *sdom; struct sdap_id_conn_ctx **clist; + struct sdap_idmap_ctx *idmap_ctx; + enum idmap_error_code map_err; + uint32_t id; + char *sid = NULL; errno_t ret; ad_ctx = talloc_get_type(be_ctx->bet_info[BET_ID].pvt_bet_data, struct ad_id_ctx); ar = talloc_get_type(be_req_get_data(be_req), struct be_acct_req); sdap_id_ctx = ad_ctx->sdap_id_ctx; + idmap_ctx = sdap_id_ctx->opts->idmap_ctx; if (be_is_offline(be_ctx)) { return be_req_terminate(be_req, DP_ERR_OFFLINE, EAGAIN, "Offline"); } + /* Try to shortcut if this is ID or SID search and it belongs to + * other domain range than is in ar->domain. */ + if (sdap_idmap_domain_has_algorithmic_mapping(idmap_ctx, + be_ctx->domain->name, + be_ctx->domain->domain_id)) { + if (ar->filter_type == BE_FILTER_IDNUM + || ar->filter_type == BE_FILTER_SECID) { + if (ar->filter_type == BE_FILTER_IDNUM) { + id = strtouint32(ar->filter_value, NULL, 10); + if (errno != EOK) { + ret = EINVAL; + goto fail; + } + + /* Convert the ID to its objectSID */ + map_err = sss_idmap_unix_to_sid(idmap_ctx->map, id, &sid); + if (map_err != IDMAP_SUCCESS) { + DEBUG(SSSDBG_MINOR_FAILURE, + ("Mapping ID [%s] to SID failed: [%s]\n", + ar->filter_value, idmap_error_string(map_err))); + ret = EIO; + goto fail; + } + } else { + sid = ar->filter_value; + } + + dom = find_subdomain_by_sid(be_ctx->domain, sid); + if (dom == NULL) { + DEBUG(SSSDBG_OP_FAILURE, ("Invalid domain\n")); + ret = EINVAL; + goto fail; + } + + if (strcasecmp(dom->name, ar->domain) != 0) { + be_req_terminate(be_req, DP_ERR_OK, EOK, NULL); + return; + } + } + } + dom = be_ctx->domain; if (strcasecmp(ar->domain, be_ctx->domain->name) != 0) { /* Subdomain request, verify subdomain */ -- 1.8.3.1