/* * Copyright 2000, International Business Machines Corporation and others. * All Rights Reserved. * * This software has been released under the terms of the IBM Public * License. For details, see the LICENSE file in the top-level source * directory or online at http://www.openafs.org/dl/license10.html */ #ifndef lint #endif #include #include #include #include #ifdef AFS_NT40_ENV #include #include #else #include #include #include #endif #include #include #include #include #include #include #include "ptclient.h" #include "pterror.h" #include extern char *ucstring(); extern char *lcstring(); static char *whoami = "testpr"; static struct afsconf_dir *conf; /* cell info, set by MyBeforeProc */ static char conf_dir[100]; static char lcell[MAXCELLCHARS]; ListUsedIds (as, arock) struct cmd_syndesc *as; char *arock; { afs_int32 code; namelist lnames; idlist lids; int i,j; int group = 0; /* check groups */ int unused = 0; /* print unused */ int number = 100; /* check 100 ids */ afs_int32 startId = 1; afs_int32 maxId; int range; if (as->parms[0].items) startId = atoi (as->parms[0].items->data); if (as->parms[1].items) number = atoi (as->parms[1].items->data); if (as->parms[2].items) unused = 1; code = pr_Initialize(1, conf_dir,(char *)0); if (code) { com_err (whoami, code, "initializing pruser"); exit (1); } if (startId < 0) { group = 1; code = pr_ListMaxGroupId (&maxId); if (code) { bad_max: com_err (whoami, code, "getting maximum id"); exit (2); } if (startId < maxId) { fprintf (stderr, "Max group id is only %d.\n", maxId); exit (3); } } else { code = pr_ListMaxUserId (&maxId); if (code) goto bad_max; if (startId > maxId) { fprintf (stderr, "Max user id is only %d.\n", maxId); exit (3); } } range = abs(startId - maxId); if (range < 0) range = -range; range++; /* number that can be printed */ if (range < number) { fprintf (stderr, "Only %d ids to be checked.\n", range); number = range; } printf ("Checking for %d %sused ids starting at %d.\n", number, (unused ? "un" : ""), startId); #define NUM 100 lids.idlist_val = (afs_int32 *)malloc(sizeof(afs_int32)*NUM); lnames.namelist_len = 0; lnames.namelist_val = 0; while (number) { if (number < NUM) i = number; else i = NUM; for (j=0; j *b) return 1; if (*a == *b) return 0; if (*a < *b) return -1; } static int sqr (n) int n; { return n*n; } static int GetGroupLimit (N, x) int N; int x; { int y; double sqrt(); if ((x >= N) || (x < 0)) { printf ("GetGroupLimit: input value out of range %d (%d)\n", x, N); exit (10); } if (steepDropOff) { /* Use exponential decrease */ int i; y = N; for (i=0; i N) || (y < 1)) { printf ("filling value out of range: %d (%d) => %d\n", x, N, y); exit (11); } return y; } CreateUser (u) int u; { afs_int32 code; char name[16]; afs_int32 id; sprintf (name, "%s%d", createPrefix, u); id = 0; code = pr_CreateUser (name, &id); if (code) { if (code == PREXIST) { code = pr_Delete (name); if (code == 0) { nUDels++; code = pr_CreateUser (name, &id); if (code == 0) { if (verbose) printf ("RE-"); goto done; } } } com_err (whoami, code, "couldn't create %s", name); exit (12); } done: if (verbose) printf ("Creating user %s (%di)\n", name, id); users[u] = id; nUsers++; if (ownerUser == 0) { ownerUser = id; strcpy (ownerUserName, name); } return; } CreateGroup (g) int g; { afs_int32 code; char name[16]; afs_int32 id = 0; afs_int32 flags = PRGRP; afs_int32 owner; char *ownerName; int ownerType; /* type of ownership */ static char *lastGroupPrefix; /* prefix used for type==2 */ /* At least 50 groups should be owned by another group to test long owner * chains during deletion. Also let's create some long owners of owners * lists. */ ownerType = random() % 3; if (!ownerUser) ownerType = 0; if (!lastGroup) ownerType = 0; switch (ownerType) { case 0: owner = callerId; ownerName = callerName; break; case 1: owner = ownerUser; ownerName = ownerUserName; break; case 2: owner = lastGroup; ownerName = lastGroupPrefix; break; } sprintf (name, "%s:%s%d", ownerName, createPrefix, g); code = ubik_Call (PR_NewEntry, pruclient, 0, name, PRGRP, owner, &id); if (code) { if (code == PREXIST) { code = pr_Delete (name); if (code == 0) { nGDels++; code = ubik_Call (PR_NewEntry, pruclient, 0, name, PRGRP, owner, &id); if (code == 0) { if (verbose) printf ("RE-"); goto done; } } } com_err (whoami, code, "couldn't create %s w/ owner=%d", name, owner); exit (13); } done: if (verbose) printf ("Creating group %s (%di)\n", name, id); groups[g] = id; groupOwners[g] = owner; nGroups++; if (!lastGroup || (ownerType == 2)) { lastGroup = id; lastGroupPrefix = ownerName; } return; } int DeleteRandomId (list) afs_int32 *list; { afs_int32 code; afs_int32 id; int j,k; int m; k = random(); /* random starting point */ for (j=0; j 0) { fprintf (stderr, "can't handle non-null instance %s.%s\n", user.name, user.cell); exit (4); } if (strncmp (user.name, "AFS ID ", 7) == 0) { callerId = atoi (user.name+7); code = pr_SIdToName (callerId, callerName); if (code) { com_err (whoami, code, "call get name for id %d", callerId); exit (6); } } else { strcpy (callerName, user.name); code = pr_SNameToId (callerName, &callerId); if ((code == 0) && (callerId == ANONYMOUSID)) code = PRNOENT; } #if 0 /* don't create user */ if (code == PRNOENT) { callerId = 0; code = pr_CreateUser (callerName, &callerId); if (code) { com_err (whoami, code, "can't create caller %s", callerName); exit (5); } printf ("Creating caller %s (%di)\n", callerName, callerId); } /* else */ #endif if (code) { com_err (whoami, code, "can't find caller %s", callerName); exit (6); } else printf ("Assuming caller is %s (%di)\n", callerName, callerId); } /* Parse arguments */ if (as->parms[0].items) number = atoi (as->parms[0].items->data); if (as->parms[1].items) { steepDropOff = atoi (as->parms[1].items->data); if ((steepDropOff < 0) || (steepDropOff > 100)) { fprintf (stderr, "Illegal value for dropoff: %d, must be between 0 and 100, inclusive.\n", steepDropOff); exit (7); } } else steepDropOff = 0; /* use quadratic dropoff */ if (as->parms[2].items) createPrefix = as->parms[2].items->data; else createPrefix = "u"; if (as->parms[3].items) verbose = 1; else verbose = 0; if (as->parms[4].items) seed = atoi(as->parms[4].items->data); else seed = 1; srandom(seed); users = (afs_int32 *) malloc (number*sizeof(afs_int32)); groups = (afs_int32 *) malloc (number*sizeof(afs_int32)); filled = (char *) malloc (number*sizeof(char)); cleaned = (char *) malloc (number*sizeof(char)); population = (char *)malloc (sqr(number)*sizeof(char)); nFilled = 0; bzero (filled, number); nCleaned = 0; bzero (cleaned, number); bzero (population, sqr(number)); bzero (users, number*sizeof(afs_int32)); bzero (groups, number*sizeof(afs_int32)); ownerUser = lastGroup = 0; groupOwners = (afs_int32 *) malloc (number*sizeof(afs_int32)); nUsers = nGroups = nAdds = nRems = nUDels = nGDels = 0; while ((nFilled < number) || (nCleaned < number)) { /* pick a user at random, using */ u = random() % number; if (!filled[u]) { n = GetGroupLimit (number, u); /* get group limit for that user */ g = random() % (n+1); /* pick a random group */ if (g == n) { /* in a few cases create any user */ n = number; /* in the whole range */ g = random() % n; } for (i=0; i= n) goto remed; /* but half the time do nothing */ } for (i=0; i>6) + '0'; *ascii++ = (c>>3 & 7) + '0'; *ascii++ = (c&7) + '0'; alen -= 4; } } *ascii = 0; /* terminate string */ } /* This runs various tests on the server. It creates, then deletes, a bunch of * users and groups, so it would be safest to run it on a test database. * * These are the things I check for: * User names longer than PR_MAXNAMELEN - strlen(cellname). * Group names longer than PR_MAXNAMELEN. * User names containing all legal 8-bit ascii characters. This excludes * only ':', '@', and '\n'. * Group names as above, but at least one colon is required, and the owner * must be correct. */ TestPrServ (as, arock) struct cmd_syndesc *as; char *arock; { afs_int32 id; char name[PR_MAXNAMELEN+1]; char creator[PR_MAXNAMELEN]; /* our name */ struct prcheckentry ent; afs_int32 code; int i,j; int maxLen = PR_MAXNAMELEN-1 - strlen(lcell) - 1; code = pr_Initialize(1, conf_dir,(char *)0); if (code) { com_err (whoami, code, "initializing pruser"); exit (1); } for (i=0; iparms[12].items) { /* if conf dir specified */ cdir = as->parms[12].items->data; if (as->parms[13].items || as->parms[14].items || as->parms[15].items) { printf ("Can't specify conf dir and other cell parameters\n"); return AFSCONF_SYNTAX; } } /* if we need to default cell name or cell servers, get local conf info */ if (!(local_conf = afsconf_Open (AFSDIR_CLIENT_ETC_DIRPATH)) && !(local_conf = afsconf_Open (AFSDIR_SERVER_ETC_DIRPATH))){ printf("** Can't local configuration!\n"); return AFSCONF_NOCELL; } if (as->parms[13].items) { /* if cell name specified */ lcstring (lcell, as->parms[13].items->data, sizeof(lcell)); code = afsconf_GetCellInfo (local_conf, lcell, 0, &cellinfo); if (code == 0) strncpy (lcell, cellinfo.name, sizeof(lcell)); } else { code = afsconf_GetLocalCell (local_conf, lcell, sizeof(lcell)); if (code) return code; } if (as->parms[14].items) { /* noauth flag */ noAuth = 1; } if (as->parms[15].items) { /* servers list */ serverList = as->parms[15].items; for (i=0; serverList; i++, serverList = serverList->next) { struct hostent *th; if (i >= MAXHOSTSPERCELL) return AFSCONF_FULL; strncpy (cellinfo.hostName[i], serverList->data, MAXHOSTCHARS); th = gethostbyname(cellinfo.hostName[i]); if (!th) return UBADHOST; bcopy(th->h_addr, &cellinfo.hostAddr[i].sin_addr, sizeof(afs_int32)); cellinfo.hostAddr[i].sin_family = AF_INET; cellinfo.hostAddr[i].sin_port = 0; } cellinfo.numServers = i; strcpy (cellinfo.name, lcell); } else { code = afsconf_GetCellInfo (local_conf, lcell, 0, &cellinfo); if (code) return code; } if (local_conf) afsconf_Close (local_conf); if (cdir == 0) { FILE *f; sprintf (tmp_conf_dir, "%s/afsconf.%lu", gettmpdir(), (unsigned long) getpid()); code = mkdir (tmp_conf_dir, 0777); if ((code < 0) && (errno != EEXIST)) { com_err (whoami, errno, "can't create temporary afsconf dir: %s", cdir); return errno; } strcompose(tmp_conf_file, 128, tmp_conf_dir, "/", AFSDIR_CELLSERVDB_FILE, NULL); f = fopen (tmp_conf_file, "w"); if (f == 0) { cantcreate: com_err (whoami, errno, "can't create conf file %s", tmp_conf_file); return errno; } fprintf (f, ">%s\n", lcell); for (i=0; i