Bug Summary

File:tptserver/./../ptserver/testpt.c
Location:line 687, column 3
Description:Branch condition evaluates to a garbage value

Annotated Source Code

1/*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
4 *
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
9
10#include <afsconfig.h>
11#include <afs/param.h>
12
13#include <roken.h>
14
15#include <ctype.h>
16#include <math.h>
17
18#ifdef AFS_NT40_ENV
19#include <WINNT/afsevent.h>
20#endif
21
22#include <rx/rx.h>
23#include <rx/xdr.h>
24#include <afs/rxgen_consts.h>
25#include <afs/cmd.h>
26#include <afs/auth.h>
27#include <afs/cellconfig.h>
28#include <afs/afsutil.h>
29#include <afs/com_err.h>
30
31#include "ptclient.h"
32#include "pterror.h"
33#include "ptuser.h"
34#include "ptprototypes.h"
35
36static char *whoami = "testpr";
37static struct afsconf_dir *conf; /* cell info, set by MyBeforeProc */
38static char conf_dir[100];
39static char lcell[MAXCELLCHARS64];
40
41int
42ListUsedIds(struct cmd_syndesc *as, void *arock)
43{
44 afs_int32 code;
45 namelist lnames;
46 idlist lids;
47 int i, j;
48 int group = 0; /* check groups */
49 int unused = 0; /* print unused */
50 int number = 100; /* check 100 ids */
51 afs_int32 startId = 1;
52 afs_int32 maxId;
53 int range;
54
55 if (as->parms[0].items)
56 startId = atoi(as->parms[0].items->data);
57 if (as->parms[1].items)
58 number = atoi(as->parms[1].items->data);
59 if (as->parms[2].items)
60 unused = 1;
61
62 code = pr_Initialize(1, conf_dir, NULL((void *)0));
63 if (code) {
64 afs_com_err(whoami, code, "initializing pruser");
65 exit(1);
66 }
67 if (startId < 0) {
68 group = 1;
69 code = pr_ListMaxGroupId(&maxId);
70 if (code) {
71 bad_max:
72 afs_com_err(whoami, code, "getting maximum id");
73 exit(2);
74 }
75 if (startId < maxId) {
76 fprintf(stderr__stderrp, "Max group id is only %d.\n", maxId);
77 exit(3);
78 }
79 } else {
80 code = pr_ListMaxUserId(&maxId);
81 if (code)
82 goto bad_max;
83 if (startId > maxId) {
84 fprintf(stderr__stderrp, "Max user id is only %d.\n", maxId);
85 exit(3);
86 }
87 }
88 range = abs(startId - maxId);
89 if (range < 0)
90 range = -range;
91 range++; /* number that can be printed */
92 if (range < number) {
93 fprintf(stderr__stderrp, "Only %d ids to be checked.\n", range);
94 number = range;
95 }
96
97 printf("Checking for %d %sused ids starting at %d.\n", number,
98 (unused ? "un" : ""), startId);
99#define NUM100 100
100 lids.idlist_val = (afs_int32 *) malloc(sizeof(afs_int32) * NUM100);
101 lnames.namelist_len = 0;
102 lnames.namelist_val = 0;
103 while (number) {
104 if (number < NUM100)
105 i = number;
106 else
107 i = NUM100;
108 for (j = 0; j < i; j++) {
109 lids.idlist_val[j] = startId;
110 if (group)
111 startId--;
112 else
113 startId++;
114 }
115 lids.idlist_len = i;
116 code = pr_IdToName(&lids, &lnames);
117 if (code) {
118 afs_com_err(whoami, code, "converting id to name");
119 exit(2);
120 }
121 for (j = 0; j < lnames.namelist_len; j++) {
122 if (lids.idlist_val[j] == atoi(lnames.namelist_val[j])) {
123 if (unused)
124 printf("%s is free\n", lnames.namelist_val[j]);
125 } else {
126 if (!unused)
127 printf("%s is id %d\n", lnames.namelist_val[j],
128 lids.idlist_val[j]);
129 }
130 }
131 number -= i;
132 }
133 if (lids.idlist_val)
134 free(lids.idlist_val);
135 if (lnames.namelist_val)
136 free(lnames.namelist_val);
137 return 0;
138}
139
140/* TestManyMembers - called with a number N. Try creating N users and N groups
141 * and put all the users on one of the groups and one of the users on all the
142 * groups. Also put many users on many groups.
143 *
144 * To keep track of this create an NxN matrix of membership and fill it in with
145 * a function that looks like a quarter of a circle. That makes the first
146 * group contain every user and the first user be a member of every group. */
147
148int verbose;
149char callerName[PR_MAXNAMELEN64];
150afs_int32 callerId;
151afs_int32 lastGroup; /* id of last group created */
152afs_int32 ownerUser; /* first created user */
153char ownerUserName[PR_MAXNAMELEN64]; /* " " " name */
154int steepDropOff; /* precentage decreate in GroupLimit */
155char *createPrefix; /* prefix for naming users&groups */
156extern struct ubik_client *pruclient; /* initialized by pr_Initialize */
157
158/* These variables form the state if this test */
159int number; /* max number of members */
160char *population; /* matrix of memberships */
161afs_int32 *users; /* ids of users */
162afs_int32 *groups; /* ids of groups */
163afs_int32 *groupOwners; /* ids of owners of groups */
164
165/* statistics */
166int nUsers, nGroups, nAdds, nRems, nUDels, nGDels;
167
168int
169IdCmp(const void *a, const void *b)
170{
171 if (*(afs_int32 *)a > *(afs_int32 *)b) {
172 return 1;
173 } else if (*(afs_int32 *)a == *(afs_int32 *)b) {
174 return 0;
175 } else /* (*a < *b) */ {
176 return -1;
177 }
178}
179
180static int
181sqr(int n)
182{
183 return n * n;
184}
185
186static int
187GetGroupLimit(int N, int x)
188{
189 int y;
190
191 if ((x >= N) || (x < 0)) {
192 printf("GetGroupLimit: input value out of range %d (%d)\n", x, N);
193 exit(10);
194 }
195 if (steepDropOff) { /* Use exponential decrease */
196 int i;
197 y = N;
198 for (i = 0; i < x; i++) {
199 y = (y * steepDropOff) / 100; /* parameter is a percentage */
200 if (y == 0) {
201 y = 1; /* with a floor of 1 */
202 break;
203 }
204 }
205 } else { /* Use a circle's third quadrant */
206 y = sqr(N - 1) - sqr(N - 1 - x);
207 y = (int)(sqrt((double)y) + 0.5); /* round off */
208 y = N - y;
209 }
210 if ((y > N) || (y < 1)) {
211 printf("filling value out of range: %d (%d) => %d\n", x, N, y);
212 exit(11);
213 }
214 return y;
215}
216
217void
218CreateUser(int u)
219{
220 afs_int32 code;
221 char name[16];
222 afs_int32 id;
223
224 sprintf(name, "%s%d", createPrefix, u);
225 id = 0;
226 code = pr_CreateUser(name, &id);
227 if (code) {
228 if (code == PREXIST(267264L)) {
229 code = pr_Delete(name);
230 if (code == 0) {
231 nUDels++;
232 code = pr_CreateUser(name, &id);
233 if (code == 0) {
234 if (verbose)
235 printf("RE-");
236 goto done;
237 }
238 }
239 }
240 afs_com_err(whoami, code, "couldn't create %s", name);
241 exit(12);
242 }
243 done:
244 if (verbose)
245 printf("Creating user %s (%di)\n", name, id);
246 users[u] = id;
247 nUsers++;
248
249 if (ownerUser == 0) {
250 ownerUser = id;
251 strcpy(ownerUserName, name);
252 }
253}
254
255void
256CreateGroup(int g)
257{
258 afs_int32 code;
259 char name[16];
260 afs_int32 id = 0;
261 afs_int32 owner = 0;
262 char *ownerName = NULL((void *)0);
263 int ownerType; /* type of ownership */
264 static char *lastGroupPrefix; /* prefix used for type==2 */
265
266 /* At least 50 groups should be owned by another group to test long owner
267 * chains during deletion. Also let's create some long owners of owners
268 * lists. */
269 ownerType = random() % 3;
270
271 if (!ownerUser)
272 ownerType = 0;
273 if (!lastGroup)
274 ownerType = 0;
275 switch (ownerType) {
276 case 0:
277 owner = callerId;
278 ownerName = callerName;
279 break;
280 case 1:
281 owner = ownerUser;
282 ownerName = ownerUserName;
283 break;
284 case 2:
285 owner = lastGroup;
286 ownerName = lastGroupPrefix;
287 break;
288 }
289
290 sprintf(name, "%s:%s%d", ownerName, createPrefix, g);
291 code = ubik_PR_NewEntry(pruclient, 0, name, PRGRP2, owner, &id);
292 if (code) {
293 if (code == PREXIST(267264L)) {
294 code = pr_Delete(name);
295 if (code == 0) {
296 nGDels++;
297 code =
298 ubik_PR_NewEntry(pruclient, 0, name, PRGRP2, owner,
299 &id);
300 if (code == 0) {
301 if (verbose)
302 printf("RE-");
303 goto done;
304 }
305 }
306 }
307 afs_com_err(whoami, code, "couldn't create %s w/ owner=%d", name, owner);
308 exit(13);
309 }
310 done:
311 if (verbose)
312 printf("Creating group %s (%di)\n", name, id);
313 groups[g] = id;
314 groupOwners[g] = owner;
315 nGroups++;
316 if (!lastGroup || (ownerType == 2)) {
317 lastGroup = id;
318 lastGroupPrefix = ownerName;
319 }
320}
321
322int
323DeleteRandomId(afs_int32 *list)
324{
325 afs_int32 code;
326 afs_int32 id;
327 int j, k;
328 int m;
329
330 k = random(); /* random starting point */
331 for (j = 0; j < number; j++) { /* find an undeleted id */
332 m = (k + j) % number;
333 if ((id = list[m])) {
334 code = ubik_PR_Delete(pruclient, 0, id);
335 if (code) {
336 afs_com_err(whoami, code, "Couldn't delete %di", id);
337 exit(22);
338 }
339 list[m] = 0;
340 if (list == users)
341 nUDels++;
342 else
343 nGDels++;
344 return 0;
345 }
346 }
347 return -1; /* none left */
348}
349
350void
351AddUser(int u, int g)
352{
353 afs_int32 code;
354 afs_int32 ui, gi;
355
356 if (users[u] == 0) /* create if necessary */
357 CreateUser(u);
358 if (groups[g] == 0) /* create group if necessary */
359 CreateGroup(g);
360 ui = users[u];
361 gi = groups[g];
362 code = ubik_PR_AddToGroup(pruclient, 0, ui, gi);
363 if (code) {
364 afs_com_err(whoami, code, "couldn't add %d to %d", ui, gi);
365 exit(14);
366 }
367 if (verbose)
368 printf("Adding user (%di) to group (%di)\n", ui, gi);
369 population[u * number + g]++;
370 nAdds++;
371}
372
373void
374RemUser(int u, int g)
375{
376 afs_int32 code;
377 afs_int32 ui, gi;
378
379 ui = users[u];
380 gi = groups[g];
381 code = ubik_PR_RemoveFromGroup(pruclient, 0, ui, gi);
382 if (code) {
383 afs_com_err(whoami, code, "couldn't remove %d from %d", ui, gi);
384 exit(14);
385 }
386 if (verbose)
387 printf("Removing user (%di) from group (%di)\n", ui, gi);
388 population[u * number + g]--;
389 nRems++;
390}
391
392int
393TestManyMembers(struct cmd_syndesc *as, void *arock)
394{
395 char *filled; /* users filled up */
396 char *cleaned; /* users cleaned up */
397
398 int nFilled, nCleaned;
399 int u, g, i, j, n;
400 int seed; /* random number generator seed */
401
402 afs_int32 *glist; /* membership list */
403
404 afs_int32 code;
405
406 code = pr_Initialize(1, conf_dir, NULL((void *)0));
407 if (code) {
1
Taking false branch
408 afs_com_err(whoami, code, "initializing pruser");
409 exit(1);
410 }
411 /* get name of person running command */
412 {
413 struct ktc_principal afs, user;
414 struct ktc_token token;
415
416 strcpy(afs.name, "afs");
417 strcpy(afs.instance, "");
418 code = afsconf_GetLocalCell(conf, afs.cell, sizeof(afs.cell));
419 if (code)
2
Taking false branch
420 exit(2);
421 code = ktc_GetToken(&afs, &token, sizeof(token), &user);
422 if (code) {
3
Taking false branch
423 afs_com_err(whoami, code, "getting afs tokens");
424 exit(3);
425 }
426 if (strlen(user.instance) > 0) {
4
Taking false branch
427 fprintf(stderr__stderrp, "can't handle non-null instance %s.%s\n",
428 user.name, user.cell);
429 exit(4);
430 }
431 if (strncmp(user.name, "AFS ID ", 7) == 0) {
5
Taking false branch
432 callerId = atoi(user.name + 7);
433 code = pr_SIdToName(callerId, callerName);
434 if (code) {
435 afs_com_err(whoami, code, "call get name for id %d", callerId);
436 exit(6);
437 }
438 } else {
439 strcpy(callerName, user.name);
440 code = pr_SNameToId(callerName, &callerId);
441 if ((code == 0) && (callerId == ANONYMOUSID32766))
6
Taking false branch
442 code = PRNOENT(267268L);
443 }
444#if 0 /* don't create user */
445 if (code == PRNOENT(267268L)) {
446 callerId = 0;
447 code = pr_CreateUser(callerName, &callerId);
448 if (code) {
449 afs_com_err(whoami, code, "can't create caller %s", callerName);
450 exit(5);
451 }
452 printf("Creating caller %s (%di)\n", callerName, callerId);
453 }
454 /* else */
455#endif
456 if (code) {
7
Taking false branch
457 afs_com_err(whoami, code, "can't find caller %s", callerName);
458 exit(6);
459 } else
460 printf("Assuming caller is %s (%di)\n", callerName, callerId);
461 }
462
463 /* Parse arguments */
464 if (as->parms[0].items)
8
Taking false branch
465 number = atoi(as->parms[0].items->data);
466 if (as->parms[1].items) {
9
Taking false branch
467 steepDropOff = atoi(as->parms[1].items->data);
468 if ((steepDropOff < 0) || (steepDropOff > 100)) {
469 fprintf(stderr__stderrp,
470 "Illegal value for dropoff: %d, must be between 0 and 100, inclusive.\n",
471 steepDropOff);
472 exit(7);
473 }
474 } else
475 steepDropOff = 0; /* use quadratic dropoff */
476 if (as->parms[2].items)
10
Taking false branch
477 createPrefix = as->parms[2].items->data;
478 else
479 createPrefix = "u";
480 if (as->parms[3].items)
11
Taking false branch
481 verbose = 1;
482 else
483 verbose = 0;
484 if (as->parms[4].items)
12
Taking false branch
485 seed = atoi(as->parms[4].items->data);
486 else
487 seed = 1;
488
489 srandom(seed);
490
491 users = (afs_int32 *) malloc(number * sizeof(afs_int32));
492 groups = (afs_int32 *) malloc(number * sizeof(afs_int32));
493 filled = (char *)malloc(number * sizeof(char));
494 cleaned = (char *)malloc(number * sizeof(char));
495 population = (char *)malloc(sqr(number) * sizeof(char));
496
497 nFilled = 0;
498 memset(filled, 0, number);
499 nCleaned = 0;
500 memset(cleaned, 0, number);
501 memset(population, 0, sqr(number));
502 memset(users, 0, number * sizeof(afs_int32));
503 memset(groups, 0, number * sizeof(afs_int32));
504
505 ownerUser = lastGroup = 0;
506 groupOwners = (afs_int32 *) malloc(number * sizeof(afs_int32));
507 nUsers = nGroups = nAdds = nRems = nUDels = nGDels = 0;
508
509 while ((nFilled < number) || (nCleaned < number)) {
13
Loop condition is false. Execution continues on line 564
510 /* pick a user at random, using */
511 u = random() % number;
512 if (!filled[u]) {
513 n = GetGroupLimit(number, u); /* get group limit for that user */
514 g = random() % (n + 1); /* pick a random group */
515 if (g == n) { /* in a few cases create any user */
516 n = number; /* in the whole range */
517 g = random() % n;
518 }
519 for (i = 0; i < n; i++) { /* rotate until unused one found */
520 j = (g + i) % n;
521 if (!population[u * number + j]) {
522 /* add this user/group membership */
523 AddUser(u, j);
524 goto added;
525 }
526 }
527 filled[u]++;
528 nFilled++;
529 added:;
530 }
531 if (!cleaned[u]) {
532 int base;
533 if (filled[u]) { /* only clean above GroupLimit */
534 base = GetGroupLimit(number, u);
535 n = number - base;
536 if (n == 0)
537 goto iscleaned;
538 g = random() % n;
539 } else {
540 base = 0;
541 n = number; /* pick a group from the whole range */
542 g = random() % 2 * n; /* at random for removal */
543 if (g >= n)
544 goto remed; /* but half the time do nothing */
545 }
546 for (i = 0; i < n; i++) { /* rotate until used one found */
547 j = (g + i) % n + base;
548 if (population[u * number + j]) {
549 /* remove this user/group membership */
550 RemUser(u, j);
551 goto remed;
552 }
553 }
554 if (filled[u]) { /* track finished ones */
555 iscleaned:
556 cleaned[u]++;
557 nCleaned++;
558 }
559 remed:;
560 }
561 }
562
563 /* check the membership list of all users for correctness */
564 printf("Starting check of memberships\n");
565 glist = (afs_int32 *) malloc(number * sizeof(afs_int32));
566 for (u = 0; u < number; u++) {
14
Loop condition is true. Entering loop body
567 afs_int32 ui = users[u];
568 if (ui) {
15
Taking true branch
569 int i;
570 int ng; /* number groups */
571 int over;
572 int (*proc)(struct ubik_client *, afs_int32, afs_int32, prlist *,
573 afs_int32 *);
574 prlist alist;
575
576 alist.prlist_len = 0;
577 alist.prlist_val = 0;
578 if (random() & 4) {
16
Taking false branch
579 proc = ubik_PR_ListElements;
580 } else {
581 proc = ubik_PR_GetCPS;
582 }
583 code = (*proc)(pruclient, 0, ui, &alist, &over);
584 if (code) {
17
Taking false branch
585 afs_com_err(whoami, code,
586 "getting membership list of (%di) using %s", ui,
587 (proc == ubik_PR_ListElements?"ListElements":"GetCPS"));
588 exit(24);
589 }
590 if (over) {
18
Taking false branch
591 fprintf(stderr__stderrp, "membership list for id %di too long\n", ui);
592 }
593 ng = 0;
594 for (i = 0; i < number; i++)
19
Loop condition is false. Execution continues on line 597
595 if (population[u * number + i])
596 glist[ng++] = groups[i];
597 qsort(glist, ng, sizeof(afs_int32), IdCmp);
598 if (ng != (alist.prlist_len - ((proc == ubik_PR_GetCPS) ? 3 : 0))) {
20
'?' condition is true
21
Taking false branch
599 fprintf(stderr__stderrp,
600 "Membership list for %di of unexpected length: was %d but expected %d\n",
601 ui, alist.prlist_len, ng);
602 exit(20);
603 }
604 /* all the extra entries for the CPS should be at the end. */
605 code = 0;
606 for (i = 0; i < ng; i++)
22
Loop condition is false. Execution continues on line 613
607 if (alist.prlist_val[i] != glist[i]) {
608 fprintf(stderr__stderrp,
609 "membership for %di not correct: was %di but expected %di\n",
610 ui, alist.prlist_val[i], glist[i]);
611 code++;
612 }
613 if (code)
23
Taking false branch
614 exit(21);
615 if (proc == ubik_PR_GetCPS) {
24
Taking true branch
616 if ((alist.prlist_val[i /* =ng */ ] != AUTHUSERID-102) ||
25
Taking false branch
617 (alist.prlist_val[++i] != ANYUSERID-101)
618 || (alist.prlist_val[++i] != ui)) {
619 fprintf(stderr__stderrp, "CPS doesn't have extra entries\n");
620 exit(27);
621 }
622 }
623 if (alist.prlist_val)
26
Taking true branch
624 free(alist.prlist_val);
625
626 /* User 0 is a member of all groups all of which should also be on
627 * the owner list of the caller or the ownerUser, although there
628 * may also be others. Check this. */
629 if (u == 0) {
27
Taking true branch
630 prlist callerList;
631 prlist ownerList;
632 prlist lastGroupList;
633 int i, j, k, l;
634
635 if (ng != number) {
28
Taking false branch
636 fprintf(stderr__stderrp, "User 0 not a member of all groups\n");
637 exit(26);
638 }
639#define GETOWNED(xlist,xid)(xlist).prlist_val = 0; (xlist).prlist_len = 0; code = ubik_PR_ListOwned
(pruclient, 0, (xid), &(xlist), &over); if (code) { afs_com_err
(whoami, code, "getting owner list of (%di)", (xid)); exit (
23); } if (over) { fprintf (__stderrp, "membership of id %di too long\n"
, (xid)); }
\
640 (xlist).prlist_val = 0; (xlist).prlist_len = 0; \
641 code = ubik_PR_ListOwned(pruclient, 0, (xid), &(xlist), &over); \
642 if (code) { \
643 afs_com_err (whoami, code, "getting owner list of (%di)", (xid)); \
644 exit (23); } \
645 if (over) \
646 { fprintf (stderr__stderrp, "membership of id %di too long\n", (xid)); }
647
648 GETOWNED(callerList, callerId)(callerList).prlist_val = 0; (callerList).prlist_len = 0; code
= ubik_PR_ListOwned(pruclient, 0, (callerId), &(callerList
), &over); if (code) { afs_com_err (whoami, code, "getting owner list of (%di)"
, (callerId)); exit (23); } if (over) { fprintf (__stderrp, "membership of id %di too long\n"
, (callerId)); }
;
649 GETOWNED(ownerList, ownerUser)(ownerList).prlist_val = 0; (ownerList).prlist_len = 0; code =
ubik_PR_ListOwned(pruclient, 0, (ownerUser), &(ownerList
), &over); if (code) { afs_com_err (whoami, code, "getting owner list of (%di)"
, (ownerUser)); exit (23); } if (over) { fprintf (__stderrp, "membership of id %di too long\n"
, (ownerUser)); }
;
650
651 /* look for every entry in glist, in all the owner lists */
652 for (i = j = k = l = 0; i < number; i++) {
29
Loop condition is false. Execution continues on line 683
653 while ((j < callerList.prlist_len)
654 && (callerList.prlist_val[j] < glist[i]))
655 j++;
656 while ((k < ownerList.prlist_len)
657 && (ownerList.prlist_val[k] < glist[i]))
658 k++;
659#define PRLISTCMP(l,i)(((l).prlist_len == 0) || (glist[i] != (l).prlist_val[(i)])) \
660 (((l).prlist_len == 0) || (glist[i] != (l).prlist_val[(i)]))
661 if (PRLISTCMP(callerList, j)(((callerList).prlist_len == 0) || (glist[j] != (callerList).
prlist_val[(j)]))
&& PRLISTCMP(ownerList, k)(((ownerList).prlist_len == 0) || (glist[k] != (ownerList).prlist_val
[(k)]))
) {
662 for (l = 0; l < number; l++) {
663 if (groups[l] == glist[i]) {
664 if ((groupOwners[l] != callerId)
665 && (groupOwners[l] != ownerUser)) {
666 GETOWNED(lastGroupList, groupOwners[l])(lastGroupList).prlist_val = 0; (lastGroupList).prlist_len = 0
; code = ubik_PR_ListOwned(pruclient, 0, (groupOwners[l]), &
(lastGroupList), &over); if (code) { afs_com_err (whoami,
code, "getting owner list of (%di)", (groupOwners[l])); exit
(23); } if (over) { fprintf (__stderrp, "membership of id %di too long\n"
, (groupOwners[l])); }
;
667 if ((lastGroupList.prlist_len != 1)
668 || (lastGroupList.prlist_val[0] !=
669 glist[i])) {
670 fprintf(stderr__stderrp,
671 "Group (%di) not on any owner list\n",
672 glist[i]);
673 exit(25);
674 }
675 }
676 goto foundLast;
677 }
678 }
679 fprintf(stderr__stderrp, "unexpected group %di\n", glist[i]);
680 foundLast:;
681 }
682 }
683 if (callerList.prlist_val)
30
Taking false branch
684 free(callerList.prlist_val);
685 if (ownerList.prlist_val)
31
Taking false branch
686 free(ownerList.prlist_val);
687 if (lastGroupList.prlist_val)
32
Branch condition evaluates to a garbage value
688 free(lastGroupList.prlist_val);
689 }
690 }
691 }
692
693 /* cleanup by deleting all the users and groups */
694 printf("Starting deletion of users and groups\n");
695 for (i = 0; i < number; i++) {
696 DeleteRandomId(users);
697 DeleteRandomId(groups);
698 }
699
700 printf
701 ("Created/deleted %d/%d users and %d/%d groups; added %d and removed %d.\n",
702 nUsers, nUDels, nGroups, nGDels, nAdds, nRems);
703 return 0;
704}
705
706/* from ka_ConvertBytes included here to avoid circularity */
707/* Converts a byte string to ascii. Return the number of unconverted bytes. */
708
709static int
710ka_ConvertBytes(char *ascii, /* output buffer */
711 int alen, /* buffer length */
712 char bs[], /* byte string */
713 int bl) /* number of bytes */
714{
715 int i;
716 unsigned char c;
717
718 alen--; /* make room for termination */
719 for (i = 0; i < bl; i++) {
720 c = bs[i];
721 if (alen <= 0)
722 return bl - i;
723 if (isalnum(c)__sbistype((c), 0x00000100L|0x00000400L) || ispunct(c)__sbistype((c), 0x00002000L))
724 (*ascii++ = c), alen--;
725 else {
726 if (alen <= 3)
727 return bl - i;
728 *ascii++ = '\\';
729 *ascii++ = (c >> 6) + '0';
730 *ascii++ = (c >> 3 & 7) + '0';
731 *ascii++ = (c & 7) + '0';
732 alen -= 4;
733 }
734 }
735 *ascii = 0; /* terminate string */
736 return 0;
737}
738
739/* This runs various tests on the server. It creates, then deletes, a bunch of
740 * users and groups, so it would be safest to run it on a test database.
741 *
742 * These are the things I check for:
743 * User names longer than PR_MAXNAMELEN - strlen(cellname).
744 * Group names longer than PR_MAXNAMELEN.
745 * User names containing all legal 8-bit ascii characters. This excludes
746 * only ':', '@', and '\n'.
747 * Group names as above, but at least one colon is required, and the owner
748 * must be correct.
749 */
750
751int
752TestPrServ(struct cmd_syndesc *as, void *arock)
753{
754 afs_int32 id;
755 char name[PR_MAXNAMELEN64 + 1];
756 char creator[PR_MAXNAMELEN64]; /* our name */
757 struct prcheckentry ent;
758 afs_int32 code;
759 int i, j;
760 int maxLen = PR_MAXNAMELEN64 - 1 - strlen(lcell) - 1;
761
762 code = pr_Initialize(1, conf_dir, NULL((void *)0));
763 if (code) {
764 afs_com_err(whoami, code, "initializing pruser");
765 exit(1);
766 }
767
768 for (i = 0; i < maxLen; i++)
769 name[i] = 'a';
770 name[i] = 'a'; /* too long a name... */
771 name[i + 1] = 0;
772 id = 0;
773 code = pr_CreateUser(name, &id);
774 if ((code != RXGEN_CC_MARSHAL-450) && (code != PRBADNAM(267272L))) {
775 afs_com_err(whoami, code, "succeeded creating %s", name);
776 exit(2);
777 }
778 name[i] = 0;
779 id = 0;
780 code = pr_CreateUser(name, &id);
781 if (code == PREXIST(267264L)) {
782 fprintf(stderr__stderrp, "group already exists, skipping\n");
783 pr_SNameToId(name, &id);
784 } else if (code) {
785 afs_com_err(whoami, code, "failed creating %s", name);
786 exit(3);
787 }
788 if ((code = pr_ListEntry(id, &ent))
789 || (code = pr_SIdToName(ent.creator, creator))) {
790 afs_com_err(whoami, code, "getting creator's name");
791 exit(5);
792 }
793 code = pr_DeleteByID(id);
794 if (code) {
795 afs_com_err(whoami, code, "deleting %s", name);
796 exit(6);
797 }
798 /* now make sure the illegal chars are detected */
799 {
800 char *illegalChars;
801 for (illegalChars = "@:\n"; *illegalChars; illegalChars++) {
802 name[10] = *illegalChars;
803 id = 0;
804 code = pr_CreateUser(name, &id);
805 if (code != PRBADNAM(267272L)) {
806 afs_com_err(whoami, code, "succeeded creating %s", name);
807 exit(8);
808 }
809 }
810 }
811
812 for (i = 1; i <= 255;) { /* for all 8-bit ascii... */
813 j = 0; /* build a new name */
814 while ((j < maxLen) && (i <= 255)) {
815 if (!((i == ':') || (i == '@') || (i == '\n')))
816 name[j++] = i;
817 i++;
818 }
819 name[j] = 0; /* terminate string */
820 id = 0;
821 code = pr_CreateUser(name, &id);
822 if (code == PREXIST(267264L)) {
823 fprintf(stderr__stderrp, "user already exists, skipping\n");
824 pr_SNameToId(name, &id);
825 } else if (code) {
826 char ascii[BUFSIZ1024];
827 ka_ConvertBytes(ascii, sizeof(ascii), name, strlen(name));
828 afs_com_err(whoami, code, "failed creating %s", ascii);
829 exit(4);
830 }
831 code = pr_DeleteByID(id);
832 if (code) {
833 afs_com_err(whoami, code, "deleting %s", name);
834 exit(7);
835 }
836 }
837
838 /* now check group names */
839 strcpy(name, creator);
840 strcat(name, ":abcdefghijklmnopqrstuvwxyz");
841 name[0] = 1; /* bash the owner name */
842 id = 0;
843 code = pr_CreateGroup(name, creator, &id);
844 if (code != PRNOENT(267268L)) { /* owner doesn't exist */
845 afs_com_err(whoami, code, "succeeded creating %s", name);
846 exit(9);
847 }
848 name[0] = creator[0]; /* fix owner */
849 /* Make sure the illegal chars are detected */
850 {
851 char *illegalChars;
852 for (illegalChars = ":@\n"; *illegalChars; illegalChars++) {
853 name[strlen(creator) + 10] = *illegalChars;
854 id = 0;
855 code = pr_CreateGroup(name, creator, &id);
856 if (code != PRBADNAM(267272L)) {
857 afs_com_err(whoami, code, "succeeded creating %s", name);
858 exit(10);
859 }
860 }
861 }
862 for (i = 1; i <= 255;) { /* for all 8-bit ascii... */
863 j = strlen(creator) + 1; /* build a new name */
864 while ((j < PR_MAXNAMELEN64 - 1) && (i <= 255)) {
865 if (!((i == ':') || (i == '@') || (i == '\n')))
866 name[j++] = i;
867 i++;
868 }
869 name[j] = 0; /* terminate string */
870 id = 0;
871 code = pr_CreateGroup(name, creator, &id);
872 if (code == PREXIST(267264L)) {
873 fprintf(stderr__stderrp, "group already exists, skipping\n");
874 pr_SNameToId(name, &id);
875 } else if (code) {
876 char ascii[BUFSIZ1024];
877 ka_ConvertBytes(ascii, sizeof(ascii), name, strlen(name));
878 afs_com_err(whoami, code, "failed creating %s", ascii);
879 exit(4);
880 }
881 code = pr_DeleteByID(id);
882 if (code) {
883 afs_com_err(whoami, code, "deleting %s", name);
884 exit(7);
885 }
886 }
887
888 printf("All OK\n");
889 return 0;
890}
891
892static char tmp_conf_dir[128] = "";
893static char tmp_conf_file[128] = "";
894static char tmp_cell_file[128] = "";
895static char tmp_noauth_file[128] = "";
896
897static int
898MyAfterProc(struct cmd_syndesc *as, void *arock)
899{
900 if (strlen(tmp_conf_file))
901 unlink(tmp_conf_file);
902 if (strlen(tmp_cell_file))
903 unlink(tmp_cell_file);
904 if (strlen(tmp_noauth_file))
905 unlink(tmp_noauth_file);
906 if (strlen(tmp_conf_dir))
907 rmdir(tmp_conf_dir);
908 return 0;
909}
910
911static int
912MyBeforeProc(struct cmd_syndesc *as, void *arock)
913{
914 afs_int32 code;
915 int i;
916 char *cdir = 0;
917 int noAuth = 0;
918 struct cmd_item *serverList = 0;
919 struct afsconf_dir *local_conf = 0; /* so we can default stuff nicely */
920 struct afsconf_cell cellinfo;
921
922 if (as->parms[12].items) { /* if conf dir specified */
923 cdir = as->parms[12].items->data;
924 if (as->parms[13].items || as->parms[14].items || as->parms[15].items) {
925 printf("Can't specify conf dir and other cell parameters\n");
926 return AFSCONF_SYNTAX(70354692L);
927 }
928 }
929
930 /* if we need to default cell name or cell servers, get local conf info */
931
932 if (!(local_conf = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATHgetDirPath(AFSDIR_CLIENT_ETC_DIRPATH_ID)))
933 && !(local_conf = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATHgetDirPath(AFSDIR_SERVER_ETC_DIRPATH_ID)))) {
934 printf("** Can't local configuration!\n");
935 return AFSCONF_NOCELL(70354691L);
936 }
937
938 if (as->parms[13].items) { /* if cell name specified */
939 lcstring(lcell, as->parms[13].items->data, sizeof(lcell));
940 code = afsconf_GetCellInfo(local_conf, lcell, 0, &cellinfo);
941 if (code == 0)
942 strncpy(lcell, cellinfo.name, sizeof(lcell));
943 } else {
944 code = afsconf_GetLocalCell(local_conf, lcell, sizeof(lcell));
945 if (code)
946 return code;
947 }
948
949 if (as->parms[14].items) { /* noauth flag */
950 noAuth = 1;
951 }
952
953 if (as->parms[15].items) { /* servers list */
954 serverList = as->parms[15].items;
955 for (i = 0; serverList; i++, serverList = serverList->next) {
956 struct hostent *th;
957 if (i >= MAXHOSTSPERCELL8)
958 return AFSCONF_FULL(70354694L);
959 strncpy(cellinfo.hostName[i], serverList->data, MAXHOSTCHARS64);
960 th = gethostbyname(cellinfo.hostName[i]);
961 if (!th)
962 return UBADHOST(5385L);
963 memcpy(&cellinfo.hostAddr[i].sin_addr, th->h_addrh_addr_list[0],
964 sizeof(afs_int32));
965 cellinfo.hostAddr[i].sin_family = AF_INET2;
966 cellinfo.hostAddr[i].sin_port = 0;
967#ifdef STRUCT_SOCKADDR_HAS_SA_LEN1
968 cellinfo.hostAddr[i].sin_len = sizeof(struct sockaddr_in);
969#endif
970 }
971 cellinfo.numServers = i;
972 strcpy(cellinfo.name, lcell);
973 } else {
974 code = afsconf_GetCellInfo(local_conf, lcell, 0, &cellinfo);
975 if (code)
976 return code;
977 }
978
979 if (local_conf)
980 afsconf_Close(local_conf);
981
982 if (cdir == 0) {
983 FILE *f;
984
985 sprintf(tmp_conf_dir, "%s/afsconf.%lu", gettmpdir(),
986 (unsigned long)getpid());
987 code = mkdir(tmp_conf_dir, 0777);
988 if ((code < 0) && (errno(* __error()) != EEXIST17)) {
989 afs_com_err(whoami, errno(* __error()), "can't create temporary afsconf dir: %s",
990 cdir);
991 return errno(* __error());
992 }
993
994 strcompose(tmp_conf_file, 128, tmp_conf_dir, "/",
995 AFSDIR_CELLSERVDB_FILE"CellServDB", NULL((void *)0));
996 f = fopen(tmp_conf_file, "w");
997 if (f == 0) {
998 cantcreate:
999 afs_com_err(whoami, errno(* __error()), "can't create conf file %s",
1000 tmp_conf_file);
1001 return errno(* __error());
1002 }
1003 fprintf(f, ">%s\n", lcell);
1004 for (i = 0; i < cellinfo.numServers; i++) {
1005 unsigned char *tp =
1006 (unsigned char *)&cellinfo.hostAddr[i].sin_addr;
1007 fprintf(f, "%d.%d.%d.%d\t#%s\n", tp[0], tp[1], tp[2], tp[3],
1008 cellinfo.hostName[i]);
1009 }
1010 if (fclose(f) == EOF(-1)) {
1011 cantclose:
1012 afs_com_err(whoami, errno(* __error()), "can't write to conf file %s",
1013 tmp_conf_file);
1014 return errno(* __error());
1015 }
1016
1017 strcompose(tmp_cell_file, 128, tmp_conf_dir, "/",
1018 AFSDIR_THISCELL_FILE"ThisCell", NULL((void *)0));
1019 f = fopen(tmp_cell_file, "w");
1020 if (f == 0)
1021 goto cantcreate;
1022 fprintf(f, "%s", lcell);
1023 if (fclose(f) == EOF(-1))
1024 goto cantclose;
1025
1026 strcompose(tmp_noauth_file, 128, tmp_conf_dir, "/",
1027 AFSDIR_NOAUTH_FILE"NoAuth", NULL((void *)0));
1028 if (noAuth) {
1029 code = creat(tmp_noauth_file, 0777);
1030 if (code && (errno(* __error()) != EEXIST17))
1031 return errno(* __error());
1032 } else { /* make sure file doesn't exist */
1033 code = unlink(tmp_noauth_file);
1034 if (code && (errno(* __error()) != ENOENT2))
1035 return errno(* __error());
1036 }
1037 }
1038
1039 strncpy(conf_dir, tmp_conf_dir, sizeof(conf_dir));
1040 conf = afsconf_Open(conf_dir);
1041 if (conf == 0)
1042 return AFSCONF_NOTFOUND(70354689L);
1043 return 0;
1044}
1045
1046static void
1047add_std_args(struct cmd_syndesc *ts)
1048{
1049 cmd_Seek(ts, 12);
1050 cmd_AddParm(ts, "-confdir", CMD_SINGLE2, CMD_OPTIONAL1,
1051 "AFS Conf dir pathname");
1052 cmd_AddParm(ts, "-cell", CMD_SINGLE2, CMD_OPTIONAL1, "Cell name");
1053 cmd_AddParm(ts, "-noauth", CMD_FLAG1, CMD_OPTIONAL1, "Don't authenticate");
1054 cmd_AddParm(ts, "-servers", CMD_LIST3, CMD_OPTIONAL1, "Server config");
1055}
1056
1057int
1058osi_audit(void)
1059{
1060/* OK, this REALLY sucks bigtime, but I can't tell who is calling
1061 * afsconf_CheckAuth easily, and only *SERVERS* should be calling osi_audit
1062 * anyway. It's gonna give somebody fits to debug, I know, I know.
1063 */
1064 return 0;
1065}
1066
1067#include "AFS_component_version_number.c"
1068
1069int
1070main(int argc, char *argv[])
1071{
1072 afs_int32 code;
1073 struct cmd_syndesc *ts; /* ptr to parsed command line syntax */
1074
1075 whoami = argv[0];
1076 initialize_CMD_error_table();
1077 initialize_ACFG_error_table();
1078 initialize_KTC_error_table();
1079 initialize_U_error_table();
1080 initialize_PT_error_table();
1081 initialize_RXK_error_table();
1082
1083#ifdef AFS_NT40_ENV
1084 /* initialize winsock */
1085 if (afs_winsockInit() < 0) {
1086 fprintf(stderr__stderrp, "%s: couldn't initialize winsock. \n", whoami);
1087 exit(1);
1088 }
1089#endif
1090
1091 cmd_SetBeforeProc(MyBeforeProc, NULL((void *)0));
1092 cmd_SetAfterProc(MyAfterProc, NULL((void *)0));
1093
1094 ts = cmd_CreateSyntax("usedIds", ListUsedIds, NULL((void *)0),
1095 "Find used (or unused) user (or group) ids");
1096 cmd_AddParm(ts, "-startId", CMD_SINGLE2, CMD_OPTIONAL1,
1097 "id to start checking");
1098 cmd_AddParm(ts, "-number", CMD_SINGLE2, CMD_OPTIONAL1,
1099 "number of ids to check");
1100 cmd_AddParm(ts, "-unused", CMD_FLAG1, CMD_OPTIONAL1, "print unused ids");
1101 add_std_args(ts);
1102
1103 ts = cmd_CreateSyntax("initcmd", TestPrServ, NULL((void *)0), "test the prserver");
1104 add_std_args(ts);
1105
1106 ts = cmd_CreateSyntax("testmanymembers", TestManyMembers, NULL((void *)0),
1107 "test creating users and groups w/ many members");
1108 cmd_AddParm(ts, "-number", CMD_SINGLE2, 0,
1109 "number of users/groups to create");
1110 cmd_AddParm(ts, "-dropoff", CMD_SINGLE2, CMD_OPTIONAL1,
1111 "precentage for exponential dropoff");
1112 cmd_AddParm(ts, "-prefix", CMD_SINGLE2, CMD_OPTIONAL1, "naming prefix");
1113 cmd_AddParm(ts, "-long", CMD_FLAG1, CMD_OPTIONAL1, "show progress");
1114 cmd_AddParm(ts, "-seed", CMD_SINGLE2, CMD_OPTIONAL1, "random number seed");
1115 add_std_args(ts);
1116 cmd_CreateAlias(ts, "mm");
1117
1118
1119 code = cmd_Dispatch(argc, argv);
1120 if (code)
1121 afs_com_err(whoami, code, "calling cmd_Dispatch");
1122 exit(code);
1123}