Line data Source code
1 : /*
2 : Authors:
3 : Jakub Hrozek <jhrozek@redhat.com>
4 :
5 : Copyright (C) 2013 Red Hat
6 :
7 : SSSD tests: NSS responder tests
8 :
9 : This program is free software; you can redistribute it and/or modify
10 : it under the terms of the GNU General Public License as published by
11 : the Free Software Foundation; either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : This program is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with this program. If not, see <http://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include <talloc.h>
24 : #include <tevent.h>
25 : #include <errno.h>
26 : #include <popt.h>
27 :
28 : #include "tests/cmocka/common_mock.h"
29 : #include "tests/cmocka/common_mock_resp.h"
30 : #include "responder/common/negcache.h"
31 : #include "responder/nss/nsssrv.h"
32 : #include "responder/nss/nsssrv_private.h"
33 : #include "sss_client/idmap/sss_nss_idmap.h"
34 : #include "util/util_sss_idmap.h"
35 : #include "db/sysdb_private.h" /* new_subdomain() */
36 :
37 : #define TESTS_PATH "tp_" BASE_FILE_STEM
38 : #define TEST_CONF_DB "test_nss_conf.ldb"
39 : #define TEST_DOM_NAME "nss_test"
40 : #define TEST_SUBDOM_NAME "test.subdomain"
41 : #define TEST_ID_PROVIDER "ldap"
42 : #define TEST_DOM_SID "S-1-5-21-444379608-1639770488-2995963434"
43 :
44 : struct nss_test_ctx {
45 : struct sss_test_ctx *tctx;
46 : struct sss_domain_info *subdom;
47 :
48 : struct resp_ctx *rctx;
49 : struct cli_ctx *cctx;
50 : struct sss_cmd_table *nss_cmds;
51 : struct nss_ctx *nctx;
52 :
53 : int ncache_hits;
54 : };
55 :
56 : const char *global_extra_attrs[] = {"phone", "mobile", NULL};
57 :
58 : struct nss_test_ctx *nss_test_ctx;
59 :
60 : /* Mock NSS structure */
61 : struct nss_ctx *
62 44 : mock_nctx(TALLOC_CTX *mem_ctx)
63 : {
64 : struct nss_ctx *nctx;
65 : errno_t ret;
66 : enum idmap_error_code err;
67 :
68 44 : nctx = talloc_zero(mem_ctx, struct nss_ctx);
69 44 : if (!nctx) {
70 0 : return NULL;
71 : }
72 :
73 44 : ret = sss_ncache_init(nctx, &nctx->ncache);
74 44 : if (ret != EOK) {
75 0 : talloc_free(nctx);
76 0 : return NULL;
77 : }
78 44 : nctx->neg_timeout = 10;
79 44 : nctx->pwfield = discard_const("*");
80 :
81 44 : err = sss_idmap_init(sss_idmap_talloc, nctx, sss_idmap_talloc_free,
82 : &nctx->idmap_ctx);
83 44 : if (err != IDMAP_SUCCESS) {
84 0 : DEBUG(SSSDBG_FATAL_FAILURE, "sss_idmap_init failed.\n");
85 0 : talloc_free(nctx);
86 0 : return NULL;
87 : }
88 :
89 44 : return nctx;
90 : }
91 :
92 : /* Mock reading requests from a client. Use values passed from mock
93 : * instead
94 : */
95 : void __real_sss_packet_get_body(struct sss_packet *packet,
96 : uint8_t **body, size_t *blen);
97 :
98 138 : void __wrap_sss_packet_get_body(struct sss_packet *packet,
99 : uint8_t **body, size_t *blen)
100 : {
101 138 : enum sss_test_wrapper_call wtype = sss_mock_type(enum sss_test_wrapper_call);
102 : size_t len;
103 :
104 138 : if (wtype == WRAP_CALL_REAL) {
105 85 : return __real_sss_packet_get_body(packet, body, blen);
106 : }
107 :
108 53 : *body = sss_mock_ptr_type(uint8_t *);
109 53 : len = sss_mock_type(size_t);
110 53 : if (len == 0) {
111 48 : len = strlen((const char *) *body)+1;
112 : }
113 53 : *blen = len;
114 53 : return;
115 : }
116 :
117 : /* Mock returning result to client. Terminate the unit test instead. */
118 : typedef int (*cmd_cb_fn_t)(uint32_t, uint8_t *, size_t );
119 :
120 41 : static void set_cmd_cb(cmd_cb_fn_t fn)
121 : {
122 41 : will_return(__wrap_sss_cmd_done, fn);
123 41 : }
124 :
125 41 : void __wrap_sss_cmd_done(struct cli_ctx *cctx, void *freectx)
126 : {
127 41 : struct sss_packet *packet = cctx->creq->out;
128 : uint8_t *body;
129 : size_t blen;
130 : cmd_cb_fn_t check_cb;
131 :
132 41 : check_cb = sss_mock_ptr_type(cmd_cb_fn_t);
133 :
134 41 : __real_sss_packet_get_body(packet, &body, &blen);
135 :
136 41 : nss_test_ctx->tctx->error = check_cb(sss_packet_get_status(packet),
137 : body, blen);
138 41 : nss_test_ctx->tctx->done = true;
139 41 : }
140 :
141 41 : enum sss_cli_command __wrap_sss_packet_get_cmd(struct sss_packet *packet)
142 : {
143 41 : return sss_mock_type(enum sss_cli_command);
144 : }
145 :
146 12 : int __wrap_sss_cmd_send_empty(struct cli_ctx *cctx, TALLOC_CTX *freectx)
147 : {
148 12 : nss_test_ctx->tctx->done = true;
149 12 : nss_test_ctx->tctx->error = ENOENT;
150 12 : return EOK;
151 : }
152 :
153 : /* Intercept negative cache lookups */
154 : int __real_sss_ncache_check_user(struct sss_nc_ctx *ctx, int ttl,
155 : struct sss_domain_info *dom, const char *name);
156 :
157 39 : int __wrap_sss_ncache_check_user(struct sss_nc_ctx *ctx, int ttl,
158 : struct sss_domain_info *dom, const char *name)
159 : {
160 : int ret;
161 :
162 39 : ret = __real_sss_ncache_check_user(ctx, ttl, dom, name);
163 39 : if (ret == EEXIST) {
164 6 : nss_test_ctx->ncache_hits++;
165 : }
166 39 : return ret;
167 : }
168 :
169 : int __real_sss_ncache_check_uid(struct sss_nc_ctx *ctx, int ttl,
170 : struct sss_domain_info *dom, uid_t uid);
171 :
172 5 : int __wrap_sss_ncache_check_uid(struct sss_nc_ctx *ctx, int ttl,
173 : struct sss_domain_info *dom, uid_t uid)
174 : {
175 : int ret;
176 :
177 5 : ret = __real_sss_ncache_check_uid(ctx, ttl, dom, uid);
178 5 : if (ret == EEXIST) {
179 1 : nss_test_ctx->ncache_hits++;
180 : }
181 5 : return ret;
182 : }
183 :
184 : int __real_sss_ncache_check_sid(struct sss_nc_ctx *ctx,
185 : int ttl, const char *sid);
186 :
187 6 : int __wrap_sss_ncache_check_sid(struct sss_nc_ctx *ctx,
188 : int ttl, const char *sid)
189 : {
190 : int ret;
191 :
192 6 : ret = __real_sss_ncache_check_sid(ctx, ttl, sid);
193 6 : if (ret == EEXIST) {
194 1 : nss_test_ctx->ncache_hits++;
195 : }
196 6 : return ret;
197 : }
198 :
199 : /* Mock input from the client library */
200 38 : static void mock_input_user_or_group(const char *username)
201 : {
202 38 : will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER);
203 38 : will_return(__wrap_sss_packet_get_body, username);
204 38 : will_return(__wrap_sss_packet_get_body, 0);
205 38 : }
206 :
207 5 : static void mock_input_id(TALLOC_CTX *mem_ctx, uint32_t id)
208 : {
209 : uint8_t *body;
210 :
211 5 : body = talloc_zero_array(mem_ctx, uint8_t, 4);
212 5 : if (body == NULL) return;
213 :
214 5 : SAFEALIGN_SETMEM_UINT32(body, id, NULL);
215 5 : will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER);
216 5 : will_return(__wrap_sss_packet_get_body, body);
217 5 : will_return(__wrap_sss_packet_get_body, sizeof(uint32_t));
218 : }
219 :
220 12 : static void mock_fill_user(void)
221 : {
222 : /* One packet for the entry and one for num entries */
223 12 : will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
224 12 : will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
225 12 : }
226 :
227 2 : static void mock_fill_bysid(void)
228 : {
229 : /* One packet for the entry and one for num entries */
230 2 : will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
231 2 : }
232 :
233 5 : static void mock_fill_initgr_user(void)
234 : {
235 5 : will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
236 5 : }
237 :
238 9 : static void mock_fill_group_with_members(unsigned members)
239 : {
240 : unsigned i;
241 :
242 9 : will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
243 9 : will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
244 :
245 9 : if (members == 0) return;
246 :
247 6 : will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
248 :
249 : /* Member header , one per member */
250 6 : will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
251 21 : for (i=0; i<members; i++) {
252 15 : will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
253 : }
254 : }
255 :
256 :
257 12 : static int parse_user_packet(uint8_t *body, size_t blen, struct passwd *pwd)
258 : {
259 12 : size_t rp = 2 * sizeof(uint32_t);
260 :
261 12 : SAFEALIGN_COPY_UINT32(&pwd->pw_uid, body+rp, &rp);
262 12 : SAFEALIGN_COPY_UINT32(&pwd->pw_gid, body+rp, &rp);
263 :
264 : /* Sequence of null terminated strings (name, passwd, gecos, dir, shell) */
265 12 : pwd->pw_name = (char *) body+rp;
266 12 : rp += strlen(pwd->pw_name) + 1;
267 12 : if (rp >= blen) return EINVAL;
268 :
269 12 : pwd->pw_passwd = (char *) body+rp;
270 12 : rp += strlen(pwd->pw_passwd) + 1;
271 12 : if (rp >= blen) return EINVAL;
272 :
273 12 : pwd->pw_gecos = (char *) body+rp;
274 12 : rp += strlen(pwd->pw_gecos) + 1;
275 12 : if (rp >= blen) return EINVAL;
276 :
277 12 : pwd->pw_dir = (char *) body+rp;
278 12 : rp += strlen(pwd->pw_dir) + 1;
279 12 : if (rp >= blen) return EINVAL;
280 :
281 12 : pwd->pw_shell = (char *) body+rp;
282 12 : rp += strlen(pwd->pw_shell) + 1;
283 12 : if (rp != blen) return EINVAL;
284 :
285 12 : return EOK;
286 : }
287 :
288 9 : static int parse_group_packet(uint8_t *body, size_t blen, struct group *gr, uint32_t *nmem)
289 : {
290 9 : size_t rp = 2 * sizeof(uint32_t); /* Len and reserved */
291 : unsigned i;
292 :
293 9 : SAFEALIGN_COPY_UINT32(&gr->gr_gid, body+rp, &rp);
294 9 : SAFEALIGN_COPY_UINT32(nmem, body+rp, &rp);
295 :
296 9 : gr->gr_name = (char *) body+rp;
297 9 : rp += strlen(gr->gr_name) + 1;
298 9 : if (rp >= blen) return EINVAL;
299 :
300 9 : gr->gr_passwd = (char *) body+rp;
301 9 : rp += strlen(gr->gr_passwd) + 1;
302 :
303 9 : if (*nmem > 0) {
304 6 : gr->gr_mem = talloc_zero_array(nss_test_ctx, char *, *nmem);
305 6 : if (gr->gr_mem == NULL) return ENOMEM;
306 :
307 21 : for (i = 0; i < *nmem; i++) {
308 15 : if (rp >= blen) return EINVAL;
309 :
310 15 : gr->gr_mem[i] = talloc_strdup(gr->gr_mem, (char *) body+rp);
311 15 : rp += strlen(gr->gr_mem[i]) + 1;
312 : }
313 : }
314 :
315 : /* Make sure we exactly matched the end of the packet */
316 9 : if (rp != blen) return EINVAL;
317 9 : return EOK;
318 : }
319 :
320 5 : static void check_initgr_packet(uint8_t *body, size_t blen,
321 : gid_t *gids, size_t num_gids)
322 : {
323 : size_t rp;
324 : unsigned i;
325 : gid_t cur_gid;
326 : uint32_t num_ret;
327 :
328 5 : rp = 0;
329 5 : SAFEALIGN_COPY_UINT32(&num_ret, body, NULL);
330 5 : assert_int_equal(num_ret, num_gids);
331 :
332 5 : rp = 2 * sizeof(uint32_t); /* Len and reserved */
333 :
334 15 : for (i = 0; i < num_gids; i++) {
335 10 : SAFEALIGN_COPY_UINT32(&cur_gid, body + rp, &rp);
336 10 : assert_int_equal(cur_gid, gids[i]);
337 : }
338 5 : }
339 :
340 : /* ====================== The tests =============================== */
341 :
342 : /* Check getting cached and valid user from cache. Account callback will
343 : * not be called and test_nss_getpwnam_check will make sure the user is
344 : * the same as the test entered before starting
345 : */
346 1 : static int test_nss_getpwnam_check(uint32_t status, uint8_t *body, size_t blen)
347 : {
348 : struct passwd pwd;
349 : errno_t ret;
350 :
351 1 : assert_int_equal(status, EOK);
352 :
353 1 : ret = parse_user_packet(body, blen, &pwd);
354 1 : assert_int_equal(ret, EOK);
355 :
356 1 : assert_int_equal(pwd.pw_uid, 123);
357 1 : assert_int_equal(pwd.pw_gid, 456);
358 1 : assert_string_equal(pwd.pw_name, "testuser");
359 1 : assert_string_equal(pwd.pw_shell, "/bin/sh");
360 1 : assert_string_equal(pwd.pw_passwd, "*");
361 1 : return EOK;
362 : }
363 :
364 1 : void test_nss_getpwnam(void **state)
365 : {
366 : errno_t ret;
367 :
368 : /* Prime the cache with a valid user */
369 1 : ret = sysdb_add_user(nss_test_ctx->tctx->dom,
370 : "testuser", 123, 456, "test user",
371 : "/home/testuser", "/bin/sh", NULL,
372 : NULL, 300, 0);
373 1 : assert_int_equal(ret, EOK);
374 :
375 1 : mock_input_user_or_group("testuser");
376 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM);
377 1 : mock_fill_user();
378 :
379 : /* Query for that user, call a callback when command finishes */
380 1 : set_cmd_cb(test_nss_getpwnam_check);
381 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM,
382 1 : nss_test_ctx->nss_cmds);
383 1 : assert_int_equal(ret, EOK);
384 :
385 : /* Wait until the test finishes with EOK */
386 1 : ret = test_ev_loop(nss_test_ctx->tctx);
387 1 : assert_int_equal(ret, EOK);
388 1 : }
389 :
390 : /* Test that searching for a nonexistant user yields ENOENT.
391 : * Account callback will be called
392 : */
393 1 : void test_nss_getpwnam_neg(void **state)
394 : {
395 : errno_t ret;
396 :
397 1 : mock_input_user_or_group("testuser_neg");
398 1 : mock_account_recv_simple();
399 :
400 1 : assert_int_equal(nss_test_ctx->ncache_hits, 0);
401 :
402 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM,
403 1 : nss_test_ctx->nss_cmds);
404 1 : assert_int_equal(ret, EOK);
405 :
406 : /* Wait until the test finishes with ENOENT */
407 1 : ret = test_ev_loop(nss_test_ctx->tctx);
408 1 : assert_int_equal(ret, ENOENT);
409 1 : assert_int_equal(nss_test_ctx->ncache_hits, 0);
410 :
411 : /* Test that subsequent search for a nonexistent user yields
412 : * ENOENT and Account callback is not called, on the other hand
413 : * the ncache functions will be called
414 : */
415 1 : nss_test_ctx->tctx->done = false;
416 :
417 1 : mock_input_user_or_group("testuser_neg");
418 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM,
419 1 : nss_test_ctx->nss_cmds);
420 1 : assert_int_equal(ret, EOK);
421 :
422 : /* Wait until the test finishes with ENOENT */
423 1 : ret = test_ev_loop(nss_test_ctx->tctx);
424 1 : assert_int_equal(ret, ENOENT);
425 : /* Negative cache was hit this time */
426 1 : assert_int_equal(nss_test_ctx->ncache_hits, 1);
427 1 : }
428 :
429 1 : static int test_nss_getpwnam_search_acct_cb(void *pvt)
430 : {
431 : errno_t ret;
432 1 : struct nss_test_ctx *ctx = talloc_get_type(pvt, struct nss_test_ctx);
433 :
434 1 : ret = sysdb_add_user(ctx->tctx->dom,
435 : "testuser_search", 567, 890, "test search",
436 : "/home/testsearch", "/bin/sh", NULL,
437 : NULL, 300, 0);
438 1 : assert_int_equal(ret, EOK);
439 :
440 1 : return EOK;
441 : }
442 :
443 1 : static int test_nss_getpwnam_search_check(uint32_t status,
444 : uint8_t *body, size_t blen)
445 : {
446 : struct passwd pwd;
447 : errno_t ret;
448 :
449 1 : assert_int_equal(status, EOK);
450 :
451 1 : ret = parse_user_packet(body, blen, &pwd);
452 1 : assert_int_equal(ret, EOK);
453 :
454 1 : assert_int_equal(pwd.pw_uid, 567);
455 1 : assert_int_equal(pwd.pw_gid, 890);
456 1 : assert_string_equal(pwd.pw_name, "testuser_search");
457 1 : assert_string_equal(pwd.pw_shell, "/bin/sh");
458 1 : return EOK;
459 : }
460 :
461 1 : void test_nss_getpwnam_search(void **state)
462 : {
463 : errno_t ret;
464 : struct ldb_result *res;
465 :
466 1 : mock_input_user_or_group("testuser_search");
467 1 : mock_account_recv(0, 0, NULL, test_nss_getpwnam_search_acct_cb, nss_test_ctx);
468 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM);
469 1 : mock_fill_user();
470 1 : set_cmd_cb(test_nss_getpwnam_search_check);
471 :
472 1 : ret = sysdb_getpwnam(nss_test_ctx, nss_test_ctx->tctx->dom,
473 : "testuser_search", &res);
474 1 : assert_int_equal(ret, EOK);
475 1 : assert_int_equal(res->count, 0);
476 :
477 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM,
478 1 : nss_test_ctx->nss_cmds);
479 1 : assert_int_equal(ret, EOK);
480 :
481 : /* Wait until the test finishes with EOK */
482 1 : ret = test_ev_loop(nss_test_ctx->tctx);
483 1 : assert_int_equal(ret, EOK);
484 :
485 : /* test_nss_getpwnam_search_check will check the user attributes */
486 1 : ret = sysdb_getpwnam(nss_test_ctx, nss_test_ctx->tctx->dom,
487 : "testuser_search", &res);
488 1 : assert_int_equal(ret, EOK);
489 1 : assert_int_equal(res->count, 1);
490 1 : }
491 :
492 : /* Test that searching for a user that is expired in the cache goes to the DP
493 : * which updates the record and the NSS responder returns the updated record
494 : *
495 : * The user's shell attribute is updated.
496 : */
497 1 : static int test_nss_getpwnam_update_acct_cb(void *pvt)
498 : {
499 : errno_t ret;
500 1 : struct nss_test_ctx *ctx = talloc_get_type(pvt, struct nss_test_ctx);
501 :
502 1 : ret = sysdb_store_user(ctx->tctx->dom,
503 : "testuser_update", NULL, 10, 11, "test user",
504 : "/home/testuser", "/bin/ksh", NULL,
505 : NULL, NULL, 300, 0);
506 1 : assert_int_equal(ret, EOK);
507 :
508 1 : return EOK;
509 : }
510 :
511 1 : static int test_nss_getpwnam_update_check(uint32_t status,
512 : uint8_t *body, size_t blen)
513 : {
514 : struct passwd pwd;
515 : errno_t ret;
516 :
517 1 : assert_int_equal(status, EOK);
518 :
519 1 : ret = parse_user_packet(body, blen, &pwd);
520 1 : assert_int_equal(ret, EOK);
521 :
522 1 : assert_int_equal(pwd.pw_uid, 10);
523 1 : assert_int_equal(pwd.pw_gid, 11);
524 1 : assert_string_equal(pwd.pw_name, "testuser_update");
525 1 : assert_string_equal(pwd.pw_shell, "/bin/ksh");
526 1 : return EOK;
527 : }
528 :
529 1 : void test_nss_getpwnam_update(void **state)
530 : {
531 : errno_t ret;
532 : struct ldb_result *res;
533 : const char *shell;
534 :
535 : /* Prime the cache with a valid but expired user */
536 1 : ret = sysdb_add_user(nss_test_ctx->tctx->dom,
537 : "testuser_update", 10, 11, "test user",
538 : "/home/testuser", "/bin/sh", NULL,
539 : NULL, 1, 1);
540 1 : assert_int_equal(ret, EOK);
541 :
542 : /* Mock client input */
543 1 : mock_input_user_or_group("testuser_update");
544 : /* Mock client command */
545 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM);
546 : /* Call this function when user is updated by the mock DP request */
547 1 : mock_account_recv(0, 0, NULL, test_nss_getpwnam_update_acct_cb, nss_test_ctx);
548 : /* Call this function to check what the responder returned to the client */
549 1 : set_cmd_cb(test_nss_getpwnam_update_check);
550 : /* Mock output buffer */
551 1 : mock_fill_user();
552 :
553 : /* Fire the command */
554 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM,
555 1 : nss_test_ctx->nss_cmds);
556 1 : assert_int_equal(ret, EOK);
557 :
558 : /* Wait until the test finishes with EOK */
559 1 : ret = test_ev_loop(nss_test_ctx->tctx);
560 1 : assert_int_equal(ret, EOK);
561 :
562 : /* Check the user was updated in the cache */
563 1 : ret = sysdb_getpwnam(nss_test_ctx, nss_test_ctx->tctx->dom,
564 : "testuser_update", &res);
565 1 : assert_int_equal(ret, EOK);
566 1 : assert_int_equal(res->count, 1);
567 :
568 1 : shell = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SHELL, NULL);
569 1 : assert_string_equal(shell, "/bin/ksh");
570 1 : }
571 :
572 : /* Check that a FQDN is returned if the domain is FQDN-only and a
573 : * FQDN is requested
574 : */
575 1 : static int test_nss_getpwnam_check_fqdn(uint32_t status,
576 : uint8_t *body, size_t blen)
577 : {
578 : struct passwd pwd;
579 : errno_t ret;
580 :
581 1 : assert_int_equal(status, EOK);
582 :
583 1 : nss_test_ctx->cctx->rctx->domains[0].fqnames = false;
584 :
585 1 : ret = parse_user_packet(body, blen, &pwd);
586 1 : assert_int_equal(ret, EOK);
587 :
588 1 : assert_int_equal(pwd.pw_uid, 124);
589 1 : assert_int_equal(pwd.pw_gid, 457);
590 1 : assert_string_equal(pwd.pw_name, "testuser_fqdn@"TEST_DOM_NAME);
591 1 : assert_string_equal(pwd.pw_shell, "/bin/sh");
592 1 : return EOK;
593 : }
594 :
595 1 : void test_nss_getpwnam_fqdn(void **state)
596 : {
597 : errno_t ret;
598 :
599 : /* Prime the cache with a valid user */
600 1 : ret = sysdb_add_user(nss_test_ctx->tctx->dom,
601 : "testuser_fqdn", 124, 457, "test user",
602 : "/home/testuser", "/bin/sh", NULL,
603 : NULL, 300, 0);
604 1 : assert_int_equal(ret, EOK);
605 :
606 1 : mock_input_user_or_group("testuser_fqdn@"TEST_DOM_NAME);
607 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM);
608 1 : mock_fill_user();
609 :
610 : /* Query for that user, call a callback when command finishes */
611 1 : set_cmd_cb(test_nss_getpwnam_check_fqdn);
612 1 : nss_test_ctx->cctx->rctx->domains[0].fqnames = true;
613 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM,
614 1 : nss_test_ctx->nss_cmds);
615 1 : assert_int_equal(ret, EOK);
616 :
617 : /* Wait until the test finishes with EOK */
618 1 : ret = test_ev_loop(nss_test_ctx->tctx);
619 1 : assert_int_equal(ret, EOK);
620 1 : }
621 :
622 : /* Check that a user with a space in his username is returned fine.
623 : */
624 1 : static int test_nss_getpwnam_check_space(uint32_t status,
625 : uint8_t *body, size_t blen)
626 : {
627 : struct passwd pwd;
628 : errno_t ret;
629 :
630 1 : assert_int_equal(status, EOK);
631 :
632 1 : ret = parse_user_packet(body, blen, &pwd);
633 1 : assert_int_equal(ret, EOK);
634 :
635 1 : assert_int_equal(pwd.pw_uid, 225);
636 1 : assert_int_equal(pwd.pw_gid, 558);
637 1 : assert_string_equal(pwd.pw_name, "space user");
638 1 : assert_string_equal(pwd.pw_shell, "/bin/sh");
639 1 : return EOK;
640 : }
641 :
642 1 : void test_nss_getpwnam_space(void **state)
643 : {
644 : errno_t ret;
645 :
646 : /* Prime the cache with a valid user */
647 1 : ret = sysdb_add_user(nss_test_ctx->tctx->dom,
648 : "space user", 225, 558, "space user",
649 : "/home/testuser", "/bin/sh", NULL,
650 : NULL, 300, 0);
651 1 : assert_int_equal(ret, EOK);
652 :
653 1 : mock_input_user_or_group("space user");
654 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM);
655 1 : mock_fill_user();
656 :
657 : /* Query for that user, call a callback when command finishes */
658 1 : set_cmd_cb(test_nss_getpwnam_check_space);
659 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM,
660 1 : nss_test_ctx->nss_cmds);
661 1 : assert_int_equal(ret, EOK);
662 :
663 : /* Wait until the test finishes with EOK */
664 1 : ret = test_ev_loop(nss_test_ctx->tctx);
665 1 : assert_int_equal(ret, EOK);
666 :
667 1 : }
668 :
669 2 : static int test_nss_getpwnam_check_space_sub(uint32_t status,
670 : uint8_t *body, size_t blen)
671 : {
672 : struct passwd pwd;
673 : errno_t ret;
674 :
675 2 : assert_int_equal(status, EOK);
676 :
677 2 : ret = parse_user_packet(body, blen, &pwd);
678 2 : assert_int_equal(ret, EOK);
679 :
680 2 : assert_int_equal(pwd.pw_uid, 225);
681 2 : assert_int_equal(pwd.pw_gid, 558);
682 2 : assert_string_equal(pwd.pw_name, "space_user");
683 2 : assert_string_equal(pwd.pw_shell, "/bin/sh");
684 2 : return EOK;
685 : }
686 :
687 1 : void test_nss_getpwnam_space_sub(void **state)
688 : {
689 : errno_t ret;
690 :
691 : /* Set whitespace substitution */
692 1 : nss_test_ctx->rctx->override_space = '_';
693 :
694 1 : mock_input_user_or_group("space user");
695 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM);
696 1 : mock_fill_user();
697 :
698 : /* Query for that user, call a callback when command finishes */
699 1 : set_cmd_cb(test_nss_getpwnam_check_space_sub);
700 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM,
701 1 : nss_test_ctx->nss_cmds);
702 1 : assert_int_equal(ret, EOK);
703 :
704 : /* Wait until the test finishes with EOK */
705 1 : ret = test_ev_loop(nss_test_ctx->tctx);
706 1 : nss_test_ctx->rctx->override_space = '\0';
707 1 : assert_int_equal(ret, EOK);
708 1 : }
709 :
710 1 : void test_nss_getpwnam_space_sub_query(void **state)
711 : {
712 : errno_t ret;
713 :
714 : /* Set whitespace substitution */
715 1 : nss_test_ctx->rctx->override_space = '_';
716 :
717 1 : mock_input_user_or_group("space_user");
718 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM);
719 1 : mock_fill_user();
720 :
721 : /* Query for that user, call a callback when command finishes */
722 1 : set_cmd_cb(test_nss_getpwnam_check_space_sub);
723 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM,
724 1 : nss_test_ctx->nss_cmds);
725 1 : assert_int_equal(ret, EOK);
726 :
727 : /* Wait until the test finishes with EOK */
728 1 : ret = test_ev_loop(nss_test_ctx->tctx);
729 1 : nss_test_ctx->rctx->override_space = '\0';
730 1 : assert_int_equal(ret, EOK);
731 1 : }
732 :
733 : /*
734 : * Check that FQDN processing is able to handle arbitrarily sized
735 : * delimeter
736 : */
737 1 : static int test_nss_getpwnam_check_fancy_fqdn(uint32_t status,
738 : uint8_t *body, size_t blen)
739 : {
740 : struct passwd pwd;
741 : errno_t ret;
742 :
743 1 : assert_int_equal(status, EOK);
744 :
745 1 : nss_test_ctx->cctx->rctx->domains[0].fqnames = false;
746 :
747 1 : ret = parse_user_packet(body, blen, &pwd);
748 1 : assert_int_equal(ret, EOK);
749 :
750 1 : assert_int_equal(pwd.pw_uid, 125);
751 1 : assert_int_equal(pwd.pw_gid, 458);
752 1 : assert_string_equal(pwd.pw_name, "testuser_fqdn_fancy@@@@@"TEST_DOM_NAME);
753 1 : assert_string_equal(pwd.pw_shell, "/bin/sh");
754 1 : return EOK;
755 : }
756 :
757 1 : void test_nss_getpwnam_fqdn_fancy(void **state)
758 : {
759 : errno_t ret;
760 :
761 : /* Prime the cache with a valid user */
762 1 : ret = sysdb_add_user(nss_test_ctx->tctx->dom,
763 : "testuser_fqdn_fancy", 125, 458, "test user",
764 : "/home/testuser", "/bin/sh", NULL,
765 : NULL, 300, 0);
766 1 : assert_int_equal(ret, EOK);
767 :
768 1 : mock_input_user_or_group("testuser_fqdn_fancy@"TEST_DOM_NAME);
769 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM);
770 1 : mock_fill_user();
771 :
772 : /* Query for that user, call a callback when command finishes */
773 1 : set_cmd_cb(test_nss_getpwnam_check_fancy_fqdn);
774 1 : nss_test_ctx->cctx->rctx->domains[0].fqnames = true;
775 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM,
776 1 : nss_test_ctx->nss_cmds);
777 1 : assert_int_equal(ret, EOK);
778 :
779 : /* Wait until the test finishes with EOK */
780 1 : ret = test_ev_loop(nss_test_ctx->tctx);
781 1 : assert_int_equal(ret, EOK);
782 1 : }
783 :
784 : /* Check getting cached and valid id from cache. Account callback will
785 : * not be called and test_nss_getpwuid_check will make sure the id is
786 : * the same as the test entered before starting
787 : */
788 1 : static int test_nss_getpwuid_check(uint32_t status, uint8_t *body, size_t blen)
789 : {
790 : struct passwd pwd;
791 : errno_t ret;
792 :
793 1 : assert_int_equal(status, EOK);
794 :
795 1 : ret = parse_user_packet(body, blen, &pwd);
796 1 : assert_int_equal(ret, EOK);
797 :
798 1 : assert_int_equal(pwd.pw_uid, 101);
799 1 : assert_int_equal(pwd.pw_gid, 401);
800 1 : assert_string_equal(pwd.pw_name, "testuser1");
801 1 : assert_string_equal(pwd.pw_shell, "/bin/sh");
802 1 : assert_string_equal(pwd.pw_passwd, "*");
803 1 : return EOK;
804 : }
805 :
806 1 : void test_nss_getpwuid(void **state)
807 : {
808 : errno_t ret;
809 :
810 : /* Prime the cache with a valid user */
811 1 : ret = sysdb_add_user(nss_test_ctx->tctx->dom,
812 : "testuser1", 101, 401, "test user1",
813 : "/home/testuser1", "/bin/sh", NULL,
814 : NULL, 300, 0);
815 1 : assert_int_equal(ret, EOK);
816 :
817 1 : uint32_t id = 101;
818 1 : mock_input_id(nss_test_ctx, id);
819 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWUID);
820 1 : mock_fill_user();
821 :
822 : /* Query for that id, call a callback when command finishes */
823 1 : set_cmd_cb(test_nss_getpwuid_check);
824 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWUID,
825 1 : nss_test_ctx->nss_cmds);
826 1 : assert_int_equal(ret, EOK);
827 :
828 : /* Wait until the test finishes with EOK */
829 1 : ret = test_ev_loop(nss_test_ctx->tctx);
830 1 : assert_int_equal(ret, EOK);
831 1 : }
832 :
833 : /* Test that searching for a nonexistent id yields ENOENT.
834 : * Account callback will be called
835 : */
836 1 : void test_nss_getpwuid_neg(void **state)
837 : {
838 : errno_t ret;
839 :
840 1 : uint8_t id = 102;
841 1 : mock_input_id(nss_test_ctx, id);
842 1 : mock_account_recv_simple();
843 :
844 1 : assert_int_equal(nss_test_ctx->ncache_hits, 0);
845 :
846 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWUID,
847 1 : nss_test_ctx->nss_cmds);
848 1 : assert_int_equal(ret, EOK);
849 :
850 : /* Wait until the test finishes with ENOENT */
851 1 : ret = test_ev_loop(nss_test_ctx->tctx);
852 1 : assert_int_equal(ret, ENOENT);
853 1 : assert_int_equal(nss_test_ctx->ncache_hits, 0);
854 :
855 : /* Test that subsequent search for a nonexistent id yields
856 : * ENOENT and Account callback is not called, on the other hand
857 : * the ncache functions will be called
858 : */
859 1 : nss_test_ctx->tctx->done = false;
860 :
861 1 : mock_input_id(nss_test_ctx, id);
862 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWUID,
863 1 : nss_test_ctx->nss_cmds);
864 1 : assert_int_equal(ret, EOK);
865 :
866 : /* Wait until the test finishes with ENOENT */
867 1 : ret = test_ev_loop(nss_test_ctx->tctx);
868 1 : assert_int_equal(ret, ENOENT);
869 : /* Negative cache was hit this time */
870 1 : assert_int_equal(nss_test_ctx->ncache_hits, 1);
871 1 : }
872 :
873 1 : static int test_nss_getpwuid_search_acct_cb(void *pvt)
874 : {
875 : errno_t ret;
876 1 : struct nss_test_ctx *ctx = talloc_get_type(pvt, struct nss_test_ctx);
877 :
878 1 : ret = sysdb_add_user(ctx->tctx->dom,
879 : "exampleuser_search", 107, 987, "example search",
880 : "/home/examplesearch", "/bin/sh", NULL,
881 : NULL, 300, 0);
882 1 : assert_int_equal(ret, EOK);
883 :
884 1 : return EOK;
885 : }
886 :
887 1 : static int test_nss_getpwuid_search_check(uint32_t status,
888 : uint8_t *body, size_t blen)
889 : {
890 : struct passwd pwd;
891 : errno_t ret;
892 :
893 1 : assert_int_equal(status, EOK);
894 :
895 1 : ret = parse_user_packet(body, blen, &pwd);
896 1 : assert_int_equal(ret, EOK);
897 :
898 1 : assert_int_equal(pwd.pw_uid, 107);
899 1 : assert_int_equal(pwd.pw_gid, 987);
900 1 : assert_string_equal(pwd.pw_name, "exampleuser_search");
901 1 : assert_string_equal(pwd.pw_shell, "/bin/sh");
902 1 : return EOK;
903 : }
904 :
905 1 : void test_nss_getpwuid_search(void **state)
906 : {
907 : errno_t ret;
908 : struct ldb_result *res;
909 :
910 1 : uint8_t id = 107;
911 1 : mock_input_id(nss_test_ctx, id);
912 1 : mock_account_recv(0, 0, NULL, test_nss_getpwuid_search_acct_cb, nss_test_ctx);
913 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWUID);
914 1 : mock_fill_user();
915 1 : set_cmd_cb(test_nss_getpwuid_search_check);
916 :
917 1 : ret = sysdb_getpwuid(nss_test_ctx, nss_test_ctx->tctx->dom,
918 : 107, &res);
919 1 : assert_int_equal(ret, EOK);
920 1 : assert_int_equal(res->count, 0);
921 :
922 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWUID,
923 1 : nss_test_ctx->nss_cmds);
924 1 : assert_int_equal(ret, EOK);
925 :
926 : /* Wait until the test finishes with EOK */
927 1 : ret = test_ev_loop(nss_test_ctx->tctx);
928 1 : assert_int_equal(ret, EOK);
929 :
930 : /* test_nss_getpwuid_search_check will check the id attributes */
931 1 : ret = sysdb_getpwuid(nss_test_ctx, nss_test_ctx->tctx->dom,
932 : 107, &res);
933 1 : assert_int_equal(ret, EOK);
934 1 : assert_int_equal(res->count, 1);
935 1 : }
936 :
937 : /* Test that searching for an id that is expired in the cache goes to the DP
938 : * which updates the record and the NSS responder returns the updated record
939 : *
940 : * The user's shell attribute is updated.
941 : */
942 1 : static int test_nss_getpwuid_update_acct_cb(void *pvt)
943 : {
944 : errno_t ret;
945 1 : struct nss_test_ctx *ctx = talloc_get_type(pvt, struct nss_test_ctx);
946 :
947 1 : ret = sysdb_store_user(ctx->tctx->dom,
948 : "exampleuser_update", NULL, 109, 11000, "example user",
949 : "/home/exampleuser", "/bin/ksh", NULL,
950 : NULL, NULL, 300, 0);
951 1 : assert_int_equal(ret, EOK);
952 :
953 1 : return EOK;
954 : }
955 :
956 1 : static int test_nss_getpwuid_update_check(uint32_t status,
957 : uint8_t *body, size_t blen)
958 : {
959 : struct passwd pwd;
960 : errno_t ret;
961 :
962 1 : assert_int_equal(status, EOK);
963 :
964 1 : ret = parse_user_packet(body, blen, &pwd);
965 1 : assert_int_equal(ret, EOK);
966 :
967 1 : assert_int_equal(pwd.pw_uid, 109);
968 1 : assert_int_equal(pwd.pw_gid, 11000);
969 1 : assert_string_equal(pwd.pw_name, "exampleuser_update");
970 1 : assert_string_equal(pwd.pw_shell, "/bin/ksh");
971 1 : return EOK;
972 : }
973 :
974 1 : void test_nss_getpwuid_update(void **state)
975 : {
976 : errno_t ret;
977 : struct ldb_result *res;
978 : const char *shell;
979 :
980 : /* Prime the cache with a valid but expired user */
981 1 : ret = sysdb_add_user(nss_test_ctx->tctx->dom,
982 : "exampleuser_update", 109, 11000, "example user",
983 : "/home/exampleuser", "/bin/sh", NULL,
984 : NULL, 1, 1);
985 1 : assert_int_equal(ret, EOK);
986 :
987 : /* Mock client input */
988 1 : uint8_t id = 109;
989 1 : mock_input_id(nss_test_ctx, id);
990 : /* Mock client command */
991 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWUID);
992 : /* Call this function when id is updated by the mock DP request */
993 1 : mock_account_recv(0, 0, NULL, test_nss_getpwuid_update_acct_cb, nss_test_ctx);
994 : /* Call this function to check what the responder returned to the client */
995 1 : set_cmd_cb(test_nss_getpwuid_update_check);
996 : /* Mock output buffer */
997 1 : mock_fill_user();
998 :
999 : /* Fire the command */
1000 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWUID,
1001 1 : nss_test_ctx->nss_cmds);
1002 1 : assert_int_equal(ret, EOK);
1003 :
1004 : /* Wait until the test finishes with EOK */
1005 1 : ret = test_ev_loop(nss_test_ctx->tctx);
1006 1 : assert_int_equal(ret, EOK);
1007 :
1008 : /* Check the user was updated in the cache */
1009 1 : ret = sysdb_getpwuid(nss_test_ctx, nss_test_ctx->tctx->dom,
1010 : 109, &res);
1011 1 : assert_int_equal(ret, EOK);
1012 1 : assert_int_equal(res->count, 1);
1013 :
1014 1 : shell = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SHELL, NULL);
1015 1 : assert_string_equal(shell, "/bin/ksh");
1016 1 : }
1017 :
1018 : /* Testsuite setup and teardown */
1019 44 : void test_nss_setup(struct sss_test_conf_param params[],
1020 : void **state)
1021 : {
1022 : errno_t ret;
1023 :
1024 44 : nss_test_ctx = talloc_zero(NULL, struct nss_test_ctx);
1025 44 : assert_non_null(nss_test_ctx);
1026 :
1027 44 : nss_test_ctx->tctx = create_dom_test_ctx(nss_test_ctx, TESTS_PATH,
1028 : TEST_CONF_DB, TEST_DOM_NAME,
1029 : TEST_ID_PROVIDER, params);
1030 44 : assert_non_null(nss_test_ctx->tctx);
1031 :
1032 44 : nss_test_ctx->tctx->dom->domain_id = discard_const(TEST_DOM_SID);
1033 :
1034 44 : nss_test_ctx->nss_cmds = get_nss_cmds();
1035 44 : assert_non_null(nss_test_ctx->nss_cmds);
1036 :
1037 : /* FIXME - perhaps this should be folded into sssd_domain_init or stricty
1038 : * used together
1039 : */
1040 44 : ret = sss_names_init(nss_test_ctx, nss_test_ctx->tctx->confdb,
1041 44 : TEST_DOM_NAME, &nss_test_ctx->tctx->dom->names);
1042 44 : assert_int_equal(ret, EOK);
1043 :
1044 : /* Initialize the NSS responder */
1045 44 : nss_test_ctx->nctx = mock_nctx(nss_test_ctx);
1046 44 : assert_non_null(nss_test_ctx->nctx);
1047 :
1048 44 : ret = sss_ad_default_names_ctx(nss_test_ctx->nctx,
1049 44 : &nss_test_ctx->nctx->global_names);
1050 44 : assert_int_equal(ret, EOK);
1051 44 : assert_non_null(nss_test_ctx->nctx->global_names);
1052 :
1053 88 : nss_test_ctx->rctx = mock_rctx(nss_test_ctx, nss_test_ctx->tctx->ev,
1054 44 : nss_test_ctx->tctx->dom, nss_test_ctx->nctx);
1055 44 : assert_non_null(nss_test_ctx->rctx);
1056 44 : nss_test_ctx->rctx->cdb = nss_test_ctx->tctx->confdb;
1057 44 : nss_test_ctx->nctx->rctx = nss_test_ctx->rctx;
1058 :
1059 : /* Create client context */
1060 44 : nss_test_ctx->cctx = mock_cctx(nss_test_ctx, nss_test_ctx->rctx);
1061 44 : assert_non_null(nss_test_ctx->cctx);
1062 44 : }
1063 :
1064 9 : static int test_nss_getgrnam_check(struct group *expected, struct group *gr, const int nmem)
1065 : {
1066 : int i;
1067 :
1068 9 : assert_int_equal(gr->gr_gid, expected->gr_gid);
1069 9 : assert_string_equal(gr->gr_name, expected->gr_name);
1070 9 : assert_string_equal(gr->gr_passwd, expected->gr_passwd);
1071 :
1072 24 : for (i = 0; i < nmem; i++) {
1073 15 : assert_string_equal(gr->gr_mem[i], expected->gr_mem[i]);
1074 : }
1075 9 : return EOK;
1076 : }
1077 :
1078 1 : static int test_nss_getgrnam_no_members_check(uint32_t status,
1079 : uint8_t *body, size_t blen)
1080 : {
1081 : int ret;
1082 : uint32_t nmem;
1083 : struct group gr;
1084 1 : struct group expected = {
1085 : .gr_gid = 1123,
1086 : .gr_name = discard_const("testgroup"),
1087 : .gr_passwd = discard_const("*"),
1088 : .gr_mem = NULL,
1089 : };
1090 :
1091 1 : assert_int_equal(status, EOK);
1092 :
1093 1 : ret = parse_group_packet(body, blen, &gr, &nmem);
1094 1 : assert_int_equal(ret, EOK);
1095 1 : assert_int_equal(nmem, 0);
1096 :
1097 1 : ret = test_nss_getgrnam_check(&expected, &gr, nmem);
1098 1 : assert_int_equal(ret, EOK);
1099 :
1100 1 : return EOK;
1101 : }
1102 :
1103 : /* Test that requesting a valid, cached group with no members returns a valid
1104 : * group structure
1105 : */
1106 1 : void test_nss_getgrnam_no_members(void **state)
1107 : {
1108 : errno_t ret;
1109 :
1110 : /* Prime the cache with a valid group */
1111 1 : ret = sysdb_add_group(nss_test_ctx->tctx->dom,
1112 : "testgroup", 1123,
1113 : NULL, 300, 0);
1114 1 : assert_int_equal(ret, EOK);
1115 :
1116 1 : mock_input_user_or_group("testgroup");
1117 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM);
1118 1 : mock_fill_group_with_members(0);
1119 :
1120 : /* Query for that group, call a callback when command finishes */
1121 1 : set_cmd_cb(test_nss_getgrnam_no_members_check);
1122 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM,
1123 1 : nss_test_ctx->nss_cmds);
1124 1 : assert_int_equal(ret, EOK);
1125 :
1126 : /* Wait until the test finishes with EOK */
1127 1 : ret = test_ev_loop(nss_test_ctx->tctx);
1128 1 : assert_int_equal(ret, EOK);
1129 1 : }
1130 :
1131 1 : static int test_nss_getgrnam_members_check(uint32_t status,
1132 : uint8_t *body, size_t blen)
1133 : {
1134 : int ret;
1135 : uint32_t nmem;
1136 : struct group gr;
1137 1 : const char *exp_members[] = { "testmember1", "testmember2" };
1138 1 : struct group expected = {
1139 : .gr_gid = 1124,
1140 : .gr_name = discard_const("testgroup_members"),
1141 : .gr_passwd = discard_const("*"),
1142 : .gr_mem = discard_const(exp_members)
1143 : };
1144 :
1145 1 : assert_int_equal(status, EOK);
1146 :
1147 1 : ret = parse_group_packet(body, blen, &gr, &nmem);
1148 1 : assert_int_equal(ret, EOK);
1149 1 : assert_int_equal(nmem, 2);
1150 :
1151 1 : ret = test_nss_getgrnam_check(&expected, &gr, nmem);
1152 1 : assert_int_equal(ret, EOK);
1153 :
1154 1 : return EOK;
1155 : }
1156 :
1157 : /* Test that requesting a valid, cached group with some members returns a valid
1158 : * group structure with those members present
1159 : */
1160 1 : void test_nss_getgrnam_members(void **state)
1161 : {
1162 : errno_t ret;
1163 :
1164 : /* Prime the cache with a valid group and some members */
1165 1 : ret = sysdb_add_group(nss_test_ctx->tctx->dom,
1166 : "testgroup_members", 1124,
1167 : NULL, 300, 0);
1168 1 : assert_int_equal(ret, EOK);
1169 :
1170 1 : ret = sysdb_add_user(nss_test_ctx->tctx->dom,
1171 : "testmember1", 2001, 456, "test member1",
1172 : "/home/testmember2", "/bin/sh", NULL,
1173 : NULL, 300, 0);
1174 1 : assert_int_equal(ret, EOK);
1175 :
1176 1 : ret = sysdb_add_user(nss_test_ctx->tctx->dom,
1177 : "testmember2", 2002, 456, "test member2",
1178 : "/home/testmember2", "/bin/sh", NULL,
1179 : NULL, 300, 0);
1180 1 : assert_int_equal(ret, EOK);
1181 :
1182 1 : ret = sysdb_add_group_member(nss_test_ctx->tctx->dom,
1183 : "testgroup_members", "testmember1",
1184 : SYSDB_MEMBER_USER, false);
1185 1 : assert_int_equal(ret, EOK);
1186 :
1187 1 : ret = sysdb_add_group_member(nss_test_ctx->tctx->dom,
1188 : "testgroup_members", "testmember2",
1189 : SYSDB_MEMBER_USER, false);
1190 1 : assert_int_equal(ret, EOK);
1191 :
1192 1 : mock_input_user_or_group("testgroup_members");
1193 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM);
1194 1 : mock_fill_group_with_members(2);
1195 :
1196 : /* Query for that group, call a callback when command finishes */
1197 1 : set_cmd_cb(test_nss_getgrnam_members_check);
1198 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM,
1199 1 : nss_test_ctx->nss_cmds);
1200 1 : assert_int_equal(ret, EOK);
1201 :
1202 : /* Wait until the test finishes with EOK */
1203 1 : ret = test_ev_loop(nss_test_ctx->tctx);
1204 1 : assert_int_equal(ret, EOK);
1205 1 : }
1206 :
1207 1 : static int test_nss_getgrnam_members_check_fqdn(uint32_t status,
1208 : uint8_t *body, size_t blen)
1209 : {
1210 : int ret;
1211 : uint32_t nmem;
1212 : struct group gr;
1213 1 : const char *exp_members[] = { "testmember1@"TEST_DOM_NAME,
1214 : "testmember2@"TEST_DOM_NAME };
1215 1 : struct group expected = {
1216 : .gr_gid = 1124,
1217 : .gr_name = discard_const("testgroup_members@"TEST_DOM_NAME),
1218 : .gr_passwd = discard_const("*"),
1219 : .gr_mem = discard_const(exp_members)
1220 : };
1221 :
1222 1 : assert_int_equal(status, EOK);
1223 :
1224 1 : ret = parse_group_packet(body, blen, &gr, &nmem);
1225 1 : assert_int_equal(ret, EOK);
1226 1 : assert_int_equal(nmem, 2);
1227 :
1228 1 : ret = test_nss_getgrnam_check(&expected, &gr, nmem);
1229 1 : assert_int_equal(ret, EOK);
1230 :
1231 1 : return EOK;
1232 : }
1233 :
1234 : /* Test that requesting a valid, cached group with some members returns a valid
1235 : * group structure with those members present as fully qualified names
1236 : */
1237 1 : void test_nss_getgrnam_members_fqdn(void **state)
1238 : {
1239 : errno_t ret;
1240 :
1241 1 : nss_test_ctx->tctx->dom->fqnames = true;
1242 :
1243 1 : mock_input_user_or_group("testgroup_members@"TEST_DOM_NAME);
1244 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM);
1245 1 : mock_fill_group_with_members(2);
1246 :
1247 : /* Query for that group, call a callback when command finishes */
1248 1 : set_cmd_cb(test_nss_getgrnam_members_check_fqdn);
1249 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM,
1250 1 : nss_test_ctx->nss_cmds);
1251 1 : assert_int_equal(ret, EOK);
1252 :
1253 : /* Wait until the test finishes with EOK */
1254 1 : ret = test_ev_loop(nss_test_ctx->tctx);
1255 :
1256 : /* Restore FQDN settings */
1257 1 : nss_test_ctx->tctx->dom->fqnames = false;
1258 1 : assert_int_equal(ret, EOK);
1259 1 : }
1260 :
1261 1 : static int test_nss_getgrnam_members_check_subdom(uint32_t status,
1262 : uint8_t *body, size_t blen)
1263 : {
1264 : int ret;
1265 : uint32_t nmem;
1266 : struct group gr;
1267 1 : const char *exp_members[] = { "submember1@"TEST_SUBDOM_NAME,
1268 : "submember2@"TEST_SUBDOM_NAME };
1269 1 : struct group expected = {
1270 : .gr_gid = 2124,
1271 : .gr_name = discard_const("testsubdomgroup@"TEST_SUBDOM_NAME),
1272 : .gr_passwd = discard_const("*"),
1273 : .gr_mem = discard_const(exp_members)
1274 : };
1275 :
1276 1 : assert_int_equal(status, EOK);
1277 :
1278 1 : ret = parse_group_packet(body, blen, &gr, &nmem);
1279 1 : assert_int_equal(ret, EOK);
1280 1 : assert_int_equal(nmem, 2);
1281 :
1282 1 : ret = test_nss_getgrnam_check(&expected, &gr, nmem);
1283 1 : assert_int_equal(ret, EOK);
1284 :
1285 1 : return EOK;
1286 : }
1287 :
1288 : /* Test that requesting a valid, cached group with some members returns a valid
1289 : * group structure with those members present as fully qualified names
1290 : */
1291 1 : void test_nss_getgrnam_members_subdom(void **state)
1292 : {
1293 : errno_t ret;
1294 :
1295 1 : nss_test_ctx->tctx->dom->fqnames = true;
1296 :
1297 : /* Add a group from a subdomain and two members from the same subdomain
1298 : */
1299 1 : ret = sysdb_add_group(nss_test_ctx->subdom,
1300 : "testsubdomgroup@"TEST_SUBDOM_NAME,
1301 : 2124, NULL, 300, 0);
1302 1 : assert_int_equal(ret, EOK);
1303 :
1304 1 : ret = sysdb_add_user(nss_test_ctx->subdom,
1305 : "submember1@"TEST_SUBDOM_NAME,
1306 : 4001, 456, "test subdomain member1",
1307 : "/home/submember1", "/bin/sh", NULL,
1308 : NULL, 300, 0);
1309 1 : assert_int_equal(ret, EOK);
1310 :
1311 1 : ret = sysdb_add_user(nss_test_ctx->subdom,
1312 : "submember2@"TEST_SUBDOM_NAME,
1313 : 2002, 456, "test subdomain member2",
1314 : "/home/submember2", "/bin/sh", NULL,
1315 : NULL, 300, 0);
1316 1 : assert_int_equal(ret, EOK);
1317 :
1318 1 : ret = sysdb_add_group_member(nss_test_ctx->subdom,
1319 : "testsubdomgroup@"TEST_SUBDOM_NAME,
1320 : "submember1@"TEST_SUBDOM_NAME,
1321 : SYSDB_MEMBER_USER, false);
1322 1 : assert_int_equal(ret, EOK);
1323 :
1324 1 : ret = sysdb_add_group_member(nss_test_ctx->subdom,
1325 : "testsubdomgroup@"TEST_SUBDOM_NAME,
1326 : "submember2@"TEST_SUBDOM_NAME,
1327 : SYSDB_MEMBER_USER, false);
1328 1 : assert_int_equal(ret, EOK);
1329 :
1330 :
1331 1 : mock_input_user_or_group("testsubdomgroup@"TEST_SUBDOM_NAME);
1332 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM);
1333 1 : mock_fill_group_with_members(2);
1334 :
1335 : /* Query for that group, call a callback when command finishes */
1336 1 : set_cmd_cb(test_nss_getgrnam_members_check_subdom);
1337 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM,
1338 1 : nss_test_ctx->nss_cmds);
1339 1 : assert_int_equal(ret, EOK);
1340 :
1341 : /* Wait until the test finishes with EOK */
1342 1 : ret = test_ev_loop(nss_test_ctx->tctx);
1343 :
1344 : /* Restore FQDN settings */
1345 1 : nss_test_ctx->tctx->dom->fqnames = false;
1346 1 : assert_int_equal(ret, EOK);
1347 1 : }
1348 :
1349 1 : static int test_nss_getgrnam_check_mix_dom(uint32_t status,
1350 : uint8_t *body, size_t blen)
1351 : {
1352 : int ret;
1353 : uint32_t nmem;
1354 : struct group gr;
1355 1 : const char *exp_members[] = { "testmember1",
1356 : "testmember2",
1357 : "submember1@"TEST_SUBDOM_NAME };
1358 1 : struct group expected = {
1359 : .gr_gid = 1124,
1360 : .gr_name = discard_const("testgroup_members"),
1361 : .gr_passwd = discard_const("*"),
1362 : .gr_mem = discard_const(exp_members)
1363 : };
1364 :
1365 1 : assert_int_equal(status, EOK);
1366 :
1367 1 : ret = parse_group_packet(body, blen, &gr, &nmem);
1368 1 : assert_int_equal(ret, EOK);
1369 1 : assert_int_equal(nmem, 3);
1370 :
1371 1 : ret = test_nss_getgrnam_check(&expected, &gr, nmem);
1372 1 : assert_int_equal(ret, EOK);
1373 :
1374 1 : return EOK;
1375 : }
1376 :
1377 1 : void test_nss_getgrnam_mix_dom(void **state)
1378 : {
1379 : errno_t ret;
1380 1 : const char *group_strdn = NULL;
1381 1 : const char *add_groups[] = { NULL, NULL };
1382 :
1383 : /* Add a subdomain user to a parent domain group */
1384 1 : group_strdn = sysdb_group_strdn(nss_test_ctx,
1385 1 : nss_test_ctx->tctx->dom->name,
1386 : "testgroup_members");
1387 1 : assert_non_null(group_strdn);
1388 1 : add_groups[0] = group_strdn;
1389 :
1390 1 : ret = sysdb_update_members_dn(nss_test_ctx->subdom,
1391 : "submember1@"TEST_SUBDOM_NAME,
1392 : SYSDB_MEMBER_USER,
1393 : add_groups, NULL);
1394 1 : assert_int_equal(ret, EOK);
1395 :
1396 1 : mock_input_user_or_group("testgroup_members");
1397 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM);
1398 1 : mock_fill_group_with_members(3);
1399 :
1400 : /* Query for that group, call a callback when command finishes */
1401 1 : set_cmd_cb(test_nss_getgrnam_check_mix_dom);
1402 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM,
1403 1 : nss_test_ctx->nss_cmds);
1404 1 : assert_int_equal(ret, EOK);
1405 :
1406 : /* Wait until the test finishes with EOK */
1407 1 : ret = test_ev_loop(nss_test_ctx->tctx);
1408 1 : assert_int_equal(ret, EOK);
1409 1 : }
1410 :
1411 1 : static int test_nss_getgrnam_check_mix_dom_fqdn(uint32_t status,
1412 : uint8_t *body, size_t blen)
1413 : {
1414 : int ret;
1415 : uint32_t nmem;
1416 : struct group gr;
1417 1 : const char *exp_members[] = { "testmember1@"TEST_DOM_NAME,
1418 : "testmember2@"TEST_DOM_NAME,
1419 : "submember1@"TEST_SUBDOM_NAME };
1420 1 : struct group expected = {
1421 : .gr_gid = 1124,
1422 : .gr_name = discard_const("testgroup_members@"TEST_DOM_NAME),
1423 : .gr_passwd = discard_const("*"),
1424 : .gr_mem = discard_const(exp_members)
1425 : };
1426 :
1427 1 : assert_int_equal(status, EOK);
1428 :
1429 1 : ret = parse_group_packet(body, blen, &gr, &nmem);
1430 1 : assert_int_equal(ret, EOK);
1431 1 : assert_int_equal(nmem, 3);
1432 :
1433 1 : ret = test_nss_getgrnam_check(&expected, &gr, nmem);
1434 1 : assert_int_equal(ret, EOK);
1435 :
1436 1 : return EOK;
1437 : }
1438 :
1439 1 : void test_nss_getgrnam_mix_dom_fqdn(void **state)
1440 : {
1441 : errno_t ret;
1442 :
1443 1 : nss_test_ctx->tctx->dom->fqnames = true;
1444 :
1445 1 : mock_input_user_or_group("testgroup_members@"TEST_DOM_NAME);
1446 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM);
1447 1 : mock_fill_group_with_members(3);
1448 :
1449 : /* Query for that group, call a callback when command finishes */
1450 1 : set_cmd_cb(test_nss_getgrnam_check_mix_dom_fqdn);
1451 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM,
1452 1 : nss_test_ctx->nss_cmds);
1453 1 : assert_int_equal(ret, EOK);
1454 :
1455 : /* Wait until the test finishes with EOK */
1456 1 : ret = test_ev_loop(nss_test_ctx->tctx);
1457 :
1458 : /* Restore FQDN settings */
1459 1 : nss_test_ctx->tctx->dom->fqnames = false;
1460 1 : assert_int_equal(ret, EOK);
1461 1 : }
1462 :
1463 1 : static int test_nss_getgrnam_check_mix_subdom(uint32_t status,
1464 : uint8_t *body, size_t blen)
1465 : {
1466 : int ret;
1467 : uint32_t nmem;
1468 : struct group gr;
1469 1 : const char *exp_members[] = { "submember1@"TEST_SUBDOM_NAME,
1470 : "submember2@"TEST_SUBDOM_NAME,
1471 : "testmember1@"TEST_DOM_NAME };
1472 1 : struct group expected = {
1473 : .gr_gid = 2124,
1474 : .gr_name = discard_const("testsubdomgroup@"TEST_SUBDOM_NAME),
1475 : .gr_passwd = discard_const("*"),
1476 : .gr_mem = discard_const(exp_members)
1477 : };
1478 :
1479 1 : assert_int_equal(status, EOK);
1480 :
1481 1 : ret = parse_group_packet(body, blen, &gr, &nmem);
1482 1 : assert_int_equal(ret, EOK);
1483 1 : assert_int_equal(nmem, 3);
1484 :
1485 1 : ret = test_nss_getgrnam_check(&expected, &gr, nmem);
1486 1 : assert_int_equal(ret, EOK);
1487 :
1488 1 : return EOK;
1489 : }
1490 :
1491 1 : void test_nss_getgrnam_mix_subdom(void **state)
1492 : {
1493 : errno_t ret;
1494 1 : const char *group_strdn = NULL;
1495 1 : const char *add_groups[] = { NULL, NULL };
1496 :
1497 : /* Add a subdomain user to a parent domain group */
1498 1 : group_strdn = sysdb_group_strdn(nss_test_ctx,
1499 1 : nss_test_ctx->subdom->name,
1500 : "testsubdomgroup@"TEST_SUBDOM_NAME);
1501 1 : assert_non_null(group_strdn);
1502 1 : add_groups[0] = group_strdn;
1503 :
1504 1 : ret = sysdb_update_members_dn(nss_test_ctx->tctx->dom,
1505 : "testmember1",
1506 : SYSDB_MEMBER_USER,
1507 : add_groups, NULL);
1508 1 : assert_int_equal(ret, EOK);
1509 :
1510 1 : mock_input_user_or_group("testsubdomgroup@"TEST_SUBDOM_NAME);
1511 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM);
1512 1 : mock_fill_group_with_members(3);
1513 :
1514 : /* Query for that group, call a callback when command finishes */
1515 1 : set_cmd_cb(test_nss_getgrnam_check_mix_subdom);
1516 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM,
1517 1 : nss_test_ctx->nss_cmds);
1518 1 : assert_int_equal(ret, EOK);
1519 :
1520 : /* Wait until the test finishes with EOK */
1521 1 : ret = test_ev_loop(nss_test_ctx->tctx);
1522 1 : assert_int_equal(ret, EOK);
1523 1 : }
1524 :
1525 1 : static int test_nss_getgrnam_space_check(uint32_t status,
1526 : uint8_t *body, size_t blen)
1527 : {
1528 : int ret;
1529 : uint32_t nmem;
1530 : struct group gr;
1531 1 : struct group expected = {
1532 : .gr_gid = 2123,
1533 : .gr_name = discard_const("space group"),
1534 : .gr_passwd = discard_const("*"),
1535 : .gr_mem = NULL,
1536 : };
1537 :
1538 1 : assert_int_equal(status, EOK);
1539 :
1540 1 : ret = parse_group_packet(body, blen, &gr, &nmem);
1541 1 : assert_int_equal(ret, EOK);
1542 1 : assert_int_equal(nmem, 0);
1543 :
1544 1 : ret = test_nss_getgrnam_check(&expected, &gr, nmem);
1545 1 : assert_int_equal(ret, EOK);
1546 :
1547 1 : return EOK;
1548 : }
1549 :
1550 : /* Test that requesting a valid, cached group with space in its name returns a valid
1551 : * group structure
1552 : */
1553 1 : void test_nss_getgrnam_space(void **state)
1554 : {
1555 : errno_t ret;
1556 :
1557 : /* Prime the cache with a valid group */
1558 1 : ret = sysdb_add_group(nss_test_ctx->tctx->dom,
1559 : "space group", 2123,
1560 : NULL, 300, 0);
1561 1 : assert_int_equal(ret, EOK);
1562 :
1563 1 : mock_input_user_or_group("space group");
1564 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM);
1565 1 : mock_fill_group_with_members(0);
1566 :
1567 : /* Query for that group, call a callback when command finishes */
1568 1 : set_cmd_cb(test_nss_getgrnam_space_check);
1569 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM,
1570 1 : nss_test_ctx->nss_cmds);
1571 1 : assert_int_equal(ret, EOK);
1572 :
1573 : /* Wait until the test finishes with EOK */
1574 1 : ret = test_ev_loop(nss_test_ctx->tctx);
1575 1 : assert_int_equal(ret, EOK);
1576 1 : }
1577 :
1578 1 : static int test_nss_getgrnam_space_sub_check(uint32_t status,
1579 : uint8_t *body, size_t blen)
1580 : {
1581 : int ret;
1582 : uint32_t nmem;
1583 : struct group gr;
1584 1 : struct group expected = {
1585 : .gr_gid = 2123,
1586 : .gr_name = discard_const("space_group"),
1587 : .gr_passwd = discard_const("*"),
1588 : .gr_mem = NULL,
1589 : };
1590 :
1591 1 : assert_int_equal(status, EOK);
1592 :
1593 1 : ret = parse_group_packet(body, blen, &gr, &nmem);
1594 1 : assert_int_equal(ret, EOK);
1595 1 : assert_int_equal(nmem, 0);
1596 :
1597 1 : ret = test_nss_getgrnam_check(&expected, &gr, nmem);
1598 1 : assert_int_equal(ret, EOK);
1599 :
1600 1 : return EOK;
1601 : }
1602 :
1603 : /* Test that requesting a valid, cached group with space in its name returns a valid
1604 : * group structure
1605 : */
1606 1 : void test_nss_getgrnam_space_sub(void **state)
1607 : {
1608 : errno_t ret;
1609 :
1610 : /* Set whitespace substitution */
1611 1 : nss_test_ctx->rctx->override_space = '_';
1612 :
1613 1 : mock_input_user_or_group("space group");
1614 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM);
1615 1 : mock_fill_group_with_members(0);
1616 :
1617 : /* Query for that group, call a callback when command finishes */
1618 1 : set_cmd_cb(test_nss_getgrnam_space_sub_check);
1619 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM,
1620 1 : nss_test_ctx->nss_cmds);
1621 1 : assert_int_equal(ret, EOK);
1622 :
1623 : /* Wait until the test finishes with EOK */
1624 1 : ret = test_ev_loop(nss_test_ctx->tctx);
1625 1 : nss_test_ctx->rctx->override_space = '\0';
1626 1 : assert_int_equal(ret, EOK);
1627 1 : }
1628 :
1629 10 : static int test_nss_well_known_sid_check(uint32_t status,
1630 : uint8_t *body, size_t blen)
1631 : {
1632 : const char *name;
1633 : enum sss_id_type type;
1634 10 : size_t rp = 2 * sizeof(uint32_t);
1635 10 : char *expected_result = sss_mock_ptr_type(char *);
1636 :
1637 10 : if (expected_result == NULL) {
1638 4 : assert_int_equal(status, EINVAL);
1639 4 : assert_int_equal(blen, 0);
1640 : } else {
1641 6 : assert_int_equal(status, EOK);
1642 :
1643 6 : SAFEALIGN_COPY_UINT32(&type, body+rp, &rp);
1644 :
1645 6 : name = (char *) body+rp;
1646 :
1647 6 : assert_int_equal(type, SSS_ID_TYPE_GID);
1648 6 : assert_string_equal(name, expected_result);
1649 : }
1650 :
1651 10 : return EOK;
1652 : }
1653 :
1654 1 : void test_nss_well_known_getnamebysid(void **state)
1655 : {
1656 : errno_t ret;
1657 :
1658 1 : will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER);
1659 1 : will_return(__wrap_sss_packet_get_body, "S-1-5-32-550");
1660 1 : will_return(__wrap_sss_packet_get_body, 0);
1661 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETNAMEBYSID);
1662 1 : will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
1663 1 : will_return(test_nss_well_known_sid_check, "Print Operators@BUILTIN");
1664 :
1665 1 : set_cmd_cb(test_nss_well_known_sid_check);
1666 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETNAMEBYSID,
1667 1 : nss_test_ctx->nss_cmds);
1668 1 : assert_int_equal(ret, EOK);
1669 :
1670 : /* Wait until the test finishes with EOK */
1671 1 : ret = test_ev_loop(nss_test_ctx->tctx);
1672 1 : assert_int_equal(ret, EOK);
1673 1 : }
1674 :
1675 1 : void test_nss_well_known_getnamebysid_special(void **state)
1676 : {
1677 : errno_t ret;
1678 :
1679 1 : will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER);
1680 1 : will_return(__wrap_sss_packet_get_body, "S-1-2-0");
1681 1 : will_return(__wrap_sss_packet_get_body, 0);
1682 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETNAMEBYSID);
1683 1 : will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
1684 1 : will_return(test_nss_well_known_sid_check, "LOCAL@LOCAL AUTHORITY");
1685 :
1686 1 : set_cmd_cb(test_nss_well_known_sid_check);
1687 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETNAMEBYSID,
1688 1 : nss_test_ctx->nss_cmds);
1689 1 : assert_int_equal(ret, EOK);
1690 :
1691 : /* Wait until the test finishes with EOK */
1692 1 : ret = test_ev_loop(nss_test_ctx->tctx);
1693 1 : assert_int_equal(ret, EOK);
1694 1 : }
1695 :
1696 1 : void test_nss_well_known_getnamebysid_non_existing(void **state)
1697 : {
1698 : errno_t ret;
1699 :
1700 1 : will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER);
1701 1 : will_return(__wrap_sss_packet_get_body, "S-1-5-32-123");
1702 1 : will_return(__wrap_sss_packet_get_body, 0);
1703 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETNAMEBYSID);
1704 1 : will_return(test_nss_well_known_sid_check, NULL);
1705 :
1706 1 : set_cmd_cb(test_nss_well_known_sid_check);
1707 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETNAMEBYSID,
1708 1 : nss_test_ctx->nss_cmds);
1709 1 : assert_int_equal(ret, EOK);
1710 :
1711 : /* Wait until the test finishes with EOK */
1712 1 : ret = test_ev_loop(nss_test_ctx->tctx);
1713 1 : assert_int_equal(ret, EOK);
1714 1 : }
1715 :
1716 1 : void test_nss_well_known_getidbysid_failure(void **state)
1717 : {
1718 : errno_t ret;
1719 :
1720 1 : will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER);
1721 1 : will_return(__wrap_sss_packet_get_body, "S-1-5-32-550");
1722 1 : will_return(__wrap_sss_packet_get_body, 0);
1723 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETIDBYSID);
1724 1 : will_return(test_nss_well_known_sid_check, NULL);
1725 :
1726 1 : set_cmd_cb(test_nss_well_known_sid_check);
1727 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETIDBYSID,
1728 1 : nss_test_ctx->nss_cmds);
1729 1 : assert_int_equal(ret, EOK);
1730 :
1731 : /* Wait until the test finishes with EOK */
1732 1 : ret = test_ev_loop(nss_test_ctx->tctx);
1733 1 : assert_int_equal(ret, EOK);
1734 1 : }
1735 :
1736 1 : void test_nss_well_known_getsidbyname(void **state)
1737 : {
1738 : errno_t ret;
1739 1 : const char *names[] = { "Cryptographic Operators@BUILTIN",
1740 : "BUILTIN\\Cryptographic Operators", NULL};
1741 : size_t c;
1742 :
1743 3 : for (c = 0; names[c] != NULL; c++) {
1744 2 : will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER);
1745 2 : will_return(__wrap_sss_packet_get_body, names[c]);
1746 2 : will_return(__wrap_sss_packet_get_body, 0);
1747 2 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETSIDBYNAME);
1748 2 : will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
1749 2 : will_return(test_nss_well_known_sid_check, "S-1-5-32-569");
1750 :
1751 2 : set_cmd_cb(test_nss_well_known_sid_check);
1752 2 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETSIDBYNAME,
1753 2 : nss_test_ctx->nss_cmds);
1754 2 : assert_int_equal(ret, EOK);
1755 :
1756 : /* Wait until the test finishes with EOK */
1757 2 : ret = test_ev_loop(nss_test_ctx->tctx);
1758 2 : assert_int_equal(ret, EOK);
1759 : }
1760 1 : }
1761 :
1762 1 : void test_nss_well_known_getsidbyname_nonexisting(void **state)
1763 : {
1764 : errno_t ret;
1765 1 : const char *names[] = { "Abc@BUILTIN", "BUILTIN\\Abc", NULL };
1766 : size_t c;
1767 :
1768 3 : for (c = 0; names[c] != NULL; c++) {
1769 2 : will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER);
1770 2 : will_return(__wrap_sss_packet_get_body, names[c]);
1771 2 : will_return(__wrap_sss_packet_get_body, 0);
1772 2 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETSIDBYNAME);
1773 2 : will_return(test_nss_well_known_sid_check, NULL);
1774 :
1775 2 : set_cmd_cb(test_nss_well_known_sid_check);
1776 2 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETSIDBYNAME,
1777 2 : nss_test_ctx->nss_cmds);
1778 2 : assert_int_equal(ret, EOK);
1779 :
1780 : /* Wait until the test finishes with EOK */
1781 2 : ret = test_ev_loop(nss_test_ctx->tctx);
1782 2 : assert_int_equal(ret, EOK);
1783 : }
1784 1 : }
1785 :
1786 1 : void test_nss_well_known_getsidbyname_special(void **state)
1787 : {
1788 : errno_t ret;
1789 1 : const char *names[] = { "CREATOR OWNER@CREATOR AUTHORITY",
1790 : "CREATOR AUTHORITY\\CREATOR OWNER", NULL };
1791 : size_t c;
1792 :
1793 3 : for (c = 0; names[c] != NULL; c++) {
1794 2 : will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER);
1795 2 : will_return(__wrap_sss_packet_get_body, names[c]);
1796 2 : will_return(__wrap_sss_packet_get_body, 0);
1797 2 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETSIDBYNAME);
1798 2 : will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
1799 2 : will_return(test_nss_well_known_sid_check, "S-1-3-0");
1800 :
1801 2 : set_cmd_cb(test_nss_well_known_sid_check);
1802 2 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETSIDBYNAME,
1803 2 : nss_test_ctx->nss_cmds);
1804 2 : assert_int_equal(ret, EOK);
1805 :
1806 : /* Wait until the test finishes with EOK */
1807 2 : ret = test_ev_loop(nss_test_ctx->tctx);
1808 2 : assert_int_equal(ret, EOK);
1809 : }
1810 1 : }
1811 :
1812 1 : static int test_nss_getorigbyname_check(uint32_t status, uint8_t *body,
1813 : size_t blen)
1814 : {
1815 : const char *s;
1816 : enum sss_id_type id_type;
1817 1 : size_t rp = 2 * sizeof(uint32_t);
1818 :
1819 1 : assert_int_equal(status, EOK);
1820 :
1821 1 : SAFEALIGN_COPY_UINT32(&id_type, body+rp, &rp);
1822 1 : assert_int_equal(id_type, SSS_ID_TYPE_UID);
1823 :
1824 : /* Sequence of null terminated strings */
1825 1 : s = (char *) body+rp;
1826 1 : assert_string_equal(s, SYSDB_SID_STR);
1827 1 : rp += strlen(s) + 1;
1828 1 : assert_true(rp < blen);
1829 :
1830 1 : s = (char *) body+rp;
1831 1 : assert_string_equal(s, "S-1-2-3-4");
1832 1 : rp += strlen(s) + 1;
1833 1 : assert_true(rp < blen);
1834 :
1835 1 : s = (char *) body+rp;
1836 1 : assert_string_equal(s, ORIGINALAD_PREFIX SYSDB_NAME);
1837 1 : rp += strlen(s) + 1;
1838 1 : assert_true(rp < blen);
1839 :
1840 1 : s = (char *) body+rp;
1841 1 : assert_string_equal(s, "orig_name");
1842 1 : rp += strlen(s) + 1;
1843 1 : assert_true(rp < blen);
1844 :
1845 1 : s = (char *) body+rp;
1846 1 : assert_string_equal(s, ORIGINALAD_PREFIX SYSDB_UIDNUM);
1847 1 : rp += strlen(s) + 1;
1848 1 : assert_true(rp < blen);
1849 :
1850 1 : s = (char *) body+rp;
1851 1 : assert_string_equal(s, "1234");
1852 1 : rp += strlen(s) + 1;
1853 1 : assert_int_equal(rp, blen);
1854 :
1855 1 : return EOK;
1856 : }
1857 :
1858 1 : void test_nss_getorigbyname(void **state)
1859 : {
1860 : errno_t ret;
1861 : struct sysdb_attrs *attrs;
1862 :
1863 1 : attrs = sysdb_new_attrs(nss_test_ctx);
1864 1 : assert_non_null(attrs);
1865 :
1866 1 : ret = sysdb_attrs_add_string(attrs, SYSDB_SID_STR, "S-1-2-3-4");
1867 1 : assert_int_equal(ret, EOK);
1868 :
1869 1 : ret = sysdb_attrs_add_string(attrs, ORIGINALAD_PREFIX SYSDB_NAME,
1870 : "orig_name");
1871 1 : assert_int_equal(ret, EOK);
1872 :
1873 1 : ret = sysdb_attrs_add_uint32(attrs, ORIGINALAD_PREFIX SYSDB_UIDNUM, 1234);
1874 1 : assert_int_equal(ret, EOK);
1875 :
1876 : /* Prime the cache with a valid user */
1877 1 : ret = sysdb_add_user(nss_test_ctx->tctx->dom,
1878 : "testuserorig", 1234, 5689, "test user orig",
1879 : "/home/testuserorig", "/bin/sh", NULL,
1880 : attrs, 300, 0);
1881 1 : assert_int_equal(ret, EOK);
1882 :
1883 1 : mock_input_user_or_group("testuserorig");
1884 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETORIGBYNAME);
1885 1 : will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
1886 :
1887 : /* Query for that user, call a callback when command finishes */
1888 1 : set_cmd_cb(test_nss_getorigbyname_check);
1889 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETORIGBYNAME,
1890 1 : nss_test_ctx->nss_cmds);
1891 1 : assert_int_equal(ret, EOK);
1892 :
1893 : /* Wait until the test finishes with EOK */
1894 1 : ret = test_ev_loop(nss_test_ctx->tctx);
1895 1 : assert_int_equal(ret, EOK);
1896 1 : }
1897 :
1898 1 : static int test_nss_getorigbyname_extra_check(uint32_t status, uint8_t *body,
1899 : size_t blen)
1900 : {
1901 : const char *s;
1902 : enum sss_id_type id_type;
1903 1 : size_t rp = 2 * sizeof(uint32_t);
1904 :
1905 1 : assert_int_equal(status, EOK);
1906 :
1907 1 : SAFEALIGN_COPY_UINT32(&id_type, body+rp, &rp);
1908 1 : assert_int_equal(id_type, SSS_ID_TYPE_UID);
1909 :
1910 : /* Sequence of null terminated strings */
1911 1 : s = (char *) body+rp;
1912 1 : assert_string_equal(s, SYSDB_SID_STR);
1913 1 : rp += strlen(s) + 1;
1914 1 : assert_true(rp < blen);
1915 :
1916 1 : s = (char *) body+rp;
1917 1 : assert_string_equal(s, "S-1-2-3-4");
1918 1 : rp += strlen(s) + 1;
1919 1 : assert_true(rp < blen);
1920 :
1921 1 : s = (char *) body+rp;
1922 1 : assert_string_equal(s, ORIGINALAD_PREFIX SYSDB_NAME);
1923 1 : rp += strlen(s) + 1;
1924 1 : assert_true(rp < blen);
1925 :
1926 1 : s = (char *) body+rp;
1927 1 : assert_string_equal(s, "orig_name");
1928 1 : rp += strlen(s) + 1;
1929 1 : assert_true(rp < blen);
1930 :
1931 1 : s = (char *) body+rp;
1932 1 : assert_string_equal(s, ORIGINALAD_PREFIX SYSDB_UIDNUM);
1933 1 : rp += strlen(s) + 1;
1934 1 : assert_true(rp < blen);
1935 :
1936 1 : s = (char *) body+rp;
1937 1 : assert_string_equal(s, "1234");
1938 1 : rp += strlen(s) + 1;
1939 1 : assert_true(rp < blen);
1940 :
1941 1 : s = (char *) body+rp;
1942 1 : assert_string_equal(s, "phone");
1943 1 : rp += strlen(s) + 1;
1944 1 : assert_true(rp < blen);
1945 :
1946 1 : s = (char *) body+rp;
1947 1 : assert_string_equal(s, "+12-34 56 78");
1948 1 : rp += strlen(s) + 1;
1949 1 : assert_true(rp < blen);
1950 :
1951 1 : s = (char *) body+rp;
1952 1 : assert_string_equal(s, "mobile");
1953 1 : rp += strlen(s) + 1;
1954 1 : assert_true(rp < blen);
1955 :
1956 1 : s = (char *) body+rp;
1957 1 : assert_string_equal(s, "+98-76 54 32");
1958 1 : rp += strlen(s) + 1;
1959 1 : assert_int_equal(rp, blen);
1960 :
1961 1 : return EOK;
1962 : }
1963 :
1964 1 : void test_nss_getorigbyname_extra_attrs(void **state)
1965 : {
1966 : errno_t ret;
1967 : struct sysdb_attrs *attrs;
1968 :
1969 1 : attrs = sysdb_new_attrs(nss_test_ctx);
1970 1 : assert_non_null(attrs);
1971 :
1972 1 : ret = sysdb_attrs_add_string(attrs, SYSDB_SID_STR, "S-1-2-3-4");
1973 1 : assert_int_equal(ret, EOK);
1974 :
1975 1 : ret = sysdb_attrs_add_string(attrs, ORIGINALAD_PREFIX SYSDB_NAME,
1976 : "orig_name");
1977 1 : assert_int_equal(ret, EOK);
1978 :
1979 1 : ret = sysdb_attrs_add_uint32(attrs, ORIGINALAD_PREFIX SYSDB_UIDNUM, 1234);
1980 1 : assert_int_equal(ret, EOK);
1981 :
1982 1 : ret = sysdb_attrs_add_string(attrs, "phone", "+12-34 56 78");
1983 1 : assert_int_equal(ret, EOK);
1984 :
1985 1 : ret = sysdb_attrs_add_string(attrs, "mobile", "+98-76 54 32");
1986 1 : assert_int_equal(ret, EOK);
1987 :
1988 1 : ret = sysdb_attrs_add_string(attrs, "not_extra", "abc");
1989 1 : assert_int_equal(ret, EOK);
1990 :
1991 : /* Prime the cache with a valid user */
1992 1 : ret = sysdb_add_user(nss_test_ctx->tctx->dom,
1993 : "testuserorigextra", 2345, 6789,
1994 : "test user orig extra",
1995 : "/home/testuserorigextra", "/bin/sh", NULL,
1996 : attrs, 300, 0);
1997 1 : assert_int_equal(ret, EOK);
1998 :
1999 1 : mock_input_user_or_group("testuserorigextra");
2000 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETORIGBYNAME);
2001 1 : will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
2002 :
2003 : /* Query for that user, call a callback when command finishes */
2004 1 : set_cmd_cb(test_nss_getorigbyname_extra_check);
2005 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETORIGBYNAME,
2006 1 : nss_test_ctx->nss_cmds);
2007 1 : assert_int_equal(ret, EOK);
2008 :
2009 : /* Wait until the test finishes with EOK */
2010 1 : ret = test_ev_loop(nss_test_ctx->tctx);
2011 1 : assert_int_equal(ret, EOK);
2012 1 : }
2013 :
2014 :
2015 1 : static int test_nss_getorigbyname_multi_check(uint32_t status, uint8_t *body,
2016 : size_t blen)
2017 : {
2018 : const char *s;
2019 : enum sss_id_type id_type;
2020 1 : size_t rp = 2 * sizeof(uint32_t);
2021 :
2022 1 : assert_int_equal(status, EOK);
2023 :
2024 1 : SAFEALIGN_COPY_UINT32(&id_type, body+rp, &rp);
2025 1 : assert_int_equal(id_type, SSS_ID_TYPE_UID);
2026 :
2027 : /* Sequence of null terminated strings */
2028 1 : s = (char *) body+rp;
2029 1 : assert_string_equal(s, SYSDB_SID_STR);
2030 1 : rp += strlen(s) + 1;
2031 1 : assert_true(rp < blen);
2032 :
2033 1 : s = (char *) body+rp;
2034 1 : assert_string_equal(s, "S-1-2-3-4");
2035 1 : rp += strlen(s) + 1;
2036 1 : assert_true(rp < blen);
2037 :
2038 1 : s = (char *) body+rp;
2039 1 : assert_string_equal(s, ORIGINALAD_PREFIX SYSDB_NAME);
2040 1 : rp += strlen(s) + 1;
2041 1 : assert_true(rp < blen);
2042 :
2043 1 : s = (char *) body+rp;
2044 1 : assert_string_equal(s, "orig_name");
2045 1 : rp += strlen(s) + 1;
2046 1 : assert_true(rp < blen);
2047 :
2048 1 : s = (char *) body+rp;
2049 1 : assert_string_equal(s, ORIGINALAD_PREFIX SYSDB_UIDNUM);
2050 1 : rp += strlen(s) + 1;
2051 1 : assert_true(rp < blen);
2052 :
2053 1 : s = (char *) body+rp;
2054 1 : assert_string_equal(s, "1234");
2055 1 : rp += strlen(s) + 1;
2056 1 : assert_true(rp < blen);
2057 :
2058 1 : s = (char *) body+rp;
2059 1 : assert_string_equal(s, SYSDB_ORIG_MEMBEROF);
2060 1 : rp += strlen(s) + 1;
2061 1 : assert_true(rp < blen);
2062 :
2063 1 : s = (char *) body+rp;
2064 1 : assert_string_equal(s, "cn=abc");
2065 1 : rp += strlen(s) + 1;
2066 1 : assert_true(rp < blen);
2067 :
2068 1 : s = (char *) body+rp;
2069 1 : assert_string_equal(s, SYSDB_ORIG_MEMBEROF);
2070 1 : rp += strlen(s) + 1;
2071 1 : assert_true(rp < blen);
2072 :
2073 1 : s = (char *) body+rp;
2074 1 : assert_string_equal(s, "cn=def");
2075 1 : rp += strlen(s) + 1;
2076 1 : assert_true(rp < blen);
2077 :
2078 1 : s = (char *) body+rp;
2079 1 : assert_string_equal(s, SYSDB_ORIG_MEMBEROF);
2080 1 : rp += strlen(s) + 1;
2081 1 : assert_true(rp < blen);
2082 :
2083 1 : s = (char *) body+rp;
2084 1 : assert_string_equal(s, "cn=123");
2085 1 : rp += strlen(s) + 1;
2086 1 : assert_int_equal(rp, blen);
2087 :
2088 1 : return EOK;
2089 : }
2090 1 : void test_nss_getorigbyname_multi_value_attrs(void **state)
2091 : {
2092 : errno_t ret;
2093 : struct sysdb_attrs *attrs;
2094 :
2095 1 : attrs = sysdb_new_attrs(nss_test_ctx);
2096 1 : assert_non_null(attrs);
2097 :
2098 1 : ret = sysdb_attrs_add_string(attrs, SYSDB_SID_STR, "S-1-2-3-4");
2099 1 : assert_int_equal(ret, EOK);
2100 :
2101 1 : ret = sysdb_attrs_add_string(attrs, ORIGINALAD_PREFIX SYSDB_NAME,
2102 : "orig_name");
2103 1 : assert_int_equal(ret, EOK);
2104 :
2105 1 : ret = sysdb_attrs_add_uint32(attrs, ORIGINALAD_PREFIX SYSDB_UIDNUM, 1234);
2106 1 : assert_int_equal(ret, EOK);
2107 :
2108 1 : ret = sysdb_attrs_add_string(attrs, SYSDB_ORIG_MEMBEROF, "cn=abc");
2109 1 : assert_int_equal(ret, EOK);
2110 :
2111 1 : ret = sysdb_attrs_add_string(attrs, SYSDB_ORIG_MEMBEROF, "cn=def");
2112 1 : assert_int_equal(ret, EOK);
2113 :
2114 1 : ret = sysdb_attrs_add_string(attrs, SYSDB_ORIG_MEMBEROF, "cn=123");
2115 1 : assert_int_equal(ret, EOK);
2116 :
2117 : /* Prime the cache with a valid user */
2118 1 : ret = sysdb_add_user(nss_test_ctx->tctx->dom,
2119 : "testuserorigmulti", 3456, 7890,
2120 : "test user orig multi value",
2121 : "/home/testuserorigextra", "/bin/sh", NULL,
2122 : attrs, 300, 0);
2123 1 : assert_int_equal(ret, EOK);
2124 :
2125 1 : mock_input_user_or_group("testuserorigmulti");
2126 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETORIGBYNAME);
2127 1 : will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
2128 :
2129 : /* Query for that user, call a callback when command finishes */
2130 1 : set_cmd_cb(test_nss_getorigbyname_multi_check);
2131 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETORIGBYNAME,
2132 1 : nss_test_ctx->nss_cmds);
2133 1 : assert_int_equal(ret, EOK);
2134 :
2135 : /* Wait until the test finishes with EOK */
2136 1 : ret = test_ev_loop(nss_test_ctx->tctx);
2137 1 : assert_int_equal(ret, EOK);
2138 1 : }
2139 :
2140 1 : static int test_nss_getpwnam_upn_check(uint32_t status,
2141 : uint8_t *body,
2142 : size_t blen)
2143 : {
2144 : struct passwd pwd;
2145 : errno_t ret;
2146 :
2147 1 : assert_int_equal(status, EOK);
2148 :
2149 1 : ret = parse_user_packet(body, blen, &pwd);
2150 1 : assert_int_equal(ret, EOK);
2151 :
2152 1 : assert_int_equal(pwd.pw_uid, 34567);
2153 1 : assert_int_equal(pwd.pw_gid, 45678);
2154 1 : assert_string_equal(pwd.pw_name, "upnuser");
2155 1 : assert_string_equal(pwd.pw_shell, "/bin/sh");
2156 1 : assert_string_equal(pwd.pw_passwd, "*");
2157 1 : return EOK;
2158 : }
2159 :
2160 1 : void test_nss_getpwnam_upn(void **state)
2161 : {
2162 : errno_t ret;
2163 : struct sysdb_attrs *attrs;
2164 :
2165 1 : attrs = sysdb_new_attrs(nss_test_ctx);
2166 1 : assert_non_null(attrs);
2167 :
2168 1 : ret = sysdb_attrs_add_string(attrs, SYSDB_UPN, "upnuser@upndomain.test");
2169 1 : assert_int_equal(ret, EOK);
2170 :
2171 : /* Prime the cache with a valid user */
2172 1 : ret = sysdb_add_user(nss_test_ctx->tctx->dom,
2173 : "upnuser", 34567, 45678, "up user",
2174 : "/home/upnuser", "/bin/sh", NULL,
2175 : attrs, 300, 0);
2176 1 : assert_int_equal(ret, EOK);
2177 :
2178 1 : mock_input_user_or_group("upnuser@upndomain.test");
2179 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM);
2180 1 : mock_fill_user();
2181 :
2182 : /* Query for that user, call a callback when command finishes */
2183 1 : set_cmd_cb(test_nss_getpwnam_upn_check);
2184 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM,
2185 1 : nss_test_ctx->nss_cmds);
2186 1 : assert_int_equal(ret, EOK);
2187 :
2188 : /* Wait until the test finishes with EOK */
2189 1 : ret = test_ev_loop(nss_test_ctx->tctx);
2190 1 : assert_int_equal(ret, EOK);
2191 1 : }
2192 :
2193 : /* Test that searching for a nonexistant user yields ENOENT.
2194 : * Account callback will be called
2195 : */
2196 1 : void test_nss_getpwnam_upn_neg(void **state)
2197 : {
2198 : errno_t ret;
2199 :
2200 1 : mock_input_user_or_group("nosuchupnuser@upndomain.test");
2201 1 : mock_account_recv_simple();
2202 :
2203 1 : assert_int_equal(nss_test_ctx->ncache_hits, 0);
2204 :
2205 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM,
2206 1 : nss_test_ctx->nss_cmds);
2207 1 : assert_int_equal(ret, EOK);
2208 :
2209 : /* Wait until the test finishes with ENOENT */
2210 1 : ret = test_ev_loop(nss_test_ctx->tctx);
2211 1 : assert_int_equal(ret, ENOENT);
2212 1 : assert_int_equal(nss_test_ctx->ncache_hits, 1);
2213 :
2214 : /* Test that subsequent search for a nonexistent user yields
2215 : * ENOENT and Account callback is not called, on the other hand
2216 : * the ncache functions will be called
2217 : */
2218 1 : nss_test_ctx->tctx->done = false;
2219 1 : nss_test_ctx->ncache_hits = 0;
2220 :
2221 1 : mock_input_user_or_group("nosuchupnuser@upndomain.test");
2222 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM,
2223 1 : nss_test_ctx->nss_cmds);
2224 1 : assert_int_equal(ret, EOK);
2225 :
2226 : /* Wait until the test finishes with ENOENT */
2227 1 : ret = test_ev_loop(nss_test_ctx->tctx);
2228 1 : assert_int_equal(ret, ENOENT);
2229 : /* Negative cache was hit this time */
2230 1 : assert_int_equal(nss_test_ctx->ncache_hits, 1);
2231 1 : }
2232 :
2233 2 : static int test_nss_initgr_check(uint32_t status, uint8_t *body, size_t blen)
2234 : {
2235 2 : gid_t expected_gids[] = { 3211, 3212 };
2236 :
2237 2 : assert_int_equal(status, EOK);
2238 2 : check_initgr_packet(body, blen, expected_gids, N_ELEMENTS(expected_gids));
2239 2 : return EOK;
2240 : }
2241 :
2242 1 : void test_nss_initgroups(void **state)
2243 : {
2244 : errno_t ret;
2245 : struct sysdb_attrs *attrs;
2246 :
2247 1 : attrs = sysdb_new_attrs(nss_test_ctx);
2248 1 : assert_non_null(attrs);
2249 :
2250 1 : ret = sysdb_attrs_add_time_t(attrs, SYSDB_INITGR_EXPIRE,
2251 1 : time(NULL) + 300);
2252 1 : assert_int_equal(ret, EOK);
2253 :
2254 1 : ret = sysdb_attrs_add_string(attrs, SYSDB_UPN, "upninitgr@upndomain.test");
2255 1 : assert_int_equal(ret, EOK);
2256 :
2257 1 : ret = sysdb_add_user(nss_test_ctx->tctx->dom,
2258 : "testinitgr", 321, 654, "test initgroups",
2259 : "/home/testinitgr", "/bin/sh", NULL,
2260 : attrs, 300, 0);
2261 1 : assert_int_equal(ret, EOK);
2262 :
2263 1 : ret = sysdb_add_group(nss_test_ctx->tctx->dom,
2264 : "testinitgr_gr1", 3211,
2265 : NULL, 300, 0);
2266 1 : assert_int_equal(ret, EOK);
2267 :
2268 1 : ret = sysdb_add_group(nss_test_ctx->tctx->dom,
2269 : "testinitgr_gr2", 3212,
2270 : NULL, 300, 0);
2271 1 : assert_int_equal(ret, EOK);
2272 :
2273 1 : ret = sysdb_add_group_member(nss_test_ctx->tctx->dom,
2274 : "testinitgr_gr1", "testinitgr",
2275 : SYSDB_MEMBER_USER, false);
2276 1 : assert_int_equal(ret, EOK);
2277 :
2278 1 : ret = sysdb_add_group_member(nss_test_ctx->tctx->dom,
2279 : "testinitgr_gr2", "testinitgr",
2280 : SYSDB_MEMBER_USER, false);
2281 1 : assert_int_equal(ret, EOK);
2282 :
2283 1 : mock_input_user_or_group("testinitgr");
2284 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_INITGR);
2285 1 : mock_fill_initgr_user();
2286 :
2287 : /* Query for that user, call a callback when command finishes */
2288 1 : set_cmd_cb(test_nss_initgr_check);
2289 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_INITGR,
2290 1 : nss_test_ctx->nss_cmds);
2291 1 : assert_int_equal(ret, EOK);
2292 :
2293 : /* Wait until the test finishes with EOK */
2294 1 : ret = test_ev_loop(nss_test_ctx->tctx);
2295 1 : assert_int_equal(ret, EOK);
2296 1 : }
2297 :
2298 : /* Test that searching for a nonexistant user yields ENOENT.
2299 : * Account callback will be called
2300 : */
2301 2 : void test_initgr_neg_by_name(const char *name, bool is_upn)
2302 : {
2303 : errno_t ret;
2304 :
2305 2 : mock_input_user_or_group(name);
2306 2 : mock_account_recv_simple();
2307 :
2308 2 : assert_int_equal(nss_test_ctx->ncache_hits, 0);
2309 :
2310 2 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_INITGR,
2311 2 : nss_test_ctx->nss_cmds);
2312 2 : assert_int_equal(ret, EOK);
2313 :
2314 : /* Wait until the test finishes with ENOENT */
2315 2 : ret = test_ev_loop(nss_test_ctx->tctx);
2316 2 : assert_int_equal(ret, ENOENT);
2317 : /* UPN lookup will first hit negcache with the username */
2318 2 : assert_int_equal(nss_test_ctx->ncache_hits, is_upn ? 1 : 0);
2319 :
2320 : /* Test that subsequent search for a nonexistent user yields
2321 : * ENOENT and Account callback is not called, on the other hand
2322 : * the ncache functions will be called
2323 : */
2324 2 : nss_test_ctx->tctx->done = false;
2325 2 : nss_test_ctx->ncache_hits = 0;
2326 :
2327 2 : mock_input_user_or_group(name);
2328 2 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_INITGR,
2329 2 : nss_test_ctx->nss_cmds);
2330 2 : assert_int_equal(ret, EOK);
2331 :
2332 : /* Wait until the test finishes with ENOENT */
2333 2 : ret = test_ev_loop(nss_test_ctx->tctx);
2334 2 : assert_int_equal(ret, ENOENT);
2335 : /* Negative cache was hit this time */
2336 2 : assert_int_equal(nss_test_ctx->ncache_hits, 1);
2337 2 : }
2338 :
2339 1 : void test_nss_initgr_neg(void **state)
2340 : {
2341 1 : test_initgr_neg_by_name("testinitgr_neg", false);
2342 1 : }
2343 :
2344 1 : static int test_nss_initgr_search_acct_cb(void *pvt)
2345 : {
2346 : errno_t ret;
2347 : struct sysdb_attrs *attrs;
2348 :
2349 1 : attrs = sysdb_new_attrs(nss_test_ctx);
2350 1 : assert_non_null(attrs);
2351 :
2352 1 : ret = sysdb_attrs_add_time_t(attrs, SYSDB_INITGR_EXPIRE,
2353 1 : time(NULL) + 300);
2354 1 : assert_int_equal(ret, EOK);
2355 :
2356 1 : ret = sysdb_add_user(nss_test_ctx->tctx->dom,
2357 : "testinitgr_srch", 421, 654, "test initgroups",
2358 : "/home/testinitgr", "/bin/sh", NULL,
2359 : attrs, 300, 0);
2360 1 : assert_int_equal(ret, EOK);
2361 :
2362 1 : ret = sysdb_add_group(nss_test_ctx->tctx->dom,
2363 : "testinitgr_srch_gr1", 4211,
2364 : NULL, 300, 0);
2365 1 : assert_int_equal(ret, EOK);
2366 :
2367 1 : ret = sysdb_add_group(nss_test_ctx->tctx->dom,
2368 : "testinitgr_srch_gr2", 4212,
2369 : NULL, 300, 0);
2370 1 : assert_int_equal(ret, EOK);
2371 :
2372 1 : ret = sysdb_add_group_member(nss_test_ctx->tctx->dom,
2373 : "testinitgr_srch_gr1", "testinitgr_srch",
2374 : SYSDB_MEMBER_USER, false);
2375 1 : assert_int_equal(ret, EOK);
2376 :
2377 1 : ret = sysdb_add_group_member(nss_test_ctx->tctx->dom,
2378 : "testinitgr_srch_gr2", "testinitgr_srch",
2379 : SYSDB_MEMBER_USER, false);
2380 1 : assert_int_equal(ret, EOK);
2381 :
2382 :
2383 1 : return EOK;
2384 : }
2385 :
2386 1 : static int test_nss_initgr_search_check(uint32_t status,
2387 : uint8_t *body, size_t blen)
2388 : {
2389 1 : gid_t expected_gids[] = { 4211, 4212 };
2390 :
2391 1 : assert_int_equal(status, EOK);
2392 1 : check_initgr_packet(body, blen, expected_gids, N_ELEMENTS(expected_gids));
2393 1 : return EOK;
2394 : }
2395 :
2396 1 : void test_nss_initgr_search(void **state)
2397 : {
2398 : errno_t ret;
2399 : struct ldb_result *res;
2400 :
2401 1 : mock_input_user_or_group("testinitgr_srch");
2402 1 : mock_account_recv(0, 0, NULL, test_nss_initgr_search_acct_cb, nss_test_ctx);
2403 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_INITGR);
2404 1 : mock_fill_initgr_user();
2405 1 : set_cmd_cb(test_nss_initgr_search_check);
2406 :
2407 1 : ret = sysdb_getpwnam(nss_test_ctx, nss_test_ctx->tctx->dom,
2408 : "testinitgr_srch", &res);
2409 1 : assert_int_equal(ret, EOK);
2410 1 : assert_int_equal(res->count, 0);
2411 :
2412 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_INITGR,
2413 1 : nss_test_ctx->nss_cmds);
2414 1 : assert_int_equal(ret, EOK);
2415 :
2416 : /* Wait until the test finishes with EOK */
2417 1 : ret = test_ev_loop(nss_test_ctx->tctx);
2418 1 : assert_int_equal(ret, EOK);
2419 :
2420 : /* test_nss_getpwnam_search_check will check the user attributes */
2421 1 : ret = sysdb_getpwnam(nss_test_ctx, nss_test_ctx->tctx->dom,
2422 : "testinitgr_srch", &res);
2423 1 : assert_int_equal(ret, EOK);
2424 1 : assert_int_equal(res->count, 1);
2425 1 : }
2426 :
2427 1 : static int test_nss_initgr_update_acct_cb(void *pvt)
2428 : {
2429 : errno_t ret;
2430 : struct sysdb_attrs *attrs;
2431 :
2432 1 : attrs = sysdb_new_attrs(nss_test_ctx);
2433 1 : assert_non_null(attrs);
2434 :
2435 1 : ret = sysdb_attrs_add_time_t(attrs, SYSDB_INITGR_EXPIRE,
2436 1 : time(NULL) + 300);
2437 1 : assert_int_equal(ret, EOK);
2438 :
2439 1 : ret = sysdb_set_user_attr(nss_test_ctx->tctx->dom,
2440 : "testinitgr_update",
2441 : attrs, SYSDB_MOD_REP);
2442 1 : assert_int_equal(ret, EOK);
2443 :
2444 1 : ret = sysdb_add_group(nss_test_ctx->tctx->dom,
2445 : "testinitgr_check_gr2", 5212,
2446 : NULL, 300, 0);
2447 1 : assert_int_equal(ret, EOK);
2448 :
2449 1 : ret = sysdb_add_group_member(nss_test_ctx->tctx->dom,
2450 : "testinitgr_check_gr2",
2451 : "testinitgr_update",
2452 : SYSDB_MEMBER_USER, false);
2453 1 : assert_int_equal(ret, EOK);
2454 :
2455 1 : return EOK;
2456 : }
2457 :
2458 1 : static int test_nss_initgr_update_check(uint32_t status, uint8_t *body, size_t blen)
2459 : {
2460 1 : gid_t expected_gids[] = { 5211, 5212 };
2461 :
2462 1 : assert_int_equal(status, EOK);
2463 1 : check_initgr_packet(body, blen, expected_gids, N_ELEMENTS(expected_gids));
2464 1 : return EOK;
2465 : }
2466 :
2467 1 : void test_nss_initgr_update(void **state)
2468 : {
2469 : errno_t ret;
2470 : struct sysdb_attrs *attrs;
2471 :
2472 1 : attrs = sysdb_new_attrs(nss_test_ctx);
2473 1 : assert_non_null(attrs);
2474 :
2475 1 : ret = sysdb_attrs_add_time_t(attrs, SYSDB_INITGR_EXPIRE,
2476 1 : time(NULL) - 1);
2477 1 : assert_int_equal(ret, EOK);
2478 :
2479 1 : ret = sysdb_add_user(nss_test_ctx->tctx->dom,
2480 : "testinitgr_update", 521, 654, "test initgroups",
2481 : "/home/testinitgr", "/bin/sh", NULL,
2482 : attrs, 300, 0);
2483 1 : assert_int_equal(ret, EOK);
2484 :
2485 1 : ret = sysdb_add_group(nss_test_ctx->tctx->dom,
2486 : "testinitgr_update_gr1", 5211,
2487 : NULL, 300, 0);
2488 1 : assert_int_equal(ret, EOK);
2489 :
2490 1 : ret = sysdb_add_group_member(nss_test_ctx->tctx->dom,
2491 : "testinitgr_update_gr1", "testinitgr_update",
2492 : SYSDB_MEMBER_USER, false);
2493 1 : assert_int_equal(ret, EOK);
2494 :
2495 1 : mock_input_user_or_group("testinitgr_update");
2496 1 : mock_account_recv(0, 0, NULL, test_nss_initgr_update_acct_cb, nss_test_ctx);
2497 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_INITGR);
2498 1 : mock_fill_initgr_user();
2499 1 : set_cmd_cb(test_nss_initgr_update_check);
2500 :
2501 :
2502 : /* Query for that user, call a callback when command finishes */
2503 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_INITGR,
2504 1 : nss_test_ctx->nss_cmds);
2505 1 : assert_int_equal(ret, EOK);
2506 :
2507 : /* Wait until the test finishes with EOK */
2508 1 : ret = test_ev_loop(nss_test_ctx->tctx);
2509 1 : assert_int_equal(ret, EOK);
2510 1 : }
2511 :
2512 1 : static int test_nss_initgr_update_acct_2expire_attributes_cb(void *pvt)
2513 : {
2514 : errno_t ret;
2515 : struct sysdb_attrs *attrs;
2516 :
2517 1 : attrs = sysdb_new_attrs(nss_test_ctx);
2518 1 : assert_non_null(attrs);
2519 :
2520 1 : ret = sysdb_attrs_add_time_t(attrs, SYSDB_INITGR_EXPIRE,
2521 1 : time(NULL) + 300);
2522 1 : assert_int_equal(ret, EOK);
2523 :
2524 1 : ret = sysdb_set_user_attr(nss_test_ctx->tctx->dom,
2525 : "testinitgr_2attr",
2526 : attrs, SYSDB_MOD_REP);
2527 1 : assert_int_equal(ret, EOK);
2528 :
2529 1 : ret = sysdb_add_group(nss_test_ctx->tctx->dom,
2530 : "testinitgr_2attr_gr12", 5222,
2531 : NULL, 300, 0);
2532 1 : assert_int_equal(ret, EOK);
2533 :
2534 1 : ret = sysdb_add_group_member(nss_test_ctx->tctx->dom,
2535 : "testinitgr_2attr_gr12",
2536 : "testinitgr_2attr",
2537 : SYSDB_MEMBER_USER, false);
2538 1 : assert_int_equal(ret, EOK);
2539 :
2540 1 : return EOK;
2541 : }
2542 :
2543 1 : static int test_nss_initgr_update_2expire_attributes_check(uint32_t status,
2544 : uint8_t *body,
2545 : size_t blen)
2546 : {
2547 1 : gid_t expected_gids[] = { 5221, 5222 };
2548 :
2549 1 : assert_int_equal(status, EOK);
2550 1 : check_initgr_packet(body, blen, expected_gids, N_ELEMENTS(expected_gids));
2551 1 : return EOK;
2552 : }
2553 :
2554 : /*
2555 : * SYSDB_INITGR_EXPIRE has default value 0 => initgroups was not finished.
2556 : * SYSDB_CACHE_EXPIRE has value from future => getpwnam finished successfully
2557 : *
2558 : * Test result: DP should be contacted for update.
2559 : */
2560 1 : void test_nss_initgr_update_two_expire_attributes(void **state)
2561 : {
2562 : errno_t ret;
2563 : struct sysdb_attrs *attrs;
2564 :
2565 1 : attrs = sysdb_new_attrs(nss_test_ctx);
2566 1 : assert_non_null(attrs);
2567 :
2568 1 : ret = sysdb_attrs_add_time_t(attrs, SYSDB_INITGR_EXPIRE,
2569 : 0);
2570 1 : assert_int_equal(ret, EOK);
2571 :
2572 1 : ret = sysdb_attrs_add_time_t(attrs, SYSDB_CACHE_EXPIRE,
2573 1 : time(NULL) + 100);
2574 1 : assert_int_equal(ret, EOK);
2575 :
2576 1 : ret = sysdb_add_user(nss_test_ctx->tctx->dom,
2577 : "testinitgr_2attr", 522, 655, "test initgroups2",
2578 : "/home/testinitgr_2attr", "/bin/sh", NULL,
2579 : attrs, 300, 0);
2580 1 : assert_int_equal(ret, EOK);
2581 :
2582 1 : ret = sysdb_add_group(nss_test_ctx->tctx->dom,
2583 : "testinitgr_2attr_gr11", 5221,
2584 : NULL, 300, 0);
2585 1 : assert_int_equal(ret, EOK);
2586 :
2587 1 : ret = sysdb_add_group_member(nss_test_ctx->tctx->dom,
2588 : "testinitgr_2attr_gr11", "testinitgr_2attr",
2589 : SYSDB_MEMBER_USER, false);
2590 1 : assert_int_equal(ret, EOK);
2591 :
2592 1 : mock_input_user_or_group("testinitgr_2attr");
2593 1 : mock_account_recv(0, 0, NULL,
2594 : test_nss_initgr_update_acct_2expire_attributes_cb,
2595 : nss_test_ctx);
2596 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_INITGR);
2597 1 : mock_fill_initgr_user();
2598 1 : set_cmd_cb(test_nss_initgr_update_2expire_attributes_check);
2599 :
2600 : /* Query for that user, call a callback when command finishes */
2601 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_INITGR,
2602 1 : nss_test_ctx->nss_cmds);
2603 1 : assert_int_equal(ret, EOK);
2604 :
2605 : /* Wait until the test finishes with EOK */
2606 1 : ret = test_ev_loop(nss_test_ctx->tctx);
2607 1 : assert_int_equal(ret, EOK);
2608 1 : }
2609 :
2610 1 : void test_nss_initgroups_upn(void **state)
2611 : {
2612 : errno_t ret;
2613 :
2614 1 : mock_input_user_or_group("upninitgr@upndomain.test");
2615 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_INITGR);
2616 1 : mock_fill_initgr_user();
2617 :
2618 : /* Query for that user, call a callback when command finishes */
2619 1 : set_cmd_cb(test_nss_initgr_check);
2620 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_INITGR,
2621 1 : nss_test_ctx->nss_cmds);
2622 1 : assert_int_equal(ret, EOK);
2623 :
2624 : /* Wait until the test finishes with EOK */
2625 1 : ret = test_ev_loop(nss_test_ctx->tctx);
2626 1 : assert_int_equal(ret, EOK);
2627 1 : }
2628 :
2629 : /* Test that searching for a nonexistant user yields ENOENT.
2630 : * Account callback will be called
2631 : */
2632 1 : void test_nss_initgr_neg_upn(void **state)
2633 : {
2634 1 : test_initgr_neg_by_name("upninitgr_neg@upndomain.test", true);
2635 1 : }
2636 :
2637 39 : static int nss_test_setup(void **state)
2638 : {
2639 39 : struct sss_test_conf_param params[] = {
2640 : { "enumerate", "false" },
2641 : { NULL, NULL }, /* Sentinel */
2642 : };
2643 :
2644 39 : test_nss_setup(params, state);
2645 39 : return 0;
2646 : }
2647 :
2648 2 : static int nss_fqdn_test_setup(void **state)
2649 : {
2650 2 : struct sss_test_conf_param params[] = {
2651 : { "enumerate", "false" },
2652 : { "full_name_format", "%1$s@%2$s" },
2653 : { NULL, NULL }, /* Sentinel */
2654 : };
2655 :
2656 2 : test_nss_setup(params, state);
2657 2 : return 0;
2658 : }
2659 :
2660 2 : static int nss_test_setup_extra_attr(void **state)
2661 : {
2662 2 : struct sss_test_conf_param params[] = {
2663 : { "enumerate", "false" },
2664 : { NULL, NULL }, /* Sentinel */
2665 : };
2666 :
2667 2 : test_nss_setup(params, state);
2668 :
2669 2 : nss_test_ctx->nctx->extra_attributes = global_extra_attrs;
2670 2 : return 0;
2671 : }
2672 :
2673 4 : static int nss_subdom_test_setup(void **state)
2674 : {
2675 : const char *const testdom[4] = { TEST_SUBDOM_NAME, "TEST.SUB", "test", "S-3" };
2676 : struct sss_domain_info *subdomain;
2677 : errno_t ret;
2678 :
2679 4 : nss_test_setup(state);
2680 :
2681 4 : subdomain = new_subdomain(nss_test_ctx, nss_test_ctx->tctx->dom,
2682 : testdom[0], testdom[1], testdom[2], testdom[3],
2683 : false, false, NULL, 0);
2684 4 : assert_non_null(subdomain);
2685 :
2686 4 : ret = sysdb_subdomain_store(nss_test_ctx->tctx->sysdb,
2687 : testdom[0], testdom[1], testdom[2], testdom[3],
2688 : false, false, NULL, 0);
2689 4 : assert_int_equal(ret, EOK);
2690 :
2691 4 : ret = sysdb_update_subdomains(nss_test_ctx->tctx->dom);
2692 4 : assert_int_equal(ret, EOK);
2693 :
2694 4 : nss_test_ctx->subdom = subdomain;
2695 4 : return 0;
2696 : }
2697 :
2698 1 : static int nss_fqdn_fancy_test_setup(void **state)
2699 : {
2700 1 : struct sss_test_conf_param params[] = {
2701 : { "enumerate", "false" },
2702 : { "full_name_format", "%1$s@@@@@%2$s" },
2703 : { NULL, NULL }, /* Sentinel */
2704 : };
2705 :
2706 1 : test_nss_setup(params, state);
2707 1 : return 0;
2708 : }
2709 :
2710 44 : static int nss_test_teardown(void **state)
2711 : {
2712 44 : talloc_free(nss_test_ctx);
2713 44 : return 0;
2714 : }
2715 :
2716 1 : static int test_nss_getnamebysid_check(uint32_t status, uint8_t *body, size_t blen)
2717 : {
2718 1 : size_t rp = 2 * sizeof(uint32_t); /* num_results and reserved */
2719 : uint32_t id_type;
2720 : const char *name;
2721 :
2722 1 : assert_int_equal(status, EOK);
2723 :
2724 1 : SAFEALIGN_COPY_UINT32(&id_type, body+rp, &rp);
2725 1 : assert_int_equal(id_type, SSS_ID_TYPE_UID);
2726 :
2727 1 : name = (const char *) body + rp;
2728 1 : assert_string_equal(name, "testsiduser");
2729 :
2730 1 : return EOK;
2731 : }
2732 :
2733 1 : static void test_nss_getnamebysid(void **state)
2734 : {
2735 : errno_t ret;
2736 : struct sysdb_attrs *attrs;
2737 : char *user_sid;
2738 :
2739 1 : attrs = sysdb_new_attrs(nss_test_ctx);
2740 1 : assert_non_null(attrs);
2741 :
2742 1 : user_sid = talloc_asprintf(attrs, "%s-500",
2743 1 : nss_test_ctx->tctx->dom->domain_id);
2744 1 : assert_non_null(user_sid);
2745 :
2746 1 : ret = sysdb_attrs_add_string(attrs, SYSDB_SID_STR, user_sid);
2747 1 : assert_int_equal(ret, EOK);
2748 :
2749 : /* Prime the cache with a valid user */
2750 1 : ret = sysdb_add_user(nss_test_ctx->tctx->dom,
2751 : "testsiduser", 12345, 6890, "test sid user",
2752 : "/home/testsiduser", "/bin/sh", NULL,
2753 : attrs, 300, 0);
2754 1 : assert_int_equal(ret, EOK);
2755 :
2756 1 : mock_input_user_or_group(user_sid);
2757 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETNAMEBYSID);
2758 1 : mock_fill_bysid();
2759 :
2760 : /* Query for that user, call a callback when command finishes */
2761 : /* Should go straight to back end, without contacting DP */
2762 1 : set_cmd_cb(test_nss_getnamebysid_check);
2763 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETNAMEBYSID,
2764 1 : nss_test_ctx->nss_cmds);
2765 1 : assert_int_equal(ret, EOK);
2766 :
2767 : /* Wait until the test finishes with EOK */
2768 1 : ret = test_ev_loop(nss_test_ctx->tctx);
2769 1 : assert_int_equal(ret, EOK);
2770 1 : }
2771 :
2772 : /* Test that searching for a nonexistant user yields ENOENT.
2773 : * Account callback will be called
2774 : */
2775 1 : void test_nss_getnamebysid_neg(void **state)
2776 : {
2777 : errno_t ret;
2778 : char *user_sid;
2779 :
2780 1 : user_sid = talloc_asprintf(nss_test_ctx, "%s-499",
2781 1 : nss_test_ctx->tctx->dom->domain_id);
2782 1 : assert_non_null(user_sid);
2783 :
2784 1 : mock_input_user_or_group(user_sid);
2785 1 : mock_account_recv_simple();
2786 :
2787 1 : assert_int_equal(nss_test_ctx->ncache_hits, 0);
2788 :
2789 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETNAMEBYSID,
2790 1 : nss_test_ctx->nss_cmds);
2791 1 : assert_int_equal(ret, EOK);
2792 :
2793 : /* Wait until the test finishes with ENOENT */
2794 1 : ret = test_ev_loop(nss_test_ctx->tctx);
2795 1 : assert_int_equal(ret, ENOENT);
2796 1 : assert_int_equal(nss_test_ctx->ncache_hits, 0);
2797 :
2798 : /* Test that subsequent search for a nonexistent user yields
2799 : * ENOENT and Account callback is not called, on the other hand
2800 : * the ncache functions will be called
2801 : */
2802 1 : nss_test_ctx->tctx->done = false;
2803 :
2804 1 : mock_input_user_or_group(user_sid);
2805 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETNAMEBYSID,
2806 1 : nss_test_ctx->nss_cmds);
2807 1 : assert_int_equal(ret, EOK);
2808 :
2809 : /* Wait until the test finishes with ENOENT */
2810 1 : ret = test_ev_loop(nss_test_ctx->tctx);
2811 1 : assert_int_equal(ret, ENOENT);
2812 : /* Negative cache was hit this time */
2813 1 : assert_int_equal(nss_test_ctx->ncache_hits, 1);
2814 1 : }
2815 :
2816 1 : static int test_nss_getnamebysid_update_check(uint32_t status,
2817 : uint8_t *body,
2818 : size_t blen)
2819 : {
2820 1 : size_t rp = 2 * sizeof(uint32_t); /* num_results and reserved */
2821 : uint32_t id_type;
2822 : const char *name;
2823 :
2824 1 : assert_int_equal(status, EOK);
2825 :
2826 1 : SAFEALIGN_COPY_UINT32(&id_type, body+rp, &rp);
2827 1 : assert_int_equal(id_type, SSS_ID_TYPE_UID);
2828 :
2829 1 : name = (const char *) body + rp;
2830 1 : assert_string_equal(name, "testsidbyname_update");
2831 :
2832 1 : return EOK;
2833 : }
2834 :
2835 1 : static int test_nss_getnamebysid_update_acct_cb(void *pvt)
2836 : {
2837 : errno_t ret;
2838 1 : struct nss_test_ctx *ctx = talloc_get_type(pvt, struct nss_test_ctx);
2839 :
2840 1 : ret = sysdb_store_user(ctx->tctx->dom, "testsidbyname_update", NULL,
2841 : 123456, 789, "test user",
2842 : "/home/testsidbyname_update", "/bin/ksh", NULL,
2843 : NULL, NULL, 300, 0);
2844 1 : assert_int_equal(ret, EOK);
2845 :
2846 1 : return EOK;
2847 : }
2848 :
2849 1 : void test_nss_getnamebysid_update(void **state)
2850 : {
2851 : errno_t ret;
2852 : struct ldb_result *res;
2853 : struct sysdb_attrs *attrs;
2854 : const char *shell;
2855 : char *user_sid;
2856 :
2857 1 : attrs = sysdb_new_attrs(nss_test_ctx);
2858 1 : assert_non_null(attrs);
2859 :
2860 1 : user_sid = talloc_asprintf(attrs, "%s-123456",
2861 1 : nss_test_ctx->tctx->dom->domain_id);
2862 1 : assert_non_null(user_sid);
2863 :
2864 1 : ret = sysdb_attrs_add_string(attrs, SYSDB_SID_STR, user_sid);
2865 1 : assert_int_equal(ret, EOK);
2866 :
2867 : /* Prime the cache with a valid but expired user */
2868 1 : ret = sysdb_add_user(nss_test_ctx->tctx->dom,
2869 : "testsidbyname_update", 123456, 789, "test user",
2870 : "/home/testsidbyname_update", "/bin/sh", NULL,
2871 : attrs, 1, 1);
2872 1 : assert_int_equal(ret, EOK);
2873 :
2874 : /* Mock client input */
2875 1 : mock_input_user_or_group(user_sid);
2876 : /* Mock client command */
2877 1 : will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETNAMEBYSID);
2878 : /* Call this function when user is updated by the mock DP request */
2879 1 : mock_account_recv(0, 0, NULL, test_nss_getnamebysid_update_acct_cb,
2880 : nss_test_ctx);
2881 : /* Call this function to check what the responder returned to the client */
2882 1 : set_cmd_cb(test_nss_getnamebysid_update_check);
2883 : /* Mock output buffer */
2884 1 : mock_fill_bysid();
2885 :
2886 : /* Fire the command */
2887 1 : ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETNAMEBYSID,
2888 1 : nss_test_ctx->nss_cmds);
2889 1 : assert_int_equal(ret, EOK);
2890 :
2891 : /* Wait until the test finishes with EOK */
2892 1 : ret = test_ev_loop(nss_test_ctx->tctx);
2893 1 : assert_int_equal(ret, EOK);
2894 :
2895 : /* Check the user was updated in the cache */
2896 1 : ret = sysdb_getpwnam(nss_test_ctx, nss_test_ctx->tctx->dom,
2897 : "testsidbyname_update", &res);
2898 1 : assert_int_equal(ret, EOK);
2899 1 : assert_int_equal(res->count, 1);
2900 :
2901 1 : shell = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SHELL, NULL);
2902 1 : assert_string_equal(shell, "/bin/ksh");
2903 1 : }
2904 :
2905 1 : int main(int argc, const char *argv[])
2906 : {
2907 : int rv;
2908 1 : int no_cleanup = 0;
2909 : poptContext pc;
2910 : int opt;
2911 7 : struct poptOption long_options[] = {
2912 : POPT_AUTOHELP
2913 5 : SSSD_DEBUG_OPTS
2914 : {"no-cleanup", 'n', POPT_ARG_NONE, &no_cleanup, 0,
2915 1 : _("Do not delete the test database after a test run"), NULL },
2916 : POPT_TABLEEND
2917 : };
2918 :
2919 1 : const struct CMUnitTest tests[] = {
2920 : cmocka_unit_test_setup_teardown(test_nss_getpwnam,
2921 : nss_test_setup, nss_test_teardown),
2922 : cmocka_unit_test_setup_teardown(test_nss_getpwuid,
2923 : nss_test_setup, nss_test_teardown),
2924 : cmocka_unit_test_setup_teardown(test_nss_getpwnam_neg,
2925 : nss_test_setup, nss_test_teardown),
2926 : cmocka_unit_test_setup_teardown(test_nss_getpwuid_neg,
2927 : nss_test_setup, nss_test_teardown),
2928 : cmocka_unit_test_setup_teardown(test_nss_getpwnam_search,
2929 : nss_test_setup, nss_test_teardown),
2930 : cmocka_unit_test_setup_teardown(test_nss_getpwuid_search,
2931 : nss_test_setup,
2932 : nss_test_teardown),
2933 : cmocka_unit_test_setup_teardown(test_nss_getpwnam_update,
2934 : nss_test_setup, nss_test_teardown),
2935 : cmocka_unit_test_setup_teardown(test_nss_getpwuid_update,
2936 : nss_test_setup, nss_test_teardown),
2937 : cmocka_unit_test_setup_teardown(test_nss_getpwnam_fqdn,
2938 : nss_fqdn_test_setup,
2939 : nss_test_teardown),
2940 : cmocka_unit_test_setup_teardown(test_nss_getpwnam_fqdn_fancy,
2941 : nss_fqdn_fancy_test_setup,
2942 : nss_test_teardown),
2943 : cmocka_unit_test_setup_teardown(test_nss_getpwnam_space,
2944 : nss_test_setup, nss_test_teardown),
2945 : cmocka_unit_test_setup_teardown(test_nss_getpwnam_space_sub,
2946 : nss_test_setup, nss_test_teardown),
2947 : cmocka_unit_test_setup_teardown(test_nss_getpwnam_space_sub_query,
2948 : nss_test_setup, nss_test_teardown),
2949 : cmocka_unit_test_setup_teardown(test_nss_getgrnam_no_members,
2950 : nss_test_setup, nss_test_teardown),
2951 : cmocka_unit_test_setup_teardown(test_nss_getgrnam_members,
2952 : nss_test_setup, nss_test_teardown),
2953 : cmocka_unit_test_setup_teardown(test_nss_getgrnam_members_fqdn,
2954 : nss_fqdn_test_setup, nss_test_teardown),
2955 : cmocka_unit_test_setup_teardown(test_nss_getgrnam_members_subdom,
2956 : nss_subdom_test_setup,
2957 : nss_test_teardown),
2958 : cmocka_unit_test_setup_teardown(test_nss_getgrnam_mix_dom,
2959 : nss_subdom_test_setup,
2960 : nss_test_teardown),
2961 : cmocka_unit_test_setup_teardown(test_nss_getgrnam_mix_dom_fqdn,
2962 : nss_subdom_test_setup,
2963 : nss_test_teardown),
2964 : cmocka_unit_test_setup_teardown(test_nss_getgrnam_mix_subdom,
2965 : nss_subdom_test_setup,
2966 : nss_test_teardown),
2967 : cmocka_unit_test_setup_teardown(test_nss_getgrnam_space,
2968 : nss_test_setup, nss_test_teardown),
2969 : cmocka_unit_test_setup_teardown(test_nss_getgrnam_space_sub,
2970 : nss_test_setup, nss_test_teardown),
2971 : cmocka_unit_test_setup_teardown(test_nss_well_known_getnamebysid,
2972 : nss_test_setup, nss_test_teardown),
2973 : cmocka_unit_test_setup_teardown(test_nss_well_known_getnamebysid_special,
2974 : nss_test_setup, nss_test_teardown),
2975 : cmocka_unit_test_setup_teardown(test_nss_well_known_getnamebysid_non_existing,
2976 : nss_test_setup, nss_test_teardown),
2977 : cmocka_unit_test_setup_teardown(test_nss_well_known_getidbysid_failure,
2978 : nss_test_setup, nss_test_teardown),
2979 : cmocka_unit_test_setup_teardown(test_nss_well_known_getsidbyname,
2980 : nss_test_setup, nss_test_teardown),
2981 : cmocka_unit_test_setup_teardown(test_nss_well_known_getsidbyname_nonexisting,
2982 : nss_test_setup, nss_test_teardown),
2983 : cmocka_unit_test_setup_teardown(test_nss_well_known_getsidbyname_special,
2984 : nss_test_setup, nss_test_teardown),
2985 : cmocka_unit_test_setup_teardown(test_nss_getorigbyname,
2986 : nss_test_setup,
2987 : nss_test_teardown),
2988 : cmocka_unit_test_setup_teardown(test_nss_getorigbyname_extra_attrs,
2989 : nss_test_setup_extra_attr,
2990 : nss_test_teardown),
2991 : cmocka_unit_test_setup_teardown(test_nss_getorigbyname_multi_value_attrs,
2992 : nss_test_setup_extra_attr,
2993 : nss_test_teardown),
2994 : cmocka_unit_test_setup_teardown(test_nss_getpwnam_upn,
2995 : nss_test_setup, nss_test_teardown),
2996 : cmocka_unit_test_setup_teardown(test_nss_getpwnam_upn_neg,
2997 : nss_test_setup, nss_test_teardown),
2998 : cmocka_unit_test_setup_teardown(test_nss_initgroups,
2999 : nss_test_setup, nss_test_teardown),
3000 : cmocka_unit_test_setup_teardown(test_nss_initgr_neg,
3001 : nss_test_setup, nss_test_teardown),
3002 : cmocka_unit_test_setup_teardown(test_nss_initgr_search,
3003 : nss_test_setup, nss_test_teardown),
3004 : cmocka_unit_test_setup_teardown(test_nss_initgr_update,
3005 : nss_test_setup, nss_test_teardown),
3006 : cmocka_unit_test_setup_teardown(test_nss_initgr_update_two_expire_attributes,
3007 : nss_test_setup, nss_test_teardown),
3008 : cmocka_unit_test_setup_teardown(test_nss_initgroups_upn,
3009 : nss_test_setup, nss_test_teardown),
3010 : cmocka_unit_test_setup_teardown(test_nss_initgr_neg_upn,
3011 : nss_test_setup, nss_test_teardown),
3012 : cmocka_unit_test_setup_teardown(test_nss_getnamebysid,
3013 : nss_test_setup, nss_test_teardown),
3014 : cmocka_unit_test_setup_teardown(test_nss_getnamebysid_neg,
3015 : nss_test_setup, nss_test_teardown),
3016 : cmocka_unit_test_setup_teardown(test_nss_getnamebysid_update,
3017 : nss_test_setup, nss_test_teardown),
3018 : };
3019 :
3020 : /* Set debug level to invalid value so we can deside if -d 0 was used. */
3021 1 : debug_level = SSSDBG_INVALID;
3022 :
3023 1 : pc = poptGetContext(argv[0], argc, argv, long_options, 0);
3024 1 : while((opt = poptGetNextOpt(pc)) != -1) {
3025 : switch(opt) {
3026 : default:
3027 0 : fprintf(stderr, "\nInvalid option %s: %s\n\n",
3028 : poptBadOption(pc, 0), poptStrerror(opt));
3029 0 : poptPrintUsage(pc, stderr, 0);
3030 0 : return 1;
3031 : }
3032 : }
3033 1 : poptFreeContext(pc);
3034 :
3035 1 : DEBUG_CLI_INIT(debug_level);
3036 :
3037 : /* Even though normally the tests should clean up after themselves
3038 : * they might not after a failed run. Remove the old db to be sure */
3039 1 : tests_set_cwd();
3040 1 : test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME);
3041 1 : test_dom_suite_setup(TESTS_PATH);
3042 :
3043 1 : rv = cmocka_run_group_tests(tests, NULL, NULL);
3044 1 : if (rv == 0 && !no_cleanup) {
3045 1 : test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME);
3046 : }
3047 1 : return rv;
3048 : }
|