From 662136ce5f8baa0243df1648eb0b05de320242a2 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Thu, 25 Sep 2014 09:38:44 +0200 Subject: [PATCH 07/15] nss: add view support for getpwnam/getpwuid requests For user lookups view and override aware calls to search the cache and read attribute values are used. Relates to https://fedorahosted.org/sssd/ticket/2375 --- src/responder/nss/nsssrv_cmd.c | 132 ++++++++++++++++++++++++++++++----------- 1 file changed, 99 insertions(+), 33 deletions(-) diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c index 78ef1c5..99d44e5 100644 --- a/src/responder/nss/nsssrv_cmd.c +++ b/src/responder/nss/nsssrv_cmd.c @@ -339,9 +339,54 @@ static int fill_pwent(struct sss_packet *packet, msg = msgs[i]; upn = ldb_msg_find_attr_as_string(msg, SYSDB_UPN, NULL); - orig_name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); - uid = ldb_msg_find_attr_as_uint64(msg, SYSDB_UIDNUM, 0); - gid = get_gid_override(msg, dom); + + if (DOM_HAS_VIEWS(dom)) { + orig_name = ldb_msg_find_attr_as_string(msg, + OVERRIDE_PREFIX SYSDB_NAME, + NULL); + if (orig_name != NULL && IS_SUBDOMAIN(dom)) { + /* Override names are not fully qualified */ + add_domain = true; + } + uid = ldb_msg_find_attr_as_uint64(msg, + OVERRIDE_PREFIX SYSDB_UIDNUM, 0); + gid = ldb_msg_find_attr_as_uint64(msg, + OVERRIDE_PREFIX SYSDB_GIDNUM, 0); + tmpstr = ldb_msg_find_attr_as_string(msg, + OVERRIDE_PREFIX SYSDB_GECOS, + NULL); + to_sized_string(&gecos, tmpstr); + tmpstr = ldb_msg_find_attr_as_string(msg, + OVERRIDE_PREFIX SYSDB_HOMEDIR, + NULL); + to_sized_string(&homedir, tmpstr); + tmpstr = ldb_msg_find_attr_as_string(msg, + OVERRIDE_PREFIX SYSDB_SHELL, + NULL); + to_sized_string(&shell, tmpstr); + } else { + orig_name = NULL; + uid = 0; + gid = 0; + ZERO_STRUCT(gecos); + ZERO_STRUCT(homedir); + ZERO_STRUCT(shell); + } + + if (orig_name == NULL) { + orig_name = ldb_msg_find_attr_as_string(msg, + SYSDB_DEFAULT_OVERRIDE_NAME, + NULL); + if (orig_name == NULL) { + orig_name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); + } + } + if (uid == 0) { + uid = ldb_msg_find_attr_as_uint64(msg, SYSDB_UIDNUM, 0); + } + if (gid == 0) { + gid = get_gid_override(msg, dom); + } if (!orig_name || !uid || !gid) { DEBUG(SSSDBG_OP_FAILURE, "Incomplete user object for %s[%llu]! Skipping\n", @@ -385,31 +430,38 @@ static int fill_pwent(struct sss_packet *packet, to_sized_string(&name, tmpstr); - tmpstr = ldb_msg_find_attr_as_string(msg, SYSDB_GECOS, NULL); - if (!tmpstr) { - to_sized_string(&gecos, ""); - } else { - to_sized_string(&gecos, tmpstr); + if (gecos.str == NULL) { + tmpstr = ldb_msg_find_attr_as_string(msg, SYSDB_GECOS, NULL); + if (!tmpstr) { + to_sized_string(&gecos, ""); + } else { + to_sized_string(&gecos, tmpstr); + } } - ZERO_STRUCT(homedir_ctx); + if (homedir.str == NULL) { + ZERO_STRUCT(homedir_ctx); - homedir_ctx.username = name.str; - homedir_ctx.uid = uid; - homedir_ctx.domain = dom->name; - homedir_ctx.upn = upn; + homedir_ctx.username = name.str; + homedir_ctx.uid = uid; + homedir_ctx.domain = dom->name; + homedir_ctx.upn = upn; - tmpstr = get_homedir_override(tmp_ctx, msg, nctx, dom, &homedir_ctx); - if (!tmpstr) { - to_sized_string(&homedir, "/"); - } else { - to_sized_string(&homedir, tmpstr); + tmpstr = get_homedir_override(tmp_ctx, msg, nctx, dom, &homedir_ctx); + if (!tmpstr) { + to_sized_string(&homedir, "/"); + } else { + to_sized_string(&homedir, tmpstr); + } } - tmpstr = get_shell_override(tmp_ctx, msg, nctx, dom); - if (!tmpstr) { - to_sized_string(&shell, ""); - } else { - to_sized_string(&shell, tmpstr); + + if (shell.str == NULL) { + tmpstr = get_shell_override(tmp_ctx, msg, nctx, dom); + if (!tmpstr) { + to_sized_string(&shell, ""); + } else { + to_sized_string(&shell, tmpstr); + } } rsize = 2 * sizeof(uint32_t) + name.len + gecos.len + @@ -734,6 +786,7 @@ static int nss_cmd_getpwnam_search(struct nss_dom_ctx *dctx) int ret; static const char *user_attrs[] = SYSDB_PW_ATTRS; struct ldb_message *msg; + const char *extra_flag = NULL; nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx); @@ -827,7 +880,7 @@ static int nss_cmd_getpwnam_search(struct nss_dom_ctx *dctx) dctx->res->msgs[0] = talloc_steal(dctx->res->msgs, msg); } } else { - ret = sysdb_getpwnam(cmdctx, dom, name, &dctx->res); + ret = sysdb_getpwnam_with_views(cmdctx, dom, name, &dctx->res); } if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, @@ -871,11 +924,17 @@ static int nss_cmd_getpwnam_search(struct nss_dom_ctx *dctx) /* if this is a caching provider (or if we haven't checked the cache * yet) then verify that the cache is uptodate */ if (dctx->check_provider) { - ret = check_cache(dctx, nctx, dctx->res, - SSS_DP_USER, name, 0, - cmdctx->name_is_upn ? EXTRA_NAME_IS_UPN : NULL, - nss_cmd_getby_dp_callback, - dctx); + + if (cmdctx->name_is_upn) { + extra_flag = EXTRA_NAME_IS_UPN; + } else if (DOM_HAS_VIEWS(dom) && dctx->res->count == 0) { + extra_flag = EXTRA_INPUT_MAYBE_WITH_VIEW; + } else { + extra_flag = NULL; + } + + ret = check_cache(dctx, nctx, dctx->res, SSS_DP_USER, name, 0, + extra_flag, nss_cmd_getby_dp_callback, dctx); if (ret != EOK) { /* Anything but EOK means we should reenter the mainloop * because we may be refreshing the cache @@ -1453,6 +1512,7 @@ static int nss_cmd_getpwuid_search(struct nss_dom_ctx *dctx) struct nss_ctx *nctx; int ret; int err; + const char *extra_flag = NULL; nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx); @@ -1492,7 +1552,7 @@ static int nss_cmd_getpwuid_search(struct nss_dom_ctx *dctx) goto done; } - ret = sysdb_getpwuid(cmdctx, dom, cmdctx->id, &dctx->res); + ret = sysdb_getpwuid_with_views(cmdctx, dom, cmdctx->id, &dctx->res); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to make request to our cache!\n"); @@ -1523,9 +1583,15 @@ static int nss_cmd_getpwuid_search(struct nss_dom_ctx *dctx) /* if this is a caching provider (or if we haven't checked the cache * yet) then verify that the cache is uptodate */ if (dctx->check_provider) { - ret = check_cache(dctx, nctx, dctx->res, - SSS_DP_USER, NULL, cmdctx->id, NULL, - nss_cmd_getby_dp_callback, + + if (DOM_HAS_VIEWS(dom) && dctx->res->count == 0) { + extra_flag = EXTRA_INPUT_MAYBE_WITH_VIEW; + } else { + extra_flag = NULL; + } + + ret = check_cache(dctx, nctx, dctx->res, SSS_DP_USER, NULL, + cmdctx->id, extra_flag, nss_cmd_getby_dp_callback, dctx); if (ret != EOK) { /* Anything but EOK means we should reenter the mainloop -- 1.8.3.1