nss_wrapper: resort calls to move public calls to the end.
[ira/wip.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 void print_passwd(struct passwd *pwd)
28 {
29         printf("%s:%s:%lu:%lu:%s:%s:%s\n",
30                pwd->pw_name,
31                pwd->pw_passwd,
32                (unsigned long)pwd->pw_uid,
33                (unsigned long)pwd->pw_gid,
34                pwd->pw_gecos,
35                pwd->pw_dir,
36                pwd->pw_shell);
37 }
38
39
40 static bool test_nwrap_getpwnam(struct torture_context *tctx,
41                                 const char *name)
42 {
43         struct passwd *pwd;
44
45         torture_comment(tctx, "Testing getpwnam: %s\n", name);
46
47         pwd = getpwnam(name);
48         if (pwd) {
49                 print_passwd(pwd);
50         }
51
52         return pwd ? true : false;
53 }
54
55 static bool test_nwrap_getpwuid(struct torture_context *tctx,
56                                 uid_t uid)
57 {
58         struct passwd *pwd;
59
60         torture_comment(tctx, "Testing getpwuid: %lu\n", (unsigned long)uid);
61
62         pwd = getpwuid(uid);
63         if (pwd) {
64                 print_passwd(pwd);
65         }
66
67         return pwd ? true : false;
68 }
69
70 static void print_group(struct group *grp)
71 {
72         int i;
73         printf("%s:%s:%lu:",
74                grp->gr_name,
75                grp->gr_passwd,
76                (unsigned long)grp->gr_gid);
77
78         if (!grp->gr_mem[0]) {
79                 printf("\n");
80                 return;
81         }
82
83         for (i=0; grp->gr_mem[i+1]; i++) {
84                 printf("%s,", grp->gr_mem[i]);
85         }
86         printf("%s\n", grp->gr_mem[i]);
87 }
88
89 static bool test_nwrap_getgrnam(struct torture_context *tctx,
90                                 const char *name)
91 {
92         struct group *grp;
93
94         torture_comment(tctx, "Testing getgrnam: %s\n", name);
95
96         grp = getgrnam(name);
97         if (grp) {
98                 print_group(grp);
99         }
100
101         return grp ? true : false;
102 }
103
104 static bool test_nwrap_getgrgid(struct torture_context *tctx,
105                                 gid_t gid)
106 {
107         struct group *grp;
108
109         torture_comment(tctx, "Testing getgrgid: %lu\n", (unsigned long)gid);
110
111         grp = getgrgid(gid);
112         if (grp) {
113                 print_group(grp);
114         }
115
116         return grp ? true : false;
117 }
118
119 static bool test_nwrap_enum_passwd(struct torture_context *tctx,
120                                    struct passwd **pwd_array_p,
121                                    size_t *num_pwd_p)
122 {
123         struct passwd *pwd;
124         struct passwd *pwd_array = NULL;
125         size_t num_pwd = 0;
126
127         torture_comment(tctx, "Testing setpwent\n");
128         setpwent();
129
130         while ((pwd = getpwent()) != NULL) {
131                 torture_comment(tctx, "Testing getpwent\n");
132
133                 print_passwd(pwd);
134                 if (pwd_array_p && num_pwd_p) {
135                         pwd_array = talloc_realloc(tctx, pwd_array, struct passwd, num_pwd+1);
136                         torture_assert(tctx, pwd_array, "out of memory");
137                         pwd_array[num_pwd].pw_name = talloc_strdup(tctx, pwd->pw_name);
138                         pwd_array[num_pwd].pw_uid = pwd->pw_uid;
139                         pwd_array[num_pwd].pw_gid = pwd->pw_gid;
140                         num_pwd++;
141                 }
142         }
143
144         torture_comment(tctx, "Testing endpwent\n");
145         endpwent();
146
147         if (pwd_array_p) {
148                 *pwd_array_p = pwd_array;
149         }
150         if (num_pwd_p) {
151                 *num_pwd_p = num_pwd;
152         }
153
154         return true;
155 }
156
157 static bool test_nwrap_passwd(struct torture_context *tctx)
158 {
159         int i;
160         struct passwd *pwd;
161         size_t num_pwd;
162
163         torture_assert(tctx, test_nwrap_enum_passwd(tctx, &pwd, &num_pwd),
164                                                     "failed to enumerate passwd");
165
166         for (i=0; i < num_pwd; i++) {
167                 torture_assert(tctx, test_nwrap_getpwnam(tctx, pwd[i].pw_name),
168                         "failed to call getpwnam for enumerated user");
169                 torture_assert(tctx, test_nwrap_getpwuid(tctx, pwd[i].pw_uid),
170                         "failed to call getpwuid for enumerated user");
171         }
172
173         return true;
174 }
175
176 static bool test_nwrap_enum_group(struct torture_context *tctx,
177                                   struct group **grp_array_p,
178                                   size_t *num_grp_p)
179 {
180         struct group *grp;
181         struct group *grp_array = NULL;
182         size_t num_grp = 0;
183
184         torture_comment(tctx, "Testing setgrent\n");
185         setgrent();
186
187         while ((grp = getgrent()) != NULL) {
188                 torture_comment(tctx, "Testing getgrent\n");
189
190                 print_group(grp);
191                 if (grp_array_p && num_grp_p) {
192                         grp_array = talloc_realloc(tctx, grp_array, struct group, num_grp+1);
193                         torture_assert(tctx, grp_array, "out of memory");
194                         grp_array[num_grp].gr_name = talloc_strdup(tctx, grp->gr_name);
195                         grp_array[num_grp].gr_gid = grp->gr_gid;
196                         num_grp++;
197                 }
198         }
199
200         torture_comment(tctx, "Testing endgrent\n");
201         endgrent();
202
203         if (grp_array_p) {
204                 *grp_array_p = grp_array;
205         }
206         if (num_grp_p) {
207                 *num_grp_p = num_grp;
208         }
209
210
211         return true;
212 }
213
214 static bool test_nwrap_group(struct torture_context *tctx)
215 {
216         int i;
217         struct group *grp;
218         size_t num_grp;
219
220         torture_assert(tctx, test_nwrap_enum_group(tctx, &grp, &num_grp),
221                                                    "failed to enumerate group");
222
223         for (i=0; i < num_grp; i++) {
224                 torture_assert(tctx, test_nwrap_getgrnam(tctx, grp[i].gr_name),
225                         "failed to call getgrnam for enumerated user");
226                 torture_assert(tctx, test_nwrap_getgrgid(tctx, grp[i].gr_gid),
227                         "failed to call getgrgid for enumerated user");
228         }
229
230         return true;
231 }
232
233 static bool test_nwrap_getgrouplist(struct torture_context *tctx,
234                                     const char *user,
235                                     gid_t gid,
236                                     gid_t **gids_p,
237                                     int *num_gids_p)
238 {
239         int ret;
240         int num_groups = 0;
241         gid_t *groups = NULL;
242
243         torture_comment(tctx, "Testing getgrouplist: %s\n", user);
244
245         ret = getgrouplist(user, gid, NULL, &num_groups);
246         if (ret == -1 || num_groups != 0) {
247
248                 groups = talloc_array(tctx, gid_t, num_groups);
249                 torture_assert(tctx, groups, "out of memory\n");
250
251                 ret = getgrouplist(user, gid, groups, &num_groups);
252         }
253
254         torture_assert(tctx, (ret != -1), "failed to call getgrouplist");
255
256         torture_comment(tctx, "%s is member in %d groups\n", user, num_groups);
257
258         if (gids_p) {
259                 *gids_p = groups;
260         }
261         if (num_gids_p) {
262                 *num_gids_p = num_groups;
263         }
264
265         return true;
266 }
267
268 static bool test_nwrap_membership(struct torture_context *tctx)
269 {
270         const char *old_pwd = getenv("NSS_WRAPPER_PASSWD");
271         const char *old_group = getenv("NSS_WRAPPER_GROUP");
272         struct passwd *pwd;
273         size_t num_pwd;
274         int i;
275
276         if (!old_pwd || !old_group) {
277                 torture_skip(tctx, "nothing to test\n");
278                 return true;
279         }
280
281         torture_assert(tctx, test_nwrap_enum_passwd(tctx, &pwd, &num_pwd),
282                                                     "failed to enumerate passwd");
283
284         for (i=0; i < num_pwd; i++) {
285
286                 int num_user_groups = 0;
287                 gid_t *user_groups = NULL;
288                 int g;
289
290                 torture_assert(tctx, test_nwrap_getgrouplist(tctx,
291                                                              pwd[i].pw_name,
292                                                              pwd[i].pw_gid,
293                                                              &user_groups,
294                                                              &num_user_groups),
295                                                              "failed to test getgrouplist");
296
297                 for (g=0; g < num_user_groups; g++) {
298                         torture_assert(tctx, test_nwrap_getgrgid(tctx, user_groups[g]),
299                                 "failed to find the group the user is a member of");
300                 }
301         }
302
303         return true;
304 }
305
306 static bool test_nwrap_env(struct torture_context *tctx)
307 {
308         const char *old_pwd = getenv("NSS_WRAPPER_PASSWD");
309         const char *old_group = getenv("NSS_WRAPPER_GROUP");
310
311         if (!old_pwd || !old_group) {
312                 torture_skip(tctx, "nothing to test\n");
313                 return true;
314         }
315
316         torture_assert(tctx, test_nwrap_passwd(tctx),
317                         "failed to test users");
318         torture_assert(tctx, test_nwrap_group(tctx),
319                         "failed to test groups");
320
321         return true;
322 }
323
324 struct torture_suite *torture_local_nss_wrapper(TALLOC_CTX *mem_ctx)
325 {
326         struct torture_suite *suite = torture_suite_create(mem_ctx, "NSS-WRAPPER");
327
328         torture_suite_add_simple_test(suite, "env", test_nwrap_env);
329         torture_suite_add_simple_test(suite, "membership", test_nwrap_membership);
330
331         return suite;
332 }