Line data Source code
1 : /*
2 : Authors:
3 : Pavel Březina <pbrezina@redhat.com>
4 :
5 : Copyright (C) 2013 Red Hat
6 :
7 : This program is free software; you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3 of the License, or
10 : (at your option) any later version.
11 :
12 : This program is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with this program. If not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include <talloc.h>
22 : #include <tevent.h>
23 : #include <errno.h>
24 : #include <popt.h>
25 :
26 : #include "tests/cmocka/common_mock.h"
27 : #include "tests/cmocka/common_mock_sdap.h"
28 : #include "tests/cmocka/common_mock_be.h"
29 : #include "tests/cmocka/common_mock_sysdb_objects.h"
30 : #include "providers/ldap/ldap_common.h"
31 : #include "providers/ldap/sdap.h"
32 : #include "providers/ldap/sdap_idmap.h"
33 : #include "providers/ldap/sdap_async_private.h"
34 :
35 : #define TESTS_PATH "tp_" BASE_FILE_STEM
36 : #define TEST_CONF_DB "test_ldap_nested_groups_conf.ldb"
37 : #define TEST_DOM_NAME "ldap_nested_groups_test"
38 : #define TEST_ID_PROVIDER "ldap"
39 :
40 : #define new_test(test) \
41 : cmocka_unit_test_setup_teardown(nested_groups_test_ ## test, \
42 : nested_groups_test_setup, \
43 : nested_groups_test_teardown)
44 :
45 : /* put users and groups under the same container so we can easily run the
46 : * same tests cases for several search base scenarios */
47 : #define OBJECT_BASE_DN "cn=objects,dc=test,dc=com"
48 : #define GROUP_BASE_DN "cn=groups," OBJECT_BASE_DN
49 : #define USER_BASE_DN "cn=users," OBJECT_BASE_DN
50 :
51 : struct nested_groups_test_ctx {
52 : struct sss_test_ctx *tctx;
53 :
54 : struct be_ctx *be_ctx;
55 : struct sdap_options *sdap_opts;
56 : struct sdap_handle *sdap_handle;
57 : struct sdap_domain *sdap_domain;
58 : struct sdap_idmap_ctx *idmap_ctx;
59 : struct sdap_id_ctx *sdap_id_ctx;
60 :
61 : struct sysdb_attrs **users;
62 : struct sysdb_attrs **groups;
63 : unsigned long num_users;
64 : unsigned long num_groups;
65 : };
66 :
67 7 : errno_t krb5_try_kdcip(struct confdb_ctx *cdb,
68 : const char *conf_path,
69 : struct dp_option *opts,
70 : int opt_id)
71 : {
72 7 : return EOK;
73 : }
74 :
75 : /* Both arrays must have the same length! */
76 5 : static void compare_sysdb_string_array_noorder(struct sysdb_attrs **sysdb_array,
77 : const char **string_array,
78 : size_t len)
79 : {
80 : int i, ii;
81 : errno_t ret;
82 : const char *name;
83 :
84 : /* Check the returned groups. The order is irrelevant. */
85 18 : for (i = 0; i < len; i++) {
86 13 : ret = sysdb_attrs_get_string(sysdb_array[i], SYSDB_NAME, &name);
87 13 : assert_int_equal(ret, ERR_OK);
88 :
89 24 : for (ii = 0; ii < len; ii++) {
90 24 : if (string_array[ii] == NULL) {
91 7 : continue;
92 : }
93 17 : if (strcmp(name, string_array[ii]) == 0) {
94 13 : string_array[ii] = NULL;
95 13 : break;
96 : }
97 : }
98 : }
99 :
100 18 : for (i = 0; i < len; i++) {
101 13 : assert_null(string_array[i]);
102 : }
103 5 : }
104 :
105 7 : static void nested_groups_test_done(struct tevent_req *req)
106 : {
107 7 : struct nested_groups_test_ctx *ctx = NULL;
108 :
109 7 : ctx = tevent_req_callback_data(req, struct nested_groups_test_ctx);
110 :
111 7 : ctx->tctx->error = sdap_nested_group_recv(ctx, req,
112 : &ctx->num_users, &ctx->users,
113 : &ctx->num_groups, &ctx->groups);
114 7 : talloc_zfree(req);
115 :
116 7 : ctx->tctx->done = true;
117 7 : }
118 :
119 1 : static void nested_groups_test_one_group_no_members(void **state)
120 : {
121 1 : struct nested_groups_test_ctx *test_ctx = NULL;
122 1 : struct sysdb_attrs *rootgroup = NULL;
123 1 : struct tevent_req *req = NULL;
124 1 : TALLOC_CTX *req_mem_ctx = NULL;
125 : errno_t ret;
126 :
127 1 : test_ctx = talloc_get_type_abort(*state, struct nested_groups_test_ctx);
128 :
129 1 : rootgroup = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN, 1000,
130 : "rootgroup", NULL);
131 :
132 : /* mock return values */
133 1 : sss_will_return_always(sdap_has_deref_support, false);
134 :
135 : /* run test, check for memory leaks */
136 1 : req_mem_ctx = talloc_new(global_talloc_context);
137 1 : assert_non_null(req_mem_ctx);
138 1 : check_leaks_push(req_mem_ctx);
139 :
140 1 : req = sdap_nested_group_send(req_mem_ctx, test_ctx->tctx->ev,
141 : test_ctx->sdap_domain, test_ctx->sdap_opts,
142 : test_ctx->sdap_handle, rootgroup);
143 1 : assert_non_null(req);
144 1 : tevent_req_set_callback(req, nested_groups_test_done, test_ctx);
145 :
146 1 : ret = test_ev_loop(test_ctx->tctx);
147 1 : assert_true(check_leaks_pop(req_mem_ctx) == true);
148 1 : talloc_zfree(req_mem_ctx);
149 : /* check return code */
150 1 : assert_int_equal(ret, ERR_OK);
151 :
152 : /* check generated values */
153 1 : assert_int_equal(test_ctx->num_users, 0);
154 1 : assert_null(test_ctx->users);
155 :
156 1 : assert_int_equal(test_ctx->num_groups, 1);
157 1 : assert_non_null(test_ctx->groups);
158 1 : assert_true(rootgroup == test_ctx->groups[0]);
159 1 : }
160 :
161 1 : static void nested_groups_test_one_group_unique_members(void **state)
162 : {
163 1 : struct nested_groups_test_ctx *test_ctx = NULL;
164 1 : struct sysdb_attrs *rootgroup = NULL;
165 1 : struct tevent_req *req = NULL;
166 1 : TALLOC_CTX *req_mem_ctx = NULL;
167 : errno_t ret;
168 1 : const char *users[] = { "cn=user1,"USER_BASE_DN,
169 : "cn=user2,"USER_BASE_DN,
170 : NULL };
171 1 : const struct sysdb_attrs *user1_reply[2] = { NULL };
172 1 : const struct sysdb_attrs *user2_reply[2] = { NULL };
173 1 : const char * expected[] = { "user1",
174 : "user2" };
175 :
176 :
177 1 : test_ctx = talloc_get_type_abort(*state, struct nested_groups_test_ctx);
178 :
179 : /* mock return values */
180 1 : rootgroup = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN, 1000,
181 : "rootgroup", users);
182 :
183 1 : user1_reply[0] = mock_sysdb_user(test_ctx, USER_BASE_DN, 2001, "user1");
184 1 : assert_non_null(user1_reply[0]);
185 1 : will_return(sdap_get_generic_recv, 1);
186 1 : will_return(sdap_get_generic_recv, user1_reply);
187 1 : will_return(sdap_get_generic_recv, ERR_OK);
188 :
189 1 : user2_reply[0] = mock_sysdb_user(test_ctx, USER_BASE_DN, 2002, "user2");
190 1 : assert_non_null(user2_reply[0]);
191 1 : will_return(sdap_get_generic_recv, 1);
192 1 : will_return(sdap_get_generic_recv, user2_reply);
193 1 : will_return(sdap_get_generic_recv, ERR_OK);
194 :
195 1 : sss_will_return_always(sdap_has_deref_support, false);
196 :
197 : /* run test, check for memory leaks */
198 1 : req_mem_ctx = talloc_new(global_talloc_context);
199 1 : assert_non_null(req_mem_ctx);
200 1 : check_leaks_push(req_mem_ctx);
201 :
202 1 : req = sdap_nested_group_send(req_mem_ctx, test_ctx->tctx->ev,
203 : test_ctx->sdap_domain, test_ctx->sdap_opts,
204 : test_ctx->sdap_handle, rootgroup);
205 1 : assert_non_null(req);
206 1 : tevent_req_set_callback(req, nested_groups_test_done, test_ctx);
207 :
208 1 : ret = test_ev_loop(test_ctx->tctx);
209 1 : assert_true(check_leaks_pop(req_mem_ctx) == true);
210 1 : talloc_zfree(req_mem_ctx);
211 :
212 : /* check return code */
213 1 : assert_int_equal(ret, ERR_OK);
214 :
215 : /* Check the users */
216 1 : assert_int_equal(test_ctx->num_users, N_ELEMENTS(expected));
217 1 : assert_int_equal(test_ctx->num_groups, 1);
218 :
219 1 : compare_sysdb_string_array_noorder(test_ctx->users,
220 : expected, N_ELEMENTS(expected));
221 1 : }
222 :
223 1 : static void nested_groups_test_one_group_dup_users(void **state)
224 : {
225 1 : struct nested_groups_test_ctx *test_ctx = NULL;
226 1 : struct sysdb_attrs *rootgroup = NULL;
227 1 : struct tevent_req *req = NULL;
228 1 : TALLOC_CTX *req_mem_ctx = NULL;
229 : errno_t ret;
230 : const char *name;
231 1 : const char *users[] = { "cn=user1,"USER_BASE_DN,
232 : "cn=user1,"USER_BASE_DN,
233 : NULL };
234 1 : const struct sysdb_attrs *user1_reply[2] = { NULL };
235 1 : const struct sysdb_attrs *user2_reply[2] = { NULL };
236 :
237 1 : test_ctx = talloc_get_type_abort(*state, struct nested_groups_test_ctx);
238 :
239 : /* mock return values */
240 1 : rootgroup = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN, 1000,
241 : "rootgroup", users);
242 :
243 1 : user1_reply[0] = mock_sysdb_user(test_ctx, USER_BASE_DN, 2001, "user1");
244 1 : assert_non_null(user1_reply[0]);
245 1 : will_return(sdap_get_generic_recv, 1);
246 1 : will_return(sdap_get_generic_recv, user1_reply);
247 1 : will_return(sdap_get_generic_recv, ERR_OK);
248 :
249 1 : user2_reply[0] = mock_sysdb_user(test_ctx, USER_BASE_DN, 2001, "user1");
250 1 : assert_non_null(user2_reply[0]);
251 1 : will_return(sdap_get_generic_recv, 1);
252 1 : will_return(sdap_get_generic_recv, user2_reply);
253 1 : will_return(sdap_get_generic_recv, ERR_OK);
254 :
255 1 : sss_will_return_always(sdap_has_deref_support, false);
256 :
257 : /* run test, check for memory leaks */
258 1 : req_mem_ctx = talloc_new(global_talloc_context);
259 1 : assert_non_null(req_mem_ctx);
260 1 : check_leaks_push(req_mem_ctx);
261 :
262 1 : req = sdap_nested_group_send(req_mem_ctx, test_ctx->tctx->ev,
263 : test_ctx->sdap_domain, test_ctx->sdap_opts,
264 : test_ctx->sdap_handle, rootgroup);
265 1 : assert_non_null(req);
266 1 : tevent_req_set_callback(req, nested_groups_test_done, test_ctx);
267 :
268 1 : ret = test_ev_loop(test_ctx->tctx);
269 1 : assert_true(check_leaks_pop(req_mem_ctx) == true);
270 1 : talloc_zfree(req_mem_ctx);
271 :
272 : /* check return code */
273 1 : assert_int_equal(ret, ERR_OK);
274 :
275 : /* Check the users */
276 1 : assert_int_equal(test_ctx->num_users, 1);
277 1 : assert_int_equal(test_ctx->num_groups, 1);
278 :
279 1 : ret = sysdb_attrs_get_string(test_ctx->users[0], SYSDB_NAME, &name);
280 1 : assert_int_equal(ret, ERR_OK);
281 1 : assert_string_equal(name, "user1");
282 1 : }
283 :
284 1 : static void nested_groups_test_one_group_unique_group_members(void **state)
285 : {
286 1 : struct nested_groups_test_ctx *test_ctx = NULL;
287 1 : struct sysdb_attrs *rootgroup = NULL;
288 1 : struct tevent_req *req = NULL;
289 1 : TALLOC_CTX *req_mem_ctx = NULL;
290 : errno_t ret;
291 1 : const char *groups[] = { "cn=emptygroup1,"GROUP_BASE_DN,
292 : "cn=emptygroup2,"GROUP_BASE_DN,
293 : NULL };
294 1 : const struct sysdb_attrs *group1_reply[2] = { NULL };
295 1 : const struct sysdb_attrs *group2_reply[2] = { NULL };
296 1 : const char * expected[] = { "rootgroup",
297 : "emptygroup1",
298 : "emptygroup2" };
299 :
300 1 : test_ctx = talloc_get_type_abort(*state, struct nested_groups_test_ctx);
301 :
302 : /* mock return values */
303 1 : rootgroup = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN, 1000,
304 : "rootgroup", groups);
305 :
306 1 : group1_reply[0] = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN,
307 : 1001, "emptygroup1", NULL);
308 1 : assert_non_null(group1_reply[0]);
309 1 : will_return(sdap_get_generic_recv, 1);
310 1 : will_return(sdap_get_generic_recv, group1_reply);
311 1 : will_return(sdap_get_generic_recv, ERR_OK);
312 :
313 1 : group2_reply[0] = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN,
314 : 1002, "emptygroup2", NULL);
315 1 : assert_non_null(group2_reply[0]);
316 1 : will_return(sdap_get_generic_recv, 1);
317 1 : will_return(sdap_get_generic_recv, group2_reply);
318 1 : will_return(sdap_get_generic_recv, ERR_OK);
319 :
320 1 : sss_will_return_always(sdap_has_deref_support, false);
321 :
322 : /* run test, check for memory leaks */
323 1 : req_mem_ctx = talloc_new(global_talloc_context);
324 1 : assert_non_null(req_mem_ctx);
325 1 : check_leaks_push(req_mem_ctx);
326 :
327 1 : req = sdap_nested_group_send(req_mem_ctx, test_ctx->tctx->ev,
328 : test_ctx->sdap_domain, test_ctx->sdap_opts,
329 : test_ctx->sdap_handle, rootgroup);
330 1 : assert_non_null(req);
331 1 : tevent_req_set_callback(req, nested_groups_test_done, test_ctx);
332 :
333 1 : ret = test_ev_loop(test_ctx->tctx);
334 1 : assert_true(check_leaks_pop(req_mem_ctx) == true);
335 1 : talloc_zfree(req_mem_ctx);
336 :
337 : /* check return code */
338 1 : assert_int_equal(ret, ERR_OK);
339 :
340 : /* Check the users */
341 1 : assert_int_equal(test_ctx->num_users, 0);
342 1 : assert_int_equal(test_ctx->num_groups, N_ELEMENTS(expected));
343 :
344 1 : compare_sysdb_string_array_noorder(test_ctx->groups,
345 : expected, N_ELEMENTS(expected));
346 1 : }
347 :
348 1 : static void nested_groups_test_one_group_dup_group_members(void **state)
349 : {
350 1 : struct nested_groups_test_ctx *test_ctx = NULL;
351 1 : struct sysdb_attrs *rootgroup = NULL;
352 1 : struct tevent_req *req = NULL;
353 1 : TALLOC_CTX *req_mem_ctx = NULL;
354 : errno_t ret;
355 1 : const char *groups[] = { "cn=emptygroup1,"GROUP_BASE_DN,
356 : "cn=emptygroup1,"GROUP_BASE_DN,
357 : NULL };
358 1 : const struct sysdb_attrs *group1_reply[2] = { NULL };
359 1 : const struct sysdb_attrs *group2_reply[2] = { NULL };
360 1 : const char * expected[] = { "rootgroup",
361 : "emptygroup1" };
362 :
363 1 : test_ctx = talloc_get_type_abort(*state, struct nested_groups_test_ctx);
364 :
365 : /* mock return values */
366 1 : rootgroup = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN, 1000,
367 : "rootgroup", groups);
368 :
369 1 : group1_reply[0] = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN,
370 : 1001, "emptygroup1", NULL);
371 1 : assert_non_null(group1_reply[0]);
372 1 : will_return(sdap_get_generic_recv, 1);
373 1 : will_return(sdap_get_generic_recv, group1_reply);
374 1 : will_return(sdap_get_generic_recv, ERR_OK);
375 :
376 1 : group2_reply[0] = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN,
377 : 1001, "emptygroup1", NULL);
378 1 : assert_non_null(group2_reply[0]);
379 1 : will_return(sdap_get_generic_recv, 1);
380 1 : will_return(sdap_get_generic_recv, group2_reply);
381 1 : will_return(sdap_get_generic_recv, ERR_OK);
382 :
383 1 : sss_will_return_always(sdap_has_deref_support, false);
384 :
385 : /* run test, check for memory leaks */
386 1 : req_mem_ctx = talloc_new(global_talloc_context);
387 1 : assert_non_null(req_mem_ctx);
388 1 : check_leaks_push(req_mem_ctx);
389 :
390 1 : req = sdap_nested_group_send(req_mem_ctx, test_ctx->tctx->ev,
391 : test_ctx->sdap_domain, test_ctx->sdap_opts,
392 : test_ctx->sdap_handle, rootgroup);
393 1 : assert_non_null(req);
394 1 : tevent_req_set_callback(req, nested_groups_test_done, test_ctx);
395 :
396 1 : ret = test_ev_loop(test_ctx->tctx);
397 1 : assert_true(check_leaks_pop(req_mem_ctx) == true);
398 1 : talloc_zfree(req_mem_ctx);
399 :
400 : /* check return code */
401 1 : assert_int_equal(ret, ERR_OK);
402 :
403 1 : assert_int_equal(test_ctx->num_users, 0);
404 1 : assert_int_equal(test_ctx->num_groups, N_ELEMENTS(expected));
405 :
406 1 : compare_sysdb_string_array_noorder(test_ctx->groups,
407 : expected, N_ELEMENTS(expected));
408 1 : }
409 :
410 1 : static void nested_groups_test_nested_chain(void **state)
411 : {
412 1 : struct nested_groups_test_ctx *test_ctx = NULL;
413 1 : struct tevent_req *req = NULL;
414 1 : TALLOC_CTX *req_mem_ctx = NULL;
415 : errno_t ret;
416 1 : const char *rootgroup_members[] = { "cn=user1,"USER_BASE_DN,
417 : "cn=group1,"GROUP_BASE_DN,
418 : NULL };
419 1 : const char *group1_members[] = { "cn=user2,"USER_BASE_DN,
420 : "cn=group2,"GROUP_BASE_DN,
421 : NULL };
422 1 : const char *group2_members[] = { "cn=user3,"USER_BASE_DN,
423 : NULL };
424 : struct sysdb_attrs *rootgroup;
425 1 : const struct sysdb_attrs *user1_reply[2] = { NULL };
426 1 : const struct sysdb_attrs *group1_reply[2] = { NULL };
427 1 : const struct sysdb_attrs *user2_reply[2] = { NULL };
428 1 : const struct sysdb_attrs *group2_reply[2] = { NULL };
429 1 : const struct sysdb_attrs *user3_reply[2] = { NULL };
430 1 : const char *expected_groups[] = { "rootgroup", "group1", "group2" };
431 1 : const char *expected_users[] = { "user1", "user2", "user3" };
432 :
433 1 : test_ctx = talloc_get_type_abort(*state, struct nested_groups_test_ctx);
434 :
435 : /* mock return values */
436 1 : rootgroup = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN, 1000,
437 : "rootgroup", rootgroup_members);
438 1 : assert_non_null(rootgroup);
439 :
440 1 : user1_reply[0] = mock_sysdb_user(test_ctx, USER_BASE_DN, 2001, "user1");
441 1 : assert_non_null(user1_reply[0]);
442 1 : will_return(sdap_get_generic_recv, 1);
443 1 : will_return(sdap_get_generic_recv, user1_reply);
444 1 : will_return(sdap_get_generic_recv, ERR_OK);
445 :
446 1 : group1_reply[0] = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN,
447 : 1001, "group1",
448 : group1_members);
449 1 : assert_non_null(group1_reply[0]);
450 1 : will_return(sdap_get_generic_recv, 1);
451 1 : will_return(sdap_get_generic_recv, group1_reply);
452 1 : will_return(sdap_get_generic_recv, ERR_OK);
453 :
454 1 : user2_reply[0] = mock_sysdb_user(test_ctx, USER_BASE_DN, 2002, "user2");
455 1 : assert_non_null(user2_reply[0]);
456 1 : will_return(sdap_get_generic_recv, 1);
457 1 : will_return(sdap_get_generic_recv, user2_reply);
458 1 : will_return(sdap_get_generic_recv, ERR_OK);
459 :
460 1 : group2_reply[0] = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN,
461 : 1002, "group2",
462 : group2_members);
463 1 : assert_non_null(group2_reply[0]);
464 1 : will_return(sdap_get_generic_recv, 1);
465 1 : will_return(sdap_get_generic_recv, group2_reply);
466 1 : will_return(sdap_get_generic_recv, ERR_OK);
467 :
468 1 : user3_reply[0] = mock_sysdb_user(test_ctx, USER_BASE_DN, 2003, "user3");
469 1 : assert_non_null(user3_reply[0]);
470 1 : will_return(sdap_get_generic_recv, 1);
471 1 : will_return(sdap_get_generic_recv, user3_reply);
472 1 : will_return(sdap_get_generic_recv, ERR_OK);
473 :
474 1 : sss_will_return_always(sdap_has_deref_support, false);
475 :
476 : /* run test, check for memory leaks */
477 1 : req_mem_ctx = talloc_new(global_talloc_context);
478 1 : assert_non_null(req_mem_ctx);
479 1 : check_leaks_push(req_mem_ctx);
480 :
481 1 : req = sdap_nested_group_send(req_mem_ctx, test_ctx->tctx->ev,
482 : test_ctx->sdap_domain, test_ctx->sdap_opts,
483 : test_ctx->sdap_handle, rootgroup);
484 1 : assert_non_null(req);
485 1 : tevent_req_set_callback(req, nested_groups_test_done, test_ctx);
486 :
487 1 : ret = test_ev_loop(test_ctx->tctx);
488 1 : assert_true(check_leaks_pop(req_mem_ctx) == true);
489 1 : talloc_zfree(req_mem_ctx);
490 :
491 : /* check return code */
492 1 : assert_int_equal(ret, ERR_OK);
493 :
494 : /* Check the users */
495 1 : assert_int_equal(test_ctx->num_users, N_ELEMENTS(expected_users));
496 1 : assert_int_equal(test_ctx->num_groups, N_ELEMENTS(expected_groups));
497 :
498 1 : compare_sysdb_string_array_noorder(test_ctx->groups,
499 : expected_groups,
500 : N_ELEMENTS(expected_groups));
501 1 : compare_sysdb_string_array_noorder(test_ctx->users,
502 : expected_users,
503 : N_ELEMENTS(expected_users));
504 1 : }
505 :
506 1 : static void nested_groups_test_nested_chain_with_error(void **state)
507 : {
508 1 : struct nested_groups_test_ctx *test_ctx = NULL;
509 1 : struct tevent_req *req = NULL;
510 1 : TALLOC_CTX *req_mem_ctx = NULL;
511 : errno_t ret;
512 1 : const char *rootgroup_members[] = { "cn=group1,"GROUP_BASE_DN,
513 : NULL };
514 1 : const char *group1_members[] = { "cn=group2,"GROUP_BASE_DN,
515 : NULL };
516 1 : const char *group2_members[] = { "cn=user1,"USER_BASE_DN,
517 : NULL };
518 : struct sysdb_attrs *rootgroup;
519 1 : const struct sysdb_attrs *user_reply[2] = { NULL };
520 1 : const struct sysdb_attrs *group1_reply[2] = { NULL };
521 1 : const struct sysdb_attrs *group2_reply[2] = { NULL };
522 :
523 1 : test_ctx = talloc_get_type_abort(*state, struct nested_groups_test_ctx);
524 :
525 : /* mock return values */
526 1 : rootgroup = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN, 1000,
527 : "rootgroup", rootgroup_members);
528 1 : assert_non_null(rootgroup);
529 :
530 1 : group1_reply[0] = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN,
531 : 1001, "group1",
532 : group1_members);
533 1 : assert_non_null(group1_reply[0]);
534 1 : will_return(sdap_get_generic_recv, 1);
535 1 : will_return(sdap_get_generic_recv, group1_reply);
536 1 : will_return(sdap_get_generic_recv, ERR_OK);
537 :
538 1 : group2_reply[0] = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN,
539 : 1002, "group2",
540 : group2_members);
541 1 : assert_non_null(group2_reply[0]);
542 1 : will_return(sdap_get_generic_recv, 1);
543 1 : will_return(sdap_get_generic_recv, group2_reply);
544 1 : will_return(sdap_get_generic_recv, ERR_OK);
545 :
546 1 : user_reply[0] = mock_sysdb_user(test_ctx, USER_BASE_DN, 2001, "user1");
547 1 : assert_non_null(user_reply[0]);
548 1 : will_return(sdap_get_generic_recv, 1);
549 1 : will_return(sdap_get_generic_recv, user_reply);
550 1 : will_return(sdap_get_generic_recv, EIO);
551 :
552 1 : sss_will_return_always(sdap_has_deref_support, false);
553 :
554 : /* run test, check for memory leaks */
555 1 : req_mem_ctx = talloc_new(global_talloc_context);
556 1 : assert_non_null(req_mem_ctx);
557 1 : check_leaks_push(req_mem_ctx);
558 :
559 1 : req = sdap_nested_group_send(req_mem_ctx, test_ctx->tctx->ev,
560 : test_ctx->sdap_domain, test_ctx->sdap_opts,
561 : test_ctx->sdap_handle, rootgroup);
562 1 : assert_non_null(req);
563 1 : tevent_req_set_callback(req, nested_groups_test_done, test_ctx);
564 :
565 1 : ret = test_ev_loop(test_ctx->tctx);
566 1 : assert_true(check_leaks_pop(req_mem_ctx) == true);
567 1 : talloc_zfree(req_mem_ctx);
568 :
569 : /* check return code */
570 1 : assert_int_equal(ret, EIO);
571 1 : }
572 :
573 7 : static int nested_groups_test_setup(void **state)
574 : {
575 : errno_t ret;
576 7 : struct nested_groups_test_ctx *test_ctx = NULL;
577 : static struct sss_test_conf_param params[] = {
578 : { "ldap_schema", "rfc2307bis" }, /* enable nested groups */
579 : { "ldap_search_base", OBJECT_BASE_DN },
580 : { "ldap_user_search_base", USER_BASE_DN },
581 : { "ldap_group_search_base", GROUP_BASE_DN },
582 : { NULL, NULL }
583 : };
584 :
585 7 : test_ctx = talloc_zero(NULL, struct nested_groups_test_ctx);
586 7 : assert_non_null(test_ctx);
587 7 : *state = test_ctx;
588 :
589 : /* initialize domain */
590 7 : test_ctx->tctx = create_dom_test_ctx(test_ctx, TESTS_PATH, TEST_CONF_DB,
591 : TEST_DOM_NAME,
592 : TEST_ID_PROVIDER, params);
593 7 : assert_non_null(test_ctx->tctx);
594 :
595 : /* mock SDAP */
596 14 : test_ctx->sdap_opts = mock_sdap_options_ldap(test_ctx,
597 7 : test_ctx->tctx->dom,
598 7 : test_ctx->tctx->confdb,
599 7 : test_ctx->tctx->conf_dom_path);
600 7 : assert_non_null(test_ctx->sdap_opts);
601 7 : test_ctx->sdap_domain = test_ctx->sdap_opts->sdom;
602 7 : test_ctx->sdap_handle = mock_sdap_handle(test_ctx);
603 7 : assert_non_null(test_ctx->sdap_handle);
604 :
605 7 : test_ctx->be_ctx = mock_be_ctx(test_ctx, test_ctx->tctx);
606 7 : assert_non_null(test_ctx->be_ctx);
607 :
608 7 : test_ctx->sdap_id_ctx = mock_sdap_id_ctx(test_ctx,
609 : test_ctx->be_ctx,
610 : test_ctx->sdap_opts);
611 7 : assert_non_null(test_ctx->sdap_id_ctx);
612 :
613 7 : ret = sdap_idmap_init(test_ctx, test_ctx->sdap_id_ctx, &test_ctx->idmap_ctx);
614 7 : assert_int_equal(ret, EOK);
615 7 : test_ctx->sdap_opts->idmap_ctx = test_ctx->idmap_ctx;
616 7 : return 0;
617 : }
618 :
619 7 : static int nested_groups_test_teardown(void **state)
620 : {
621 7 : talloc_zfree(*state);
622 7 : return 0;
623 : }
624 :
625 1 : int main(int argc, const char *argv[])
626 : {
627 : int rv;
628 1 : int no_cleanup = 0;
629 : poptContext pc;
630 : int opt;
631 7 : struct poptOption long_options[] = {
632 : POPT_AUTOHELP
633 5 : SSSD_DEBUG_OPTS
634 : {"no-cleanup", 'n', POPT_ARG_NONE, &no_cleanup, 0,
635 1 : _("Do not delete the test database after a test run"), NULL },
636 : POPT_TABLEEND
637 : };
638 :
639 1 : const struct CMUnitTest tests[] = {
640 : new_test(one_group_no_members),
641 : new_test(one_group_unique_members),
642 : new_test(one_group_dup_users),
643 : new_test(one_group_unique_group_members),
644 : new_test(one_group_dup_group_members),
645 : new_test(nested_chain),
646 : new_test(nested_chain_with_error),
647 : };
648 :
649 : /* Set debug level to invalid value so we can deside if -d 0 was used. */
650 1 : debug_level = SSSDBG_INVALID;
651 :
652 1 : pc = poptGetContext(argv[0], argc, argv, long_options, 0);
653 1 : while((opt = poptGetNextOpt(pc)) != -1) {
654 : switch(opt) {
655 : default:
656 0 : fprintf(stderr, "\nInvalid option %s: %s\n\n",
657 : poptBadOption(pc, 0), poptStrerror(opt));
658 0 : poptPrintUsage(pc, stderr, 0);
659 0 : return 1;
660 : }
661 : }
662 1 : poptFreeContext(pc);
663 :
664 1 : DEBUG_CLI_INIT(debug_level);
665 :
666 : /* Even though normally the tests should clean up after themselves
667 : * they might not after a failed run. Remove the old db to be sure */
668 1 : tests_set_cwd();
669 1 : test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME);
670 1 : test_dom_suite_setup(TESTS_PATH);
671 :
672 1 : rv = cmocka_run_group_tests(tests, NULL, NULL);
673 1 : if (rv == 0 && !no_cleanup) {
674 1 : test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME);
675 : }
676 1 : return rv;
677 : }
|