diff options
author | Pavel Březina <pbrezina@redhat.com> | 2015-10-11 16:45:19 +0200 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2015-10-14 13:07:23 +0200 |
commit | 2f793681b4debbe015815f908dc12c0463711609 (patch) | |
tree | a33ec62cfb3cec98f421af64e27841539bc28875 | |
parent | 8b789d6f0a39cd497d1115203db2f1f8dc195456 (diff) | |
download | sssd-2f793681b4debbe015815f908dc12c0463711609.tar.gz sssd-2f793681b4debbe015815f908dc12c0463711609.tar.xz sssd-2f793681b4debbe015815f908dc12c0463711609.zip |
nss: send original name and id with local views if possible
Resolves:
https://fedorahosted.org/sssd/ticket/2833
Reviewed-by: Sumit Bose <sbose@redhat.com>
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
-rw-r--r-- | src/responder/nss/nsssrv_cmd.c | 131 |
1 files changed, 128 insertions, 3 deletions
diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c index 4f151b1a1..c29b4091d 100644 --- a/src/responder/nss/nsssrv_cmd.c +++ b/src/responder/nss/nsssrv_cmd.c @@ -600,6 +600,124 @@ is_refreshed_on_bg(enum sss_dp_acct_type req_type, static void nsssrv_dp_send_acct_req_done(struct tevent_req *req); +static void get_dp_name_and_id(TALLOC_CTX *mem_ctx, + struct sss_domain_info *dom, + enum sss_dp_acct_type req_type, + const char *opt_name, + uint32_t opt_id, + const char **_name, + uint32_t *_id) +{ + TALLOC_CTX *tmp_ctx; + struct ldb_result *res = NULL; + const char *attr; + const char *name; + uint32_t id; + errno_t ret; + + /* First set the same values to make things easier. */ + *_name = opt_name; + *_id = opt_id; + + if (!DOM_HAS_VIEWS(dom) || !is_local_view(dom->view_name)) { + DEBUG(SSSDBG_TRACE_FUNC, "Not a LOCAL view, continuing with " + "provided values.\n"); + return; + } + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); + return; + } + + if (opt_name != NULL) { + switch (req_type) { + case SSS_DP_USER: + case SSS_DP_INITGROUPS: + ret = sysdb_getpwnam_with_views(tmp_ctx, dom, opt_name, &res); + if (ret != EOK) { + DEBUG(SSSDBG_CONF_SETTINGS, + "sysdb_getpwnam_with_views() failed [%d]: %s\n", + ret, sss_strerror(ret)); + goto done; + } + break; + case SSS_DP_GROUP: + ret = sysdb_getgrnam_with_views(tmp_ctx, dom, opt_name, &res); + if (ret != EOK) { + DEBUG(SSSDBG_CONF_SETTINGS, + "sysdb_getgrnam_with_views() failed [%d]: %s\n", + ret, sss_strerror(ret)); + goto done; + } + break; + default: + goto done; + } + + if (res == NULL || res->count != 1) { + /* This should not happen with LOCAL view and overridden value. */ + DEBUG(SSSDBG_TRACE_FUNC, "Entry is missing?! Continuing with " + "provided values.\n"); + goto done; + } + + name = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_NAME, NULL); + if (name == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: name cannot be NULL\n"); + goto done; + } + + *_name = talloc_steal(mem_ctx, name); + } else if (opt_id != 0) { + switch (req_type) { + case SSS_DP_USER: + ret = sysdb_getpwuid_with_views(tmp_ctx, dom, opt_id, &res); + if (ret != EOK) { + DEBUG(SSSDBG_CONF_SETTINGS, + "sysdb_getpwuid_with_views() failed [%d]: %s\n", + ret, sss_strerror(ret)); + goto done; + } + + attr = SYSDB_UIDNUM; + break; + case SSS_DP_GROUP: + ret = sysdb_getgrgid_with_views(tmp_ctx, dom, opt_id, &res); + if (ret != EOK) { + DEBUG(SSSDBG_CONF_SETTINGS, + "sysdb_getgrgid_with_views() failed [%d]: %s\n", + ret, sss_strerror(ret)); + goto done; + } + + attr = SYSDB_GIDNUM; + break; + default: + goto done; + } + + if (res == NULL || res->count != 1) { + /* This should not happen with LOCAL view and overridden value. */ + DEBUG(SSSDBG_TRACE_FUNC, "Entry is missing?! Continuing with " + "provided values.\n"); + goto done; + } + + id = ldb_msg_find_attr_as_uint64(res->msgs[0], attr, 0); + if (id == 0) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: id cannot be 0\n"); + goto done; + } + + *_id = id; + } + +done: + talloc_free(tmp_ctx); +} + /* FIXME: do not check res->count, but get in a msgs and check in parent */ errno_t check_cache(struct nss_dom_ctx *dctx, struct nss_ctx *nctx, @@ -617,6 +735,8 @@ errno_t check_cache(struct nss_dom_ctx *dctx, struct tevent_req *req = NULL; struct dp_callback_ctx *cb_ctx = NULL; uint64_t cacheExpire = 0; + const char *name = opt_name; + uint32_t id = opt_id; /* when searching for a user or netgroup, more than one reply is a * db error @@ -628,6 +748,11 @@ errno_t check_cache(struct nss_dom_ctx *dctx, return ENOENT; } + /* In case of local view we have to always contant DP with the original + * name or id. */ + get_dp_name_and_id(dctx->cmdctx, dctx->domain, req_type, opt_name, opt_id, + &name, &id); + /* if we have any reply let's check cache validity, but ignore netgroups * if refresh_expired_interval is set (which implies that another method * is used to refresh netgroups) @@ -672,10 +797,10 @@ errno_t check_cache(struct nss_dom_ctx *dctx, * immediately. */ DEBUG(SSSDBG_TRACE_FUNC, - "Performing midpoint cache update on [%s]\n", opt_name); + "Performing midpoint cache update on [%s]\n", name); req = sss_dp_get_account_send(cctx, cctx->rctx, dctx->domain, true, - req_type, opt_name, opt_id, extra); + req_type, name, id, extra); if (!req) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory sending out-of-band data provider " @@ -704,7 +829,7 @@ errno_t check_cache(struct nss_dom_ctx *dctx, } req = sss_dp_get_account_send(cctx, cctx->rctx, dctx->domain, true, - req_type, opt_name, opt_id, extra); + req_type, name, id, extra); if (!req) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory sending data provider request\n"); |