nss_wrapper: add tests for getgrent_r to testsuite.
[abartlet/samba.git/.git] / lib / nss_wrapper / testsuite.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    local testing of the nss wrapper
5
6    Copyright (C) Guenther Deschner 2009
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "torture/torture.h"
24 #include "lib/replace/system/passwd.h"
25 #include "lib/nss_wrapper/nss_wrapper.h"
26
27 static bool copy_passwd(struct torture_context *tctx,
28                         const struct passwd *pwd,
29                         struct passwd *p)
30 {
31         p->pw_name      = talloc_strdup(tctx, pwd->pw_name);
32         p->pw_passwd    = talloc_strdup(tctx, pwd->pw_passwd);
33         p->pw_uid       = pwd->pw_uid;
34         p->pw_gid       = pwd->pw_gid;
35         p->pw_gecos     = talloc_strdup(tctx, pwd->pw_gecos);
36         p->pw_dir       = talloc_strdup(tctx, pwd->pw_dir);
37         p->pw_shell     = talloc_strdup(tctx, pwd->pw_shell);
38
39         return true;
40 }
41
42 static void print_passwd(struct passwd *pwd)
43 {
44         printf("%s:%s:%lu:%lu:%s:%s:%s\n",
45                pwd->pw_name,
46                pwd->pw_passwd,
47                (unsigned long)pwd->pw_uid,
48                (unsigned long)pwd->pw_gid,
49                pwd->pw_gecos,
50                pwd->pw_dir,
51                pwd->pw_shell);
52 }
53
54
55 static bool test_nwrap_getpwnam(struct torture_context *tctx,
56                                 const char *name,
57                                 struct passwd *pwd_p)
58 {
59         struct passwd *pwd;
60
61         torture_comment(tctx, "Testing getpwnam: %s\n", name);
62
63         pwd = getpwnam(name);
64         if (pwd) {
65                 print_passwd(pwd);
66         }
67
68         if (pwd_p) {
69                 copy_passwd(tctx, pwd, pwd_p);
70         }
71
72         return pwd ? true : false;
73 }
74
75 static bool test_nwrap_getpwnam_r(struct torture_context *tctx,
76                                   const char *name,
77                                   struct passwd *pwd_p)
78 {
79         struct passwd pwd, *pwdp;
80         char buffer[4096];
81         int ret;
82
83         torture_comment(tctx, "Testing getpwnam_r: %s\n", name);
84
85         ret = getpwnam_r(name, &pwd, buffer, sizeof(buffer), &pwdp);
86         if (ret != 0) {
87                 if (ret != ENOENT) {
88                         torture_comment(tctx, "got %d return code\n", ret);
89                 }
90                 return false;
91         }
92
93         print_passwd(&pwd);
94
95         if (pwd_p) {
96                 copy_passwd(tctx, &pwd, pwd_p);
97         }
98
99         return true;
100 }
101
102 static bool test_nwrap_getpwuid(struct torture_context *tctx,
103                                 uid_t uid,
104                                 struct passwd *pwd_p)
105 {
106         struct passwd *pwd;
107
108         torture_comment(tctx, "Testing getpwuid: %lu\n", (unsigned long)uid);
109
110         pwd = getpwuid(uid);
111         if (pwd) {
112                 print_passwd(pwd);
113         }
114
115         if (pwd_p) {
116                 copy_passwd(tctx, pwd, pwd_p);
117         }
118
119         return pwd ? true : false;
120 }
121
122 static bool test_nwrap_getpwuid_r(struct torture_context *tctx,
123                                   uid_t uid,
124                                   struct passwd *pwd_p)
125 {
126         struct passwd pwd, *pwdp;
127         char buffer[4096];
128         int ret;
129
130         torture_comment(tctx, "Testing getpwuid_r: %lu\n", (unsigned long)uid);
131
132         ret = getpwuid_r(uid, &pwd, buffer, sizeof(buffer), &pwdp);
133         if (ret != 0) {
134                 if (ret != ENOENT) {
135                         torture_comment(tctx, "got %d return code\n", ret);
136                 }
137                 return false;
138         }
139
140         print_passwd(&pwd);
141
142         if (pwd_p) {
143                 copy_passwd(tctx, &pwd, pwd_p);
144         }
145
146         return true;
147 }
148
149
150 static bool copy_group(struct torture_context *tctx,
151                        const struct group *grp,
152                        struct group *g)
153 {
154         int i;
155
156         g->gr_name      = talloc_strdup(tctx, grp->gr_name);
157         g->gr_passwd    = talloc_strdup(tctx, grp->gr_passwd);
158         g->gr_gid       = grp->gr_gid;
159         g->gr_mem       = NULL;
160
161         for (i=0; grp->gr_mem && grp->gr_mem[i]; i++) {
162                 g->gr_mem = talloc_realloc(tctx, g->gr_mem, char *, i + 2);
163                 g->gr_mem[i] = talloc_strdup(g->gr_mem, grp->gr_mem[i]);
164                 g->gr_mem[i+1] = NULL;
165         }
166
167         return true;
168 }
169
170 static void print_group(struct group *grp)
171 {
172         int i;
173         printf("%s:%s:%lu:",
174                grp->gr_name,
175                grp->gr_passwd,
176                (unsigned long)grp->gr_gid);
177
178         if (!grp->gr_mem[0]) {
179                 printf("\n");
180                 return;
181         }
182
183         for (i=0; grp->gr_mem[i+1]; i++) {
184                 printf("%s,", grp->gr_mem[i]);
185         }
186         printf("%s\n", grp->gr_mem[i]);
187 }
188
189 static bool test_nwrap_getgrnam(struct torture_context *tctx,
190                                 const char *name,
191                                 struct group *grp_p)
192 {
193         struct group *grp;
194
195         torture_comment(tctx, "Testing getgrnam: %s\n", name);
196
197         grp = getgrnam(name);
198         if (grp) {
199                 print_group(grp);
200         }
201
202         if (grp_p) {
203                 copy_group(tctx, grp, grp_p);
204         }
205
206         return grp ? true : false;
207 }
208
209 static bool test_nwrap_getgrnam_r(struct torture_context *tctx,
210                                   const char *name,
211                                   struct group *grp_p)
212 {
213         struct group grp, *grpp;
214         char buffer[4096];
215         int ret;
216
217         torture_comment(tctx, "Testing getgrnam_r: %s\n", name);
218
219         ret = getgrnam_r(name, &grp, buffer, sizeof(buffer), &grpp);
220         if (ret != 0) {
221                 if (ret != ENOENT) {
222                         torture_comment(tctx, "got %d return code\n", ret);
223                 }
224                 return false;
225         }
226
227         print_group(&grp);
228
229         if (grp_p) {
230                 copy_group(tctx, &grp, grp_p);
231         }
232
233         return true;
234 }
235
236
237 static bool test_nwrap_getgrgid(struct torture_context *tctx,
238                                 gid_t gid,
239                                 struct group *grp_p)
240 {
241         struct group *grp;
242
243         torture_comment(tctx, "Testing getgrgid: %lu\n", (unsigned long)gid);
244
245         grp = getgrgid(gid);
246         if (grp) {
247                 print_group(grp);
248         }
249
250         if (grp_p) {
251                 copy_group(tctx, grp, grp_p);
252         }
253
254         return grp ? true : false;
255 }
256
257 static bool test_nwrap_getgrgid_r(struct torture_context *tctx,
258                                   gid_t gid,
259                                   struct group *grp_p)
260 {
261         struct group grp, *grpp;
262         char buffer[4096];
263         int ret;
264
265         torture_comment(tctx, "Testing getgrgid_r: %lu\n", (unsigned long)gid);
266
267         ret = getgrgid_r(gid, &grp, buffer, sizeof(buffer), &grpp);
268         if (ret != 0) {
269                 if (ret != ENOENT) {
270                         torture_comment(tctx, "got %d return code\n", ret);
271                 }
272                 return false;
273         }
274
275         print_group(&grp);
276
277         if (grp_p) {
278                 copy_group(tctx, &grp, grp_p);
279         }
280
281         return true;
282 }
283
284 static bool test_nwrap_enum_passwd(struct torture_context *tctx,
285                                    struct passwd **pwd_array_p,
286                                    size_t *num_pwd_p)
287 {
288         struct passwd *pwd;
289         struct passwd *pwd_array = NULL;
290         size_t num_pwd = 0;
291
292         torture_comment(tctx, "Testing setpwent\n");
293         setpwent();
294
295         while ((pwd = getpwent()) != NULL) {
296                 torture_comment(tctx, "Testing getpwent\n");
297
298                 print_passwd(pwd);
299                 if (pwd_array_p && num_pwd_p) {
300                         pwd_array = talloc_realloc(tctx, pwd_array, struct passwd, num_pwd+1);
301                         torture_assert(tctx, pwd_array, "out of memory");
302                         copy_passwd(tctx, pwd, &pwd_array[num_pwd]);
303                         num_pwd++;
304                 }
305         }
306
307         torture_comment(tctx, "Testing endpwent\n");
308         endpwent();
309
310         if (pwd_array_p) {
311                 *pwd_array_p = pwd_array;
312         }
313         if (num_pwd_p) {
314                 *num_pwd_p = num_pwd;
315         }
316
317         return true;
318 }
319
320 static bool test_nwrap_enum_r_passwd(struct torture_context *tctx,
321                                      struct passwd **pwd_array_p,
322                                      size_t *num_pwd_p)
323 {
324         struct passwd pwd, *pwdp;
325         struct passwd *pwd_array = NULL;
326         size_t num_pwd = 0;
327         char buffer[4096];
328         int ret;
329
330         torture_comment(tctx, "Testing setpwent\n");
331         setpwent();
332
333         while (1) {
334                 torture_comment(tctx, "Testing getpwent_r\n");
335
336                 ret = getpwent_r(&pwd, buffer, sizeof(buffer), &pwdp);
337                 if (ret != 0) {
338                         if (ret != ENOENT) {
339                                 torture_comment(tctx, "got %d return code\n", ret);
340                         }
341                         break;
342                 }
343                 print_passwd(&pwd);
344                 if (pwd_array_p && num_pwd_p) {
345                         pwd_array = talloc_realloc(tctx, pwd_array, struct passwd, num_pwd+1);
346                         torture_assert(tctx, pwd_array, "out of memory");
347                         copy_passwd(tctx, &pwd, &pwd_array[num_pwd]);
348                         num_pwd++;
349                 }
350         }
351
352         torture_comment(tctx, "Testing endpwent\n");
353         endpwent();
354
355         if (pwd_array_p) {
356                 *pwd_array_p = pwd_array;
357         }
358         if (num_pwd_p) {
359                 *num_pwd_p = num_pwd;
360         }
361
362         return true;
363 }
364
365 static bool torture_assert_passwd_equal(struct torture_context *tctx,
366                                         const struct passwd *p1,
367                                         const struct passwd *p2,
368                                         const char *comment)
369 {
370         torture_assert_str_equal(tctx, p1->pw_name, p2->pw_name, comment);
371         torture_assert_str_equal(tctx, p1->pw_passwd, p2->pw_passwd, comment);
372         torture_assert_int_equal(tctx, p1->pw_uid, p2->pw_uid, comment);
373         torture_assert_int_equal(tctx, p1->pw_gid, p2->pw_gid, comment);
374         torture_assert_str_equal(tctx, p1->pw_gecos, p2->pw_gecos, comment);
375         torture_assert_str_equal(tctx, p1->pw_dir, p2->pw_dir, comment);
376         torture_assert_str_equal(tctx, p1->pw_shell, p2->pw_shell, comment);
377
378         return true;
379 }
380
381 static bool test_nwrap_passwd(struct torture_context *tctx)
382 {
383         int i;
384         struct passwd *pwd, pwd1, pwd2;
385         size_t num_pwd;
386
387         torture_assert(tctx, test_nwrap_enum_passwd(tctx, &pwd, &num_pwd),
388                                                     "failed to enumerate passwd");
389
390         for (i=0; i < num_pwd; i++) {
391                 torture_assert(tctx, test_nwrap_getpwnam(tctx, pwd[i].pw_name, &pwd1),
392                         "failed to call getpwnam for enumerated user");
393                 torture_assert_passwd_equal(tctx, &pwd[i], &pwd1,
394                         "getpwent and getpwnam gave different results");
395                 torture_assert(tctx, test_nwrap_getpwuid(tctx, pwd[i].pw_uid, &pwd2),
396                         "failed to call getpwuid for enumerated user");
397                 torture_assert_passwd_equal(tctx, &pwd[i], &pwd2,
398                         "getpwent and getpwuid gave different results");
399                 torture_assert_passwd_equal(tctx, &pwd1, &pwd2,
400                         "getpwnam and getpwuid gave different results");
401         }
402
403         return true;
404 }
405
406 static bool test_nwrap_passwd_r(struct torture_context *tctx)
407 {
408         int i;
409         struct passwd *pwd, pwd1, pwd2;
410         size_t num_pwd;
411
412         torture_assert(tctx, test_nwrap_enum_r_passwd(tctx, &pwd, &num_pwd),
413                                                       "failed to enumerate passwd");
414
415         for (i=0; i < num_pwd; i++) {
416                 torture_assert(tctx, test_nwrap_getpwnam_r(tctx, pwd[i].pw_name, &pwd1),
417                         "failed to call getpwnam_r for enumerated user");
418                 torture_assert_passwd_equal(tctx, &pwd[i], &pwd1,
419                         "getpwent_r and getpwnam_r gave different results");
420                 torture_assert(tctx, test_nwrap_getpwuid_r(tctx, pwd[i].pw_uid, &pwd2),
421                         "failed to call getpwuid_r for enumerated user");
422                 torture_assert_passwd_equal(tctx, &pwd[i], &pwd2,
423                         "getpwent_r and getpwuid_r gave different results");
424                 torture_assert_passwd_equal(tctx, &pwd1, &pwd2,
425                         "getpwnam_r and getpwuid_r gave different results");
426         }
427
428         return true;
429 }
430
431 static bool test_nwrap_enum_group(struct torture_context *tctx,
432                                   struct group **grp_array_p,
433                                   size_t *num_grp_p)
434 {
435         struct group *grp;
436         struct group *grp_array = NULL;
437         size_t num_grp = 0;
438
439         torture_comment(tctx, "Testing setgrent\n");
440         setgrent();
441
442         while ((grp = getgrent()) != NULL) {
443                 torture_comment(tctx, "Testing getgrent\n");
444
445                 print_group(grp);
446                 if (grp_array_p && num_grp_p) {
447                         grp_array = talloc_realloc(tctx, grp_array, struct group, num_grp+1);
448                         torture_assert(tctx, grp_array, "out of memory");
449                         copy_group(tctx, grp, &grp_array[num_grp]);
450                         num_grp++;
451                 }
452         }
453
454         torture_comment(tctx, "Testing endgrent\n");
455         endgrent();
456
457         if (grp_array_p) {
458                 *grp_array_p = grp_array;
459         }
460         if (num_grp_p) {
461                 *num_grp_p = num_grp;
462         }
463
464         return true;
465 }
466
467 static bool test_nwrap_enum_r_group(struct torture_context *tctx,
468                                     struct group **grp_array_p,
469                                     size_t *num_grp_p)
470 {
471         struct group grp, *grpp;
472         struct group *grp_array = NULL;
473         size_t num_grp = 0;
474         char buffer[4096];
475         int ret;
476
477         torture_comment(tctx, "Testing setgrent\n");
478         setgrent();
479
480         while (1) {
481                 torture_comment(tctx, "Testing getgrent_r\n");
482
483                 ret = getgrent_r(&grp, buffer, sizeof(buffer), &grpp);
484                 if (ret != 0) {
485                         if (ret != ENOENT) {
486                                 torture_comment(tctx, "got %d return code\n", ret);
487                         }
488                         break;
489                 }
490                 print_group(&grp);
491                 if (grp_array_p && num_grp_p) {
492                         grp_array = talloc_realloc(tctx, grp_array, struct group, num_grp+1);
493                         torture_assert(tctx, grp_array, "out of memory");
494                         copy_group(tctx, &grp, &grp_array[num_grp]);
495                         num_grp++;
496                 }
497         }
498
499         torture_comment(tctx, "Testing endgrent\n");
500         endgrent();
501
502         if (grp_array_p) {
503                 *grp_array_p = grp_array;
504         }
505         if (num_grp_p) {
506                 *num_grp_p = num_grp;
507         }
508
509         return true;
510 }
511
512 static bool torture_assert_group_equal(struct torture_context *tctx,
513                                        const struct group *g1,
514                                        const struct group *g2,
515                                        const char *comment)
516 {
517         int i;
518         torture_assert_str_equal(tctx, g1->gr_name, g2->gr_name, comment);
519         torture_assert_str_equal(tctx, g1->gr_passwd, g2->gr_passwd, comment);
520         torture_assert_int_equal(tctx, g1->gr_gid, g2->gr_gid, comment);
521         if (g1->gr_mem && !g2->gr_mem) {
522                 return false;
523         }
524         if (!g1->gr_mem && g2->gr_mem) {
525                 return false;
526         }
527         if (!g1->gr_mem && !g2->gr_mem) {
528                 return true;
529         }
530         for (i=0; g1->gr_mem[i] && g2->gr_mem[i]; i++) {
531                 torture_assert_str_equal(tctx, g1->gr_mem[i], g2->gr_mem[i], comment);
532         }
533
534         return true;
535 }
536
537 static bool test_nwrap_group(struct torture_context *tctx)
538 {
539         int i;
540         struct group *grp, grp1, grp2;
541         size_t num_grp;
542
543         torture_assert(tctx, test_nwrap_enum_group(tctx, &grp, &num_grp),
544                                                    "failed to enumerate group");
545
546         for (i=0; i < num_grp; i++) {
547                 torture_assert(tctx, test_nwrap_getgrnam(tctx, grp[i].gr_name, &grp1),
548                         "failed to call getgrnam for enumerated user");
549                 torture_assert_group_equal(tctx, &grp[i], &grp1,
550                         "getgrent and getgrnam gave different results");
551                 torture_assert(tctx, test_nwrap_getgrgid(tctx, grp[i].gr_gid, &grp2),
552                         "failed to call getgrgid for enumerated user");
553                 torture_assert_group_equal(tctx, &grp[i], &grp2,
554                         "getgrent and getgruid gave different results");
555                 torture_assert_group_equal(tctx, &grp1, &grp2,
556                         "getgrnam and getgrgid gave different results");
557         }
558
559         return true;
560 }
561
562 static bool test_nwrap_group_r(struct torture_context *tctx)
563 {
564         int i;
565         struct group *grp, grp1, grp2;
566         size_t num_grp;
567
568         torture_assert(tctx, test_nwrap_enum_r_group(tctx, &grp, &num_grp),
569                                                      "failed to enumerate group");
570
571         for (i=0; i < num_grp; i++) {
572                 torture_assert(tctx, test_nwrap_getgrnam_r(tctx, grp[i].gr_name, &grp1),
573                         "failed to call getgrnam_r for enumerated user");
574                 torture_assert_group_equal(tctx, &grp[i], &grp1,
575                         "getgrent_r and getgrnam_r gave different results");
576                 torture_assert(tctx, test_nwrap_getgrgid_r(tctx, grp[i].gr_gid, &grp2),
577                         "failed to call getgrgid_r for enumerated user");
578                 torture_assert_group_equal(tctx, &grp[i], &grp2,
579                         "getgrent_r and getgrgid_r gave different results");
580                 torture_assert_group_equal(tctx, &grp1, &grp2,
581                         "getgrnam_r and getgrgid_r gave different results");
582         }
583
584         return true;
585 }
586
587 static bool test_nwrap_getgrouplist(struct torture_context *tctx,
588                                     const char *user,
589                                     gid_t gid,
590                                     gid_t **gids_p,
591                                     int *num_gids_p)
592 {
593         int ret;
594         int num_groups = 0;
595         gid_t *groups = NULL;
596
597         torture_comment(tctx, "Testing getgrouplist: %s\n", user);
598
599         ret = getgrouplist(user, gid, NULL, &num_groups);
600         if (ret == -1 || num_groups != 0) {
601
602                 groups = talloc_array(tctx, gid_t, num_groups);
603                 torture_assert(tctx, groups, "out of memory\n");
604
605                 ret = getgrouplist(user, gid, groups, &num_groups);
606         }
607
608         torture_assert(tctx, (ret != -1), "failed to call getgrouplist");
609
610         torture_comment(tctx, "%s is member in %d groups\n", user, num_groups);
611
612         if (gids_p) {
613                 *gids_p = groups;
614         }
615         if (num_gids_p) {
616                 *num_gids_p = num_groups;
617         }
618
619         return true;
620 }
621
622 static bool test_nwrap_user_in_group(struct torture_context *tctx,
623                                      const struct passwd *pwd,
624                                      const struct group *grp)
625 {
626         int i;
627
628         for (i=0; grp->gr_mem && grp->gr_mem[i] != NULL; i++) {
629                 if (strequal(grp->gr_mem[i], pwd->pw_name)) {
630                         return true;
631                 }
632         }
633
634         return false;
635 }
636
637 static bool test_nwrap_membership_user(struct torture_context *tctx,
638                                        const struct passwd *pwd,
639                                        struct group *grp_array,
640                                        size_t num_grp)
641 {
642         int num_user_groups = 0;
643         int num_user_groups_from_enum = 0;
644         gid_t *user_groups = NULL;
645         int g, i;
646         bool primary_group_had_user_member = false;
647
648         torture_assert(tctx, test_nwrap_getgrouplist(tctx,
649                                                      pwd->pw_name,
650                                                      pwd->pw_gid,
651                                                      &user_groups,
652                                                      &num_user_groups),
653                                                      "failed to test getgrouplist");
654
655         for (g=0; g < num_user_groups; g++) {
656                 torture_assert(tctx, test_nwrap_getgrgid(tctx, user_groups[g], NULL),
657                         "failed to find the group the user is a member of");
658         }
659
660
661         for (i=0; i < num_grp; i++) {
662
663                 struct group grp = grp_array[i];
664
665                 if (test_nwrap_user_in_group(tctx, pwd, &grp)) {
666
667                         struct group current_grp;
668                         num_user_groups_from_enum++;
669
670                         torture_assert(tctx, test_nwrap_getgrnam(tctx, grp.gr_name, &current_grp),
671                                         "failed to find the group the user is a member of");
672
673                         if (current_grp.gr_gid == pwd->pw_gid) {
674                                 torture_comment(tctx, "primary group %s of user %s lists user as member\n",
675                                                 current_grp.gr_name,
676                                                 pwd->pw_name);
677                                 primary_group_had_user_member = true;
678                         }
679
680                         continue;
681                 }
682         }
683
684         if (!primary_group_had_user_member) {
685                 num_user_groups_from_enum++;
686         }
687
688         torture_assert_int_equal(tctx, num_user_groups, num_user_groups_from_enum,
689                 "getgrouplist and real inspection of grouplist gave different results\n");
690
691         return true;
692 }
693
694 static bool test_nwrap_membership(struct torture_context *tctx)
695 {
696         const char *old_pwd = getenv("NSS_WRAPPER_PASSWD");
697         const char *old_group = getenv("NSS_WRAPPER_GROUP");
698         struct passwd *pwd;
699         size_t num_pwd;
700         struct group *grp;
701         size_t num_grp;
702         int i;
703
704         if (!old_pwd || !old_group) {
705                 torture_skip(tctx, "nothing to test\n");
706                 return true;
707         }
708
709         torture_assert(tctx, test_nwrap_enum_passwd(tctx, &pwd, &num_pwd),
710                                                     "failed to enumerate passwd");
711         torture_assert(tctx, test_nwrap_enum_group(tctx, &grp, &num_grp),
712                                                     "failed to enumerate group");
713
714         for (i=0; i < num_pwd; i++) {
715
716                 torture_assert(tctx, test_nwrap_membership_user(tctx, &pwd[i], grp, num_grp),
717                         "failed to test membership for user");
718
719         }
720
721         return true;
722 }
723
724 static bool test_nwrap_enumeration(struct torture_context *tctx)
725 {
726         const char *old_pwd = getenv("NSS_WRAPPER_PASSWD");
727         const char *old_group = getenv("NSS_WRAPPER_GROUP");
728
729         if (!old_pwd || !old_group) {
730                 torture_skip(tctx, "nothing to test\n");
731                 return true;
732         }
733
734         torture_assert(tctx, test_nwrap_passwd(tctx),
735                         "failed to test users");
736         torture_assert(tctx, test_nwrap_group(tctx),
737                         "failed to test groups");
738
739         return true;
740 }
741
742 static bool test_nwrap_reentrant_enumeration(struct torture_context *tctx)
743 {
744         const char *old_pwd = getenv("NSS_WRAPPER_PASSWD");
745         const char *old_group = getenv("NSS_WRAPPER_GROUP");
746
747         if (!old_pwd || !old_group) {
748                 torture_skip(tctx, "nothing to test\n");
749                 return true;
750         }
751
752         torture_comment(tctx, "Testing re-entrant calls\n");
753
754         torture_assert(tctx, test_nwrap_passwd_r(tctx),
755                         "failed to test users");
756         torture_assert(tctx, test_nwrap_group_r(tctx),
757                         "failed to test groups");
758
759         return true;
760 }
761
762
763 struct torture_suite *torture_local_nss_wrapper(TALLOC_CTX *mem_ctx)
764 {
765         struct torture_suite *suite = torture_suite_create(mem_ctx, "NSS-WRAPPER");
766
767         torture_suite_add_simple_test(suite, "enumeration", test_nwrap_enumeration);
768         torture_suite_add_simple_test(suite, "reentrant enumeration", test_nwrap_reentrant_enumeration);
769         torture_suite_add_simple_test(suite, "membership", test_nwrap_membership);
770
771         return suite;
772 }