test_nss_srv.c revision 229c292143dcd4120acb022682b5b7d0aca622dd
1f53e295ebd19aed1767d12da7abfab9936c148cjerenkrantz/*
1f53e295ebd19aed1767d12da7abfab9936c148cjerenkrantz Authors:
1f53e295ebd19aed1767d12da7abfab9936c148cjerenkrantz Jakub Hrozek <jhrozek@redhat.com>
1f53e295ebd19aed1767d12da7abfab9936c148cjerenkrantz
1f53e295ebd19aed1767d12da7abfab9936c148cjerenkrantz Copyright (C) 2013 Red Hat
1f53e295ebd19aed1767d12da7abfab9936c148cjerenkrantz
bdd978e5ecd8daa2542d4d4e1988c78a622cd7f4nd SSSD tests: NSS responder tests
bdd978e5ecd8daa2542d4d4e1988c78a622cd7f4nd
bdd978e5ecd8daa2542d4d4e1988c78a622cd7f4nd This program is free software; you can redistribute it and/or modify
bdd978e5ecd8daa2542d4d4e1988c78a622cd7f4nd it under the terms of the GNU General Public License as published by
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen the Free Software Foundation; either version 3 of the License, or
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen (at your option) any later version.
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen This program is distributed in the hope that it will be useful,
bdd978e5ecd8daa2542d4d4e1988c78a622cd7f4nd but WITHOUT ANY WARRANTY; without even the implied warranty of
bdd978e5ecd8daa2542d4d4e1988c78a622cd7f4nd MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
bdd978e5ecd8daa2542d4d4e1988c78a622cd7f4nd GNU General Public License for more details.
af33a4994ae2ff15bc67d19ff1a7feb906745bf8rbowen
3f08db06526d6901aa08c110b5bc7dde6bc39905nd You should have received a copy of the GNU General Public License
bdd978e5ecd8daa2542d4d4e1988c78a622cd7f4nd along with this program. If not, see <http://www.gnu.org/licenses/>.
bdd978e5ecd8daa2542d4d4e1988c78a622cd7f4nd*/
bdd978e5ecd8daa2542d4d4e1988c78a622cd7f4nd
3f08db06526d6901aa08c110b5bc7dde6bc39905nd#include <talloc.h>
bdd978e5ecd8daa2542d4d4e1988c78a622cd7f4nd#include <tevent.h>
bdd978e5ecd8daa2542d4d4e1988c78a622cd7f4nd#include <errno.h>
3b3b7fc78d1f5bfc2769903375050048ff41ff26nd#include <popt.h>
0066eddda7203f6345b56f77d146a759298dc635gryzor
f086b4b402fa9a2fefc7dda85de2a3cc1cd0a654rjung#include "tests/cmocka/common_mock.h"
3b3b7fc78d1f5bfc2769903375050048ff41ff26nd#include "tests/cmocka/common_mock_resp.h"
bdd978e5ecd8daa2542d4d4e1988c78a622cd7f4nd#include "responder/common/negcache.h"
bdd978e5ecd8daa2542d4d4e1988c78a622cd7f4nd#include "responder/nss/nsssrv.h"
bdd978e5ecd8daa2542d4d4e1988c78a622cd7f4nd#include "responder/nss/nsssrv_private.h"
bdd978e5ecd8daa2542d4d4e1988c78a622cd7f4nd#include "sss_client/idmap/sss_nss_idmap.h"
bdd978e5ecd8daa2542d4d4e1988c78a622cd7f4nd#include "util/util_sss_idmap.h"
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin
bdd978e5ecd8daa2542d4d4e1988c78a622cd7f4nd#define TESTS_PATH "tests_nss"
bdd978e5ecd8daa2542d4d4e1988c78a622cd7f4nd#define TEST_CONF_DB "test_nss_conf.ldb"
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin#define TEST_DOM_NAME "nss_test"
3267af3f6fbf9743e64a9f019c745317f18cd9f7poirier#define TEST_SYSDB_FILE "cache_"TEST_DOM_NAME".ldb"
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf#define TEST_SUBDOM_NAME "test.subdomain"
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin#define TEST_ID_PROVIDER "ldap"
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirinstruct nss_test_ctx {
cb3a1082aec4b3b4f4ed238c93c3cc54933a7f0end struct sss_test_ctx *tctx;
cb3a1082aec4b3b4f4ed238c93c3cc54933a7f0end struct sss_domain_info *subdom;
f8b7daeb0e3f0ac4544fcc665de10c6b69a1ce0dsf
1f53e295ebd19aed1767d12da7abfab9936c148cjerenkrantz struct resp_ctx *rctx;
1f53e295ebd19aed1767d12da7abfab9936c148cjerenkrantz struct cli_ctx *cctx;
1f53e295ebd19aed1767d12da7abfab9936c148cjerenkrantz struct sss_cmd_table *nss_cmds;
1f53e295ebd19aed1767d12da7abfab9936c148cjerenkrantz struct nss_ctx *nctx;
1f53e295ebd19aed1767d12da7abfab9936c148cjerenkrantz
1f53e295ebd19aed1767d12da7abfab9936c148cjerenkrantz bool ncache_hit;
1f53e295ebd19aed1767d12da7abfab9936c148cjerenkrantz};
bdd978e5ecd8daa2542d4d4e1988c78a622cd7f4nd
bdd978e5ecd8daa2542d4d4e1988c78a622cd7f4ndstruct nss_test_ctx *nss_test_ctx;
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin/* Mock NSS structure */
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirinstruct nss_ctx *
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirinmock_nctx(TALLOC_CTX *mem_ctx)
35ff2d06df95b9593ee312dfff883c76f3b97798noodl{
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin struct nss_ctx *nctx;
bdd978e5ecd8daa2542d4d4e1988c78a622cd7f4nd errno_t ret;
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin enum idmap_error_code err;
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin nctx = talloc_zero(mem_ctx, struct nss_ctx);
30471a4650391f57975f60bbb6e4a90be7b284bfhumbedooh if (!nctx) {
bdd978e5ecd8daa2542d4d4e1988c78a622cd7f4nd return NULL;
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin }
35ff2d06df95b9593ee312dfff883c76f3b97798noodl
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin ret = sss_ncache_init(nctx, &nctx->ncache);
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf if (ret != EOK) {
3267af3f6fbf9743e64a9f019c745317f18cd9f7poirier talloc_free(nctx);
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf return NULL;
d8c20b2218b1aff46358f67ae5e9c66a67982efbminfrin }
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf nctx->neg_timeout = 10;
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin nctx->pwfield = discard_const("*");
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin err = sss_idmap_init(sss_idmap_talloc, nctx, sss_idmap_talloc_free,
1f53e295ebd19aed1767d12da7abfab9936c148cjerenkrantz &nctx->idmap_ctx);
f8b7daeb0e3f0ac4544fcc665de10c6b69a1ce0dsf if (err != IDMAP_SUCCESS) {
1f53e295ebd19aed1767d12da7abfab9936c148cjerenkrantz DEBUG(SSSDBG_FATAL_FAILURE, "sss_idmap_init failed.\n");
d8c20b2218b1aff46358f67ae5e9c66a67982efbminfrin talloc_free(nctx);
d8c20b2218b1aff46358f67ae5e9c66a67982efbminfrin return NULL;
d8c20b2218b1aff46358f67ae5e9c66a67982efbminfrin }
a7a43799fed7fcdeaa70584dbd3ecd130b25deb3noodl
1f53e295ebd19aed1767d12da7abfab9936c148cjerenkrantz return nctx;
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin}
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf/* Mock reading requests from a client. Use values passed from mock
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin * instead
1f53e295ebd19aed1767d12da7abfab9936c148cjerenkrantz */
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirinvoid __real_sss_packet_get_body(struct sss_packet *packet,
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf uint8_t **body, size_t *blen);
f0fa55ff14fa0bf8fd72d989f6625de6dc3260c8igalic
f0fa55ff14fa0bf8fd72d989f6625de6dc3260c8igalicvoid __wrap_sss_packet_get_body(struct sss_packet *packet,
f0fa55ff14fa0bf8fd72d989f6625de6dc3260c8igalic uint8_t **body, size_t *blen)
f0fa55ff14fa0bf8fd72d989f6625de6dc3260c8igalic{
f0fa55ff14fa0bf8fd72d989f6625de6dc3260c8igalic enum sss_test_wrapper_call wtype = sss_mock_type(enum sss_test_wrapper_call);
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin size_t len;
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf if (wtype == WRAP_CALL_REAL) {
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin return __real_sss_packet_get_body(packet, body, blen);
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf }
f0fa55ff14fa0bf8fd72d989f6625de6dc3260c8igalic
f0fa55ff14fa0bf8fd72d989f6625de6dc3260c8igalic *body = sss_mock_ptr_type(uint8_t *);
f0fa55ff14fa0bf8fd72d989f6625de6dc3260c8igalic len = sss_mock_type(size_t);
f0fa55ff14fa0bf8fd72d989f6625de6dc3260c8igalic if (len == 0) {
f0fa55ff14fa0bf8fd72d989f6625de6dc3260c8igalic len = strlen((const char *) *body)+1;
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin }
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin *blen = len;
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf return;
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin}
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf
f0fa55ff14fa0bf8fd72d989f6625de6dc3260c8igalic/* Mock returning result to client. Terminate the unit test instead. */
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirintypedef int (*cmd_cb_fn_t)(uint32_t, uint8_t *, size_t );
f0fa55ff14fa0bf8fd72d989f6625de6dc3260c8igalic
f0fa55ff14fa0bf8fd72d989f6625de6dc3260c8igalicstatic void set_cmd_cb(cmd_cb_fn_t fn)
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin{
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin will_return(__wrap_sss_cmd_done, fn);
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf}
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsfvoid __wrap_sss_cmd_done(struct cli_ctx *cctx, void *freectx)
f0fa55ff14fa0bf8fd72d989f6625de6dc3260c8igalic{
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin struct sss_packet *packet = cctx->creq->out;
f0fa55ff14fa0bf8fd72d989f6625de6dc3260c8igalic uint8_t *body;
f0fa55ff14fa0bf8fd72d989f6625de6dc3260c8igalic size_t blen;
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin cmd_cb_fn_t check_cb;
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf check_cb = sss_mock_ptr_type(cmd_cb_fn_t);
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin __real_sss_packet_get_body(packet, &body, &blen);
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin nss_test_ctx->tctx->error = check_cb(sss_packet_get_status(packet),
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin body, blen);
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf nss_test_ctx->tctx->done = true;
f0fa55ff14fa0bf8fd72d989f6625de6dc3260c8igalic}
f0fa55ff14fa0bf8fd72d989f6625de6dc3260c8igalic
f0fa55ff14fa0bf8fd72d989f6625de6dc3260c8igalicenum sss_cli_command __wrap_sss_packet_get_cmd(struct sss_packet *packet)
f0fa55ff14fa0bf8fd72d989f6625de6dc3260c8igalic{
f0fa55ff14fa0bf8fd72d989f6625de6dc3260c8igalic return sss_mock_type(enum sss_cli_command);
1f53e295ebd19aed1767d12da7abfab9936c148cjerenkrantz}
d8c20b2218b1aff46358f67ae5e9c66a67982efbminfrin
d8c20b2218b1aff46358f67ae5e9c66a67982efbminfrinint __wrap_sss_cmd_send_empty(struct cli_ctx *cctx, TALLOC_CTX *freectx)
1f53e295ebd19aed1767d12da7abfab9936c148cjerenkrantz{
1f53e295ebd19aed1767d12da7abfab9936c148cjerenkrantz nss_test_ctx->tctx->done = true;
1f53e295ebd19aed1767d12da7abfab9936c148cjerenkrantz nss_test_ctx->tctx->error = ENOENT;
a7a43799fed7fcdeaa70584dbd3ecd130b25deb3noodl return EOK;
1f53e295ebd19aed1767d12da7abfab9936c148cjerenkrantz}
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf/* Intercept negative cache lookups */
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsfint __real_sss_ncache_check_user(struct sss_nc_ctx *ctx, int ttl,
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin struct sss_domain_info *dom, const char *name);
1f53e295ebd19aed1767d12da7abfab9936c148cjerenkrantz
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirinint __wrap_sss_ncache_check_user(struct sss_nc_ctx *ctx, int ttl,
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf struct sss_domain_info *dom, const char *name)
f0fa55ff14fa0bf8fd72d989f6625de6dc3260c8igalic{
f0fa55ff14fa0bf8fd72d989f6625de6dc3260c8igalic int ret;
f0fa55ff14fa0bf8fd72d989f6625de6dc3260c8igalic
f0fa55ff14fa0bf8fd72d989f6625de6dc3260c8igalic ret = __real_sss_ncache_check_user(ctx, ttl, dom, name);
f0fa55ff14fa0bf8fd72d989f6625de6dc3260c8igalic if (ret == EEXIST) {
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf nss_test_ctx->ncache_hit = true;
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin }
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin return ret;
9a367ec3d570bcbaf8923dad66cb3b1532963964trawick}
9a367ec3d570bcbaf8923dad66cb3b1532963964trawick
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirinint __real_sss_ncache_check_uid(struct sss_nc_ctx *ctx, int ttl, uid_t uid);
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirinint __wrap_sss_ncache_check_uid(struct sss_nc_ctx *ctx, int ttl, uid_t uid)
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin{
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin int ret;
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin ret = __real_sss_ncache_check_uid(ctx, ttl, uid);
1f53e295ebd19aed1767d12da7abfab9936c148cjerenkrantz if (ret == EEXIST) {
1f53e295ebd19aed1767d12da7abfab9936c148cjerenkrantz nss_test_ctx->ncache_hit = true;
1f53e295ebd19aed1767d12da7abfab9936c148cjerenkrantz }
1b390add6886fb1c0acdea82be0ef0920f1158casf return ret;
1b390add6886fb1c0acdea82be0ef0920f1158casf}
1b390add6886fb1c0acdea82be0ef0920f1158casf
1b390add6886fb1c0acdea82be0ef0920f1158casf/* Mock input from the client library */
1b390add6886fb1c0acdea82be0ef0920f1158casfstatic void mock_input_user_or_group(const char *username)
1b390add6886fb1c0acdea82be0ef0920f1158casf{
1b390add6886fb1c0acdea82be0ef0920f1158casf will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER);
1b390add6886fb1c0acdea82be0ef0920f1158casf will_return(__wrap_sss_packet_get_body, username);
1b390add6886fb1c0acdea82be0ef0920f1158casf will_return(__wrap_sss_packet_get_body, 0);
1b390add6886fb1c0acdea82be0ef0920f1158casf}
1b390add6886fb1c0acdea82be0ef0920f1158casf
1b390add6886fb1c0acdea82be0ef0920f1158casfstatic void mock_input_id(TALLOC_CTX *mem_ctx, uint32_t id)
1b390add6886fb1c0acdea82be0ef0920f1158casf{
1b390add6886fb1c0acdea82be0ef0920f1158casf uint8_t *body;
f0fa55ff14fa0bf8fd72d989f6625de6dc3260c8igalic
1b390add6886fb1c0acdea82be0ef0920f1158casf body = talloc_zero_array(mem_ctx, uint8_t, 4);
f0fa55ff14fa0bf8fd72d989f6625de6dc3260c8igalic if (body == NULL) return;
f0fa55ff14fa0bf8fd72d989f6625de6dc3260c8igalic
1b390add6886fb1c0acdea82be0ef0920f1158casf SAFEALIGN_SETMEM_UINT32(body, id, NULL);
1b390add6886fb1c0acdea82be0ef0920f1158casf will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER);
5f9231b22f11ab2ba17c96400438fd1244087efdrbowen will_return(__wrap_sss_packet_get_body, body);
5f9231b22f11ab2ba17c96400438fd1244087efdrbowen will_return(__wrap_sss_packet_get_body, sizeof(uint32_t));
5f9231b22f11ab2ba17c96400438fd1244087efdrbowen}
5f9231b22f11ab2ba17c96400438fd1244087efdrbowen
5f9231b22f11ab2ba17c96400438fd1244087efdrbowenstatic void mock_fill_user(void)
5f9231b22f11ab2ba17c96400438fd1244087efdrbowen{
5f9231b22f11ab2ba17c96400438fd1244087efdrbowen /* One packet for the entry and one for num entries */
5f9231b22f11ab2ba17c96400438fd1244087efdrbowen will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
5f9231b22f11ab2ba17c96400438fd1244087efdrbowen will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
5f9231b22f11ab2ba17c96400438fd1244087efdrbowen}
5f9231b22f11ab2ba17c96400438fd1244087efdrbowen
5f9231b22f11ab2ba17c96400438fd1244087efdrbowenstatic void mock_fill_group_with_members(unsigned members)
bdd978e5ecd8daa2542d4d4e1988c78a622cd7f4nd{
bdd978e5ecd8daa2542d4d4e1988c78a622cd7f4nd unsigned i;
3b3b7fc78d1f5bfc2769903375050048ff41ff26nd
0066eddda7203f6345b56f77d146a759298dc635gryzor will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
f086b4b402fa9a2fefc7dda85de2a3cc1cd0a654rjung will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
ccb709596bad11241fad96d128bbaae408ad78a7rbowen
0d0ba3a410038e179b695446bb149cce6264e0abnd if (members == 0) return;
ccb709596bad11241fad96d128bbaae408ad78a7rbowen
ccb709596bad11241fad96d128bbaae408ad78a7rbowen will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
0d0ba3a410038e179b695446bb149cce6264e0abnd
cc7e1025de9ac63bd4db6fe7f71c158b2cf09fe4humbedooh /* Member header , one per member */
ccb709596bad11241fad96d128bbaae408ad78a7rbowen will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
0d0ba3a410038e179b695446bb149cce6264e0abnd for (i=0; i<members; i++) {
0d0ba3a410038e179b695446bb149cce6264e0abnd will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
0d0ba3a410038e179b695446bb149cce6264e0abnd }
ac082aefa89416cbdc9a1836eaf3bed9698201c8humbedooh}
0d0ba3a410038e179b695446bb149cce6264e0abnd
0d0ba3a410038e179b695446bb149cce6264e0abnd
0d0ba3a410038e179b695446bb149cce6264e0abndstatic int parse_user_packet(uint8_t *body, size_t blen, struct passwd *pwd)
ccb709596bad11241fad96d128bbaae408ad78a7rbowen{
0d0ba3a410038e179b695446bb149cce6264e0abnd size_t rp = 2 * sizeof(uint32_t);
0d0ba3a410038e179b695446bb149cce6264e0abnd
30471a4650391f57975f60bbb6e4a90be7b284bfhumbedooh SAFEALIGN_COPY_UINT32(&pwd->pw_uid, body+rp, &rp);
1a1356f375e36db7bee379ea0684ab389579f798rbowen SAFEALIGN_COPY_UINT32(&pwd->pw_gid, body+rp, &rp);
af33a4994ae2ff15bc67d19ff1a7feb906745bf8rbowen
0d0ba3a410038e179b695446bb149cce6264e0abnd /* Sequence of null terminated strings (name, passwd, gecos, dir, shell) */
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd pwd->pw_name = (char *) body+rp;
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd rp += strlen(pwd->pw_name) + 1;
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd if (rp >= blen) return EINVAL;
bdd978e5ecd8daa2542d4d4e1988c78a622cd7f4nd
pwd->pw_passwd = (char *) body+rp;
rp += strlen(pwd->pw_passwd) + 1;
if (rp >= blen) return EINVAL;
pwd->pw_gecos = (char *) body+rp;
rp += strlen(pwd->pw_gecos) + 1;
if (rp >= blen) return EINVAL;
pwd->pw_dir = (char *) body+rp;
rp += strlen(pwd->pw_dir) + 1;
if (rp >= blen) return EINVAL;
pwd->pw_shell = (char *) body+rp;
rp += strlen(pwd->pw_shell) + 1;
if (rp != blen) return EINVAL;
return EOK;
}
static int parse_group_packet(uint8_t *body, size_t blen, struct group *gr, uint32_t *nmem)
{
size_t rp = 2 * sizeof(uint32_t); /* Len and reserved */
unsigned i;
SAFEALIGN_COPY_UINT32(&gr->gr_gid, body+rp, &rp);
SAFEALIGN_COPY_UINT32(nmem, body+rp, &rp);
gr->gr_name = (char *) body+rp;
rp += strlen(gr->gr_name) + 1;
if (rp >= blen) return EINVAL;
gr->gr_passwd = (char *) body+rp;
rp += strlen(gr->gr_passwd) + 1;
if (*nmem > 0) {
gr->gr_mem = talloc_zero_array(nss_test_ctx, char *, *nmem);
if (gr->gr_mem == NULL) return ENOMEM;
for (i = 0; i < *nmem; i++) {
if (rp >= blen) return EINVAL;
gr->gr_mem[i] = talloc_strdup(gr->gr_mem, (char *) body+rp);
rp += strlen(gr->gr_mem[i]) + 1;
}
}
/* Make sure we exactly matched the end of the packet */
if (rp != blen) return EINVAL;
return EOK;
}
/* ====================== The tests =============================== */
/* 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
* the same as the test entered before starting
*/
static int test_nss_getpwnam_check(uint32_t status, uint8_t *body, size_t blen)
{
struct passwd pwd;
errno_t ret;
assert_int_equal(status, EOK);
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, "*");
return EOK;
}
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", 123, 456, "test user",
"/home/testuser", "/bin/sh", NULL,
NULL, 300, 0);
assert_int_equal(ret, EOK);
mock_input_user_or_group("testuser");
will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM);
mock_fill_user();
/* Query for that user, call a callback when command finishes */
set_cmd_cb(test_nss_getpwnam_check);
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* Wait until the test finishes with EOK */
ret = test_ev_loop(nss_test_ctx->tctx);
assert_int_equal(ret, EOK);
}
/* Test that searching for a nonexistant user yields ENOENT.
* Account callback will be called
*/
void test_nss_getpwnam_neg(void **state)
{
errno_t ret;
mock_input_user_or_group("testuser_neg");
mock_account_recv_simple();
assert_true(nss_test_ctx->ncache_hit == false);
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* Wait until the test finishes with ENOENT */
ret = test_ev_loop(nss_test_ctx->tctx);
assert_int_equal(ret, ENOENT);
assert_true(nss_test_ctx->ncache_hit == false);
/* Test that subsequent search for a nonexistent user yields
* ENOENT and Account callback is not called, on the other hand
* the ncache functions will be called
*/
nss_test_ctx->tctx->done = false;
mock_input_user_or_group("testuser_neg");
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* Wait until the test finishes with ENOENT */
ret = test_ev_loop(nss_test_ctx->tctx);
assert_int_equal(ret, ENOENT);
/* Negative cache was hit this time */
assert_true(nss_test_ctx->ncache_hit == true);
}
static int test_nss_getpwnam_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,
"testuser_search", 567, 890, "test search",
"/home/testsearch", "/bin/sh", NULL,
NULL, 300, 0);
assert_int_equal(ret, EOK);
return EOK;
}
static int test_nss_getpwnam_search_check(uint32_t status,
uint8_t *body, size_t blen)
{
struct passwd pwd;
errno_t ret;
assert_int_equal(status, EOK);
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");
return EOK;
}
void test_nss_getpwnam_search(void **state)
{
errno_t ret;
struct ldb_result *res;
mock_input_user_or_group("testuser_search");
mock_account_recv(0, 0, NULL, test_nss_getpwnam_search_acct_cb, nss_test_ctx);
will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM);
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);
assert_int_equal(ret, EOK);
assert_int_equal(res->count, 0);
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* Wait until the test finishes with EOK */
ret = test_ev_loop(nss_test_ctx->tctx);
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);
assert_int_equal(ret, EOK);
assert_int_equal(res->count, 1);
}
/* Test that searching for a user that is expired in the cache goes to the DP
* which updates the record and the NSS responder returns the updated record
*
* The user's shell attribute is updated.
*/
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", NULL, 10, 11, "test user",
"/home/testuser", "/bin/ksh", NULL,
NULL, NULL, 300, 0);
assert_int_equal(ret, EOK);
return EOK;
}
static int test_nss_getpwnam_update_check(uint32_t status,
uint8_t *body, size_t blen)
{
struct passwd pwd;
errno_t ret;
assert_int_equal(status, EOK);
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");
return EOK;
}
void test_nss_getpwnam_update(void **state)
{
errno_t ret;
struct ldb_result *res;
const char *shell;
/* Prime the cache with a valid but expired user */
ret = sysdb_add_user(nss_test_ctx->tctx->dom,
"testuser_update", 10, 11, "test user",
"/home/testuser", "/bin/sh", NULL,
NULL, 1, 1);
assert_int_equal(ret, EOK);
/* Mock client input */
mock_input_user_or_group("testuser_update");
/* Mock client command */
will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM);
/* Call this function when user is updated by the mock DP request */
mock_account_recv(0, 0, NULL, test_nss_getpwnam_update_acct_cb, nss_test_ctx);
/* Call this function to check what the responder returned to the client */
set_cmd_cb(test_nss_getpwnam_update_check);
/* Mock output buffer */
mock_fill_user();
/* Fire the command */
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* Wait until the test finishes with EOK */
ret = test_ev_loop(nss_test_ctx->tctx);
assert_int_equal(ret, EOK);
/* Check the user was updated in the cache */
ret = sysdb_getpwnam(nss_test_ctx, nss_test_ctx->tctx->dom,
"testuser_update", &res);
assert_int_equal(ret, EOK);
assert_int_equal(res->count, 1);
shell = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SHELL, NULL);
assert_string_equal(shell, "/bin/ksh");
}
/* Check that a FQDN is returned if the domain is FQDN-only and a
* FQDN is requested
*/
static int test_nss_getpwnam_check_fqdn(uint32_t status,
uint8_t *body, size_t blen)
{
struct passwd pwd;
errno_t ret;
assert_int_equal(status, EOK);
nss_test_ctx->cctx->rctx->domains[0].fqnames = false;
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");
return EOK;
}
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", 124, 457, "test user",
"/home/testuser", "/bin/sh", NULL,
NULL, 300, 0);
assert_int_equal(ret, EOK);
mock_input_user_or_group("testuser_fqdn@"TEST_DOM_NAME);
will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM);
mock_fill_user();
/* Query for that user, call a callback when command finishes */
set_cmd_cb(test_nss_getpwnam_check_fqdn);
nss_test_ctx->cctx->rctx->domains[0].fqnames = true;
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* Wait until the test finishes with EOK */
ret = test_ev_loop(nss_test_ctx->tctx);
assert_int_equal(ret, EOK);
}
/* Check that a user with a space in his username is returned fine.
*/
static int test_nss_getpwnam_check_space(uint32_t status,
uint8_t *body, size_t blen)
{
struct passwd pwd;
errno_t ret;
assert_int_equal(status, EOK);
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");
return EOK;
}
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", 225, 558, "space user",
"/home/testuser", "/bin/sh", NULL,
NULL, 300, 0);
assert_int_equal(ret, EOK);
mock_input_user_or_group("space user");
will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM);
mock_fill_user();
/* Query for that user, call a callback when command finishes */
set_cmd_cb(test_nss_getpwnam_check_space);
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* Wait until the test finishes with EOK */
ret = test_ev_loop(nss_test_ctx->tctx);
assert_int_equal(ret, EOK);
}
static int test_nss_getpwnam_check_space_sub(uint32_t status,
uint8_t *body, size_t blen)
{
struct passwd pwd;
errno_t ret;
assert_int_equal(status, EOK);
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");
return EOK;
}
void test_nss_getpwnam_space_sub(void **state)
{
errno_t ret;
/* Set whitespace substitution */
nss_test_ctx->rctx->override_space = '_';
mock_input_user_or_group("space user");
will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM);
mock_fill_user();
/* Query for that user, call a callback when command finishes */
set_cmd_cb(test_nss_getpwnam_check_space_sub);
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* Wait until the test finishes with EOK */
ret = test_ev_loop(nss_test_ctx->tctx);
nss_test_ctx->rctx->override_space = '\0';
assert_int_equal(ret, EOK);
}
void test_nss_getpwnam_space_sub_query(void **state)
{
errno_t ret;
/* Set whitespace substitution */
nss_test_ctx->rctx->override_space = '_';
mock_input_user_or_group("space_user");
will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM);
mock_fill_user();
/* Query for that user, call a callback when command finishes */
set_cmd_cb(test_nss_getpwnam_check_space_sub);
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* Wait until the test finishes with EOK */
ret = test_ev_loop(nss_test_ctx->tctx);
nss_test_ctx->rctx->override_space = '\0';
assert_int_equal(ret, EOK);
}
/*
* Check that FQDN processing is able to handle arbitrarily sized
* delimeter
*/
static int test_nss_getpwnam_check_fancy_fqdn(uint32_t status,
uint8_t *body, size_t blen)
{
struct passwd pwd;
errno_t ret;
assert_int_equal(status, EOK);
nss_test_ctx->cctx->rctx->domains[0].fqnames = false;
ret = parse_user_packet(body, blen, &pwd);
assert_int_equal(ret, EOK);
assert_int_equal(pwd.pw_uid, 125);
assert_int_equal(pwd.pw_gid, 458);
assert_string_equal(pwd.pw_name, "testuser_fqdn_fancy@@@@@"TEST_DOM_NAME);
assert_string_equal(pwd.pw_shell, "/bin/sh");
return EOK;
}
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", 125, 458, "test user",
"/home/testuser", "/bin/sh", NULL,
NULL, 300, 0);
assert_int_equal(ret, EOK);
mock_input_user_or_group("testuser_fqdn_fancy@"TEST_DOM_NAME);
will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM);
mock_fill_user();
/* Query for that user, call a callback when command finishes */
set_cmd_cb(test_nss_getpwnam_check_fancy_fqdn);
nss_test_ctx->cctx->rctx->domains[0].fqnames = true;
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* Wait until the test finishes with EOK */
ret = test_ev_loop(nss_test_ctx->tctx);
assert_int_equal(ret, EOK);
}
/* Check getting cached and valid id from cache. Account callback will
* not be called and test_nss_getpwuid_check will make sure the id is
* the same as the test entered before starting
*/
static int test_nss_getpwuid_check(uint32_t status, uint8_t *body, size_t blen)
{
struct passwd pwd;
errno_t ret;
assert_int_equal(status, EOK);
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, "*");
return EOK;
}
void test_nss_getpwuid(void **state)
{
errno_t ret;
/* Prime the cache with a valid user */
ret = sysdb_add_user(nss_test_ctx->tctx->dom,
"testuser1", 101, 401, "test user1",
"/home/testuser1", "/bin/sh", NULL,
NULL, 300, 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();
/* Query for that id, call a callback when command finishes */
set_cmd_cb(test_nss_getpwuid_check);
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWUID,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* Wait until the test finishes with EOK */
ret = test_ev_loop(nss_test_ctx->tctx);
assert_int_equal(ret, EOK);
}
/* Test that searching for a nonexistent id yields ENOENT.
* Account callback will be called
*/
void test_nss_getpwuid_neg(void **state)
{
errno_t ret;
uint8_t id = 102;
mock_input_id(nss_test_ctx, id);
mock_account_recv_simple();
assert_true(nss_test_ctx->ncache_hit == false);
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWUID,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* Wait until the test finishes with ENOENT */
ret = test_ev_loop(nss_test_ctx->tctx);
assert_int_equal(ret, ENOENT);
assert_true(nss_test_ctx->ncache_hit == false);
/* Test that subsequent search for a nonexistent id yields
* ENOENT and Account callback is not called, on the other hand
* the ncache functions will be called
*/
nss_test_ctx->tctx->done = false;
mock_input_id(nss_test_ctx, id);
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWUID,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* Wait until the test finishes with ENOENT */
ret = test_ev_loop(nss_test_ctx->tctx);
assert_int_equal(ret, ENOENT);
/* Negative cache was hit this time */
assert_true(nss_test_ctx->ncache_hit == true);
}
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", 107, 987, "example search",
"/home/examplesearch", "/bin/sh", NULL,
NULL, 300, 0);
assert_int_equal(ret, EOK);
return EOK;
}
static int test_nss_getpwuid_search_check(uint32_t status,
uint8_t *body, size_t blen)
{
struct passwd pwd;
errno_t ret;
assert_int_equal(status, EOK);
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");
return EOK;
}
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_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);
assert_int_equal(ret, EOK);
assert_int_equal(res->count, 0);
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWUID,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* Wait until the test finishes with EOK */
ret = test_ev_loop(nss_test_ctx->tctx);
assert_int_equal(ret, EOK);
/* test_nss_getpwuid_search_check will check the id attributes */
ret = sysdb_getpwuid(nss_test_ctx, nss_test_ctx->tctx->dom,
107, &res);
assert_int_equal(ret, EOK);
assert_int_equal(res->count, 1);
}
/* Test that searching for an id that is expired in the cache goes to the DP
* which updates the record and the NSS responder returns the updated record
*
* The user's shell attribute is updated.
*/
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", NULL, 109, 11000, "example user",
"/home/exampleuser", "/bin/ksh", NULL,
NULL, NULL, 300, 0);
assert_int_equal(ret, EOK);
return EOK;
}
static int test_nss_getpwuid_update_check(uint32_t status,
uint8_t *body, size_t blen)
{
struct passwd pwd;
errno_t ret;
assert_int_equal(status, EOK);
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");
return EOK;
}
void test_nss_getpwuid_update(void **state)
{
errno_t ret;
struct ldb_result *res;
const char *shell;
/* Prime the cache with a valid but expired user */
ret = sysdb_add_user(nss_test_ctx->tctx->dom,
"exampleuser_update", 109, 11000, "example user",
"/home/exampleuser", "/bin/sh", NULL,
NULL, 1, 1);
assert_int_equal(ret, EOK);
/* Mock client input */
uint8_t id = 109;
mock_input_id(nss_test_ctx, id);
/* 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 */
mock_account_recv(0, 0, NULL, test_nss_getpwuid_update_acct_cb, nss_test_ctx);
/* Call this function to check what the responder returned to the client */
set_cmd_cb(test_nss_getpwuid_update_check);
/* Mock output buffer */
mock_fill_user();
/* Fire the command */
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWUID,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* Wait until the test finishes with EOK */
ret = test_ev_loop(nss_test_ctx->tctx);
assert_int_equal(ret, EOK);
/* Check the user was updated in the cache */
ret = sysdb_getpwuid(nss_test_ctx, nss_test_ctx->tctx->dom,
109, &res);
assert_int_equal(ret, EOK);
assert_int_equal(res->count, 1);
shell = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SHELL, NULL);
assert_string_equal(shell, "/bin/ksh");
}
/* Testsuite setup and teardown */
void test_nss_setup(struct sss_test_conf_param params[],
void **state)
{
errno_t ret;
nss_test_ctx = talloc_zero(NULL, struct nss_test_ctx);
assert_non_null(nss_test_ctx);
nss_test_ctx->tctx = create_dom_test_ctx(nss_test_ctx, TESTS_PATH,
TEST_CONF_DB, TEST_DOM_NAME,
TEST_ID_PROVIDER, params);
assert_non_null(nss_test_ctx->tctx);
nss_test_ctx->nss_cmds = get_nss_cmds();
assert_non_null(nss_test_ctx->nss_cmds);
/* FIXME - perhaps this should be folded into sssd_domain_init or stricty
* used together
*/
ret = sss_names_init(nss_test_ctx, nss_test_ctx->tctx->confdb,
TEST_DOM_NAME, &nss_test_ctx->tctx->dom->names);
assert_int_equal(ret, EOK);
/* Initialize the NSS responder */
nss_test_ctx->nctx = mock_nctx(nss_test_ctx);
assert_non_null(nss_test_ctx->nctx);
ret = sss_names_init(nss_test_ctx->nctx, nss_test_ctx->tctx->confdb,
NULL, &nss_test_ctx->nctx->global_names);
assert_int_equal(ret, EOK);
assert_non_null(nss_test_ctx->nctx->global_names);
nss_test_ctx->rctx = mock_rctx(nss_test_ctx, nss_test_ctx->tctx->ev,
nss_test_ctx->tctx->dom, nss_test_ctx->nctx);
assert_non_null(nss_test_ctx->rctx);
nss_test_ctx->nctx->rctx = nss_test_ctx->rctx;
/* Create client context */
nss_test_ctx->cctx = mock_cctx(nss_test_ctx, nss_test_ctx->rctx);
assert_non_null(nss_test_ctx->cctx);
}
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;
}
static int test_nss_getgrnam_no_members_check(uint32_t status,
uint8_t *body, size_t blen)
{
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);
ret = parse_group_packet(body, blen, &gr, &nmem);
assert_int_equal(ret, EOK);
assert_int_equal(nmem, 0);
ret = test_nss_getgrnam_check(&expected, &gr, nmem);
assert_int_equal(ret, EOK);
return EOK;
}
/* Test that requesting a valid, cached group with no members returns a valid
* group structure
*/
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", 1123,
NULL, 300, 0);
assert_int_equal(ret, EOK);
mock_input_user_or_group("testgroup");
will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM);
mock_fill_group_with_members(0);
/* Query for that group, call a callback when command finishes */
set_cmd_cb(test_nss_getgrnam_no_members_check);
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* Wait until the test finishes with EOK */
ret = test_ev_loop(nss_test_ctx->tctx);
assert_int_equal(ret, EOK);
}
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" };
struct group expected = {
.gr_gid = 1124,
.gr_name = discard_const("testgroup_members"),
.gr_passwd = discard_const("*"),
.gr_mem = discard_const(exp_members)
};
assert_int_equal(status, EOK);
ret = parse_group_packet(body, blen, &gr, &nmem);
assert_int_equal(ret, EOK);
assert_int_equal(nmem, 2);
ret = test_nss_getgrnam_check(&expected, &gr, nmem);
assert_int_equal(ret, EOK);
return EOK;
}
/* Test that requesting a valid, cached group with some members returns a valid
* group structure with those members present
*/
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", 1124,
NULL, 300, 0);
assert_int_equal(ret, EOK);
ret = sysdb_add_user(nss_test_ctx->tctx->dom,
"testmember1", 2001, 456, "test member1",
"/home/testmember2", "/bin/sh", NULL,
NULL, 300, 0);
assert_int_equal(ret, EOK);
ret = sysdb_add_user(nss_test_ctx->tctx->dom,
"testmember2", 2002, 456, "test member2",
"/home/testmember2", "/bin/sh", NULL,
NULL, 300, 0);
assert_int_equal(ret, EOK);
ret = sysdb_add_group_member(nss_test_ctx->tctx->dom,
"testgroup_members", "testmember1",
SYSDB_MEMBER_USER, false);
assert_int_equal(ret, EOK);
ret = sysdb_add_group_member(nss_test_ctx->tctx->dom,
"testgroup_members", "testmember2",
SYSDB_MEMBER_USER, false);
assert_int_equal(ret, EOK);
mock_input_user_or_group("testgroup_members");
will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM);
mock_fill_group_with_members(2);
/* Query for that group, call a callback when command finishes */
set_cmd_cb(test_nss_getgrnam_members_check);
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* Wait until the test finishes with EOK */
ret = test_ev_loop(nss_test_ctx->tctx);
assert_int_equal(ret, EOK);
}
static int test_nss_getgrnam_members_check_fqdn(uint32_t status,
uint8_t *body, size_t blen)
{
int ret;
uint32_t nmem;
struct group gr;
const char *exp_members[] = { "testmember1@"TEST_DOM_NAME,
"testmember2@"TEST_DOM_NAME };
struct group expected = {
.gr_gid = 1124,
.gr_name = discard_const("testgroup_members@"TEST_DOM_NAME),
.gr_passwd = discard_const("*"),
.gr_mem = discard_const(exp_members)
};
assert_int_equal(status, EOK);
ret = parse_group_packet(body, blen, &gr, &nmem);
assert_int_equal(ret, EOK);
assert_int_equal(nmem, 2);
ret = test_nss_getgrnam_check(&expected, &gr, nmem);
assert_int_equal(ret, EOK);
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_fqdn(void **state)
{
errno_t ret;
nss_test_ctx->tctx->dom->fqnames = true;
mock_input_user_or_group("testgroup_members@"TEST_DOM_NAME);
will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM);
mock_fill_group_with_members(2);
/* Query for that group, call a callback when command finishes */
set_cmd_cb(test_nss_getgrnam_members_check_fqdn);
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* 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);
}
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 };
struct group expected = {
.gr_gid = 2124,
.gr_name = discard_const("testsubdomgroup@"TEST_SUBDOM_NAME),
.gr_passwd = discard_const("*"),
.gr_mem = discard_const(exp_members)
};
assert_int_equal(status, EOK);
ret = parse_group_packet(body, blen, &gr, &nmem);
assert_int_equal(ret, EOK);
assert_int_equal(nmem, 2);
ret = test_nss_getgrnam_check(&expected, &gr, nmem);
assert_int_equal(ret, EOK);
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;
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@"TEST_SUBDOM_NAME,
2124, NULL, 300, 0);
assert_int_equal(ret, EOK);
ret = sysdb_add_user(nss_test_ctx->subdom,
"submember1@"TEST_SUBDOM_NAME,
4001, 456, "test subdomain member1",
"/home/submember1", "/bin/sh", NULL,
NULL, 300, 0);
assert_int_equal(ret, EOK);
ret = sysdb_add_user(nss_test_ctx->subdom,
"submember2@"TEST_SUBDOM_NAME,
2002, 456, "test subdomain member2",
"/home/submember2", "/bin/sh", NULL,
NULL, 300, 0);
assert_int_equal(ret, EOK);
ret = sysdb_add_group_member(nss_test_ctx->subdom,
"testsubdomgroup@"TEST_SUBDOM_NAME,
"submember1@"TEST_SUBDOM_NAME,
SYSDB_MEMBER_USER, false);
assert_int_equal(ret, EOK);
ret = sysdb_add_group_member(nss_test_ctx->subdom,
"testsubdomgroup@"TEST_SUBDOM_NAME,
"submember2@"TEST_SUBDOM_NAME,
SYSDB_MEMBER_USER, false);
assert_int_equal(ret, EOK);
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);
/* Query for that group, call a callback when command finishes */
set_cmd_cb(test_nss_getgrnam_members_check_subdom);
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* 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);
}
static int test_nss_getgrnam_check_mix_dom(uint32_t status,
uint8_t *body, size_t blen)
{
int ret;
uint32_t nmem;
struct group gr;
const char *exp_members[] = { "testmember1",
"testmember2",
"submember1@"TEST_SUBDOM_NAME };
struct group expected = {
.gr_gid = 1124,
.gr_name = discard_const("testgroup_members"),
.gr_passwd = discard_const("*"),
.gr_mem = discard_const(exp_members)
};
assert_int_equal(status, EOK);
ret = parse_group_packet(body, blen, &gr, &nmem);
assert_int_equal(ret, EOK);
assert_int_equal(nmem, 3);
ret = test_nss_getgrnam_check(&expected, &gr, nmem);
assert_int_equal(ret, EOK);
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);
assert_int_equal(ret, EOK);
mock_input_user_or_group("testgroup_members");
will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM);
mock_fill_group_with_members(3);
/* Query for that group, call a callback when command finishes */
set_cmd_cb(test_nss_getgrnam_check_mix_dom);
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* Wait until the test finishes with EOK */
ret = test_ev_loop(nss_test_ctx->tctx);
assert_int_equal(ret, EOK);
}
static int test_nss_getgrnam_check_mix_dom_fqdn(uint32_t status,
uint8_t *body, size_t blen)
{
int ret;
uint32_t nmem;
struct group gr;
const char *exp_members[] = { "testmember1@"TEST_DOM_NAME,
"testmember2@"TEST_DOM_NAME,
"submember1@"TEST_SUBDOM_NAME };
struct group expected = {
.gr_gid = 1124,
.gr_name = discard_const("testgroup_members@"TEST_DOM_NAME),
.gr_passwd = discard_const("*"),
.gr_mem = discard_const(exp_members)
};
assert_int_equal(status, EOK);
ret = parse_group_packet(body, blen, &gr, &nmem);
assert_int_equal(ret, EOK);
assert_int_equal(nmem, 3);
ret = test_nss_getgrnam_check(&expected, &gr, nmem);
assert_int_equal(ret, EOK);
return EOK;
}
void test_nss_getgrnam_mix_dom_fqdn(void **state)
{
errno_t ret;
nss_test_ctx->tctx->dom->fqnames = true;
mock_input_user_or_group("testgroup_members@"TEST_DOM_NAME);
will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM);
mock_fill_group_with_members(3);
/* Query for that group, call a callback when command finishes */
set_cmd_cb(test_nss_getgrnam_check_mix_dom_fqdn);
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* 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);
}
static int test_nss_getgrnam_check_mix_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,
"testmember1@"TEST_DOM_NAME };
struct group expected = {
.gr_gid = 2124,
.gr_name = discard_const("testsubdomgroup@"TEST_SUBDOM_NAME),
.gr_passwd = discard_const("*"),
.gr_mem = discard_const(exp_members)
};
assert_int_equal(status, EOK);
ret = parse_group_packet(body, blen, &gr, &nmem);
assert_int_equal(ret, EOK);
assert_int_equal(nmem, 3);
ret = test_nss_getgrnam_check(&expected, &gr, nmem);
assert_int_equal(ret, EOK);
return EOK;
}
void test_nss_getgrnam_mix_subdom(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->subdom->name,
"testsubdomgroup@"TEST_SUBDOM_NAME);
assert_non_null(group_strdn);
add_groups[0] = group_strdn;
ret = sysdb_update_members_dn(nss_test_ctx->tctx->dom,
"testmember1",
SYSDB_MEMBER_USER,
add_groups, NULL);
assert_int_equal(ret, EOK);
mock_input_user_or_group("testsubdomgroup@"TEST_SUBDOM_NAME);
will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM);
mock_fill_group_with_members(3);
/* Query for that group, call a callback when command finishes */
set_cmd_cb(test_nss_getgrnam_check_mix_subdom);
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* Wait until the test finishes with EOK */
ret = test_ev_loop(nss_test_ctx->tctx);
assert_int_equal(ret, EOK);
}
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);
ret = parse_group_packet(body, blen, &gr, &nmem);
assert_int_equal(ret, EOK);
assert_int_equal(nmem, 0);
ret = test_nss_getgrnam_check(&expected, &gr, nmem);
assert_int_equal(ret, EOK);
return EOK;
}
/* Test that requesting a valid, cached group with space in its name returns a valid
* group structure
*/
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", 2123,
NULL, 300, 0);
assert_int_equal(ret, EOK);
mock_input_user_or_group("space group");
will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM);
mock_fill_group_with_members(0);
/* Query for that group, call a callback when command finishes */
set_cmd_cb(test_nss_getgrnam_space_check);
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* Wait until the test finishes with EOK */
ret = test_ev_loop(nss_test_ctx->tctx);
assert_int_equal(ret, EOK);
}
static int test_nss_getgrnam_space_sub_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);
ret = parse_group_packet(body, blen, &gr, &nmem);
assert_int_equal(ret, EOK);
assert_int_equal(nmem, 0);
ret = test_nss_getgrnam_check(&expected, &gr, nmem);
assert_int_equal(ret, EOK);
return EOK;
}
/* Test that requesting a valid, cached group with space in its name returns a valid
* group structure
*/
void test_nss_getgrnam_space_sub(void **state)
{
errno_t ret;
/* Set whitespace substitution */
nss_test_ctx->rctx->override_space = '_';
mock_input_user_or_group("space group");
will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM);
mock_fill_group_with_members(0);
/* Query for that group, call a callback when command finishes */
set_cmd_cb(test_nss_getgrnam_space_sub_check);
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* Wait until the test finishes with EOK */
ret = test_ev_loop(nss_test_ctx->tctx);
nss_test_ctx->rctx->override_space = '\0';
assert_int_equal(ret, EOK);
}
static int test_nss_well_known_sid_check(uint32_t status,
uint8_t *body, size_t blen)
{
const char *name;
enum sss_id_type type;
size_t rp = 2 * sizeof(uint32_t);
char *expected_result = sss_mock_ptr_type(char *);
if (expected_result == NULL) {
assert_int_equal(status, EINVAL);
assert_int_equal(blen, 0);
} else {
assert_int_equal(status, EOK);
SAFEALIGN_COPY_UINT32(&type, body+rp, &rp);
name = (char *) body+rp;
assert_int_equal(type, SSS_ID_TYPE_GID);
assert_string_equal(name, expected_result);
}
return EOK;
}
void test_nss_well_known_getnamebysid(void **state)
{
errno_t ret;
will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER);
will_return(__wrap_sss_packet_get_body, "S-1-5-32-550");
will_return(__wrap_sss_packet_get_body, 0);
will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETNAMEBYSID);
will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
will_return(test_nss_well_known_sid_check, "Print Operators@BUILTIN");
set_cmd_cb(test_nss_well_known_sid_check);
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETNAMEBYSID,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* Wait until the test finishes with EOK */
ret = test_ev_loop(nss_test_ctx->tctx);
assert_int_equal(ret, EOK);
}
void test_nss_well_known_getnamebysid_special(void **state)
{
errno_t ret;
will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER);
will_return(__wrap_sss_packet_get_body, "S-1-2-0");
will_return(__wrap_sss_packet_get_body, 0);
will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETNAMEBYSID);
will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
will_return(test_nss_well_known_sid_check, "LOCAL@LOCAL AUTHORITY");
set_cmd_cb(test_nss_well_known_sid_check);
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETNAMEBYSID,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* Wait until the test finishes with EOK */
ret = test_ev_loop(nss_test_ctx->tctx);
assert_int_equal(ret, EOK);
}
void test_nss_well_known_getnamebysid_non_existing(void **state)
{
errno_t ret;
will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER);
will_return(__wrap_sss_packet_get_body, "S-1-5-32-123");
will_return(__wrap_sss_packet_get_body, 0);
will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETNAMEBYSID);
will_return(test_nss_well_known_sid_check, NULL);
set_cmd_cb(test_nss_well_known_sid_check);
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETNAMEBYSID,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* Wait until the test finishes with EOK */
ret = test_ev_loop(nss_test_ctx->tctx);
assert_int_equal(ret, EOK);
}
void test_nss_well_known_getidbysid_failure(void **state)
{
errno_t ret;
will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER);
will_return(__wrap_sss_packet_get_body, "S-1-5-32-550");
will_return(__wrap_sss_packet_get_body, 0);
will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETIDBYSID);
will_return(test_nss_well_known_sid_check, NULL);
set_cmd_cb(test_nss_well_known_sid_check);
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETIDBYSID,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* Wait until the test finishes with EOK */
ret = test_ev_loop(nss_test_ctx->tctx);
assert_int_equal(ret, EOK);
}
void test_nss_well_known_getsidbyname(void **state)
{
errno_t ret;
will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER);
will_return(__wrap_sss_packet_get_body, "Cryptographic Operators@BUILTIN");
will_return(__wrap_sss_packet_get_body, 0);
will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETSIDBYNAME);
will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
will_return(test_nss_well_known_sid_check, "S-1-5-32-569");
set_cmd_cb(test_nss_well_known_sid_check);
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETSIDBYNAME,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* Wait until the test finishes with EOK */
ret = test_ev_loop(nss_test_ctx->tctx);
assert_int_equal(ret, EOK);
}
void test_nss_well_known_getsidbyname_nonexisting(void **state)
{
errno_t ret;
will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER);
will_return(__wrap_sss_packet_get_body, "Abc@BUILTIN");
will_return(__wrap_sss_packet_get_body, 0);
will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETSIDBYNAME);
will_return(test_nss_well_known_sid_check, NULL);
set_cmd_cb(test_nss_well_known_sid_check);
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETSIDBYNAME,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* Wait until the test finishes with EOK */
ret = test_ev_loop(nss_test_ctx->tctx);
assert_int_equal(ret, EOK);
}
void test_nss_well_known_getsidbyname_special(void **state)
{
errno_t ret;
will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER);
will_return(__wrap_sss_packet_get_body, "CREATOR OWNER@CREATOR AUTHORITY");
will_return(__wrap_sss_packet_get_body, 0);
will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETSIDBYNAME);
will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
will_return(test_nss_well_known_sid_check, "S-1-3-0");
set_cmd_cb(test_nss_well_known_sid_check);
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETSIDBYNAME,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* Wait until the test finishes with EOK */
ret = test_ev_loop(nss_test_ctx->tctx);
assert_int_equal(ret, EOK);
}
static int test_nss_getorigbyname_check(uint32_t status, uint8_t *body,
size_t blen)
{
const char *s;
enum sss_id_type id_type;
size_t rp = 2 * sizeof(uint32_t);
assert_int_equal(status, EOK);
SAFEALIGN_COPY_UINT32(&id_type, body+rp, &rp);
assert_int_equal(id_type, SSS_ID_TYPE_UID);
/* Sequence of null terminated strings */
s = (char *) body+rp;
assert_string_equal(s, SYSDB_SID_STR);
rp += strlen(s) + 1;
assert_true(rp < blen);
s = (char *) body+rp;
assert_string_equal(s, "S-1-2-3-4");
rp += strlen(s) + 1;
assert_true(rp < blen);
s = (char *) body+rp;
assert_string_equal(s, ORIGINALAD_PREFIX SYSDB_NAME);
rp += strlen(s) + 1;
assert_true(rp < blen);
s = (char *) body+rp;
assert_string_equal(s, "orig_name");
rp += strlen(s) + 1;
assert_true(rp < blen);
s = (char *) body+rp;
assert_string_equal(s, ORIGINALAD_PREFIX SYSDB_UIDNUM);
rp += strlen(s) + 1;
assert_true(rp < blen);
s = (char *) body+rp;
assert_string_equal(s, "1234");
rp += strlen(s) + 1;
assert_int_equal(rp, blen);
return EOK;
}
void test_nss_getorigbyname(void **state)
{
errno_t ret;
struct sysdb_attrs *attrs;
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);
ret = sysdb_attrs_add_string(attrs, ORIGINALAD_PREFIX SYSDB_NAME,
"orig_name");
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,
"testuserorig", 1234, 5689, "test user orig",
"/home/testuserorig", "/bin/sh", NULL,
attrs, 300, 0);
assert_int_equal(ret, EOK);
mock_input_user_or_group("testuserorig");
will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETORIGBYNAME);
will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
/* Query for that user, call a callback when command finishes */
set_cmd_cb(test_nss_getorigbyname_check);
ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETORIGBYNAME,
nss_test_ctx->nss_cmds);
assert_int_equal(ret, EOK);
/* Wait until the test finishes with EOK */
ret = test_ev_loop(nss_test_ctx->tctx);
assert_int_equal(ret, EOK);
}
void nss_test_setup(void **state)
{
struct sss_test_conf_param params[] = {
{ "enumerate", "false" },
{ NULL, NULL }, /* Sentinel */
};
test_nss_setup(params, state);
}
void nss_fqdn_test_setup(void **state)
{
struct sss_test_conf_param params[] = {
{ "enumerate", "false" },
{ "full_name_format", "%1$s@%2$s" },
{ NULL, NULL }, /* Sentinel */
};
test_nss_setup(params, state);
}
void nss_subdom_test_setup(void **state)
{
const char *const testdom[4] = { TEST_SUBDOM_NAME, "TEST.SUB", "test", "S-3" };
struct sss_domain_info *subdomain;
errno_t ret;
nss_test_setup(state);
subdomain = new_subdomain(nss_test_ctx, nss_test_ctx->tctx->dom,
testdom[0], testdom[1], testdom[2], testdom[3],
false, false, NULL);
assert_non_null(subdomain);
ret = sysdb_subdomain_store(nss_test_ctx->tctx->sysdb,
testdom[0], testdom[1], testdom[2], testdom[3],
false, false, NULL);
assert_int_equal(ret, EOK);
ret = sysdb_update_subdomains(nss_test_ctx->tctx->dom);
assert_int_equal(ret, EOK);
nss_test_ctx->subdom = subdomain;
}
void nss_fqdn_fancy_test_setup(void **state)
{
struct sss_test_conf_param params[] = {
{ "enumerate", "false" },
{ "full_name_format", "%1$s@@@@@%2$s" },
{ NULL, NULL }, /* Sentinel */
};
test_nss_setup(params, state);
}
void nss_test_teardown(void **state)
{
talloc_free(nss_test_ctx);
}
int main(int argc, const char *argv[])
{
int rv;
int no_cleanup = 0;
poptContext pc;
int opt;
struct poptOption long_options[] = {
POPT_AUTOHELP
SSSD_DEBUG_OPTS
{"no-cleanup", 'n', POPT_ARG_NONE, &no_cleanup, 0,
_("Do not delete the test database after a test run"), NULL },
POPT_TABLEEND
};
const UnitTest tests[] = {
unit_test_setup_teardown(test_nss_getpwnam,
nss_test_setup, nss_test_teardown),
unit_test_setup_teardown(test_nss_getpwuid,
nss_test_setup, nss_test_teardown),
unit_test_setup_teardown(test_nss_getpwnam_neg,
nss_test_setup, nss_test_teardown),
unit_test_setup_teardown(test_nss_getpwuid_neg,
nss_test_setup, nss_test_teardown),
unit_test_setup_teardown(test_nss_getpwnam_search,
nss_test_setup, nss_test_teardown),
unit_test_setup_teardown(test_nss_getpwuid_search,
nss_test_setup, nss_test_teardown),
unit_test_setup_teardown(test_nss_getpwnam_update,
nss_test_setup, nss_test_teardown),
unit_test_setup_teardown(test_nss_getpwuid_update,
nss_test_setup, nss_test_teardown),
unit_test_setup_teardown(test_nss_getpwnam_fqdn,
nss_fqdn_test_setup, nss_test_teardown),
unit_test_setup_teardown(test_nss_getpwnam_fqdn_fancy,
nss_fqdn_fancy_test_setup, nss_test_teardown),
unit_test_setup_teardown(test_nss_getpwnam_space,
nss_test_setup, nss_test_teardown),
unit_test_setup_teardown(test_nss_getpwnam_space_sub,
nss_test_setup, nss_test_teardown),
unit_test_setup_teardown(test_nss_getpwnam_space_sub_query,
nss_test_setup, nss_test_teardown),
unit_test_setup_teardown(test_nss_getgrnam_no_members,
nss_test_setup, nss_test_teardown),
unit_test_setup_teardown(test_nss_getgrnam_members,
nss_test_setup, nss_test_teardown),
unit_test_setup_teardown(test_nss_getgrnam_members_fqdn,
nss_fqdn_test_setup, nss_test_teardown),
unit_test_setup_teardown(test_nss_getgrnam_members_subdom,
nss_subdom_test_setup, nss_test_teardown),
unit_test_setup_teardown(test_nss_getgrnam_mix_dom,
nss_subdom_test_setup, nss_test_teardown),
unit_test_setup_teardown(test_nss_getgrnam_mix_dom_fqdn,
nss_subdom_test_setup, nss_test_teardown),
unit_test_setup_teardown(test_nss_getgrnam_mix_subdom,
nss_subdom_test_setup, nss_test_teardown),
unit_test_setup_teardown(test_nss_getgrnam_space,
nss_test_setup, nss_test_teardown),
unit_test_setup_teardown(test_nss_getgrnam_space_sub,
nss_test_setup, nss_test_teardown),
unit_test_setup_teardown(test_nss_well_known_getnamebysid,
nss_test_setup, nss_test_teardown),
unit_test_setup_teardown(test_nss_well_known_getnamebysid_special,
nss_test_setup, nss_test_teardown),
unit_test_setup_teardown(test_nss_well_known_getnamebysid_non_existing,
nss_test_setup, nss_test_teardown),
unit_test_setup_teardown(test_nss_well_known_getidbysid_failure,
nss_test_setup, nss_test_teardown),
unit_test_setup_teardown(test_nss_well_known_getsidbyname,
nss_test_setup, nss_test_teardown),
unit_test_setup_teardown(test_nss_well_known_getsidbyname_nonexisting,
nss_test_setup, nss_test_teardown),
unit_test_setup_teardown(test_nss_well_known_getsidbyname_special,
nss_test_setup, nss_test_teardown),
unit_test_setup_teardown(test_nss_getorigbyname,
nss_test_setup, nss_test_teardown),
};
/* Set debug level to invalid value so we can deside if -d 0 was used. */
debug_level = SSSDBG_INVALID;
pc = poptGetContext(argv[0], argc, argv, long_options, 0);
while((opt = poptGetNextOpt(pc)) != -1) {
switch(opt) {
default:
fprintf(stderr, "\nInvalid option %s: %s\n\n",
poptBadOption(pc, 0), poptStrerror(opt));
poptPrintUsage(pc, stderr, 0);
return 1;
}
}
poptFreeContext(pc);
DEBUG_CLI_INIT(debug_level);
/* Even though normally the tests should clean up after themselves
* they might not after a failed run. Remove the old db to be sure */
tests_set_cwd();
test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_SYSDB_FILE);
test_dom_suite_setup(TESTS_PATH);
rv = run_tests(tests);
if (rv == 0 && !no_cleanup) {
test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_SYSDB_FILE);
}
return rv;
}