diff options
| author | Jakub Hrozek <jhrozek@redhat.com> | 2016-03-17 08:19:18 +0100 |
|---|---|---|
| committer | Jakub Hrozek <jhrozek@redhat.com> | 2016-07-07 10:26:01 +0200 |
| commit | 2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034 (patch) | |
| tree | ddea07a4ba5ce486464137c8dcc8d39d7b98b11a /src | |
| parent | 27bf39ed3e197497cf4aca58038d788ea5b5ddbc (diff) | |
NSS: Fix NSS responder to cope with fully-qualified usernames
Adds a utility function sized_output_name() which wraps the output_name()
function and returns the sized_struct structure. This function is used
when formatting the output name for the client, but also when
saving/deleting the memory cache entries.
Its sister function sized_member_name() is very similar, but infers the
domain name from memberuid or ghost attribute.
Because all names internally are used in the same format, the logic to
append domain or format the usename for output in the fill_XXX() family
of functions is much simpler. In general, adding a domain suffix no
longer relies in the domain being a subdomain, but only the dom->fqnames
The parse_member() function was removed because it is no longer
required.
The nss test was amended to store names in the internal fqdn format on
input and checks for either shortnames or qualified names with the right
format created using sss_tc_fqname() on output.
Reviewed-by: Sumit Bose <sbose@redhat.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/responder/nss/nsssrv_cmd.c | 590 | ||||
| -rw-r--r-- | src/tests/cmocka/test_nss_srv.c | 1295 |
2 files changed, 1028 insertions, 857 deletions
diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c index a54d3d8ba..700998974 100644 --- a/src/responder/nss/nsssrv_cmd.c +++ b/src/responder/nss/nsssrv_cmd.c @@ -193,22 +193,11 @@ static const char *get_homedir_override(TALLOC_CTX *mem_ctx, struct sss_nss_homedir_ctx *homedir_ctx) { const char *homedir; - const char *orig_name = homedir_ctx->username; - errno_t ret; homedir = sss_view_ldb_msg_find_attr_as_string(dom, msg, SYSDB_HOMEDIR, NULL); homedir_ctx->original = homedir; - /* Subdomain users store FQDN in their name attribute */ - ret = sss_parse_name_const(mem_ctx, dom->names, orig_name, - NULL, &homedir_ctx->username); - if (ret != EOK) { - DEBUG(SSSDBG_MINOR_FAILURE, "Could not parse [%s] into " - "name-value components.\n", orig_name); - return NULL; - } - /* Check to see which homedir_prefix to use. */ if (dom->homedir_substr != NULL) { homedir_ctx->config_homedir_substr = dom->homedir_substr; @@ -324,6 +313,93 @@ static const char *get_shell_override(TALLOC_CTX *mem_ctx, return talloc_strdup(mem_ctx, NOLOGIN_SHELL); } +static int sized_output_name(TALLOC_CTX *mem_ctx, + struct resp_ctx *rctx, + const char *orig_name, + struct sss_domain_info *name_dom, + struct sized_string **_name) +{ + TALLOC_CTX *tmp_ctx = NULL; + errno_t ret; + char *username; + struct sized_string *name; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + return ENOMEM; + } + + username = sss_output_name(tmp_ctx, orig_name, name_dom->case_preserve, + rctx->override_space); + if (username == NULL) { + ret = EIO; + goto done; + } + + if (name_dom->fqnames) { + username = sss_tc_fqname(tmp_ctx, name_dom->names, name_dom, username); + if (username == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "sss_replace_space failed\n"); + ret = EIO; + goto done; + } + } + + name = talloc_zero(tmp_ctx, struct sized_string); + if (name == NULL) { + ret = ENOMEM; + goto done; + } + + to_sized_string(name, username); + name->str = talloc_steal(name, username); + *_name = talloc_steal(mem_ctx, name); + ret = EOK; +done: + talloc_zfree(tmp_ctx); + return ret; +} + +static int sized_member_name(TALLOC_CTX *mem_ctx, + struct resp_ctx *rctx, + const char *member_name, + struct sized_string **_name) +{ + TALLOC_CTX *tmp_ctx = NULL; + errno_t ret; + char *domname; + struct sss_domain_info *member_dom; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + return ENOMEM; + } + + ret = sss_parse_internal_fqname(tmp_ctx, member_name, NULL, &domname); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "sss_parse_internal_fqname failed\n"); + goto done; + } + + if (domname == NULL) { + ret = ERR_WRONG_NAME_FORMAT; + goto done; + } + + member_dom = find_domain_by_name(get_domains_head(rctx->domains), + domname, true); + if (member_dom == NULL) { + ret = ERR_DOMAIN_NOT_FOUND; + goto done; + } + + ret = sized_output_name(mem_ctx, rctx, member_name, + member_dom, _name); +done: + talloc_free(tmp_ctx); + return ret; +} + static int fill_pwent(struct sss_packet *packet, struct sss_domain_info *dom, struct nss_ctx *nctx, @@ -336,18 +412,15 @@ static int fill_pwent(struct sss_packet *packet, const char *upn; const char *tmpstr; const char *orig_name; - struct sized_string name; + struct sized_string *name; struct sized_string gecos; struct sized_string homedir; struct sized_string shell; struct sized_string pwfield; - struct sized_string fullname; uint32_t uid; uint32_t gid; size_t rsize, rp, blen; - int fq_len = 0; int i, ret, num; - bool add_domain = (!IS_SUBDOMAIN(dom) && dom->fqnames); const char *domain = dom->name; bool packet_initialized = false; int ncret; @@ -371,10 +444,6 @@ static int fill_pwent(struct sss_packet *packet, 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; - } gid = ldb_msg_find_attr_as_uint64(msg, OVERRIDE_PREFIX SYSDB_GIDNUM, 0); @@ -408,8 +477,7 @@ static int fill_pwent(struct sss_packet *packet, ncret = sss_ncache_check_user(nctx->rctx->ncache, dom, orig_name); if (ncret == EEXIST) { DEBUG(SSSDBG_TRACE_FUNC, - "User [%s@%s] filtered out! (negative cache)\n", - orig_name, domain); + "User [%s] filtered out! (negative cache)\n", orig_name); continue; } } @@ -421,23 +489,14 @@ static int fill_pwent(struct sss_packet *packet, packet_initialized = true; } - tmpstr = sss_get_cased_name(tmp_ctx, orig_name, dom->case_preserve); - if (tmpstr == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, - "sss_get_cased_name failed, skipping\n"); - continue; - } - - tmpstr = sss_replace_space(tmp_ctx, tmpstr, - nctx->rctx->override_space); - if (tmpstr == NULL) { + ret = sized_output_name(tmp_ctx, nctx->rctx, orig_name, + dom, &name); + if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, - "sss_replace_space failed, skipping\n"); + "sized_output_name failed, skipping\n"); continue; } - to_sized_string(&name, tmpstr); - tmpstr = sss_view_ldb_msg_find_attr_as_string(dom, msg, SYSDB_GECOS, NULL); if (!tmpstr) { @@ -447,8 +506,7 @@ static int fill_pwent(struct sss_packet *packet, } ZERO_STRUCT(homedir_ctx); - - homedir_ctx.username = name.str; + homedir_ctx.username = orig_name; homedir_ctx.uid = uid; homedir_ctx.domain = dom->name; homedir_ctx.upn = upn; @@ -467,20 +525,9 @@ static int fill_pwent(struct sss_packet *packet, to_sized_string(&shell, tmpstr); } - rsize = 2 * sizeof(uint32_t) + name.len + gecos.len + + rsize = 2 * sizeof(uint32_t) + name->len + gecos.len + homedir.len + shell.len + pwfield.len; - if (add_domain) { - fq_len = sss_fqname(NULL, 0, dom->names, dom, name.str); - if (fq_len >= 0) { - fq_len += 1; - rsize -= name.len; - rsize += fq_len; - } else { - fq_len = 0; - } - } - ret = sss_packet_grow(packet, rsize); if (ret != EOK) { num = 0; @@ -490,20 +537,8 @@ static int fill_pwent(struct sss_packet *packet, SAFEALIGN_SET_UINT32(&body[rp], uid, &rp); SAFEALIGN_SET_UINT32(&body[rp], gid, &rp); - - if (add_domain) { - ret = sss_fqname((char *) &body[rp], fq_len, dom->names, dom, name.str); - if (ret < 0 || ret != fq_len - 1) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Failed to generate a fully qualified name for user " - "[%s] in [%s]! Skipping user.\n", name.str, domain); - continue; - } - } else { - memcpy(&body[rp], name.str, name.len); - } - to_sized_string(&fullname, (const char *)&body[rp]); - rp += fullname.len; + memcpy(&body[rp], name->str, name->len); + rp += name->len; memcpy(&body[rp], pwfield.str, pwfield.len); rp += pwfield.len; @@ -518,13 +553,13 @@ static int fill_pwent(struct sss_packet *packet, if (pw_mmap_cache && nctx->pwd_mc_ctx) { ret = sss_mmap_cache_pw_store(&nctx->pwd_mc_ctx, - &fullname, &pwfield, + name, &pwfield, uid, gid, &gecos, &homedir, &shell); if (ret != EOK && ret != ENOMEM) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to store user %s(%s) in mmap cache!\n", - name.str, domain); + name->str, domain); } } } @@ -881,13 +916,14 @@ static void nsssrv_dp_send_acct_req_done(struct tevent_req *req) cb_ctx->callback(err_maj, err_min, err_msg, cb_ctx->ptr); } -static int delete_entry_from_memcache(struct sss_domain_info *dom, char *name, +static int delete_entry_from_memcache(struct sss_domain_info *dom, + char *name, + struct resp_ctx *rctx, struct sss_mc_ctx *mc_ctx, enum sss_mc_type type) { TALLOC_CTX *tmp_ctx = NULL; - struct sized_string delete_name; - char *fqdn = NULL; + struct sized_string *delete_name; int ret; tmp_ctx = talloc_new(NULL); @@ -896,21 +932,15 @@ static int delete_entry_from_memcache(struct sss_domain_info *dom, char *name, return ENOMEM; } - if (dom->fqnames) { - fqdn = sss_tc_fqname(tmp_ctx, dom->names, dom, name); - if (fqdn == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory.\n"); - ret = ENOMEM; - goto done; - } - to_sized_string(&delete_name, fqdn); - } else { - to_sized_string(&delete_name, name); + ret = sized_output_name(tmp_ctx, rctx, name, dom, &delete_name); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "sized_output_name failed: %d\n", ret); + goto done; } switch (type) { case SSS_MC_PASSWD: - ret = sss_mmap_cache_pw_invalidate(mc_ctx, &delete_name); + ret = sss_mmap_cache_pw_invalidate(mc_ctx, delete_name); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Internal failure in memory cache code: %d [%s]\n", @@ -919,7 +949,7 @@ static int delete_entry_from_memcache(struct sss_domain_info *dom, char *name, } break; case SSS_MC_GROUP: - ret = sss_mmap_cache_gr_invalidate(mc_ctx, &delete_name); + ret = sss_mmap_cache_gr_invalidate(mc_ctx, delete_name); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Internal failure in memory cache code: %d [%s]\n", @@ -928,7 +958,7 @@ static int delete_entry_from_memcache(struct sss_domain_info *dom, char *name, } break; case SSS_MC_INITGROUPS: - ret = sss_mmap_cache_initgr_invalidate(mc_ctx, &delete_name); + ret = sss_mmap_cache_initgr_invalidate(mc_ctx, delete_name); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Internal failure in memory cache code: %d [%s]\n", @@ -993,14 +1023,9 @@ static int nss_cmd_getpwnam_search(struct nss_dom_ctx *dctx) dctx->domain = dom; talloc_free(name); - name = sss_get_cased_name(cmdctx, cmdctx->name, dom->case_sensitive); - if (!name) return ENOMEM; - - name = sss_reverse_replace_space(dctx, name, - nctx->rctx->override_space); + name = sss_resp_create_fqname(dctx, nctx->rctx, dctx->domain, + cmdctx->name_is_upn, cmdctx->name); if (name == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, - "sss_reverse_replace_space failed\n"); return ENOMEM; } @@ -1028,8 +1053,7 @@ static int nss_cmd_getpwnam_search(struct nss_dom_ctx *dctx) return ENOENT; } - DEBUG(SSSDBG_CONF_SETTINGS, - "Requesting info for [%s@%s]\n", name, dom->name); + DEBUG(SSSDBG_CONF_SETTINGS, "Requesting info for [%s]\n", name); if (dom->sysdb == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, @@ -1078,9 +1102,9 @@ static int nss_cmd_getpwnam_search(struct nss_dom_ctx *dctx) DEBUG(SSSDBG_FATAL_FAILURE, "getpwnam call returned more than one result !?!\n"); sss_log(SSS_LOG_ERR, - "More users have the same name [%s@%s] in SSSD cache. " + "More users have the same name [%s] in SSSD cache. " "SSSD will not work correctly.\n", - name, dom->name); + name); return ENOENT; } @@ -1088,8 +1112,8 @@ static int nss_cmd_getpwnam_search(struct nss_dom_ctx *dctx) /* set negative cache only if not result of cache check */ ret = sss_ncache_set_user(nctx->rctx->ncache, false, dom, name); if (ret != EOK) { - DEBUG(SSSDBG_MINOR_FAILURE, "Cannot set negcache for %s@%s\n", - name, dom->name); + DEBUG(SSSDBG_MINOR_FAILURE, "Cannot set negcache for %s\n", + name); } /* if a multidomain search, try with next */ @@ -1105,14 +1129,15 @@ static int nss_cmd_getpwnam_search(struct nss_dom_ctx *dctx) DEBUG(SSSDBG_OP_FAILURE, "No results for getpwnam call\n"); /* User not found in ldb -> delete user from memory cache. */ - ret = delete_entry_from_memcache(dctx->domain, name, + ret = delete_entry_from_memcache(dctx->domain, name, nctx->rctx, nctx->pwd_mc_ctx, SSS_MC_PASSWD); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Deleting user from memcache failed.\n"); } - ret = delete_entry_from_memcache(dctx->domain, name, + ret = delete_entry_from_memcache(dctx->domain, + name, nctx->rctx, nctx->initgr_mc_ctx, SSS_MC_INITGROUPS); if (ret != EOK) { @@ -1149,9 +1174,7 @@ static int nss_cmd_getpwnam_search(struct nss_dom_ctx *dctx) } /* One result found */ - DEBUG(SSSDBG_TRACE_FUNC, - "Returning info for user [%s@%s]\n", name, dom->name); - + DEBUG(SSSDBG_TRACE_FUNC, "Returning info for user [%s]\n", name); return EOK; } @@ -2750,53 +2773,8 @@ void nss_update_gr_memcache(struct nss_ctx *nctx) #define MNUM_ROFFSET sizeof(uint32_t) #define STRS_ROFFSET 2*sizeof(uint32_t) -static int parse_member(TALLOC_CTX *mem_ctx, struct sss_domain_info *group_dom, - const char *member, struct sss_domain_info **_member_dom, - struct sized_string *_name, bool *_add_domain) -{ - errno_t ret; - char *username; - char *domname; - const char *use_member; - struct sss_domain_info *member_dom; - bool add_domain; - - ret = sss_parse_name(mem_ctx, group_dom->names, member, &domname, &username); - if (ret != EOK) { - DEBUG(SSSDBG_MINOR_FAILURE, "Could not parse [%s] into " - "name-value components.\n", member); - return ret; - } - - add_domain = (!IS_SUBDOMAIN(group_dom) && group_dom->fqnames); - use_member = member; - member_dom = group_dom; - - if (IS_SUBDOMAIN(group_dom) == false && domname != NULL) { - /* The group is stored in the parent domain, but the member comes from. - * a subdomain. No need to add the domain component, it's already - * present in the memberuid/ghost attribute - */ - add_domain = false; - } - - if (IS_SUBDOMAIN(group_dom) == true && domname == NULL) { - /* The group is stored in a subdomain, but the member comes - * from the parent domain. Need to add the domain component - * of the parent domain - */ - add_domain = true; - use_member = username; - member_dom = group_dom->parent; - } - - to_sized_string(_name, use_member); - *_add_domain = add_domain; - *_member_dom = member_dom; - return EOK; -} - static int fill_members(struct sss_packet *packet, + struct resp_ctx *rctx, struct sss_domain_info *dom, struct nss_ctx *nctx, struct ldb_message_element *el, @@ -2804,105 +2782,51 @@ static int fill_members(struct sss_packet *packet, size_t *_rsize, int *_memnum) { - int i, ret = EOK; + int ret = EOK; int memnum = *_memnum; size_t rzero= *_rzero; size_t rsize = *_rsize; - const char *tmpstr; - struct sized_string name; + struct sized_string *name; TALLOC_CTX *tmp_ctx = NULL; - int nlen = 0; - + const char *fqname; uint8_t *body; size_t blen; - const char *domain = dom->name; - bool add_domain; - struct sss_domain_info *member_dom; - tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } sss_packet_get_body(packet, &body, &blen); - for (i = 0; i < el->num_values; i++) { - tmpstr = sss_get_cased_name(tmp_ctx, (char *)el->values[i].data, - dom->case_preserve); - if (tmpstr == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, - "sss_get_cased_name failed, skipping\n"); - continue; - } - - tmpstr = sss_replace_space(tmp_ctx, tmpstr, - nctx->rctx->override_space); - if (tmpstr == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, - "sss_replace_space failed\n"); - ret = ENOMEM; - goto done; - } + for (unsigned i = 0; i < el->num_values; i++) { + fqname = (const char *)el->values[i].data; if (nctx->filter_users_in_groups) { - ret = sss_ncache_check_user(nctx->rctx->ncache, dom, tmpstr); + ret = sss_ncache_check_user(nctx->rctx->ncache, dom, fqname); if (ret == EEXIST) { DEBUG(SSSDBG_TRACE_FUNC, - "Group [%s] member [%s@%s] filtered out!" + "Group [%s] member [%s] filtered out!" " (negative cache)\n", - (char *)&body[rzero+STRS_ROFFSET], tmpstr, domain); + (char *)&body[rzero+STRS_ROFFSET], fqname); continue; } } - ret = parse_member(tmp_ctx, dom, tmpstr, &member_dom, &name, &add_domain); + ret = sized_member_name(tmp_ctx, rctx, fqname, &name); if (ret != EOK) { - DEBUG(SSSDBG_MINOR_FAILURE, - "Could not process member %s, skipping\n", tmpstr); - continue; - } - - if (add_domain) { - nlen = sss_fqname(NULL, 0, member_dom->names, member_dom, - name.str); - if (nlen >= 0) { - nlen += 1; - } else { - /* Other failures caught below */ - nlen = 0; - } - } else { - nlen = name.len; + DEBUG(SSSDBG_OP_FAILURE, "sized_member_name failed: %d\n", ret); + goto done; } - ret = sss_packet_grow(packet, nlen); + ret = sss_packet_grow(packet, name->len); if (ret != EOK) { goto done; } sss_packet_get_body(packet, &body, &blen); - if (add_domain) { - ret = sss_fqname((char *)&body[rzero + rsize], nlen, - member_dom->names, member_dom, name.str); - if (ret < 0 || ret != nlen - 1) { - DEBUG(SSSDBG_OP_FAILURE, "Failed to generate a fully qualified name" - " for member [%s@%s] of group [%s]!" - " Skipping\n", name.str, domain, - (char *)&body[rzero+STRS_ROFFSET]); - /* reclaim space */ - ret = sss_packet_shrink(packet, nlen); - if (ret != EOK) { - goto done; - } - continue; - } - - } else { - memcpy(&body[rzero + rsize], name.str, name.len); - } - - rsize += nlen; + memcpy(&body[rzero + rsize], name->str, name->len); + rsize += name->len; memnum++; } @@ -2928,16 +2852,12 @@ static int fill_grent(struct sss_packet *packet, uint8_t *body; size_t blen; uint32_t gid; - const char *tmpstr; const char *orig_name = NULL; - struct sized_string name; + struct sized_string *name; struct sized_string pwfield; - struct sized_string fullname; - int fq_len = 0; int i = 0; int ret, num, memnum; size_t rzero, rsize; - bool add_domain = (!IS_SUBDOMAIN(dom) && dom->fqnames); const char *domain = dom->name; TALLOC_CTX *tmp_ctx = NULL; @@ -2979,10 +2899,6 @@ static int fill_grent(struct sss_packet *packet, 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; - } } if (orig_name == NULL) { orig_name = ldb_msg_find_attr_as_string(msg, @@ -3005,43 +2921,20 @@ static int fill_grent(struct sss_packet *packet, ret = sss_ncache_check_group(nctx->rctx->ncache, dom, orig_name); if (ret == EEXIST) { DEBUG(SSSDBG_TRACE_FUNC, - "Group [%s@%s] filtered out! (negative cache)\n", - orig_name, domain); + "Group [%s] filtered out! (negative cache)\n", orig_name); continue; } } - tmpstr = sss_get_cased_name(tmp_ctx, orig_name, dom->case_preserve); - if (tmpstr == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, - "sss_get_cased_name failed, skipping\n"); - continue; - } - - tmpstr = sss_replace_space(tmp_ctx, tmpstr, - nctx->rctx->override_space); - if (tmpstr == NULL) { + ret = sized_output_name(tmp_ctx, nctx->rctx, orig_name, dom, &name); + if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, - "sss_replace_space failed, skipping\n"); + "sized_output_name failed, skipping\n"); continue; } - to_sized_string(&name, tmpstr); - /* fill in gid and name and set pointer for number of members */ - rsize = STRS_ROFFSET + name.len + pwfield.len; /* name\0x\0 */ - - if (add_domain) { - fq_len = sss_fqname(NULL, 0, dom->names, dom, name.str); - if (fq_len >= 0) { - fq_len += 1; - rsize -= name.len; - rsize += fq_len; - } else { - /* Other failures caught below */ - fq_len = 0; - } - } + rsize = STRS_ROFFSET + name->len + pwfield.len; /* name\0x\0 */ ret = sss_packet_grow(packet, rsize); if (ret != EOK) { @@ -3057,37 +2950,18 @@ static int fill_grent(struct sss_packet *packet, SAFEALIGN_SET_UINT32(&body[rzero+MNUM_ROFFSET], 0, NULL); /* 8-X: sequence of strings (name, passwd, mem..) */ - if (add_domain) { - ret = sss_fqname((char *)&body[rzero+STRS_ROFFSET], fq_len, - dom->names, dom, name.str); - if (ret < 0 || ret != fq_len - 1) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Failed to generate a fully qualified name for" - " group [%s] in [%s]! Skipping\n", name.str, domain); - /* reclaim space */ - ret = sss_packet_shrink(packet, rsize); - if (ret != EOK) { - num = 0; - goto done; - } - rsize = 0; - continue; - } - } else { - memcpy(&body[rzero+STRS_ROFFSET], name.str, name.len); - } - to_sized_string(&fullname, (const char *)&body[rzero+STRS_ROFFSET]); + memcpy(&body[rzero+STRS_ROFFSET], name->str, name->len); /* group passwd field */ - memcpy(&body[rzero+STRS_ROFFSET + fullname.len], + memcpy(&body[rzero+STRS_ROFFSET + name->len], pwfield.str, pwfield.len); memnum = 0; if (!dom->ignore_group_members) { el = sss_view_ldb_msg_find_element(dom, msg, SYSDB_MEMBERUID); if (el) { - ret = fill_members(packet, dom, nctx, el, &rzero, &rsize, - &memnum); + ret = fill_members(packet, nctx->rctx, dom, nctx, el, + &rzero, &rsize, &memnum); if (ret != EOK) { num = 0; goto done; @@ -3104,8 +2978,8 @@ static int fill_grent(struct sss_packet *packet, num = 0; goto done; } - ret = fill_members(packet, dom, nctx, el, &rzero, &rsize, - &memnum); + ret = fill_members(packet, nctx->rctx, dom, nctx, el, + &rzero, &rsize, &memnum); if (ret != EOK) { num = 0; goto done; @@ -3123,17 +2997,16 @@ static int fill_grent(struct sss_packet *packet, if (gr_mmap_cache && nctx->grp_mc_ctx) { /* body was reallocated, so fullname might be pointing to * where body used to be, not where it is */ - to_sized_string(&fullname, (const char *)&body[rzero+STRS_ROFFSET]); ret = sss_mmap_cache_gr_store(&nctx->grp_mc_ctx, - &fullname, &pwfield, gid, memnum, + name, &pwfield, gid, memnum, (char *)&body[rzero] + STRS_ROFFSET + - fullname.len + pwfield.len, + name->len + pwfield.len, rsize - STRS_ROFFSET - - fullname.len - pwfield.len); + name->len - pwfield.len); if (ret != EOK && ret != ENOMEM) { DEBUG(SSSDBG_OP_FAILURE, "Failed to store group %s(%s) in mmap cache!\n", - name.str, domain); + name->str, domain); } } @@ -3227,14 +3100,9 @@ static int nss_cmd_getgrnam_search(struct nss_dom_ctx *dctx) dctx->domain = dom; talloc_free(name); - name = sss_get_cased_name(dctx, cmdctx->name, dom->case_sensitive); - if (!name) return ENOMEM; - - name = sss_reverse_replace_space(dctx, name, - nctx->rctx->override_space); + name = sss_resp_create_fqname(dctx, nctx->rctx, dctx->domain, + cmdctx->name_is_upn, cmdctx->name); if (name == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, - "sss_reverse_replace_space failed\n"); return ENOMEM; } @@ -3258,8 +3126,7 @@ static int nss_cmd_getgrnam_search(struct nss_dom_ctx *dctx) return ENOENT; } - DEBUG(SSSDBG_CONF_SETTINGS, - "Requesting info for [%s@%s]\n", name, dom->name); + DEBUG(SSSDBG_CONF_SETTINGS, "Requesting info for [%s]\n", name); if (dom->sysdb == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, @@ -3278,9 +3145,9 @@ static int nss_cmd_getgrnam_search(struct nss_dom_ctx *dctx) DEBUG(SSSDBG_FATAL_FAILURE, "getgrnam call returned more than one result !?!\n"); sss_log(SSS_LOG_ERR, - "More groups have the same name [%s@%s] in SSSD cache. " + "More groups have the same name [%s] in SSSD cache. " "SSSD will not work correctly.\n", - name, dom->name); + name); return ENOENT; } @@ -3288,8 +3155,8 @@ static int nss_cmd_getgrnam_search(struct nss_dom_ctx *dctx) /* set negative cache only if not result of cache check */ ret = sss_ncache_set_group(nctx->rctx->ncache, false, dom, name); if (ret != EOK) { - DEBUG(SSSDBG_MINOR_FAILURE, "Cannot set negcache for %s@%s\n", - name, dom->name); + DEBUG(SSSDBG_MINOR_FAILURE, + "Cannot set negcache for %s\n", name); } /* if a multidomain search, try with next */ @@ -3301,7 +3168,7 @@ static int nss_cmd_getgrnam_search(struct nss_dom_ctx *dctx) DEBUG(SSSDBG_OP_FAILURE, "No results for getgrnam call\n"); /* Group not found in ldb -> delete group from memory cache. */ - ret = delete_entry_from_memcache(dctx->domain, name, + ret = delete_entry_from_memcache(dctx->domain, name, nctx->rctx, nctx->grp_mc_ctx, SSS_MC_GROUP); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, @@ -3337,7 +3204,7 @@ static int nss_cmd_getgrnam_search(struct nss_dom_ctx *dctx) /* One result found */ DEBUG(SSSDBG_TRACE_FUNC, - "Returning info for group [%s@%s]\n", name, dom->name); + "Returning info for group [%s]\n", name); return EOK; } @@ -4277,15 +4144,9 @@ static int fill_initgr(struct sss_packet *packet, if (nctx->initgr_mc_ctx) { struct sized_string unique_name; - char *fq_name = sss_tc_fqname(packet, dom->names, dom, name); - if (!fq_name) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Could not create fq name\n"); - return ENOMEM; - } to_sized_string(&rawname, mc_name); - to_sized_string(&unique_name, fq_name); + to_sized_string(&unique_name, name); ret = sss_mmap_cache_initgr_store(&nctx->initgr_mc_ctx, &rawname, &unique_name, num - skipped, gids); if (ret != EOK && ret != ENOMEM) { @@ -4361,19 +4222,16 @@ static int nss_cmd_initgroups_search(struct nss_dom_ctx *dctx) dctx->domain = dom; talloc_zfree(cmdctx->normalized_name); - name = sss_get_cased_name(dctx, cmdctx->name, dom->case_sensitive); - if (!name) return ENOMEM; - name = sss_reverse_replace_space(cmdctx, name, - nctx->rctx->override_space); - /* save name so it can be used in initgr reply */ - cmdctx->normalized_name = name; + name = sss_resp_create_fqname(dctx, nctx->rctx, dctx->domain, + cmdctx->name_is_upn, cmdctx->name); if (name == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, - "sss_reverse_replace_space failed\n"); return ENOMEM; } + /* save name so it can be used in initgr reply */ + cmdctx->normalized_name = name; + /* verify this user has not yet been negatively cached, * or has been permanently filtered */ ret = sss_ncache_check_user(nctx->rctx->ncache, dom, name); @@ -4394,8 +4252,7 @@ static int nss_cmd_initgroups_search(struct nss_dom_ctx *dctx) return ENOENT; } - DEBUG(SSSDBG_CONF_SETTINGS, - "Requesting info for [%s@%s]\n", name, dom->name); + DEBUG(SSSDBG_CONF_SETTINGS, "Requesting info for [%s]\n", name); if (dom->sysdb == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, @@ -4453,8 +4310,8 @@ static int nss_cmd_initgroups_search(struct nss_dom_ctx *dctx) /* set negative cache only if not result of cache check */ ret = sss_ncache_set_user(nctx->rctx->ncache, false, dom, name); if (ret != EOK) { - DEBUG(SSSDBG_MINOR_FAILURE, "Cannot set negcache for %s@%s\n", - name, dom->name); + DEBUG(SSSDBG_MINOR_FAILURE, "Cannot set negcache for %s\n", + name); } /* if a multidomain search, try with next */ @@ -4493,8 +4350,7 @@ static int nss_cmd_initgroups_search(struct nss_dom_ctx *dctx) } } - DEBUG(SSSDBG_TRACE_FUNC, - "Initgroups for [%s@%s] completed\n", name, dom->name); + DEBUG(SSSDBG_TRACE_FUNC, "Initgroups for [%s] completed\n", name); return EOK; } @@ -4538,7 +4394,6 @@ static errno_t nss_cmd_getsidby_search(struct nss_dom_ctx *dctx) bool user_found = false; bool group_found = false; struct ldb_message *msg = NULL; - char *sysdb_name = NULL; char *name = NULL; char *req_name; uint32_t req_id; @@ -4607,42 +4462,21 @@ static errno_t nss_cmd_getsidby_search(struct nss_dom_ctx *dctx) } else { talloc_free(name); - talloc_zfree(sysdb_name); - name = sss_get_cased_name(cmdctx, cmdctx->name, dom->case_sensitive); + name = sss_resp_create_fqname(cmdctx, nctx->rctx, dom, false, cmdctx->name); if (name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sss_get_cased_name failed.\n"); ret = ENOMEM; goto done; } - name = sss_reverse_replace_space(dctx, name, - nctx->rctx->override_space); - if (name == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, - "sss_reverse_replace_space failed\n"); - ret = ENOMEM; - goto done; - } - - /* For subdomains a fully qualified name is needed for - * sysdb_search_user_by_name and sysdb_search_group_by_name. */ - if (IS_SUBDOMAIN(dom)) { - sysdb_name = sss_tc_fqname(cmdctx, dom->names, dom, name); - if (sysdb_name == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); - ret = ENOMEM; - goto done; - } - } - - /* verify this name has not yet been negatively cached, as user * and groupm, or has been permanently filtered */ - ret = sss_ncache_check_user(nctx->rctx->ncache, dom, name); + ret = sss_ncache_check_user(nctx->rctx->ncache, dom, cmdctx->name); if (ret == EEXIST) { - ret = sss_ncache_check_group(nctx->rctx->ncache, dom, name); + ret = sss_ncache_check_group(nctx->rctx->ncache, + dom, cmdctx->name); if (ret == EEXIST) { /* if neg cached, return we didn't find it */ DEBUG(SSSDBG_TRACE_FUNC, @@ -4661,8 +4495,7 @@ static errno_t nss_cmd_getsidby_search(struct nss_dom_ctx *dctx) } } - DEBUG(SSSDBG_TRACE_FUNC, "Requesting info for [%s@%s]\n", - name, dom->name); + DEBUG(SSSDBG_TRACE_FUNC, "Requesting info for [%s]\n", name); } @@ -4714,9 +4547,8 @@ static errno_t nss_cmd_getsidby_search(struct nss_dom_ctx *dctx) } } } else { - ret = sysdb_search_user_by_name(cmdctx, dom, - sysdb_name ? sysdb_name : name, - attrs, &msg); + ret = sysdb_search_user_by_name(cmdctx, dom, name, attrs, + &msg); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to make request to our cache!\n"); @@ -4728,8 +4560,7 @@ static errno_t nss_cmd_getsidby_search(struct nss_dom_ctx *dctx) user_found = true; } else { talloc_free(msg); - ret = sysdb_search_group_by_name(cmdctx, dom, - sysdb_name ? sysdb_name : name, + ret = sysdb_search_group_by_name(cmdctx, dom, name, attrs, &msg); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, @@ -4765,16 +4596,18 @@ static errno_t nss_cmd_getsidby_search(struct nss_dom_ctx *dctx) if (dctx->res->count == 0 && !dctx->check_provider) { if (cmdctx->cmd == SSS_NSS_GETSIDBYNAME || cmdctx->cmd == SSS_NSS_GETORIGBYNAME) { - ret = sss_ncache_set_user(nctx->rctx->ncache, false, dom, name); + ret = sss_ncache_set_user(nctx->rctx->ncache, false, + dom, name); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, - "Cannot set negcache for %s@%s\n", name, dom->name); + "Cannot set negcache for %s\n", name); } - ret = sss_ncache_set_group(nctx->rctx->ncache, false, dom, name); + ret = sss_ncache_set_group(nctx->rctx->ncache, false, + dom, name); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, - "Cannot set negcache for %s@%s\n", name, dom->name); + "Cannot set negcache for %s\n", name); } } /* if a multidomain search, try with next */ @@ -4823,8 +4656,8 @@ static errno_t nss_cmd_getsidby_search(struct nss_dom_ctx *dctx) DEBUG(SSSDBG_TRACE_FUNC, "Returning info for id [%"PRIu32"@%s]\n", cmdctx->id, dom->name); } else { - DEBUG(SSSDBG_TRACE_FUNC, "Returning info for user/group [%s@%s]\n", - name, dom->name); + DEBUG(SSSDBG_TRACE_FUNC, "Returning info for user/group [%s]\n", + name); } /* Success. Break from the loop and return EOK */ @@ -4870,8 +4703,7 @@ static errno_t nss_cmd_getbysid_search(struct nss_dom_ctx *dctx) nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx); - DEBUG(SSSDBG_TRACE_FUNC, "Requesting info for [%s@%s]\n", cmdctx->secid, - dom->name); + DEBUG(SSSDBG_TRACE_FUNC, "Requesting info for [%s]\n", cmdctx->secid); sysdb = dom->sysdb; if (sysdb == NULL) { @@ -4938,9 +4770,7 @@ static errno_t nss_cmd_getbysid_search(struct nss_dom_ctx *dctx) } /* One result found */ - DEBUG(SSSDBG_TRACE_FUNC, "Returning info for sid [%s@%s]\n", cmdctx->secid, - dom->name); - + DEBUG(SSSDBG_TRACE_FUNC, "Returning info for sid [%s]\n", cmdctx->secid); return EOK; } @@ -5049,6 +4879,7 @@ static errno_t process_attr_list(TALLOC_CTX *mem_ctx, struct ldb_message *msg, if (strcmp(attr_list[c], SYSDB_USER_CERT) == 0) { use_base64 = true; } + for (d = 0; d < el->num_values; d++) { to_sized_string(&keys[*found], attr_list[c]); *sum += keys[*found].len; @@ -5062,6 +4893,7 @@ static errno_t process_attr_list(TALLOC_CTX *mem_ctx, struct ldb_message *msg, } else { val = el->values[d]; } + if (val.data == NULL || val.data[val.length] != '\0') { DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected attribute value found for [%s].\n", @@ -5186,6 +5018,7 @@ done: } static errno_t fill_name(struct sss_packet *packet, + struct resp_ctx *rctx, struct sss_domain_info *dom, enum sss_id_type id_type, bool apply_no_view, @@ -5194,10 +5027,7 @@ static errno_t fill_name(struct sss_packet *packet, int ret; TALLOC_CTX *tmp_ctx = NULL; const char *orig_name = NULL; - const char *cased_name; - const char *fq_name; - struct sized_string name; - bool add_domain = (!IS_SUBDOMAIN(dom) && dom->fqnames); + struct sized_string *name; uint8_t *body; size_t blen; size_t pctr = 0; @@ -5211,10 +5041,6 @@ static errno_t fill_name(struct sss_packet *packet, orig_name = ldb_msg_find_attr_as_string(msg, OVERRIDE_PREFIX SYSDB_NAME, NULL); - if (orig_name != NULL && IS_SUBDOMAIN(dom)) { - /* Override names are un-qualified */ - add_domain = true; - } } } @@ -5232,26 +5058,15 @@ static errno_t fill_name(struct sss_packet *packet, return ENOMEM; } - cased_name= sss_get_cased_name(tmp_ctx, orig_name, dom->case_sensitive); - if (cased_name == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "sss_get_cased_name failed.\n"); - ret = ENOMEM; + ret = sized_output_name(tmp_ctx, rctx, orig_name, dom, &name); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "sized_output_name failed for %s: (%d): %s\n", + orig_name, ret, sss_strerror(ret)); goto done; } - if (add_domain) { - fq_name = sss_tc_fqname(tmp_ctx, dom->names, dom, cased_name); - if (fq_name == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); - ret = ENOMEM; - goto done; - } - to_sized_string(&name, fq_name); - } else { - to_sized_string(&name, cased_name); - } - - ret = sss_packet_grow(packet, name.len + 3 * sizeof(uint32_t)); + ret = sss_packet_grow(packet, name->len + 3 * sizeof(uint32_t)); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_packet_grow failed.\n"); goto done; @@ -5261,7 +5076,7 @@ static errno_t fill_name(struct sss_packet *packet, SAFEALIGN_SETMEM_UINT32(body, 1, &pctr); /* Num results */ SAFEALIGN_SETMEM_UINT32(body + pctr, 0, &pctr); /* reserved */ SAFEALIGN_COPY_UINT32(body + pctr, &id_type, &pctr); - memcpy(&body[pctr], name.str, name.len); + memcpy(&body[pctr], name->str, name->len); ret = EOK; @@ -5342,6 +5157,7 @@ static errno_t nss_cmd_getbysid_send_reply(struct nss_dom_ctx *dctx) switch(cmdctx->cmd) { case SSS_NSS_GETNAMEBYSID: ret = fill_name(pctx->creq->out, + cctx->rctx, dctx->domain, id_type, true, @@ -5639,8 +5455,8 @@ static void users_find_by_cert_done(struct tevent_req *req) goto done; } - ret = fill_name(pctx->creq->out, domain, SSS_ID_TYPE_UID, true, - result->msgs[0]); + ret = fill_name(pctx->creq->out, cctx->rctx, domain, + SSS_ID_TYPE_UID, true, result->msgs[0]); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "fill_name failed.\n"); goto done; diff --git a/src/tests/cmocka/test_nss_srv.c b/src/tests/cmocka/test_nss_srv.c index a043a8076..c894164a8 100644 --- a/src/tests/cmocka/test_nss_srv.c +++ b/src/tests/cmocka/test_nss_srv.c @@ -352,7 +352,170 @@ static void check_initgr_packet(uint8_t *body, size_t blen, } } +static errno_t store_user(struct nss_test_ctx *ctx, + struct sss_domain_info *dom, + struct passwd *user, + struct sysdb_attrs *attrs, + time_t cache_update) +{ + errno_t ret; + char *fqname; + + fqname = sss_create_internal_fqname(ctx, + user->pw_name, + dom->name); + if (fqname == NULL) { + return ENOMEM; + } + + /* Prime the cache with a valid user */ + ret = sysdb_store_user(dom, + fqname, + user->pw_passwd, + user->pw_uid, + user->pw_gid, + user->pw_gecos, + user->pw_dir, + user->pw_shell, + NULL, attrs, + NULL, 300, cache_update); + talloc_free(fqname); + return ret; +} + +static errno_t set_user_attr(struct nss_test_ctx *ctx, + struct sss_domain_info *dom, + struct passwd *user, + struct sysdb_attrs *attrs) +{ + errno_t ret; + char *fqname; + + fqname = sss_create_internal_fqname(ctx, + user->pw_name, + dom->name); + if (fqname == NULL) { + return ENOMEM; + } + + ret = sysdb_set_user_attr(nss_test_ctx->tctx->dom, + fqname, + attrs, SYSDB_MOD_REP); + talloc_free(fqname); + return ret; +} + +static int get_user(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + const char *shortname, + struct ldb_result **_res) +{ + errno_t ret; + char *fqname; + + fqname = sss_create_internal_fqname(mem_ctx, shortname, + domain->name); + if (fqname == NULL) { + return ENOMEM; + } + + ret = sysdb_getpwnam(mem_ctx, domain, fqname, _res); + talloc_free(fqname); + return ret; +} + +static void assert_users_equal(struct passwd *a, struct passwd *b) +{ + assert_int_equal(a->pw_uid, b->pw_uid); + assert_int_equal(a->pw_gid, b->pw_gid); + assert_string_equal(a->pw_name, b->pw_name); + assert_string_equal(a->pw_shell, b->pw_shell); + assert_string_equal(a->pw_passwd, b->pw_passwd); +} + +static errno_t store_group(struct nss_test_ctx *ctx, + struct sss_domain_info *dom, + struct group *group, + time_t cache_update) +{ + errno_t ret; + char *fqname; + + fqname = sss_create_internal_fqname(ctx, + group->gr_name, + dom->name); + if (fqname == NULL) { + return ENOMEM; + } + + ret = sysdb_add_group(dom, + fqname, + group->gr_gid, + NULL, 300, 0); + talloc_free(fqname); + return ret; +} + +static void assert_groups_equal(struct group *expected, + struct group *gr, const int nmem) +{ + int i; + + assert_int_equal(gr->gr_gid, expected->gr_gid); + assert_string_equal(gr->gr_name, expected->gr_name); + assert_string_equal(gr->gr_passwd, expected->gr_passwd); + + for (i = 0; i < nmem; i++) { + assert_string_equal(gr->gr_mem[i], expected->gr_mem[i]); + } +} + +static errno_t store_group_member(struct nss_test_ctx *ctx, + const char *shortname_group, + struct sss_domain_info *group_dom, + const char *shortname_member, + struct sss_domain_info *member_dom, + enum sysdb_member_type type) +{ + errno_t ret; + char *group_fqname = NULL; + char *member_fqname = NULL; + + group_fqname = sss_create_internal_fqname(ctx, + shortname_group, + group_dom->name); + if (group_fqname == NULL) { + return ENOMEM; + } + + member_fqname = sss_create_internal_fqname(ctx, + shortname_member, + member_dom->name); + if (member_fqname == NULL) { + talloc_free(group_fqname); + return ENOMEM; + } + + ret = sysdb_add_group_member(group_dom, + group_fqname, + member_fqname, + SYSDB_MEMBER_USER, false); + talloc_free(group_fqname); + talloc_free(member_fqname); + return ret; +} + + /* ====================== The tests =============================== */ +struct passwd getpwnam_usr = { + .pw_name = discard_const("testuser"), + .pw_uid = 123, + .pw_gid = 456, + .pw_dir = discard_const("/home/testuser"), + .pw_gecos = discard_const("test user"), + .pw_shell = discard_const("/bin/sh"), + .pw_passwd = discard_const("*"), +}; /* Check getting cached and valid user from cache. Account callback will * not be called and test_nss_getpwnam_check will make sure the user is @@ -368,11 +531,7 @@ static int test_nss_getpwnam_check(uint32_t status, uint8_t *body, size_t blen) ret = parse_user_packet(body, blen, &pwd); assert_int_equal(ret, EOK); - assert_int_equal(pwd.pw_uid, 123); - assert_int_equal(pwd.pw_gid, 456); - assert_string_equal(pwd.pw_name, "testuser"); - assert_string_equal(pwd.pw_shell, "/bin/sh"); - assert_string_equal(pwd.pw_passwd, "*"); + assert_users_equal(&pwd, &getpwnam_usr); return EOK; } @@ -380,11 +539,8 @@ void test_nss_getpwnam(void **state) { errno_t ret; - /* Prime the cache with a valid user */ - ret = sysdb_add_user(nss_test_ctx->tctx->dom, - "testuser@"TEST_DOM_NAME, 123, 456, "test user", - "/home/testuser", "/bin/sh", NULL, - NULL, 300, 0); + ret = store_user(nss_test_ctx, nss_test_ctx->tctx->dom, + &getpwnam_usr, NULL, 0); assert_int_equal(ret, EOK); mock_input_user_or_group("testuser"); @@ -441,22 +597,21 @@ void test_nss_getpwnam_neg(void **state) assert_int_equal(nss_test_ctx->ncache_hits, 1); } +struct passwd getpwnam_search_usr = { + .pw_name = discard_const("testuser_search"), + .pw_uid = 567, + .pw_gid = 890, + .pw_dir = discard_const("/home/testuser_search"), + .pw_gecos = discard_const("test search user"), + .pw_shell = discard_const("/bin/sh"), + .pw_passwd = discard_const("*"), +}; + static int test_nss_getpwnam_search_acct_cb(void *pvt) { - errno_t ret; - char *fqname; struct nss_test_ctx *ctx = talloc_get_type(pvt, struct nss_test_ctx); - fqname = sss_create_internal_fqname(ctx->tctx, "testuser_search", - ctx->tctx->dom->name); - assert_non_null(fqname); - ret = sysdb_add_user(ctx->tctx->dom, - fqname, 567, 890, "test search", - "/home/testsearch", "/bin/sh", NULL, - NULL, 300, 0); - assert_int_equal(ret, EOK); - - return EOK; + return store_user(ctx, ctx->tctx->dom, &getpwnam_search_usr, NULL, 0); } static int test_nss_getpwnam_search_check(uint32_t status, @@ -470,10 +625,7 @@ static int test_nss_getpwnam_search_check(uint32_t status, ret = parse_user_packet(body, blen, &pwd); assert_int_equal(ret, EOK); - assert_int_equal(pwd.pw_uid, 567); - assert_int_equal(pwd.pw_gid, 890); - assert_string_equal(pwd.pw_name, "testuser_search"); - assert_string_equal(pwd.pw_shell, "/bin/sh"); + assert_users_equal(&pwd, &getpwnam_search_usr); return EOK; } @@ -488,8 +640,8 @@ void test_nss_getpwnam_search(void **state) mock_fill_user(); set_cmd_cb(test_nss_getpwnam_search_check); - ret = sysdb_getpwnam(nss_test_ctx, nss_test_ctx->tctx->dom, - "testuser_search", &res); + ret = get_user(nss_test_ctx, nss_test_ctx->tctx->dom, + "testuser_search", &res); assert_int_equal(ret, EOK); assert_int_equal(res->count, 0); @@ -502,8 +654,8 @@ void test_nss_getpwnam_search(void **state) assert_int_equal(ret, EOK); /* test_nss_getpwnam_search_check will check the user attributes */ - ret = sysdb_getpwnam(nss_test_ctx, nss_test_ctx->tctx->dom, - "testuser_search", &res); + ret = get_user(nss_test_ctx, nss_test_ctx->tctx->dom, + "testuser_search", &res); assert_int_equal(ret, EOK); assert_int_equal(res->count, 1); } @@ -513,19 +665,23 @@ void test_nss_getpwnam_search(void **state) * * The user's shell attribute is updated. */ + +struct passwd getpwnam_update = { + .pw_name = discard_const("testuser_update"), + .pw_uid = 10, + .pw_gid = 11, + .pw_dir = discard_const("/home/testuser"), + .pw_gecos = discard_const("test user"), + .pw_shell = discard_const("/bin/sh"), + .pw_passwd = discard_const("*"), +}; + static int test_nss_getpwnam_update_acct_cb(void *pvt) { - errno_t ret; struct nss_test_ctx *ctx = talloc_get_type(pvt, struct nss_test_ctx); - ret = sysdb_store_user(ctx->tctx->dom, - "testuser_update@"TEST_DOM_NAME, - NULL, 10, 11, "test user", - "/home/testuser", "/bin/ksh", NULL, - NULL, NULL, 300, 0); - assert_int_equal(ret, EOK); - - return EOK; + getpwnam_update.pw_shell = discard_const("/bin/ksh"); + return store_user(ctx, ctx->tctx->dom, &getpwnam_update, NULL, 0); } static int test_nss_getpwnam_update_check(uint32_t status, @@ -539,10 +695,7 @@ static int test_nss_getpwnam_update_check(uint32_t status, ret = parse_user_packet(body, blen, &pwd); assert_int_equal(ret, EOK); - assert_int_equal(pwd.pw_uid, 10); - assert_int_equal(pwd.pw_gid, 11); - assert_string_equal(pwd.pw_name, "testuser_update"); - assert_string_equal(pwd.pw_shell, "/bin/ksh"); + assert_users_equal(&pwd, &getpwnam_update); return EOK; } @@ -551,17 +704,9 @@ void test_nss_getpwnam_update(void **state) errno_t ret; struct ldb_result *res; const char *shell; - char *username; - username = sss_create_internal_fqname(nss_test_ctx, - "testuser_update", - nss_test_ctx->tctx->dom->name); - assert_non_null(username); - /* Prime the cache with a valid but expired user */ - ret = sysdb_add_user(nss_test_ctx->tctx->dom, - username, 10, 11, "test user", - "/home/testuser", "/bin/sh", NULL, - NULL, 1, 1); + ret = store_user(nss_test_ctx, nss_test_ctx->tctx->dom, + &getpwnam_update, NULL, 1); assert_int_equal(ret, EOK); /* Mock client input */ @@ -585,8 +730,8 @@ void test_nss_getpwnam_update(void **state) assert_int_equal(ret, EOK); /* Check the user was updated in the cache */ - ret = sysdb_getpwnam(nss_test_ctx, nss_test_ctx->tctx->dom, - username , &res); + ret = get_user(nss_test_ctx, nss_test_ctx->tctx->dom, + "testuser_update" , &res); assert_int_equal(ret, EOK); assert_int_equal(res->count, 1); @@ -597,6 +742,16 @@ void test_nss_getpwnam_update(void **state) /* Check that a FQDN is returned if the domain is FQDN-only and a * FQDN is requested */ +struct passwd getpwnam_fqdn = { + .pw_name = discard_const("testuser_fqdn"), + .pw_uid = 124, + .pw_gid = 457, + .pw_dir = discard_const("/home/testuser"), + .pw_gecos = discard_const("test user"), + .pw_shell = discard_const("/bin/sh"), + .pw_passwd = discard_const("*"), +}; + static int test_nss_getpwnam_check_fqdn(uint32_t status, uint8_t *body, size_t blen) { @@ -610,10 +765,8 @@ static int test_nss_getpwnam_check_fqdn(uint32_t status, ret = parse_user_packet(body, blen, &pwd); assert_int_equal(ret, EOK); - assert_int_equal(pwd.pw_uid, 124); - assert_int_equal(pwd.pw_gid, 457); - assert_string_equal(pwd.pw_name, "testuser_fqdn@"TEST_DOM_NAME); - assert_string_equal(pwd.pw_shell, "/bin/sh"); + getpwnam_fqdn.pw_name = discard_const("testuser_fqdn@"TEST_DOM_NAME); + assert_users_equal(&pwd, &getpwnam_fqdn); return EOK; } @@ -621,12 +774,8 @@ void test_nss_getpwnam_fqdn(void **state) { errno_t ret; - /* Prime the cache with a valid user */ - ret = sysdb_add_user(nss_test_ctx->tctx->dom, - "testuser_fqdn@"TEST_DOM_NAME, - 124, 457, "test user", - "/home/testuser", "/bin/sh", NULL, - NULL, 300, 0); + ret = store_user(nss_test_ctx, nss_test_ctx->tctx->dom, + &getpwnam_fqdn, NULL, 0); assert_int_equal(ret, EOK); mock_input_user_or_group("testuser_fqdn@"TEST_DOM_NAME); @@ -647,6 +796,16 @@ void test_nss_getpwnam_fqdn(void **state) /* Check that a user with a space in his username is returned fine. */ +struct passwd getpwnam_space = { + .pw_name = discard_const("space user"), + .pw_uid = 225, + .pw_gid = 558, + .pw_dir = discard_const("/home/testuser"), + .pw_gecos = discard_const("test user"), + .pw_shell = discard_const("/bin/sh"), + .pw_passwd = discard_const("*"), +}; + static int test_nss_getpwnam_check_space(uint32_t status, uint8_t *body, size_t blen) { @@ -658,10 +817,7 @@ static int test_nss_getpwnam_check_space(uint32_t status, ret = parse_user_packet(body, blen, &pwd); assert_int_equal(ret, EOK); - assert_int_equal(pwd.pw_uid, 225); - assert_int_equal(pwd.pw_gid, 558); - assert_string_equal(pwd.pw_name, "space user"); - assert_string_equal(pwd.pw_shell, "/bin/sh"); + assert_users_equal(&pwd, &getpwnam_space); return EOK; } @@ -670,10 +826,8 @@ void test_nss_getpwnam_space(void **state) errno_t ret; /* Prime the cache with a valid user */ - ret = sysdb_add_user(nss_test_ctx->tctx->dom, - "space user@"TEST_DOM_NAME, 225, 558, "space user", - "/home/testuser", "/bin/sh", NULL, - NULL, 300, 0); + ret = store_user(nss_test_ctx, nss_test_ctx->tctx->dom, + &getpwnam_space, NULL, 0); assert_int_equal(ret, EOK); mock_input_user_or_group("space user"); @@ -760,6 +914,16 @@ void test_nss_getpwnam_space_sub_query(void **state) * Check that FQDN processing is able to handle arbitrarily sized * delimeter */ +struct passwd getpwnam_fancy_fqdn = { + .pw_name = discard_const("testuser_fqdn_fancy"), + .pw_uid = 125, + .pw_gid = 458, + .pw_dir = discard_const("/home/testuser"), + .pw_gecos = discard_const("test user"), + .pw_shell = discard_const("/bin/sh"), + .pw_passwd = discard_const("*"), +}; + static int test_nss_getpwnam_check_fancy_fqdn(uint32_t status, uint8_t *body, size_t blen) { @@ -785,11 +949,8 @@ void test_nss_getpwnam_fqdn_fancy(void **state) errno_t ret; /* Prime the cache with a valid user */ - ret = sysdb_add_user(nss_test_ctx->tctx->dom, - "testuser_fqdn_fancy@"TEST_DOM_NAME, - 125, 458, "test user", - "/home/testuser", "/bin/sh", NULL, - NULL, 300, 0); + ret = store_user(nss_test_ctx, nss_test_ctx->tctx->dom, + &getpwnam_fancy_fqdn, NULL, 0); assert_int_equal(ret, EOK); mock_input_user_or_group("testuser_fqdn_fancy@"TEST_DOM_NAME); @@ -812,6 +973,16 @@ void test_nss_getpwnam_fqdn_fancy(void **state) * not be called and test_nss_getpwuid_check will make sure the id is * the same as the test entered before starting */ +struct passwd getpwuid_usr = { + .pw_name = discard_const("testuser1"), + .pw_uid = 101, + .pw_gid = 401, + .pw_dir = discard_const("/home/testuser1"), + .pw_gecos = discard_const("test user1"), + .pw_shell = discard_const("/bin/sh"), + .pw_passwd = discard_const("*"), +}; + static int test_nss_getpwuid_check(uint32_t status, uint8_t *body, size_t blen) { struct passwd pwd; @@ -822,27 +993,20 @@ static int test_nss_getpwuid_check(uint32_t status, uint8_t *body, size_t blen) ret = parse_user_packet(body, blen, &pwd); assert_int_equal(ret, EOK); - assert_int_equal(pwd.pw_uid, 101); - assert_int_equal(pwd.pw_gid, 401); - assert_string_equal(pwd.pw_name, "testuser1"); - assert_string_equal(pwd.pw_shell, "/bin/sh"); - assert_string_equal(pwd.pw_passwd, "*"); + assert_users_equal(&pwd, &getpwuid_usr); return EOK; } void test_nss_getpwuid(void **state) { errno_t ret; + uint32_t id = 101; /* Prime the cache with a valid user */ - ret = sysdb_add_user(nss_test_ctx->tctx->dom, - "testuser1@"TEST_DOM_NAME, - 101, 401, "test user1", - "/home/testuser1", "/bin/sh", NULL, - NULL, 300, 0); + ret = store_user(nss_test_ctx, nss_test_ctx->tctx->dom, + &getpwuid_usr, NULL, 0); assert_int_equal(ret, EOK); - uint32_t id = 101; mock_input_id(nss_test_ctx, id); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWUID); mock_fill_user(); @@ -864,9 +1028,9 @@ void test_nss_getpwuid(void **state) void test_nss_getpwuid_neg(void **state) { errno_t ret; + uid_t uid_neg = 102; - uint8_t id = 102; - mock_input_id(nss_test_ctx, id); + mock_input_id(nss_test_ctx, uid_neg); mock_account_recv_simple(); assert_int_equal(nss_test_ctx->ncache_hits, 0); @@ -886,7 +1050,7 @@ void test_nss_getpwuid_neg(void **state) */ nss_test_ctx->tctx->done = false; - mock_input_id(nss_test_ctx, id); + mock_input_id(nss_test_ctx, uid_neg); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWUID, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); @@ -898,19 +1062,24 @@ void test_nss_getpwuid_neg(void **state) assert_int_equal(nss_test_ctx->ncache_hits, 1); } +/* Test that lookup by UID for a user that does + * not exist in the cache fetches the user from DP + */ +struct passwd getpwuid_srch = { + .pw_name = discard_const("exampleuser_search"), + .pw_uid = 107, + .pw_gid = 987, + .pw_dir = discard_const("/home/examplesearch"), + .pw_gecos = discard_const("example search"), + .pw_shell = discard_const("/bin/sh"), + .pw_passwd = discard_const("*"), +}; + static int test_nss_getpwuid_search_acct_cb(void *pvt) { - errno_t ret; struct nss_test_ctx *ctx = talloc_get_type(pvt, struct nss_test_ctx); - ret = sysdb_add_user(ctx->tctx->dom, - "exampleuser_search@"TEST_DOM_NAME, - 107, 987, "example search", - "/home/examplesearch", "/bin/sh", NULL, - NULL, 300, 0); - assert_int_equal(ret, EOK); - - return EOK; + return store_user(ctx, ctx->tctx->dom, &getpwuid_srch, NULL, 0); } static int test_nss_getpwuid_search_check(uint32_t status, @@ -924,10 +1093,7 @@ static int test_nss_getpwuid_search_check(uint32_t status, ret = parse_user_packet(body, blen, &pwd); assert_int_equal(ret, EOK); - assert_int_equal(pwd.pw_uid, 107); - assert_int_equal(pwd.pw_gid, 987); - assert_string_equal(pwd.pw_name, "exampleuser_search"); - assert_string_equal(pwd.pw_shell, "/bin/sh"); + assert_users_equal(&pwd, &getpwuid_srch); return EOK; } @@ -936,15 +1102,14 @@ void test_nss_getpwuid_search(void **state) errno_t ret; struct ldb_result *res; - uint8_t id = 107; - mock_input_id(nss_test_ctx, id); + mock_input_id(nss_test_ctx, getpwuid_srch.pw_uid); mock_account_recv(0, 0, NULL, test_nss_getpwuid_search_acct_cb, nss_test_ctx); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWUID); mock_fill_user(); set_cmd_cb(test_nss_getpwuid_search_check); ret = sysdb_getpwuid(nss_test_ctx, nss_test_ctx->tctx->dom, - 107, &res); + getpwuid_srch.pw_uid, &res); assert_int_equal(ret, EOK); assert_int_equal(res->count, 0); @@ -958,7 +1123,7 @@ void test_nss_getpwuid_search(void **state) /* test_nss_getpwuid_search_check will check the id attributes */ ret = sysdb_getpwuid(nss_test_ctx, nss_test_ctx->tctx->dom, - 107, &res); + getpwuid_srch.pw_uid, &res); assert_int_equal(ret, EOK); assert_int_equal(res->count, 1); } @@ -968,19 +1133,22 @@ void test_nss_getpwuid_search(void **state) * * The user's shell attribute is updated. */ +struct passwd getpwuid_update = { + .pw_name = discard_const("exampleuser_update"), + .pw_uid = 109, + .pw_gid = 11000, + .pw_dir = discard_const("/home/exampleuser"), + .pw_gecos = discard_const("example user"), + .pw_shell = discard_const("/bin/sh"), + .pw_passwd = discard_const("*"), +}; + static int test_nss_getpwuid_update_acct_cb(void *pvt) { - errno_t ret; struct nss_test_ctx *ctx = talloc_get_type(pvt, struct nss_test_ctx); - ret = sysdb_store_user(ctx->tctx->dom, - "exampleuser_update@"TEST_DOM_NAME, - NULL, 109, 11000, "example user", - "/home/exampleuser", "/bin/ksh", NULL, - NULL, NULL, 300, 0); - assert_int_equal(ret, EOK); - - return EOK; + getpwuid_update.pw_shell = discard_const("/bin/ksh"); + return store_user(ctx, ctx->tctx->dom, &getpwuid_update, NULL, 0); } static int test_nss_getpwuid_update_check(uint32_t status, @@ -994,10 +1162,7 @@ static int test_nss_getpwuid_update_check(uint32_t status, ret = parse_user_packet(body, blen, &pwd); assert_int_equal(ret, EOK); - assert_int_equal(pwd.pw_uid, 109); - assert_int_equal(pwd.pw_gid, 11000); - assert_string_equal(pwd.pw_name, "exampleuser_update"); - assert_string_equal(pwd.pw_shell, "/bin/ksh"); + assert_users_equal(&pwd, &getpwuid_update); return EOK; } @@ -1008,16 +1173,12 @@ void test_nss_getpwuid_update(void **state) const char *shell; /* Prime the cache with a valid but expired user */ - ret = sysdb_add_user(nss_test_ctx->tctx->dom, - "exampleuser_update@"TEST_DOM_NAME, - 109, 11000, "example user", - "/home/exampleuser", "/bin/sh", NULL, - NULL, 1, 1); + ret = store_user(nss_test_ctx, nss_test_ctx->tctx->dom, + &getpwuid_update, NULL, 1); assert_int_equal(ret, EOK); /* Mock client input */ - uint8_t id = 109; - mock_input_id(nss_test_ctx, id); + mock_input_id(nss_test_ctx, getpwuid_update.pw_uid); /* Mock client command */ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWUID); /* Call this function when id is updated by the mock DP request */ @@ -1038,7 +1199,7 @@ void test_nss_getpwuid_update(void **state) /* Check the user was updated in the cache */ ret = sysdb_getpwuid(nss_test_ctx, nss_test_ctx->tctx->dom, - 109, &res); + getpwuid_update.pw_uid, &res); assert_int_equal(ret, EOK); assert_int_equal(res->count, 1); @@ -1101,19 +1262,12 @@ void test_nss_setup(struct sss_test_conf_param params[], } -static int test_nss_getgrnam_check(struct group *expected, struct group *gr, const int nmem) -{ - int i; - - assert_int_equal(gr->gr_gid, expected->gr_gid); - assert_string_equal(gr->gr_name, expected->gr_name); - assert_string_equal(gr->gr_passwd, expected->gr_passwd); - - for (i = 0; i < nmem; i++) { - assert_string_equal(gr->gr_mem[i], expected->gr_mem[i]); - } - return EOK; -} +struct group getgrnam_no_members = { + .gr_gid = 1123, + .gr_name = discard_const("testgroup"), + .gr_passwd = discard_const("*"), + .gr_mem = NULL, +}; static int test_nss_getgrnam_no_members_check(uint32_t status, uint8_t *body, size_t blen) @@ -1121,12 +1275,6 @@ static int test_nss_getgrnam_no_members_check(uint32_t status, int ret; uint32_t nmem; struct group gr; - struct group expected = { - .gr_gid = 1123, - .gr_name = discard_const("testgroup"), - .gr_passwd = discard_const("*"), - .gr_mem = NULL, - }; assert_int_equal(status, EOK); @@ -1134,9 +1282,7 @@ static int test_nss_getgrnam_no_members_check(uint32_t status, assert_int_equal(ret, EOK); assert_int_equal(nmem, 0); - ret = test_nss_getgrnam_check(&expected, &gr, nmem); - assert_int_equal(ret, EOK); - + assert_groups_equal(&getgrnam_no_members, &gr, nmem); return EOK; } @@ -1148,12 +1294,11 @@ void test_nss_getgrnam_no_members(void **state) errno_t ret; /* Prime the cache with a valid group */ - ret = sysdb_add_group(nss_test_ctx->tctx->dom, - "testgroup@"TEST_DOM_NAME, 1123, - NULL, 300, 0); + ret = store_group(nss_test_ctx, nss_test_ctx->tctx->dom, + &getgrnam_no_members, 0); assert_int_equal(ret, EOK); - mock_input_user_or_group("testgroup"); + mock_input_user_or_group(getgrnam_no_members.gr_name); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM); mock_fill_group_with_members(0); @@ -1168,17 +1313,45 @@ void test_nss_getgrnam_no_members(void **state) assert_int_equal(ret, EOK); } +struct passwd testmember1 = { + .pw_name = discard_const("testmember1"), + .pw_uid = 2001, + .pw_gid = 456, + .pw_dir = discard_const("/home/testmember1"), + .pw_gecos = discard_const("test member1"), + .pw_shell = discard_const("/bin/sh"), + .pw_passwd = discard_const("*"), +}; + +struct passwd testmember2 = { + .pw_name = discard_const("testmember2"), + .pw_uid = 2002, + .pw_gid = 456, + .pw_dir = discard_const("/home/testmember2"), + .pw_gecos = discard_const("test member2"), + .pw_shell = discard_const("/bin/sh"), + .pw_passwd = discard_const("*"), +}; + +struct group testgroup_members = { + .gr_gid = 1124, + .gr_name = discard_const("testgroup_members"), + .gr_passwd = discard_const("*"), + .gr_mem = NULL, +}; + static int test_nss_getgrnam_members_check(uint32_t status, uint8_t *body, size_t blen) { int ret; uint32_t nmem; struct group gr; - const char *exp_members[] = { "testmember1", "testmember2" }; + const char *exp_members[] = { testmember1.pw_name, + testmember2.pw_name }; struct group expected = { - .gr_gid = 1124, - .gr_name = discard_const("testgroup_members"), - .gr_passwd = discard_const("*"), + .gr_gid = testgroup_members.gr_gid, + .gr_name = testgroup_members.gr_name, + .gr_passwd = testgroup_members.gr_passwd, .gr_mem = discard_const(exp_members) }; @@ -1188,9 +1361,7 @@ static int test_nss_getgrnam_members_check(uint32_t status, assert_int_equal(ret, EOK); assert_int_equal(nmem, 2); - ret = test_nss_getgrnam_check(&expected, &gr, nmem); - assert_int_equal(ret, EOK); - + assert_groups_equal(&expected, &gr, nmem); return EOK; } @@ -1201,36 +1372,32 @@ void test_nss_getgrnam_members(void **state) { errno_t ret; - /* Prime the cache with a valid group and some members */ - ret = sysdb_add_group(nss_test_ctx->tctx->dom, - "testgroup_members@"TEST_DOM_NAME, 1124, - NULL, 300, 0); + ret = store_group(nss_test_ctx, nss_test_ctx->tctx->dom, + &testgroup_members, 0); assert_int_equal(ret, EOK); - ret = sysdb_add_user(nss_test_ctx->tctx->dom, - "testmember1@"TEST_DOM_NAME, - 2001, 456, "test member1", - "/home/testmember2", "/bin/sh", NULL, - NULL, 300, 0); + ret = store_user(nss_test_ctx, nss_test_ctx->tctx->dom, + &testmember1, NULL, 0); assert_int_equal(ret, EOK); - ret = sysdb_add_user(nss_test_ctx->tctx->dom, - "testmember2@"TEST_DOM_NAME, - 2002, 456, "test member2", - "/home/testmember2", "/bin/sh", NULL, - NULL, 300, 0); + ret = store_user(nss_test_ctx, nss_test_ctx->tctx->dom, + &testmember2, NULL, 0); assert_int_equal(ret, EOK); - ret = sysdb_add_group_member(nss_test_ctx->tctx->dom, - "testgroup_members@"TEST_DOM_NAME, - "testmember1@"TEST_DOM_NAME, - SYSDB_MEMBER_USER, false); + ret = store_group_member(nss_test_ctx, + testgroup_members.gr_name, + nss_test_ctx->tctx->dom, + testmember1.pw_name, + nss_test_ctx->tctx->dom, + SYSDB_MEMBER_USER); assert_int_equal(ret, EOK); - ret = sysdb_add_group_member(nss_test_ctx->tctx->dom, - "testgroup_members@"TEST_DOM_NAME, - "testmember2@"TEST_DOM_NAME, - SYSDB_MEMBER_USER, false); + ret = store_group_member(nss_test_ctx, + testgroup_members.gr_name, + nss_test_ctx->tctx->dom, + testmember2.pw_name, + nss_test_ctx->tctx->dom, + SYSDB_MEMBER_USER); assert_int_equal(ret, EOK); mock_input_user_or_group("testgroup_members"); @@ -1254,14 +1421,29 @@ static int test_nss_getgrnam_members_check_fqdn(uint32_t status, int ret; uint32_t nmem; struct group gr; - const char *exp_members[] = { "testmember1@"TEST_DOM_NAME, - "testmember2@"TEST_DOM_NAME }; + const char *exp_members[2]; struct group expected = { - .gr_gid = 1124, - .gr_name = discard_const("testgroup_members@"TEST_DOM_NAME), - .gr_passwd = discard_const("*"), + .gr_gid = testgroup_members.gr_gid, + .gr_passwd = testgroup_members.gr_passwd, .gr_mem = discard_const(exp_members) }; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(nss_test_ctx); + assert_non_null(tmp_ctx); + + exp_members[0] = sss_tc_fqname(tmp_ctx, nss_test_ctx->tctx->dom->names, + nss_test_ctx->tctx->dom, testmember1.pw_name); + assert_non_null(exp_members[0]); + exp_members[1] = sss_tc_fqname(tmp_ctx, nss_test_ctx->tctx->dom->names, + nss_test_ctx->tctx->dom, testmember2.pw_name); + assert_non_null(exp_members[1]); + + expected.gr_name = sss_tc_fqname(tmp_ctx, + nss_test_ctx->tctx->dom->names, + nss_test_ctx->tctx->dom, + testgroup_members.gr_name); + assert_non_null(expected.gr_name); assert_int_equal(status, EOK); @@ -1269,9 +1451,10 @@ static int test_nss_getgrnam_members_check_fqdn(uint32_t status, assert_int_equal(ret, EOK); assert_int_equal(nmem, 2); - ret = test_nss_getgrnam_check(&expected, &gr, nmem); + assert_groups_equal(&expected, &gr, nmem); assert_int_equal(ret, EOK); + talloc_free(tmp_ctx); return EOK; } @@ -1302,20 +1485,64 @@ void test_nss_getgrnam_members_fqdn(void **state) assert_int_equal(ret, EOK); } +/* Test that requesting a valid, cached group with subdomain members returns + * a valid * group structure with those members present as fully + * qualified names + */ +struct passwd submember1 = { + .pw_name = discard_const("submember1"), + .pw_uid = 4001, + .pw_gid = 456, + .pw_dir = discard_const("/home/submember1"), + .pw_gecos = discard_const("sub member1"), + .pw_shell = discard_const("/bin/sh"), + .pw_passwd = discard_const("*"), +}; + +struct passwd submember2 = { + .pw_name = discard_const("submember2"), + .pw_uid = 4002, + .pw_gid = 456, + .pw_dir = discard_const("/home/submember2"), + .pw_gecos = discard_const("sub member2"), + .pw_shell = discard_const("/bin/sh"), + .pw_passwd = discard_const("*"), +}; + +struct group testsubdomgroup = { + .gr_gid = 2002, + .gr_name = discard_const("testsubdomgroup"), + .gr_passwd = discard_const("*"), + .gr_mem = NULL, +}; + static int test_nss_getgrnam_members_check_subdom(uint32_t status, uint8_t *body, size_t blen) { int ret; uint32_t nmem; struct group gr; - const char *exp_members[] = { "submember1@"TEST_SUBDOM_NAME, - "submember2@"TEST_SUBDOM_NAME }; + const char *exp_members[2]; struct group expected = { - .gr_gid = 2124, - .gr_name = discard_const("testsubdomgroup@"TEST_SUBDOM_NAME), - .gr_passwd = discard_const("*"), + .gr_gid = testsubdomgroup.gr_gid, + .gr_passwd = testsubdomgroup.gr_passwd, .gr_mem = discard_const(exp_members) }; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(nss_test_ctx); + assert_non_null(tmp_ctx); + + exp_members[0] = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names, + nss_test_ctx->subdom, submember1.pw_name); + assert_non_null(exp_members[0]); + exp_members[1] = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names, + nss_test_ctx->subdom, submember2.pw_name); + assert_non_null(exp_members[1]); + + expected.gr_name = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names, + nss_test_ctx->subdom, testsubdomgroup.gr_name); + assert_non_null(expected.gr_name); assert_int_equal(status, EOK); @@ -1323,70 +1550,46 @@ static int test_nss_getgrnam_members_check_subdom(uint32_t status, assert_int_equal(ret, EOK); assert_int_equal(nmem, 2); - ret = test_nss_getgrnam_check(&expected, &gr, nmem); + assert_groups_equal(&expected, &gr, nmem); assert_int_equal(ret, EOK); + talloc_free(tmp_ctx); return EOK; } -/* Test that requesting a valid, cached group with some members returns a valid - * group structure with those members present as fully qualified names - */ void test_nss_getgrnam_members_subdom(void **state) { errno_t ret; - char *submember1; - char *submember2; - char *testsubdomgroup; - submember1 = sss_create_internal_fqname(nss_test_ctx, "submember1", - nss_test_ctx->subdom->name); - submember2 = sss_create_internal_fqname(nss_test_ctx, "submember2", - nss_test_ctx->subdom->name); - testsubdomgroup = sss_create_internal_fqname(nss_test_ctx, - "testsubdomgroup", - nss_test_ctx->subdom->name); - assert_non_null(submember1); - assert_non_null(submember2); - assert_non_null(testsubdomgroup); - - nss_test_ctx->tctx->dom->fqnames = true; - - /* Add a group from a subdomain and two members from the same subdomain - */ - ret = sysdb_add_group(nss_test_ctx->subdom, - testsubdomgroup, - 2124, NULL, 300, 0); + ret = store_group(nss_test_ctx, nss_test_ctx->subdom, + &testsubdomgroup, 0); assert_int_equal(ret, EOK); - ret = sysdb_add_user(nss_test_ctx->subdom, - submember1, - 4001, 456, "test subdomain member1", - "/home/submember1", "/bin/sh", NULL, - NULL, 300, 0); + ret = store_user(nss_test_ctx, nss_test_ctx->subdom, + &submember1, NULL, 0); assert_int_equal(ret, EOK); - ret = sysdb_add_user(nss_test_ctx->subdom, - submember2, - 2002, 456, "test subdomain member2", - "/home/submember2", "/bin/sh", NULL, - NULL, 300, 0); + ret = store_user(nss_test_ctx, nss_test_ctx->subdom, + &submember2, NULL, 0); assert_int_equal(ret, EOK); - ret = sysdb_add_group_member(nss_test_ctx->subdom, - testsubdomgroup, - submember1, - SYSDB_MEMBER_USER, false); + ret = store_group_member(nss_test_ctx, + testsubdomgroup.gr_name, + nss_test_ctx->subdom, + submember1.pw_name, + nss_test_ctx->subdom, + SYSDB_MEMBER_USER); assert_int_equal(ret, EOK); - ret = sysdb_add_group_member(nss_test_ctx->subdom, - testsubdomgroup, - submember2, - SYSDB_MEMBER_USER, false); + ret = store_group_member(nss_test_ctx, + testsubdomgroup.gr_name, + nss_test_ctx->subdom, + submember2.pw_name, + nss_test_ctx->subdom, + SYSDB_MEMBER_USER); assert_int_equal(ret, EOK); - - mock_input_user_or_group(testsubdomgroup); + mock_input_user_or_group("testsubdomgroup@"TEST_SUBDOM_NAME); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM); mock_fill_group_with_members(2); @@ -1399,8 +1602,6 @@ void test_nss_getgrnam_members_subdom(void **state) /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); - /* Restore FQDN settings */ - nss_test_ctx->tctx->dom->fqnames = false; assert_int_equal(ret, EOK); } @@ -1410,15 +1611,23 @@ static int test_nss_getgrnam_check_mix_dom(uint32_t status, int ret; uint32_t nmem; struct group gr; - const char *exp_members[] = { "testmember1", - "testmember2", - "submember1@"TEST_SUBDOM_NAME }; + const char *exp_members[3]; struct group expected = { - .gr_gid = 1124, - .gr_name = discard_const("testgroup_members"), - .gr_passwd = discard_const("*"), + .gr_name = testgroup_members.gr_name, + .gr_gid = testgroup_members.gr_gid, + .gr_passwd = testgroup_members.gr_passwd, .gr_mem = discard_const(exp_members) }; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(nss_test_ctx); + assert_non_null(tmp_ctx); + + exp_members[0] = testmember1.pw_name; + exp_members[1] = testmember2.pw_name; + exp_members[2] = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names, + nss_test_ctx->subdom, submember1.pw_name); + assert_non_null(exp_members[2]); assert_int_equal(status, EOK); @@ -1426,29 +1635,23 @@ static int test_nss_getgrnam_check_mix_dom(uint32_t status, assert_int_equal(ret, EOK); assert_int_equal(nmem, 3); - ret = test_nss_getgrnam_check(&expected, &gr, nmem); + assert_groups_equal(&expected, &gr, nmem); assert_int_equal(ret, EOK); + talloc_free(tmp_ctx); return EOK; } void test_nss_getgrnam_mix_dom(void **state) { errno_t ret; - const char *group_strdn = NULL; - const char *add_groups[] = { NULL, NULL }; - - /* Add a subdomain user to a parent domain group */ - group_strdn = sysdb_group_strdn(nss_test_ctx, - nss_test_ctx->tctx->dom->name, - "testgroup_members"); - assert_non_null(group_strdn); - add_groups[0] = group_strdn; - ret = sysdb_update_members_dn(nss_test_ctx->subdom, - "submember1@"TEST_SUBDOM_NAME, - SYSDB_MEMBER_USER, - add_groups, NULL); + ret = store_group_member(nss_test_ctx, + testgroup_members.gr_name, + nss_test_ctx->tctx->dom, + submember1.pw_name, + nss_test_ctx->subdom, + SYSDB_MEMBER_USER); assert_int_equal(ret, EOK); mock_input_user_or_group("testgroup_members"); @@ -1472,15 +1675,32 @@ static int test_nss_getgrnam_check_mix_dom_fqdn(uint32_t status, int ret; uint32_t nmem; struct group gr; - const char *exp_members[] = { "testmember1@"TEST_DOM_NAME, - "testmember2@"TEST_DOM_NAME, - "submember1@"TEST_SUBDOM_NAME }; + const char *exp_members[3]; struct group expected = { - .gr_gid = 1124, - .gr_name = discard_const("testgroup_members@"TEST_DOM_NAME), - .gr_passwd = discard_const("*"), + .gr_gid = testgroup_members.gr_gid, + .gr_passwd = testgroup_members.gr_passwd, .gr_mem = discard_const(exp_members) }; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(nss_test_ctx); + assert_non_null(tmp_ctx); + + exp_members[0] = sss_tc_fqname(tmp_ctx, nss_test_ctx->tctx->dom->names, + nss_test_ctx->tctx->dom, testmember1.pw_name); + assert_non_null(exp_members[0]); + exp_members[1] = sss_tc_fqname(tmp_ctx, nss_test_ctx->tctx->dom->names, + nss_test_ctx->tctx->dom, testmember2.pw_name); + assert_non_null(exp_members[1]); + exp_members[2] = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names, + nss_test_ctx->subdom, submember1.pw_name); + assert_non_null(exp_members[2]); + + expected.gr_name = sss_tc_fqname(tmp_ctx, + nss_test_ctx->tctx->dom->names, + nss_test_ctx->tctx->dom, + testgroup_members.gr_name); + assert_non_null(expected.gr_name); assert_int_equal(status, EOK); @@ -1488,9 +1708,10 @@ static int test_nss_getgrnam_check_mix_dom_fqdn(uint32_t status, assert_int_equal(ret, EOK); assert_int_equal(nmem, 3); - ret = test_nss_getgrnam_check(&expected, &gr, nmem); + assert_groups_equal(&expected, &gr, nmem); assert_int_equal(ret, EOK); + talloc_free(tmp_ctx); return EOK; } @@ -1524,15 +1745,31 @@ static int test_nss_getgrnam_check_mix_subdom(uint32_t status, int ret; uint32_t nmem; struct group gr; - const char *exp_members[] = { "submember1@"TEST_SUBDOM_NAME, - "submember2@"TEST_SUBDOM_NAME, - "testmember1@"TEST_DOM_NAME }; + const char *exp_members[3]; struct group expected = { - .gr_gid = 2124, - .gr_name = discard_const("testsubdomgroup@"TEST_SUBDOM_NAME), - .gr_passwd = discard_const("*"), + .gr_gid = testsubdomgroup.gr_gid, + .gr_passwd = testsubdomgroup.gr_passwd, .gr_mem = discard_const(exp_members) }; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(nss_test_ctx); + assert_non_null(tmp_ctx); + + exp_members[0] = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names, + nss_test_ctx->subdom, submember1.pw_name); + assert_non_null(exp_members[0]); + exp_members[1] = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names, + nss_test_ctx->subdom, submember2.pw_name); + assert_non_null(exp_members[1]); + /* Important: this member is from a non-qualified domain, so his name will + * not be qualified either + */ + exp_members[2] = testmember1.pw_name; + + expected.gr_name = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names, + nss_test_ctx->subdom, testsubdomgroup.gr_name); + assert_non_null(expected.gr_name); assert_int_equal(status, EOK); @@ -1540,32 +1777,23 @@ static int test_nss_getgrnam_check_mix_subdom(uint32_t status, assert_int_equal(ret, EOK); assert_int_equal(nmem, 3); - ret = test_nss_getgrnam_check(&expected, &gr, nmem); + assert_groups_equal(&expected, &gr, nmem); assert_int_equal(ret, EOK); + talloc_free(tmp_ctx); return EOK; } void test_nss_getgrnam_mix_subdom(void **state) { errno_t ret; - const char *group_strdn = NULL; - const char *add_groups[] = { NULL, NULL }; - char *testmember1_fqname = sss_create_internal_fqname(nss_test_ctx, - "testmember1", - TEST_DOM_NAME); - /* Add a parent domain user to a subdomain group */ - group_strdn = sysdb_group_strdn(nss_test_ctx, - nss_test_ctx->subdom->name, - "testsubdomgroup"); - assert_non_null(group_strdn); - add_groups[0] = group_strdn; - - ret = sysdb_update_members_dn(nss_test_ctx->tctx->dom, - testmember1_fqname, - SYSDB_MEMBER_USER, - add_groups, NULL); + ret = store_group_member(nss_test_ctx, + testsubdomgroup.gr_name, + nss_test_ctx->subdom, + testmember1.pw_name, + nss_test_ctx->tctx->dom, + SYSDB_MEMBER_USER); assert_int_equal(ret, EOK); mock_input_user_or_group("testsubdomgroup@"TEST_SUBDOM_NAME); @@ -1583,18 +1811,19 @@ void test_nss_getgrnam_mix_subdom(void **state) assert_int_equal(ret, EOK); } +struct group space_group = { + .gr_gid = 2123, + .gr_name = discard_const("space group"), + .gr_passwd = discard_const("*"), + .gr_mem = NULL, +}; + static int test_nss_getgrnam_space_check(uint32_t status, uint8_t *body, size_t blen) { int ret; uint32_t nmem; struct group gr; - struct group expected = { - .gr_gid = 2123, - .gr_name = discard_const("space group"), - .gr_passwd = discard_const("*"), - .gr_mem = NULL, - }; assert_int_equal(status, EOK); @@ -1602,7 +1831,7 @@ static int test_nss_getgrnam_space_check(uint32_t status, assert_int_equal(ret, EOK); assert_int_equal(nmem, 0); - ret = test_nss_getgrnam_check(&expected, &gr, nmem); + assert_groups_equal(&space_group, &gr, nmem); assert_int_equal(ret, EOK); return EOK; @@ -1616,9 +1845,8 @@ void test_nss_getgrnam_space(void **state) errno_t ret; /* Prime the cache with a valid group */ - ret = sysdb_add_group(nss_test_ctx->tctx->dom, - "space group@"TEST_DOM_NAME, 2123, - NULL, 300, 0); + ret = store_group(nss_test_ctx, nss_test_ctx->tctx->dom, + &space_group, 0); assert_int_equal(ret, EOK); mock_input_user_or_group("space group"); @@ -1642,12 +1870,6 @@ static int test_nss_getgrnam_space_sub_check(uint32_t status, int ret; uint32_t nmem; struct group gr; - struct group expected = { - .gr_gid = 2123, - .gr_name = discard_const("space_group"), - .gr_passwd = discard_const("*"), - .gr_mem = NULL, - }; assert_int_equal(status, EOK); @@ -1655,7 +1877,8 @@ static int test_nss_getgrnam_space_sub_check(uint32_t status, assert_int_equal(ret, EOK); assert_int_equal(nmem, 0); - ret = test_nss_getgrnam_check(&expected, &gr, nmem); + space_group.gr_name = discard_const("space_group"); + assert_groups_equal(&space_group, &gr, nmem); assert_int_equal(ret, EOK); return EOK; @@ -1916,33 +2139,43 @@ static int test_nss_getorigbyname_check(uint32_t status, uint8_t *body, return EOK; } +struct passwd orig_name = { + .pw_name = discard_const("testuserorig"), + .pw_uid = 1234, + .pw_gid = 5678, + .pw_dir = discard_const("/home/testuserorig"), + .pw_gecos = discard_const("test user"), + .pw_shell = discard_const("/bin/sh"), + .pw_passwd = discard_const("*"), +}; + void test_nss_getorigbyname(void **state) { errno_t ret; struct sysdb_attrs *attrs; - char *fqname; + char *fqorigname; - fqname = sss_create_internal_fqname(nss_test_ctx, "testuserorig", - nss_test_ctx->tctx->dom->name); - assert_non_null(fqname); attrs = sysdb_new_attrs(nss_test_ctx); assert_non_null(attrs); ret = sysdb_attrs_add_string(attrs, SYSDB_SID_STR, "S-1-2-3-4"); assert_int_equal(ret, EOK); + fqorigname = sss_create_internal_fqname(attrs, "orig_name", + nss_test_ctx->tctx->dom->name); + assert_non_null(fqorigname); + ret = sysdb_attrs_add_string(attrs, ORIGINALAD_PREFIX SYSDB_NAME, - "orig_name"); + fqorigname); + talloc_free(fqorigname); assert_int_equal(ret, EOK); ret = sysdb_attrs_add_uint32(attrs, ORIGINALAD_PREFIX SYSDB_UIDNUM, 1234); assert_int_equal(ret, EOK); /* Prime the cache with a valid user */ - ret = sysdb_add_user(nss_test_ctx->tctx->dom, - fqname, 1234, 5689, "test user orig", - "/home/testuserorig", "/bin/sh", NULL, - attrs, 300, 0); + ret = store_user(nss_test_ctx, nss_test_ctx->tctx->dom, + &orig_name, attrs, 0); assert_int_equal(ret, EOK); mock_input_user_or_group("testuserorig"); @@ -2026,15 +2259,21 @@ static int test_nss_getorigbyname_extra_check(uint32_t status, uint8_t *body, return EOK; } +struct passwd orig_extra = { + .pw_name = discard_const("testuserorigextra"), + .pw_uid = 2345, + .pw_gid = 6789, + .pw_dir = discard_const("/home/testuserorigextra"), + .pw_gecos = discard_const("test user"), + .pw_shell = discard_const("/bin/sh"), + .pw_passwd = discard_const("*"), +}; + void test_nss_getorigbyname_extra_attrs(void **state) { errno_t ret; struct sysdb_attrs *attrs; - char *fqname; - - fqname = sss_create_internal_fqname(nss_test_ctx, "testuserorigextra", - nss_test_ctx->tctx->dom->name); - assert_non_null(fqname); + char *fqorigname; attrs = sysdb_new_attrs(nss_test_ctx); assert_non_null(attrs); @@ -2042,8 +2281,13 @@ void test_nss_getorigbyname_extra_attrs(void **state) ret = sysdb_attrs_add_string(attrs, SYSDB_SID_STR, "S-1-2-3-4"); assert_int_equal(ret, EOK); + fqorigname = sss_create_internal_fqname(attrs, "orig_name", + nss_test_ctx->tctx->dom->name); + assert_non_null(fqorigname); + ret = sysdb_attrs_add_string(attrs, ORIGINALAD_PREFIX SYSDB_NAME, - "orig_name"); + fqorigname); + talloc_free(fqorigname); assert_int_equal(ret, EOK); ret = sysdb_attrs_add_uint32(attrs, ORIGINALAD_PREFIX SYSDB_UIDNUM, 1234); @@ -2058,12 +2302,8 @@ void test_nss_getorigbyname_extra_attrs(void **state) ret = sysdb_attrs_add_string(attrs, "not_extra", "abc"); assert_int_equal(ret, EOK); - /* Prime the cache with a valid user */ - ret = sysdb_add_user(nss_test_ctx->tctx->dom, - fqname, 2345, 6789, - "test user orig extra", - "/home/testuserorigextra", "/bin/sh", NULL, - attrs, 300, 0); + ret = store_user(nss_test_ctx, nss_test_ctx->tctx->dom, + &orig_extra, attrs, 0); assert_int_equal(ret, EOK); mock_input_user_or_group("testuserorigextra"); @@ -2081,7 +2321,6 @@ void test_nss_getorigbyname_extra_attrs(void **state) assert_int_equal(ret, EOK); } - static int test_nss_getorigbyname_multi_check(uint32_t status, uint8_t *body, size_t blen) { @@ -2157,15 +2396,22 @@ static int test_nss_getorigbyname_multi_check(uint32_t status, uint8_t *body, return EOK; } + +struct passwd orig_multi = { + .pw_name = discard_const("testuserorigmulti"), + .pw_uid = 3456, + .pw_gid = 7890, + .pw_dir = discard_const("/home/testuserorigmulti"), + .pw_gecos = discard_const("test user"), + .pw_shell = discard_const("/bin/sh"), + .pw_passwd = discard_const("*"), +}; + void test_nss_getorigbyname_multi_value_attrs(void **state) { errno_t ret; struct sysdb_attrs *attrs; - char *fqname; - - fqname = sss_create_internal_fqname(nss_test_ctx, "testuserorigmulti", - nss_test_ctx->tctx->dom->name); - assert_non_null(fqname); + char *fqorigname; attrs = sysdb_new_attrs(nss_test_ctx); assert_non_null(attrs); @@ -2173,8 +2419,13 @@ void test_nss_getorigbyname_multi_value_attrs(void **state) ret = sysdb_attrs_add_string(attrs, SYSDB_SID_STR, "S-1-2-3-4"); assert_int_equal(ret, EOK); + fqorigname = sss_create_internal_fqname(attrs, "orig_name", + nss_test_ctx->tctx->dom->name); + assert_non_null(fqorigname); + ret = sysdb_attrs_add_string(attrs, ORIGINALAD_PREFIX SYSDB_NAME, - "orig_name"); + fqorigname); + talloc_free(fqorigname); assert_int_equal(ret, EOK); ret = sysdb_attrs_add_uint32(attrs, ORIGINALAD_PREFIX SYSDB_UIDNUM, 1234); @@ -2189,12 +2440,8 @@ void test_nss_getorigbyname_multi_value_attrs(void **state) ret = sysdb_attrs_add_string(attrs, SYSDB_ORIG_MEMBEROF, "cn=123"); assert_int_equal(ret, EOK); - /* Prime the cache with a valid user */ - ret = sysdb_add_user(nss_test_ctx->tctx->dom, - fqname, 3456, 7890, - "test user orig multi value", - "/home/testuserorigextra", "/bin/sh", NULL, - attrs, 300, 0); + ret = store_user(nss_test_ctx, nss_test_ctx->tctx->dom, + &orig_multi, attrs, 0); assert_int_equal(ret, EOK); mock_input_user_or_group("testuserorigmulti"); @@ -2212,6 +2459,16 @@ void test_nss_getorigbyname_multi_value_attrs(void **state) assert_int_equal(ret, EOK); } +struct passwd upn_user = { + .pw_name = discard_const("upnuser"), + .pw_uid = 34567, + .pw_gid = 45678, + .pw_dir = discard_const("/home/testuserorig"), + .pw_gecos = discard_const("test user"), + .pw_shell = discard_const("/bin/sh"), + .pw_passwd = discard_const("*"), +}; + static int test_nss_getpwnam_upn_check(uint32_t status, uint8_t *body, size_t blen) @@ -2224,11 +2481,7 @@ static int test_nss_getpwnam_upn_check(uint32_t status, ret = parse_user_packet(body, blen, &pwd); assert_int_equal(ret, EOK); - assert_int_equal(pwd.pw_uid, 34567); - assert_int_equal(pwd.pw_gid, 45678); - assert_string_equal(pwd.pw_name, "upnuser"); - assert_string_equal(pwd.pw_shell, "/bin/sh"); - assert_string_equal(pwd.pw_passwd, "*"); + assert_users_equal(&pwd, &upn_user); return EOK; } @@ -2236,11 +2489,6 @@ void test_nss_getpwnam_upn(void **state) { errno_t ret; struct sysdb_attrs *attrs; - char *upnuser; - - upnuser = sss_create_internal_fqname(nss_test_ctx, "upnuser", - nss_test_ctx->tctx->dom->name); - assert_non_null(upnuser); attrs = sysdb_new_attrs(nss_test_ctx); assert_non_null(attrs); @@ -2249,10 +2497,8 @@ void test_nss_getpwnam_upn(void **state) assert_int_equal(ret, EOK); /* Prime the cache with a valid user */ - ret = sysdb_add_user(nss_test_ctx->tctx->dom, - upnuser, 34567, 45678, "up user", - "/home/upnuser", "/bin/sh", NULL, - attrs, 300, 0); + ret = store_user(nss_test_ctx, nss_test_ctx->tctx->dom, + &upn_user, attrs, 0); assert_int_equal(ret, EOK); mock_input_user_or_group("upnuser@upndomain.test"); @@ -2319,6 +2565,30 @@ static int test_nss_initgr_check(uint32_t status, uint8_t *body, size_t blen) return EOK; } +struct passwd testinitgr_usr = { + .pw_name = discard_const("testinitgr"), + .pw_uid = 321, + .pw_gid = 654, + .pw_dir = discard_const("/home/testinitgr"), + .pw_gecos = discard_const("test initgroups"), + .pw_shell = discard_const("/bin/sh"), + .pw_passwd = discard_const("*"), +}; + +struct group testinitgr_gr1 = { + .gr_gid = 3211, + .gr_name = discard_const("testinitgr_gr1"), + .gr_passwd = discard_const("*"), + .gr_mem = NULL, +}; + +struct group testinitgr_gr2 = { + .gr_gid = 3212, + .gr_name = discard_const("testinitgr_gr2"), + .gr_passwd = discard_const("*"), + .gr_mem = NULL, +}; + void test_nss_initgroups(void **state) { errno_t ret; @@ -2334,33 +2604,32 @@ void test_nss_initgroups(void **state) ret = sysdb_attrs_add_string(attrs, SYSDB_UPN, "upninitgr@upndomain.test"); assert_int_equal(ret, EOK); - ret = sysdb_add_user(nss_test_ctx->tctx->dom, - "testinitgr@"TEST_DOM_NAME, - 321, 654, "test initgroups", - "/home/testinitgr", "/bin/sh", NULL, - attrs, 300, 0); + ret = store_user(nss_test_ctx, nss_test_ctx->tctx->dom, + &testinitgr_usr, attrs, 0); assert_int_equal(ret, EOK); - ret = sysdb_add_group(nss_test_ctx->tctx->dom, - "testinitgr_gr1@"TEST_DOM_NAME, 3211, - NULL, 300, 0); + ret = store_group(nss_test_ctx, nss_test_ctx->tctx->dom, + &testinitgr_gr1, 0); assert_int_equal(ret, EOK); - ret = sysdb_add_group(nss_test_ctx->tctx->dom, - "testinitgr_gr2@"TEST_DOM_NAME, 3212, - NULL, 300, 0); + ret = store_group(nss_test_ctx, nss_test_ctx->tctx->dom, + &testinitgr_gr2, 0); assert_int_equal(ret, EOK); - ret = sysdb_add_group_member(nss_test_ctx->tctx->dom, - "testinitgr_gr1@"TEST_DOM_NAME, - "testinitgr@"TEST_DOM_NAME, - SYSDB_MEMBER_USER, false); + ret = store_group_member(nss_test_ctx, + testinitgr_gr1.gr_name, + nss_test_ctx->tctx->dom, + testinitgr_usr.pw_name, + nss_test_ctx->tctx->dom, + SYSDB_MEMBER_USER); assert_int_equal(ret, EOK); - ret = sysdb_add_group_member(nss_test_ctx->tctx->dom, - "testinitgr_gr2@"TEST_DOM_NAME, - "testinitgr@"TEST_DOM_NAME, - SYSDB_MEMBER_USER, false); + ret = store_group_member(nss_test_ctx, + testinitgr_gr2.gr_name, + nss_test_ctx->tctx->dom, + testinitgr_usr.pw_name, + nss_test_ctx->tctx->dom, + SYSDB_MEMBER_USER); assert_int_equal(ret, EOK); mock_input_user_or_group("testinitgr"); @@ -2424,6 +2693,30 @@ void test_nss_initgr_neg(void **state) test_initgr_neg_by_name("testinitgr_neg", false); } +struct passwd testinitgr_srch_usr = { + .pw_name = discard_const("testinitgr_srch"), + .pw_uid = 421, + .pw_gid = 654, + .pw_dir = discard_const("/home/testinitgr_srch"), + .pw_gecos = discard_const("test initgroups"), + .pw_shell = discard_const("/bin/sh"), + .pw_passwd = discard_const("*"), +}; + +struct group testinitgr_srch_gr1 = { + .gr_gid = 4211, + .gr_name = discard_const("testinitgr_srch_gr1"), + .gr_passwd = discard_const("*"), + .gr_mem = NULL, +}; + +struct group testinitgr_srch_gr2 = { + .gr_gid = 4212, + .gr_name = discard_const("testinitgr_srch_gr2"), + .gr_passwd = discard_const("*"), + .gr_mem = NULL, +}; + static int test_nss_initgr_search_acct_cb(void *pvt) { errno_t ret; @@ -2436,36 +2729,34 @@ static int test_nss_initgr_search_acct_cb(void *pvt) time(NULL) + 300); assert_int_equal(ret, EOK); - ret = sysdb_add_user(nss_test_ctx->tctx->dom, - "testinitgr_srch@"TEST_DOM_NAME, - 421, 654, "test initgroups", - "/home/testinitgr", "/bin/sh", NULL, - attrs, 300, 0); + ret = store_user(nss_test_ctx, nss_test_ctx->tctx->dom, + &testinitgr_srch_usr, attrs, 0); assert_int_equal(ret, EOK); - ret = sysdb_add_group(nss_test_ctx->tctx->dom, - "testinitgr_srch_gr1@"TEST_DOM_NAME, 4211, - NULL, 300, 0); + ret = store_group(nss_test_ctx, nss_test_ctx->tctx->dom, + &testinitgr_srch_gr1, 0); assert_int_equal(ret, EOK); - ret = sysdb_add_group(nss_test_ctx->tctx->dom, - "testinitgr_srch_gr2@"TEST_DOM_NAME, 4212, - NULL, 300, 0); + ret = store_group(nss_test_ctx, nss_test_ctx->tctx->dom, + &testinitgr_srch_gr2, 0); assert_int_equal(ret, EOK); - ret = sysdb_add_group_member(nss_test_ctx->tctx->dom, - "testinitgr_srch_gr1@"TEST_DOM_NAME, - "testinitgr_srch@"TEST_DOM_NAME, - SYSDB_MEMBER_USER, false); + ret = store_group_member(nss_test_ctx, + testinitgr_srch_gr1.gr_name, + nss_test_ctx->tctx->dom, + testinitgr_srch_usr.pw_name, + nss_test_ctx->tctx->dom, + SYSDB_MEMBER_USER); assert_int_equal(ret, EOK); - ret = sysdb_add_group_member(nss_test_ctx->tctx->dom, - "testinitgr_srch_gr2@"TEST_DOM_NAME, - "testinitgr_srch@"TEST_DOM_NAME, - SYSDB_MEMBER_USER, false); + ret = store_group_member(nss_test_ctx, + testinitgr_srch_gr2.gr_name, + nss_test_ctx->tctx->dom, + testinitgr_srch_usr.pw_name, + nss_test_ctx->tctx->dom, + SYSDB_MEMBER_USER); assert_int_equal(ret, EOK); - return EOK; } @@ -2490,8 +2781,8 @@ void test_nss_initgr_search(void **state) mock_fill_initgr_user(); set_cmd_cb(test_nss_initgr_search_check); - ret = sysdb_getpwnam(nss_test_ctx, nss_test_ctx->tctx->dom, - "testinitgr_srch", &res); + ret = get_user(nss_test_ctx, nss_test_ctx->tctx->dom, + "testinitgr_srch", &res); assert_int_equal(ret, EOK); assert_int_equal(res->count, 0); @@ -2504,12 +2795,36 @@ void test_nss_initgr_search(void **state) assert_int_equal(ret, EOK); /* test_nss_getpwnam_search_check will check the user attributes */ - ret = sysdb_getpwnam(nss_test_ctx, nss_test_ctx->tctx->dom, - "testinitgr_srch", &res); + ret = get_user(nss_test_ctx, nss_test_ctx->tctx->dom, + "testinitgr_srch", &res); assert_int_equal(ret, EOK); assert_int_equal(res->count, 1); } +struct passwd testinitgr_update_usr = { + .pw_name = discard_const("testinitgr_update"), + .pw_uid = 521, + .pw_gid = 654, + .pw_dir = discard_const("/home/testinitgr_update"), + .pw_gecos = discard_const("test initgroups"), + .pw_shell = discard_const("/bin/sh"), + .pw_passwd = discard_const("*"), +}; + +struct group testinitgr_update_gr1 = { + .gr_gid = 5211, + .gr_name = discard_const("testinitgr_update_gr1"), + .gr_passwd = discard_const("*"), + .gr_mem = NULL, +}; + +struct group testinitgr_update_gr2 = { + .gr_gid = 5212, + .gr_name = discard_const("testinitgr_update_gr2"), + .gr_passwd = discard_const("*"), + .gr_mem = NULL, +}; + static int test_nss_initgr_update_acct_cb(void *pvt) { errno_t ret; @@ -2522,20 +2837,22 @@ static int test_nss_initgr_update_acct_cb(void *pvt) time(NULL) + 300); assert_int_equal(ret, EOK); - ret = sysdb_set_user_attr(nss_test_ctx->tctx->dom, - "testinitgr_update@"TEST_DOM_NAME, - attrs, SYSDB_MOD_REP); + ret = set_user_attr(nss_test_ctx, + nss_test_ctx->tctx->dom, + &testinitgr_update_usr, + attrs); assert_int_equal(ret, EOK); - ret = sysdb_add_group(nss_test_ctx->tctx->dom, - "testinitgr_check_gr2@"TEST_DOM_NAME, 5212, - NULL, 300, 0); + ret = store_group(nss_test_ctx, nss_test_ctx->tctx->dom, + &testinitgr_update_gr2, 0); assert_int_equal(ret, EOK); - ret = sysdb_add_group_member(nss_test_ctx->tctx->dom, - "testinitgr_check_gr2@"TEST_DOM_NAME, - "testinitgr_update@"TEST_DOM_NAME, - SYSDB_MEMBER_USER, false); + ret = store_group_member(nss_test_ctx, + testinitgr_update_gr2.gr_name, + nss_test_ctx->tctx->dom, + testinitgr_update_usr.pw_name, + nss_test_ctx->tctx->dom, + SYSDB_MEMBER_USER); assert_int_equal(ret, EOK); return EOK; @@ -2562,22 +2879,20 @@ void test_nss_initgr_update(void **state) time(NULL) - 1); assert_int_equal(ret, EOK); - ret = sysdb_add_user(nss_test_ctx->tctx->dom, - "testinitgr_update@"TEST_DOM_NAME, - 521, 654, "test initgroups", - "/home/testinitgr", "/bin/sh", NULL, - attrs, 300, 0); + ret = store_user(nss_test_ctx, nss_test_ctx->tctx->dom, + &testinitgr_update_usr, attrs, 0); assert_int_equal(ret, EOK); - ret = sysdb_add_group(nss_test_ctx->tctx->dom, - "testinitgr_update_gr1@"TEST_DOM_NAME, 5211, - NULL, 300, 0); + ret = store_group(nss_test_ctx, nss_test_ctx->tctx->dom, + &testinitgr_update_gr1, 0); assert_int_equal(ret, EOK); - ret = sysdb_add_group_member(nss_test_ctx->tctx->dom, - "testinitgr_update_gr1@"TEST_DOM_NAME, - "testinitgr_update@"TEST_DOM_NAME, - SYSDB_MEMBER_USER, false); + ret = store_group_member(nss_test_ctx, + testinitgr_update_gr1.gr_name, + nss_test_ctx->tctx->dom, + testinitgr_update_usr.pw_name, + nss_test_ctx->tctx->dom, + SYSDB_MEMBER_USER); assert_int_equal(ret, EOK); mock_input_user_or_group("testinitgr_update"); @@ -2586,7 +2901,6 @@ void test_nss_initgr_update(void **state) mock_fill_initgr_user(); set_cmd_cb(test_nss_initgr_update_check); - /* Query for that user, call a callback when command finishes */ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_INITGR, nss_test_ctx->nss_cmds); @@ -2597,6 +2911,30 @@ void test_nss_initgr_update(void **state) assert_int_equal(ret, EOK); } +struct passwd testinitgr_2attr_usr = { + .pw_name = discard_const("testinitgr_2attr"), + .pw_uid = 521, + .pw_gid = 654, + .pw_dir = discard_const("/home/testinitgr_2attr"), + .pw_gecos = discard_const("test initgroups"), + .pw_shell = discard_const("/bin/sh"), + .pw_passwd = discard_const("*"), +}; + +struct group testinitgr_2attr_gr1 = { + .gr_gid = 5221, + .gr_name = discard_const("testinitgr_2attr_gr11"), + .gr_passwd = discard_const("*"), + .gr_mem = NULL, +}; + +struct group testinitgr_2attr_gr2 = { + .gr_gid = 5222, + .gr_name = discard_const("testinitgr_2attr_gr12"), + .gr_passwd = discard_const("*"), + .gr_mem = NULL, +}; + static int test_nss_initgr_update_acct_2expire_attributes_cb(void *pvt) { errno_t ret; @@ -2609,20 +2947,20 @@ static int test_nss_initgr_update_acct_2expire_attributes_cb(void *pvt) time(NULL) + 300); assert_int_equal(ret, EOK); - ret = sysdb_set_user_attr(nss_test_ctx->tctx->dom, - "testinitgr_2attr@"TEST_DOM_NAME, - attrs, SYSDB_MOD_REP); + ret = set_user_attr(nss_test_ctx, nss_test_ctx->tctx->dom, + &testinitgr_2attr_usr, attrs); assert_int_equal(ret, EOK); - ret = sysdb_add_group(nss_test_ctx->tctx->dom, - "testinitgr_2attr_gr12@"TEST_DOM_NAME, 5222, - NULL, 300, 0); + ret = store_group(nss_test_ctx, nss_test_ctx->tctx->dom, + &testinitgr_2attr_gr2, 0); assert_int_equal(ret, EOK); - ret = sysdb_add_group_member(nss_test_ctx->tctx->dom, - "testinitgr_2attr_gr12@"TEST_DOM_NAME, - "testinitgr_2attr@"TEST_DOM_NAME, - SYSDB_MEMBER_USER, false); + ret = store_group_member(nss_test_ctx, + testinitgr_2attr_gr2.gr_name, + nss_test_ctx->tctx->dom, + testinitgr_2attr_usr.pw_name, + nss_test_ctx->tctx->dom, + SYSDB_MEMBER_USER); assert_int_equal(ret, EOK); return EOK; @@ -2661,22 +2999,20 @@ void test_nss_initgr_update_two_expire_attributes(void **state) time(NULL) + 100); assert_int_equal(ret, EOK); - ret = sysdb_add_user(nss_test_ctx->tctx->dom, - "testinitgr_2attr@"TEST_DOM_NAME, - 522, 655, "test initgroups2", - "/home/testinitgr_2attr", "/bin/sh", NULL, - attrs, 300, 0); + ret = store_user(nss_test_ctx, nss_test_ctx->tctx->dom, + &testinitgr_2attr_usr, attrs, 0); assert_int_equal(ret, EOK); - ret = sysdb_add_group(nss_test_ctx->tctx->dom, - "testinitgr_2attr_gr11@"TEST_DOM_NAME, 5221, - NULL, 300, 0); + ret = store_group(nss_test_ctx, nss_test_ctx->tctx->dom, + &testinitgr_2attr_gr1, 0); assert_int_equal(ret, EOK); - ret = sysdb_add_group_member(nss_test_ctx->tctx->dom, - "testinitgr_2attr_gr11@"TEST_DOM_NAME, - "testinitgr_2attr@"TEST_DOM_NAME, - SYSDB_MEMBER_USER, false); + ret = store_group_member(nss_test_ctx, + testinitgr_2attr_gr1.gr_name, + nss_test_ctx->tctx->dom, + testinitgr_2attr_usr.pw_name, + nss_test_ctx->tctx->dom, + SYSDB_MEMBER_USER); assert_int_equal(ret, EOK); mock_input_user_or_group("testinitgr_2attr"); @@ -2803,6 +3139,16 @@ static int nss_test_teardown(void **state) return 0; } +struct passwd testbysid = { + .pw_name = discard_const("testsiduser"), + .pw_uid = 12345, + .pw_gid = 6890, + .pw_dir = discard_const("/home/testsiduser"), + .pw_gecos = discard_const("test bysid lookup"), + .pw_shell = discard_const("/bin/sh"), + .pw_passwd = discard_const("*"), +}; + static int test_nss_getnamebysid_check(uint32_t status, uint8_t *body, size_t blen) { size_t rp = 2 * sizeof(uint32_t); /* num_results and reserved */ @@ -2815,7 +3161,7 @@ static int test_nss_getnamebysid_check(uint32_t status, uint8_t *body, size_t bl assert_int_equal(id_type, SSS_ID_TYPE_UID); name = (const char *) body + rp; - assert_string_equal(name, "testsiduser"); + assert_string_equal(name, testbysid.pw_name); return EOK; } @@ -2836,12 +3182,8 @@ static void test_nss_getnamebysid(void **state) ret = sysdb_attrs_add_string(attrs, SYSDB_SID_STR, user_sid); assert_int_equal(ret, EOK); - /* Prime the cache with a valid user */ - ret = sysdb_add_user(nss_test_ctx->tctx->dom, - "testsiduser@"TEST_DOM_NAME, - 12345, 6890, "test sid user", - "/home/testsiduser", "/bin/sh", NULL, - attrs, 300, 0); + ret = store_user(nss_test_ctx, nss_test_ctx->tctx->dom, + &testbysid, attrs, 0); assert_int_equal(ret, EOK); mock_input_user_or_group(user_sid); @@ -2904,6 +3246,16 @@ void test_nss_getnamebysid_neg(void **state) assert_int_equal(nss_test_ctx->ncache_hits, 1); } +struct passwd testbysid_update = { + .pw_name = discard_const("testsidbyname_update"), + .pw_uid = 123456, + .pw_gid = 789, + .pw_dir = discard_const("/home/testsidbyname_update"), + .pw_gecos = discard_const("test bysid lookup"), + .pw_shell = discard_const("/bin/sh"), + .pw_passwd = discard_const("*"), +}; + static int test_nss_getnamebysid_update_check(uint32_t status, uint8_t *body, size_t blen) @@ -2928,11 +3280,9 @@ static int test_nss_getnamebysid_update_acct_cb(void *pvt) errno_t ret; struct nss_test_ctx *ctx = talloc_get_type(pvt, struct nss_test_ctx); - ret = sysdb_store_user(ctx->tctx->dom, - "testsidbyname_update@"TEST_DOM_NAME, NULL, - 123456, 789, "test user", - "/home/testsidbyname_update", "/bin/ksh", NULL, - NULL, NULL, 300, 0); + testbysid_update.pw_shell = discard_const("/bin/ksh"); + ret = store_user(ctx, nss_test_ctx->tctx->dom, + &testbysid_update, NULL, 0); assert_int_equal(ret, EOK); return EOK; @@ -2957,11 +3307,8 @@ void test_nss_getnamebysid_update(void **state) assert_int_equal(ret, EOK); /* Prime the cache with a valid but expired user */ - ret = sysdb_add_user(nss_test_ctx->tctx->dom, - "testsidbyname_update@"TEST_DOM_NAME, - 123456, 789, "test user", - "/home/testsidbyname_update", "/bin/sh", NULL, - attrs, 1, 1); + ret = store_user(nss_test_ctx, nss_test_ctx->tctx->dom, + &testbysid_update, attrs, 1); assert_int_equal(ret, EOK); /* Mock client input */ @@ -2986,8 +3333,8 @@ void test_nss_getnamebysid_update(void **state) assert_int_equal(ret, EOK); /* Check the user was updated in the cache */ - ret = sysdb_getpwnam(nss_test_ctx, nss_test_ctx->tctx->dom, - "testsidbyname_update", &res); + ret = get_user(nss_test_ctx, nss_test_ctx->tctx->dom, + testbysid_update.pw_name, &res); assert_int_equal(ret, EOK); assert_int_equal(res->count, 1); @@ -2995,6 +3342,16 @@ void test_nss_getnamebysid_update(void **state) assert_string_equal(shell, "/bin/ksh"); } +struct passwd testbycert = { + .pw_name = discard_const("testcertuser"), + .pw_uid = 23456, + .pw_gid = 6890, + .pw_dir = discard_const("/home/testcertuser"), + .pw_gecos = discard_const("test cert user"), + .pw_shell = discard_const("/bin/sh"), + .pw_passwd = discard_const("*"), +}; + #define TEST_TOKEN_CERT \ "MIIECTCCAvGgAwIBAgIBCDANBgkqhkiG9w0BAQsFADA0MRIwEAYDVQQKDAlJUEEu" \ "REVWRUwxHjAcBgNVBAMMFUNlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNTA2MjMx" \ @@ -3031,7 +3388,7 @@ static int test_nss_getnamebycert_check(uint32_t status, uint8_t *body, size_t b assert_int_equal(id_type, SSS_ID_TYPE_UID); name = (const char *)body + rp; - assert_string_equal(name, "testcertuser"); + assert_string_equal(name, testbycert.pw_name); return EOK; } @@ -3054,10 +3411,8 @@ static void test_nss_getnamebycert(void **state) assert_int_equal(ret, EOK); /* Prime the cache with a valid user */ - ret = sysdb_add_user(nss_test_ctx->tctx->dom, - "testcertuser", 23456, 6890, "test cert user", - "/home/testcertuser", "/bin/sh", NULL, - attrs, 300, 0); + ret = store_user(nss_test_ctx, nss_test_ctx->tctx->dom, + &testbycert, attrs, 0); assert_int_equal(ret, EOK); talloc_free(attrs); |
