selftest/Samba4: make more use of get_cmd_env_vars()
[Samba.git] / source4 / torture / libnetapi / libnetapi_group.c
blobf4b446d89d83f11e463ee178ec81188f23c1f432
1 /*
2 Unix SMB/CIFS implementation.
3 SMB torture tester
4 Copyright (C) Guenther Deschner 2009
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "includes.h"
21 #include "torture/smbtorture.h"
22 #include <netapi.h>
23 #include "torture/libnetapi/proto.h"
25 #undef strcasecmp
27 #define TORTURE_TEST_USER "testuser"
29 #define NETAPI_STATUS(tctx, x,y,fn) \
30 torture_warning(tctx, "FAILURE: line %d: %s failed with status: %s (%d)\n", \
31 __LINE__, fn, libnetapi_get_error_string(x,y), y);
33 #define NETAPI_STATUS_MSG(tctx, x,y,fn,z) \
34 torture_warning(tctx, "FAILURE: line %d: %s failed with status: %s (%d), %s\n", \
35 __LINE__, fn, libnetapi_get_error_string(x,y), y, z);
37 static NET_API_STATUS test_netgroupenum(struct torture_context *tctx,
38 const char *hostname,
39 uint32_t level,
40 const char *groupname)
42 NET_API_STATUS status;
43 uint32_t entries_read = 0;
44 uint32_t total_entries = 0;
45 uint32_t resume_handle = 0;
46 int found_group = 0;
47 const char *current_name = NULL;
48 uint8_t *buffer = NULL;
49 int i;
51 struct GROUP_INFO_0 *info0 = NULL;
52 struct GROUP_INFO_1 *info1 = NULL;
53 struct GROUP_INFO_2 *info2 = NULL;
54 struct GROUP_INFO_3 *info3 = NULL;
56 torture_comment(tctx, "Testing NetGroupEnum level %d\n", level);
58 do {
59 status = NetGroupEnum(hostname,
60 level,
61 &buffer,
62 (uint32_t)-1,
63 &entries_read,
64 &total_entries,
65 &resume_handle);
66 if (status == 0 || status == ERROR_MORE_DATA) {
67 switch (level) {
68 case 0:
69 info0 = (struct GROUP_INFO_0 *)buffer;
70 break;
71 case 1:
72 info1 = (struct GROUP_INFO_1 *)buffer;
73 break;
74 case 2:
75 info2 = (struct GROUP_INFO_2 *)buffer;
76 break;
77 case 3:
78 info3 = (struct GROUP_INFO_3 *)buffer;
79 break;
80 default:
81 return -1;
84 for (i=0; i<entries_read; i++) {
86 switch (level) {
87 case 0:
88 current_name = info0->grpi0_name;
89 break;
90 case 1:
91 current_name = info1->grpi1_name;
92 break;
93 case 2:
94 current_name = info2->grpi2_name;
95 break;
96 case 3:
97 current_name = info3->grpi3_name;
98 break;
99 default:
100 break;
103 if (strcasecmp(current_name, groupname) == 0) {
104 found_group = 1;
107 switch (level) {
108 case 0:
109 info0++;
110 break;
111 case 1:
112 info1++;
113 break;
114 case 2:
115 info2++;
116 break;
117 case 3:
118 info3++;
119 break;
122 NetApiBufferFree(buffer);
124 } while (status == ERROR_MORE_DATA);
126 if (status) {
127 return status;
130 if (!found_group) {
131 torture_comment(tctx, "failed to get group\n");
132 return -1;
135 return 0;
138 static NET_API_STATUS test_netgroupgetusers(struct torture_context *tctx,
139 const char *hostname,
140 uint32_t level,
141 const char *groupname,
142 const char *username)
144 NET_API_STATUS status;
145 uint32_t entries_read = 0;
146 uint32_t total_entries = 0;
147 uint32_t resume_handle = 0;
148 int found_user = 0;
149 const char *current_name = NULL;
150 uint8_t *buffer = NULL;
151 int i;
153 struct GROUP_USERS_INFO_0 *info0 = NULL;
154 struct GROUP_USERS_INFO_1 *info1 = NULL;
156 torture_comment(tctx, "Testing NetGroupGetUsers level %d\n", level);
158 do {
159 status = NetGroupGetUsers(hostname,
160 groupname,
161 level,
162 &buffer,
163 (uint32_t)-1,
164 &entries_read,
165 &total_entries,
166 &resume_handle);
167 if (status == 0 || status == ERROR_MORE_DATA) {
169 switch (level) {
170 case 0:
171 info0 = (struct GROUP_USERS_INFO_0 *)buffer;
172 break;
173 case 1:
174 info1 = (struct GROUP_USERS_INFO_1 *)buffer;
175 break;
176 default:
177 break;
179 for (i=0; i<entries_read; i++) {
180 switch (level) {
181 case 0:
182 current_name = info0->grui0_name;
183 break;
184 case 1:
185 current_name = info1->grui1_name;
186 break;
187 default:
188 break;
191 if (username && strcasecmp(current_name, username) == 0) {
192 found_user = 1;
195 switch (level) {
196 case 0:
197 info0++;
198 break;
199 case 1:
200 info1++;
201 break;
204 NetApiBufferFree(buffer);
206 } while (status == ERROR_MORE_DATA);
208 if (status) {
209 return status;
212 if (username && !found_user) {
213 torture_comment(tctx, "failed to get user\n");
214 return -1;
217 return 0;
220 static NET_API_STATUS test_netgroupsetusers(struct torture_context *tctx,
221 const char *hostname,
222 const char *groupname,
223 uint32_t level,
224 size_t num_entries,
225 const char **names)
227 NET_API_STATUS status;
228 uint8_t *buffer = NULL;
229 int i = 0;
230 size_t buf_size = 0;
232 struct GROUP_USERS_INFO_0 *g0 = NULL;
233 struct GROUP_USERS_INFO_1 *g1 = NULL;
235 torture_comment(tctx, "Testing NetGroupSetUsers level %d\n", level);
237 switch (level) {
238 case 0:
239 buf_size = sizeof(struct GROUP_USERS_INFO_0) * num_entries;
241 status = NetApiBufferAllocate(buf_size, (void **)&g0);
242 if (status) {
243 goto out;
246 for (i=0; i<num_entries; i++) {
247 g0[i].grui0_name = names[i];
250 buffer = (uint8_t *)g0;
251 break;
252 case 1:
253 buf_size = sizeof(struct GROUP_USERS_INFO_1) * num_entries;
255 status = NetApiBufferAllocate(buf_size, (void **)&g1);
256 if (status) {
257 goto out;
260 for (i=0; i<num_entries; i++) {
261 g1[i].grui1_name = names[i];
264 buffer = (uint8_t *)g1;
265 break;
266 default:
267 break;
270 /* NetGroupSetUsers */
272 status = NetGroupSetUsers(hostname,
273 groupname,
274 level,
275 buffer,
276 num_entries);
277 if (status) {
278 goto out;
281 out:
282 NetApiBufferFree(buffer);
283 return status;
286 bool torture_libnetapi_group(struct torture_context *tctx)
288 NET_API_STATUS status = 0;
289 const char *username, *groupname, *groupname2;
290 uint8_t *buffer = NULL;
291 struct GROUP_INFO_0 g0;
292 uint32_t parm_err = 0;
293 uint32_t levels[] = { 0, 1, 2, 3};
294 uint32_t enum_levels[] = { 0, 1, 2, 3};
295 uint32_t getmem_levels[] = { 0, 1};
296 int i;
297 const char *hostname = torture_setting_string(tctx, "host", NULL);
298 struct libnetapi_ctx *ctx;
300 torture_assert(tctx, torture_libnetapi_init_context(tctx, &ctx),
301 "failed to initialize libnetapi");
303 torture_comment(tctx, "NetGroup tests\n");
305 username = "torture_test_user";
306 groupname = "torture_test_group";
307 groupname2 = "torture_test_group2";
309 /* cleanup */
310 NetGroupDel(hostname, groupname);
311 NetGroupDel(hostname, groupname2);
312 NetUserDel(hostname, username);
314 /* add a group */
316 g0.grpi0_name = groupname;
318 torture_comment(tctx, "Testing NetGroupAdd\n");
320 status = NetGroupAdd(hostname, 0, (uint8_t *)&g0, &parm_err);
321 if (status) {
322 NETAPI_STATUS(tctx, ctx, status, "NetGroupAdd");
323 goto out;
326 /* 2nd add must fail */
328 status = NetGroupAdd(hostname, 0, (uint8_t *)&g0, &parm_err);
329 if (status == 0) {
330 NETAPI_STATUS(tctx, ctx, status, "NetGroupAdd");
331 status = -1;
332 goto out;
335 /* test enum */
337 for (i=0; i<ARRAY_SIZE(enum_levels); i++) {
339 status = test_netgroupenum(tctx, hostname, enum_levels[i], groupname);
340 if (status) {
341 NETAPI_STATUS(tctx, ctx, status, "NetGroupEnum");
342 goto out;
346 /* basic queries */
348 for (i=0; i<ARRAY_SIZE(levels); i++) {
350 torture_comment(tctx, "Testing NetGroupGetInfo level %d\n", levels[i]);
352 status = NetGroupGetInfo(hostname, groupname, levels[i], &buffer);
353 if (status && status != 124) {
354 NETAPI_STATUS(tctx, ctx, status, "NetGroupGetInfo");
355 goto out;
359 /* group rename */
361 g0.grpi0_name = groupname2;
363 torture_comment(tctx, "Testing NetGroupSetInfo level 0\n");
365 status = NetGroupSetInfo(hostname, groupname, 0, (uint8_t *)&g0, &parm_err);
366 switch ((uint32_t)status) {
367 case 0:
368 break;
369 case 50: /* not supported */
370 case 124: /* not implemented */
371 groupname2 = groupname;
372 goto skip_rename;
373 default:
374 NETAPI_STATUS(tctx, ctx, status, "NetGroupSetInfo");
375 goto out;
378 /* should not exist anymore */
380 status = NetGroupDel(hostname, groupname);
381 if (status == 0) {
382 NETAPI_STATUS(tctx, ctx, status, "NetGroupDel");
383 goto out;
386 skip_rename:
387 /* query info */
389 for (i=0; i<ARRAY_SIZE(levels); i++) {
391 status = NetGroupGetInfo(hostname, groupname2, levels[i], &buffer);
392 if (status && status != 124) {
393 NETAPI_STATUS(tctx, ctx, status, "NetGroupGetInfo");
394 goto out;
398 /* add user to group */
400 status = test_netuseradd(tctx, hostname, username);
401 if (status) {
402 NETAPI_STATUS(tctx, ctx, status, "NetUserAdd");
403 goto out;
406 /* should not be member */
408 for (i=0; i<ARRAY_SIZE(getmem_levels); i++) {
410 status = test_netgroupgetusers(tctx, hostname, getmem_levels[i], groupname2, NULL);
411 if (status) {
412 NETAPI_STATUS(tctx, ctx, status, "NetGroupGetUsers");
413 goto out;
417 torture_comment(tctx, "Testing NetGroupAddUser\n");
419 status = NetGroupAddUser(hostname, groupname2, username);
420 if (status) {
421 NETAPI_STATUS(tctx, ctx, status, "NetGroupAddUser");
422 goto out;
425 /* should be member */
427 for (i=0; i<ARRAY_SIZE(getmem_levels); i++) {
429 status = test_netgroupgetusers(tctx, hostname, getmem_levels[i], groupname2, username);
430 if (status) {
431 NETAPI_STATUS(tctx, ctx, status, "NetGroupGetUsers");
432 goto out;
436 torture_comment(tctx, "Testing NetGroupDelUser\n");
438 status = NetGroupDelUser(hostname, groupname2, username);
439 if (status) {
440 NETAPI_STATUS(tctx, ctx, status, "NetGroupDelUser");
441 goto out;
444 /* should not be member */
446 status = test_netgroupgetusers(tctx, hostname, 0, groupname2, NULL);
447 if (status) {
448 NETAPI_STATUS(tctx, ctx, status, "NetGroupGetUsers");
449 goto out;
452 /* set it again via exlicit member set */
454 status = test_netgroupsetusers(tctx, hostname, groupname2, 0, 1, &username);
455 if (status) {
456 NETAPI_STATUS(tctx, ctx, status, "NetGroupSetUsers");
457 goto out;
460 /* should be member */
462 status = test_netgroupgetusers(tctx, hostname, 0, groupname2, username);
463 if (status) {
464 NETAPI_STATUS(tctx, ctx, status, "NetGroupGetUsers");
465 goto out;
467 #if 0
468 /* wipe out member list */
470 status = test_netgroupsetusers(hostname, groupname2, 0, 0, NULL);
471 if (status) {
472 NETAPI_STATUS(tctx, ctx, status, "NetGroupSetUsers");
473 goto out;
476 /* should not be member */
478 status = test_netgroupgetusers(hostname, 0, groupname2, NULL);
479 if (status) {
480 NETAPI_STATUS(tctx, ctx, status, "NetGroupGetUsers");
481 goto out;
483 #endif
484 status = NetUserDel(hostname, username);
485 if (status) {
486 NETAPI_STATUS(tctx, ctx, status, "NetUserDel");
487 goto out;
490 /* delete */
492 torture_comment(tctx, "Testing NetGroupDel\n");
494 status = NetGroupDel(hostname, groupname2);
495 if (status) {
496 NETAPI_STATUS(tctx, ctx, status, "NetGroupDel");
497 goto out;
500 /* should not exist anymore */
502 status = NetGroupGetInfo(hostname, groupname2, 0, &buffer);
503 if (status == 0) {
504 NETAPI_STATUS_MSG(tctx, ctx, status, "NetGroupGetInfo", "expected failure and error code");
505 status = -1;
506 goto out;
509 status = 0;
511 torture_comment(tctx, "NetGroup tests succeeded\n");
512 out:
513 if (status != 0) {
514 torture_comment(tctx, "NetGroup testsuite failed with: %s\n",
515 libnetapi_get_error_string(ctx, status));
516 libnetapi_free(ctx);
517 return false;
520 libnetapi_free(ctx);
521 return true;