From 6d3c0f1d269193c366945dcdaeff45dd139230cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20B=C5=99ezina?= Date: Wed, 6 Jan 2016 12:45:38 +0100 Subject: [PATCH 53/86] cache_req: do not lookup views if possible This is needed for LOCAL view but also creates a shortcut for server side overrides. Resolves: https://fedorahosted.org/sssd/ticket/2849 Reviewed-by: Jakub Hrozek (cherry picked from commit 5f2b1986a16a394ecbecd16f82c7265b5b47b546) (cherry picked from commit f840cfd6c2ad61045160f301d6ae7276e3e33f54) --- src/responder/common/responder_cache_req.c | 98 +++++++++++++++++++++++++++--- 1 file changed, 88 insertions(+), 10 deletions(-) diff --git a/src/responder/common/responder_cache_req.c b/src/responder/common/responder_cache_req.c index 3a436d8e560c36f36553ca6b92204cc47d58dc2e..2344b0f09c6c4242ff3f769ae565f21c1d2b3e3b 100644 --- a/src/responder/common/responder_cache_req.c +++ b/src/responder/common/responder_cache_req.c @@ -589,24 +589,101 @@ static errno_t cache_req_expiration_status(struct cache_req_input *input, return sss_cmd_check_cache(result->msgs[0], cache_refresh_percent, expire); } -static void cache_req_dpreq_params(struct cache_req_input *input, +static void cache_req_dpreq_params(TALLOC_CTX *mem_ctx, + struct cache_req_input *input, + struct ldb_result *result, const char **_string, uint32_t *_id, const char **_flag) { + struct ldb_result *user = NULL; + const char *name = NULL; + uint32_t id = 0; + errno_t ret; + *_id = input->id; *_string = input->dom_objname; - - if (input->type == CACHE_REQ_USER_BY_CERT) { - *_string = input->cert; - } - *_flag = NULL; - if (DOM_HAS_VIEWS(input->domain)) { - *_flag = EXTRA_INPUT_MAYBE_WITH_VIEW; - } else if (cache_req_input_is_upn(input)) { + + if (cache_req_input_is_upn(input)) { *_flag = EXTRA_NAME_IS_UPN; + return; } + + if (input->type == CACHE_REQ_USER_BY_CERT) { + *_string = input->cert; + return; + } + + if (!DOM_HAS_VIEWS(input->domain)) { + return; + } + + /* We must search with views. */ + if (result == NULL || result->count == 0) { + *_flag = EXTRA_INPUT_MAYBE_WITH_VIEW; + return; + } + + /* If domain has views we will try to user original values instead of the + * overridden ones. This is a must for the LOCAL view since we can't look + * it up otherwise. But it is also a shortcut for non-local views where + * we will not fail over to the overridden value. */ + + switch (input->type) { + case CACHE_REQ_USER_BY_NAME: + case CACHE_REQ_GROUP_BY_NAME: + name = ldb_msg_find_attr_as_string(result->msgs[0], SYSDB_NAME, NULL); + if (name == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: name cannot be NULL\n"); + } + break; + case CACHE_REQ_USER_BY_ID: + id = ldb_msg_find_attr_as_uint64(result->msgs[0], SYSDB_UIDNUM, 0); + if (id == 0) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: id cannot be 0\n"); + } + break; + case CACHE_REQ_GROUP_BY_ID: + id = ldb_msg_find_attr_as_uint64(result->msgs[0], SYSDB_GIDNUM, 0); + if (id == 0) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: id cannot be 0\n"); + } + break; + case CACHE_REQ_INITGROUPS: + ret = sysdb_getpwnam_with_views(NULL, input->domain, + input->dom_objname, &user); + if (ret != EOK || user == NULL || user->count != 1) { + /* Case where the user is not found has been already handled. If + * this is not OK, it is an error. */ + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to match initgroups user " + "[%d]: %s\n", ret, sss_strerror(ret)); + break; + } + + name = ldb_msg_find_attr_as_string(user->msgs[0], SYSDB_NAME, + NULL); + if (name == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: name cannot be NULL\n"); + break; + } + + talloc_steal(mem_ctx, name); + talloc_free(user); + break; + default: + return; + } + + /* Now we have the original name and id. We don't have to search with + * views unless some error occurred. */ + if (name == NULL && id == 0) { + *_flag = EXTRA_INPUT_MAYBE_WITH_VIEW; + return; + } + + *_string = talloc_steal(mem_ctx, name); + *_id = id; } struct cache_req_cache_state { @@ -716,7 +793,8 @@ static errno_t cache_req_cache_check(struct tevent_req *req) state = tevent_req_data(req, struct cache_req_cache_state); - cache_req_dpreq_params(state->input, &search_str, &search_id, &extra_flag); + cache_req_dpreq_params(state, state->input, state->result, + &search_str, &search_id, &extra_flag); ret = cache_req_expiration_status(state->input, state->result, state->cache_refresh_percent); -- 2.5.0