2 * Copyright 2000, International Business Machines Corporation and others.
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
10 #include <afsconfig.h>
11 #include <afs/param.h>
19 #include <sys/types.h>
22 #include <WINNT/afsevent.h>
24 #include <netinet/in.h>
32 #include <afs/com_err.h>
33 #include <afs/cellconfig.h>
36 #include <afs/afsutil.h>
39 afs_int32 security = 0;
40 char confdir[AFSDIR_PATH_MAX];
44 #ifndef AFS_PTHREAD_ENV
45 extern struct ubik_client *pruclient;
48 static int ignoreExist = 0;
49 static char line[256];
50 static char *lineProgress;
52 #define WHITESPACE " \t\n"
54 #ifndef AFS_PTHREAD_ENV
58 /* OK, this REALLY sucks bigtime, but I can't tell who is calling
59 * afsconf_CheckAuth easily, and only *SERVERS* should be calling osi_audit
60 * anyway. It's gonna give somebody fits to debug, I know, I know.
64 #endif /* !AFS_PTHREAD_ENV */
67 GetToken(char *format, afs_int32 *l)
72 if (lineProgress == 0)
74 c = sscanf(lineProgress, format, l);
77 /* skip the white space */
78 lineProgress += strspn(lineProgress, WHITESPACE);
79 /* skip to end of token */
80 lineProgress = strpbrk(lineProgress, WHITESPACE);
84 #define GetInt32(l) GetToken ("%d", l)
85 #define GetXInt32(l) GetToken ("%x", l)
96 if (lineProgress == 0)
98 /* skip the white space */
99 lineProgress += strspn(lineProgress, WHITESPACE);
101 /* check for quoted string and find end */
104 l = strcspn(++beg, "\"");
105 if (l == strlen(beg))
106 return -1; /* unbalanced quotes */
107 lineProgress = beg + l + 1;
109 l = strcspn(beg, WHITESPACE);
112 if (l >= slen) { /* don't return too much */
119 s[l] = 0; /* null termination */
129 return code && (code != PREXIST) && (code != PRIDEXIST);
133 PrintEntry(ea, e, indent)
138 /* handle screwed up versions of DumpEntry */
139 if (e->flags & PRCONT) {
140 afs_int32 id = *(afs_int32 *) (e->name);
141 if ((id != PRBADID) && ((id > (1 << 24)) || (id < -(1 << 24)))) {
142 /* assume server incorrectly swapped these bytes... */
144 while (i < sizeof(e->name)) {
147 e->name[i] = e->name[i + 3];
148 e->name[i + 3] = temp;
149 temp = e->name[i + 1];
150 e->name[i + 1] = e->name[i + 2];
151 e->name[i + 2] = temp;
156 return pr_PrintEntry(stdout, /*host order */ 1, ea, e, indent);
159 #ifndef AFS_PTHREAD_ENV
163 #include "AFS_component_version_number.c"
169 register afs_int32 code;
171 char name[PR_MAXNAMELEN];
172 afs_int32 id, oid = ANONYMOUSID, gid;
175 struct prentry entry;
179 struct hostent *hostinfo;
180 struct in_addr *hostaddr;
188 * The following signal action for AIX is necessary so that in case of a
189 * crash (i.e. core is generated) we can include the user's data section
190 * in the core dump. Unfortunately, by default, only a partial core is
191 * generated which, in many cases, isn't too useful.
193 struct sigaction nsa;
195 sigemptyset(&nsa.sa_mask);
196 nsa.sa_handler = SIG_DFL;
197 nsa.sa_flags = SA_FULLDUMP;
198 sigaction(SIGSEGV, &nsa, NULL);
202 initialize_PT_error_table();
204 strcpy(confdir, AFSDIR_CLIENT_ETC_DIRPATH);
208 int arglen = strlen(argv[i]);
210 lcstring(arg, argv[i], sizeof(arg));
211 #define IsArg(a) (strncmp (arg,a, arglen) == 0)
212 if (IsArg("-testconfdir"))
213 strncpy(confdir, argv[++i], sizeof(confdir));
214 else if (IsArg("client"))
215 strncpy(confdir, AFSDIR_CLIENT_ETC_DIRPATH, sizeof(confdir));
216 else if (IsArg("server"))
217 strncpy(confdir, AFSDIR_SERVER_ETC_DIRPATH, sizeof(confdir));
218 else if (IsArg("0") || IsArg("1") || IsArg("2"))
219 security = atoi(argv[i]);
220 else if (IsArg("-ignoreexist"))
222 else if (IsArg("-cell"))
226 ("Usage is: 'prclient [-testconfdir <dir> | server | client] [0 | 1 | 2] [-ignoreExist] [-cell <cellname>]\n");
232 printf("Using CellServDB file in %s\n", confdir);
234 printf("Making unauthenticated connection to prserver\n");
236 code = pr_Initialize(security, confdir, cell);
238 afs_com_err(whoami, code, "Couldn't initialize protection library");
246 s = fgets(line, sizeof(line), stdin);
251 code = GetString(op, sizeof(op));
253 afs_com_err(whoami, PRBADARG,
254 "error reading opcode in line '%s', got '%.*s'", line,
259 continue; /* no input */
261 if (!strcmp(op, "cr")) {
262 if (GetString(name, sizeof(name)) || GetInt32(&id)
265 /* use ubik_Call to do the work, finding an up server and handling
266 * the job of finding a sync site, if need be */
268 code = ubik_PR_INewEntry(pruclient, 0, name, id, oid);
270 afs_com_err(whoami, code, "on %s %s %d %d", op, name, id, oid);
271 } else if (!strcmp(op, "sf")) {
272 afs_int32 mask, access, gq, uq;
273 if (GetInt32(&id) || GetXInt32(&mask) || GetXInt32(&access)
274 || GetInt32(&gq) || GetInt32(&uq))
278 ubik_PR_SetFieldsEntry(pruclient, 0, id, mask,
279 access, gq, uq, 0, 0);
281 afs_com_err(whoami, code, "on %s %d %x %x %d %d", op, id, mask,
283 } else if (!strcmp(op, "ce")) {
284 char newname[PR_MAXNAMELEN];
286 if (GetInt32(&id) || GetString(newname, sizeof(newname))
287 || GetInt32(&oid) || GetInt32(&newid))
291 ubik_PR_ChangeEntry(pruclient, 0, id, newname, oid,
294 afs_com_err(whoami, code, "on %s %d %s %d %d", op, id, newname,
296 } else if (!strcmp(op, "wh")) {
297 /* scanf("%d",&id); */
301 code = ubik_PR_WhereIsIt(pruclient, 0, id, &pos);
303 printf("%s\n", pr_ErrorMsg(code));
305 printf("location %d\n", pos);
306 } else if (!strcmp(op, "du")) {
307 memset(&entry, 0, sizeof(entry));
308 /* scanf("%d",&pos); */
312 code = ubik_PR_DumpEntry(pruclient, 0, pos, &entry);
314 printf("%s\n", pr_ErrorMsg(code));
315 if (code == PRSUCCESS) {
316 PrintEntry(pos, &entry, /*indent */ 0);
318 printf("The contents of the entry for %d are:\n", entry.id);
319 printf("flags %d next %d\n", entry.flags, entry.next);
320 printf("Groups (or members) \n");
321 for (i = 0; i < PRSIZE; i++)
322 printf("%d\n", entry.entries[i]);
323 printf("nextID %d nextname %d name %s\n", entry.nextID,
324 entry.nextName, entry.name);
325 printf("owner %d creator %d\n", entry.owner, entry.creator);
328 } else if (!strcmp(op, "add") || !strcmp(op, "au")) {
329 /* scanf("%d %d",&id,&gid); */
330 if (GetInt32(&id) || GetInt32(&gid))
333 code = ubik_PR_AddToGroup(pruclient, 0, id, gid);
335 afs_com_err(whoami, code, "on %s %d %d", op, id, gid);
336 } else if (!strcmp(op, "iton")) {
337 lid.idlist_val = (afs_int32 *) malloc(20 * sizeof(afs_int32));
338 ptr = lid.idlist_val;
342 while ((lid.idlist_len < 20) && (sscanf(foo, "%d", ptr) != EOF)) {
348 fprintf(stderr, "too many values specified; max is %d\n", 20);
350 lnames.namelist_val = 0;
351 lnames.namelist_len = 0;
352 code = ubik_PR_IDToName(pruclient, 0, &lid, &lnames);
354 printf("%s\n", pr_ErrorMsg(code));
355 if (code == PRSUCCESS) {
356 for (i = 0; i < lnames.namelist_len; i++) {
357 printf("id %d name %s\n", lid.idlist_val[i],
358 lnames.namelist_val[i]);
360 free(lnames.namelist_val);
362 free(lid.idlist_val);
365 } else if (!strcmp(op, "ntoi")) {
366 lnames.namelist_val =
367 (prname *) malloc(PR_MAXLIST * PR_MAXNAMELEN);
368 lnames.namelist_len = 0;
371 for (i = 0; ((lnames.namelist_len < PR_MAXLIST)
372 && (sscanf(foo, "%s", lnames.namelist_val[i]) !=
374 lnames.namelist_len++;
378 fprintf(stderr, "too many values specified; max is %d\n",
383 code = ubik_PR_NameToID(pruclient, 0, &lnames, &lid);
385 printf("%s\n", pr_ErrorMsg(code));
386 if (code == PRSUCCESS) {
387 for (i = 0; i < lid.idlist_len; i++)
388 printf("name %s id %d\n", lnames.namelist_val[i],
390 free(lid.idlist_val);
392 free(lnames.namelist_val);
393 lnames.namelist_val = 0;
394 lnames.namelist_len = 0;
395 } else if (!strcmp(op, "del")) {
396 /* scanf("%d",&id); */
400 code = ubik_PR_Delete(pruclient, 0, id);
402 printf("%s\n", pr_ErrorMsg(code));
403 } else if (!strcmp(op, "dg")) {
404 /* scanf("%d",&id); */
408 code = ubik_PR_Delete(pruclient, 0, id);
410 printf("%s\n", pr_ErrorMsg(code));
411 } else if (!strcmp(op, "rm")) {
412 /* scanf("%d %d",&id,&gid); */
413 if (GetInt32(&id) || GetInt32(&gid))
416 code = ubik_PR_RemoveFromGroup(pruclient, 0, id, gid);
418 printf("%s\n", pr_ErrorMsg(code));
420 #if defined(SUPERGROUPS)
421 else if (!strcmp(op, "lsg")) {
422 alist.prlist_len = 0;
423 alist.prlist_val = 0;
424 /* scanf("%d",&id); */
429 ubik_PR_ListSuperGroups(pruclient, 0, id, &alist,
432 printf("%s\n", pr_ErrorMsg(code));
433 if (code == PRSUCCESS) {
434 ptr = alist.prlist_val;
436 printf("Number of groups greater than PR_MAXGROUPS!\n");
437 printf("Excess of %d.\n", over);
439 for (i = 0; i < alist.prlist_len; i++, ptr++)
440 printf("%d\n", *ptr);
441 free(alist.prlist_val);
442 alist.prlist_len = 0;
443 alist.prlist_val = 0;
446 #endif /* SUPERGROUPS */
447 else if (!strcmp(op, "l")) {
448 alist.prlist_len = 0;
449 alist.prlist_val = 0;
450 /* scanf("%d",&id); */
454 code = ubik_PR_GetCPS(pruclient, 0, id, &alist, &over);
456 printf("%s\n", pr_ErrorMsg(code));
457 if (code == PRSUCCESS) {
458 ptr = alist.prlist_val;
460 printf("Number of groups greater than PR_MAXGROUPS!\n");
461 printf("Excess of %d.\n", over);
463 for (i = 0; i < alist.prlist_len; i++, ptr++)
464 printf("%d\n", *ptr);
465 free(alist.prlist_val);
466 alist.prlist_len = 0;
467 alist.prlist_val = 0;
469 } else if (!strcmp(op, "lh")) {
470 alist.prlist_len = 0;
471 alist.prlist_val = 0;
472 /* scanf("%d",&id); */
473 if (GetString(name, sizeof(name)))
475 else if (!(hostinfo = gethostbyname(name)))
478 hostaddr = hostinfo->h_addr_list[0];
479 id = ntohl(hostaddr->s_addr);
481 ubik_PR_GetHostCPS(pruclient, 0, id, &alist, &over);
484 printf("%s\n", pr_ErrorMsg(code));
485 if (code == PRSUCCESS) {
486 ptr = alist.prlist_val;
488 printf("Number of groups greater than PR_MAXGROUPS!\n");
489 printf("Excess of %d.\n", over);
491 for (i = 0; i < alist.prlist_len; i++, ptr++)
492 printf("%d\n", *ptr);
493 free(alist.prlist_val);
494 alist.prlist_len = 0;
495 alist.prlist_val = 0;
498 #if defined(SUPERGROUPS)
499 else if (!strcmp(op, "m")) {
500 alist.prlist_len = 0;
501 alist.prlist_val = 0;
502 /* scanf("%d",&id); */
507 ubik_PR_ListElements(pruclient, 0, id, &alist,
510 printf("%s\n", pr_ErrorMsg(code));
511 if (code == PRSUCCESS) {
512 ptr = alist.prlist_val;
514 printf("Number of groups greater than PR_MAXGROUPS!\n");
515 printf("Excess of %d.\n", over);
517 for (i = 0; i < alist.prlist_len; i++, ptr++)
518 printf("%d\n", *ptr);
519 free(alist.prlist_val);
520 alist.prlist_len = 0;
521 alist.prlist_val = 0;
524 #endif /* SUPERGROUPS */
525 else if (!strcmp(op, "nu")) {
526 /* scanf("%s",name); */
527 if (GetString(name, sizeof(name)))
530 code = pr_CreateUser(name, &id);
532 printf("%s\n", pr_ErrorMsg(code));
533 if (code == PRSUCCESS)
534 printf("Id is %d.\n", id);
535 } else if (!strcmp(op, "ng")) {
536 /* scanf("%s",name); */
537 if (GetString(name, sizeof(name)))
540 code = ubik_PR_NewEntry(pruclient, 0, name, 1, oid, &id);
542 printf("%s\n", pr_ErrorMsg(code));
543 if (code == PRSUCCESS)
544 printf("Id is %d.\n", id);
545 } else if (!strcmp(op, "lm")) {
546 code = ubik_PR_ListMax(pruclient, 0, &id, &gid);
548 printf("%s\n", pr_ErrorMsg(code));
549 if (code == PRSUCCESS)
550 printf("Max user id is %d, max (really min) group is %d.\n",
552 } else if (!strcmp(op, "smu")) {
553 /* scanf("%d",&id); */
557 code = ubik_PR_SetMax(pruclient, 0, id, 0);
559 printf("%s\n", pr_ErrorMsg(code));
560 } else if (!strcmp(op, "smg")) {
561 /* scanf("%d",&id); */
565 code = ubik_PR_SetMax(pruclient, 0, id, 1);
567 printf("%s\n", pr_ErrorMsg(code));
568 } else if (!strcmp(op, "sin")) {
569 /* scanf("%d",&id); */
573 code = pr_SIdToName(id, name);
575 printf("%s\n", pr_ErrorMsg(code));
576 if (code == PRSUCCESS)
577 printf("id %d name %s\n", id, name);
578 } else if (!strcmp(op, "sni")) {
579 /* scanf("%s",name); */
580 if (GetString(name, sizeof(name)))
583 code = pr_SNameToId(name, &id);
585 printf("%s\n", pr_ErrorMsg(code));
586 if (code == PRSUCCESS)
587 printf("name %s id %d\n", name, id);
588 } else if (!strcmp(op, "fih")) {
590 struct PrUpdateEntry uentry;
591 memset(&uentry, 0, sizeof(uentry));
592 /* scanf("%s",name); */
593 if (GetString(name, sizeof(name))) {
597 code = pr_SNameToId(name, &id);
599 printf("%s\n", pr_ErrorMsg(code));
602 code = pr_SIdToName(id, tname);
603 if (code == PRSUCCESS) {
605 ("Warning: Id hash for %s (id %d) seems correct at the db; rehashing it anyway\n",
609 uentry.Mask = PRUPDATE_IDHASH;
610 code = ubik_PR_UpdateEntry(pruclient, 0, 0, name, &uentry);
612 printf("Failed to update entry %s (err=%d)\n", name, code);
615 } else if (!strcmp(op, "fnh")) {
617 struct PrUpdateEntry uentry;
618 memset(&uentry, 0, sizeof(uentry));
619 /* scanf("%d", &id); */
624 code = pr_SIdToName(id, name);
626 printf("%s\n", pr_ErrorMsg(code));
629 code = pr_SNameToId(name, &tid);
630 if (code == PRSUCCESS) {
632 ("Name hash for %d (name is %s) seems correct at the db; rehashing it anyway\n",
636 uentry.Mask = PRUPDATE_NAMEHASH;
638 ubik_PR_UpdateEntry(pruclient, 0, id, "_foo_", &uentry);
640 printf("Failed to update entry with id %d (err=%d)\n", id,
645 #if defined(SUPERGROUPS)
646 else if (!strcmp(op, "fih")) {
648 struct PrUpdateEntry uentry;
649 memset(&uentry, 0, sizeof(uentry));
650 /* scanf("%s",name); */
651 if (GetString(name, sizeof(name))) {
655 code = pr_SNameToId(name, &id);
657 printf("%s\n", pr_ErrorMsg(code));
660 code = pr_SIdToName(id, tname);
661 if (code == PRSUCCESS) {
663 ("Warning: Id hash for %s (id %d) seems correct at the db; rehashing it anyway\n",
667 uentry.Mask = PRUPDATE_IDHASH;
668 code = ubik_PR_UpdateEntry(pruclient, 0, 0, name, &uentry);
670 printf("Failed to update entry %s (err=%d)\n", name, code);
673 } else if (!strcmp(op, "fnh")) {
675 struct PrUpdateEntry uentry;
676 memset(&uentry, 0, sizeof(uentry));
677 /* scanf("%d", &id); */
682 code = pr_SIdToName(id, name);
684 printf("%s\n", pr_ErrorMsg(code));
687 code = pr_SNameToId(name, &tid);
688 if (code == PRSUCCESS) {
690 ("Name hash for %d (name is %s) seems correct at the db; rehashing it anyway\n",
694 uentry.Mask = PRUPDATE_NAMEHASH;
696 ubik_PR_UpdateEntry(pruclient, 0, id, "_foo_", &uentry);
698 printf("Failed to update entry with id %d (err=%d)\n", id,
703 #endif /* SUPERGROUPS */
704 else if (!strcmp(op, "?"))
706 else if (!strcmp(op, "q"))
709 printf("Unknown op: '%s'! ? for help\n", op);
716 printf("cr name id owner - create entry with name and id.\n");
717 printf("wh id - what is the offset into database for id?\n");
718 printf("du offset - dump the contents of the entry at offset.\n");
719 printf("add uid gid - add user uid to group gid.\n");
720 printf("iton id* - translate the list of id's to names.\n");
721 printf("ntoi name* - translate the list of names to ids.\n");
722 printf("del id - delete the entry for id.\n");
723 printf("dg gid - delete the entry for group gid.\n");
724 printf("rm id gid - remove user id from group gid.\n");
725 printf("l id - get the CPS for id.\n");
726 printf("lh host - get the host CPS for host.\n");
727 #if defined(SUPERGROUPS)
728 printf("lsg id - get the supergroups for id.\n");
729 printf("m id - list elements for id.\n");
731 printf("nu name - create new user with name - returns an id.\n");
732 printf("ng name - create new group with name - returns an id.\n");
733 printf("lm - list max user id and max (really min) group id.\n");
734 printf("smu - set max user id.\n");
735 printf("smg - set max group id.\n");
736 printf("sin id - single iton.\n");
737 printf("sni name - single ntoi.\n");
738 printf("fih name - fix id hash for <name>.\n");
739 printf("fnh id - fix name hash for <id>.\n");
740 printf("q - quit.\n?- this message.\n");
747 while (**s != ' ' && **s != '\0')
752 #endif /* !AFS_PTHREAD_ENV */