1 /* Test group merging.
2    Copyright (C) 2017-2022 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4 
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <https://www.gnu.org/licenses/>.  */
18 
19 #include <nss.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #include <support/support.h>
25 
26 #include "nss_test.h"
27 
28 /* The name choices here are arbitrary, aside from the merge_1 list
29    needing to be an expected merge of group_1 and group_2.  */
30 
31 static const char *group_1[] = {
32   "foo", "bar", NULL
33 };
34 
35 static const char *group_2[] = {
36   "foo", "dick", "harry", NULL
37 };
38 
39 /* Note that deduplication is NOT supposed to happen.  */
40 static const char *merge_1[] = {
41   "foo", "bar", "foo", "dick", "harry", NULL
42 };
43 
44 static const char *group_4[] = {
45   "fred", "wilma", NULL
46 };
47 
48 /* This is the data we're giving the service.  */
49 static struct group group_table_data1[] = {
50   GRP_N(1, "name1", group_1),
51   GRP(2),
52   GRP_LAST ()
53 };
54 
55 /* This is the data we're giving the service.  */
56 static struct group group_table_data2[] = {
57   GRP_N(1, "name1", group_2),
58   GRP(4),
59   GRP_LAST ()
60 };
61 
62 /* This is the data we compare against.  */
63 static struct group group_table[] = {
64   GRP_N(1, "name1", merge_1),
65   GRP(2),
66   GRP(4),
67   GRP_LAST ()
68 };
69 
70 void
_nss_test1_init_hook(test_tables * t)71 _nss_test1_init_hook(test_tables *t)
72 {
73   t->grp_table = group_table_data1;
74 }
75 
76 void
_nss_test2_init_hook(test_tables * t)77 _nss_test2_init_hook(test_tables *t)
78 {
79   t->grp_table = group_table_data2;
80 }
81 
82 static int
do_test(void)83 do_test (void)
84 {
85   int retval = 0;
86   int i;
87   struct group *g = NULL;
88   uintptr_t align_mask;
89 
90   __nss_configure_lookup ("group", "test1 [SUCCESS=merge] test2");
91 
92   align_mask = __alignof__ (struct group *) - 1;
93 
94   setgrent ();
95 
96   for (i = 0; group_table[i].gr_gid; ++i)
97     {
98       g = getgrgid (group_table[i].gr_gid);
99       if (g)
100 	{
101 	  retval += compare_groups (i, g, & group_table[i]);
102 	  if ((uintptr_t)g & align_mask)
103 	    {
104 	      printf("FAIL: [%d] unaligned group %p\n", i, g);
105 	      ++retval;
106 	    }
107 	  if ((uintptr_t)(g->gr_mem) & align_mask)
108 	    {
109 	      printf("FAIL: [%d] unaligned member list %p\n", i, g->gr_mem);
110 	      ++retval;
111 	    }
112 	}
113       else
114 	{
115 	  printf ("FAIL: [%d] group %u.%s not found\n", i,
116 	      group_table[i].gr_gid, group_table[i].gr_name);
117 	  ++retval;
118 	}
119     }
120 
121   endgrent ();
122 
123 #define EXPECTED 0
124   if (retval == EXPECTED)
125     {
126       if (retval > 0)
127 	printf ("PASS: Found %d expected errors\n", retval);
128       return 0;
129     }
130   else
131     {
132       printf ("FAIL: Found %d errors, expected %d\n", retval, EXPECTED);
133       return 1;
134     }
135 }
136 
137 #include <support/test-driver.c>
138