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>
17 #include <sys/types.h>
20 #include <WINNT/afsevent.h>
22 #include <netinet/in.h>
30 #include <afs/com_err.h>
31 #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;
46 static void skip(char **);
47 static void PrintHelp(void);
50 static int ignoreExist = 0;
51 static char line[256];
52 static char *lineProgress;
54 #define WHITESPACE " \t\n"
56 #ifndef AFS_PTHREAD_ENV
60 /* OK, this REALLY sucks bigtime, but I can't tell who is calling
61 * afsconf_CheckAuth easily, and only *SERVERS* should be calling osi_audit
62 * anyway. It's gonna give somebody fits to debug, I know, I know.
66 #endif /* !AFS_PTHREAD_ENV */
69 GetToken(char *format, afs_int32 *l)
74 if (lineProgress == 0)
76 c = sscanf(lineProgress, format, l);
79 /* skip the white space */
80 lineProgress += strspn(lineProgress, WHITESPACE);
81 /* skip to end of token */
82 lineProgress = strpbrk(lineProgress, WHITESPACE);
86 #define GetInt32(l) GetToken ("%d", l)
87 #define GetXInt32(l) GetToken ("%x", l)
90 GetString(char *s, int slen)
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 */
124 CodeOk(afs_int32 code)
128 return code && (code != PREXIST) && (code != PRIDEXIST);
132 PrintEntry(afs_int32 ea, struct prentry *e, int indent)
134 /* handle screwed up versions of DumpEntry */
135 if (e->flags & PRCONT) {
136 afs_int32 id = *(afs_int32 *) (e->name);
137 if ((id != PRBADID) && ((id > (1 << 24)) || (id < -(1 << 24)))) {
138 /* assume server incorrectly swapped these bytes... */
140 while (i < sizeof(e->name)) {
143 e->name[i] = e->name[i + 3];
144 e->name[i + 3] = temp;
145 temp = e->name[i + 1];
146 e->name[i + 1] = e->name[i + 2];
147 e->name[i + 2] = temp;
152 return pr_PrintEntry(stdout, /*host order */ 1, ea, e, indent);
155 #ifndef AFS_PTHREAD_ENV
159 #include "AFS_component_version_number.c"
162 main(int argc, char **argv)
164 register afs_int32 code;
166 char name[PR_MAXNAMELEN];
167 afs_int32 id, oid = ANONYMOUSID, gid;
171 struct prentry entry;
175 struct hostent *hostinfo;
176 struct in_addr *hostaddr;
184 * The following signal action for AIX is necessary so that in case of a
185 * crash (i.e. core is generated) we can include the user's data section
186 * in the core dump. Unfortunately, by default, only a partial core is
187 * generated which, in many cases, isn't too useful.
189 struct sigaction nsa;
191 sigemptyset(&nsa.sa_mask);
192 nsa.sa_handler = SIG_DFL;
193 nsa.sa_flags = SA_FULLDUMP;
194 sigaction(SIGSEGV, &nsa, NULL);
198 initialize_PT_error_table();
200 strcpy(confdir, AFSDIR_CLIENT_ETC_DIRPATH);
204 int arglen = strlen(argv[n]);
206 lcstring(arg, argv[n], sizeof(arg));
207 #define IsArg(a) (strncmp (arg,a, arglen) == 0)
208 if (IsArg("-testconfdir"))
209 strncpy(confdir, argv[++n], sizeof(confdir));
210 else if (IsArg("client"))
211 strncpy(confdir, AFSDIR_CLIENT_ETC_DIRPATH, sizeof(confdir));
212 else if (IsArg("server"))
213 strncpy(confdir, AFSDIR_SERVER_ETC_DIRPATH, sizeof(confdir));
214 else if (IsArg("0") || IsArg("1") || IsArg("2"))
215 security = atoi(argv[n]);
216 else if (IsArg("-ignoreexist"))
218 else if (IsArg("-cell"))
222 ("Usage is: 'prclient [-testconfdir <dir> | server | client] [0 | 1 | 2] [-ignoreExist] [-cell <cellname>]\n");
228 printf("Using CellServDB file in %s\n", confdir);
230 printf("Making unauthenticated connection to prserver\n");
232 code = pr_Initialize(security, confdir, cell);
234 afs_com_err(whoami, code, "Couldn't initialize protection library");
242 s = fgets(line, sizeof(line), stdin);
247 code = GetString(op, sizeof(op));
249 afs_com_err(whoami, PRBADARG,
250 "error reading opcode in line '%s', got '%.*s'", line,
255 continue; /* no input */
257 if (!strcmp(op, "cr")) {
258 if (GetString(name, sizeof(name)) || GetInt32(&id)
261 /* use ubik_Call to do the work, finding an up server and handling
262 * the job of finding a sync site, if need be */
264 code = ubik_PR_INewEntry(pruclient, 0, name, id, oid);
266 afs_com_err(whoami, code, "on %s %s %d %d", op, name, id, oid);
267 } else if (!strcmp(op, "sf")) {
268 afs_int32 mask, access, gq, uq;
269 if (GetInt32(&id) || GetXInt32(&mask) || GetXInt32(&access)
270 || GetInt32(&gq) || GetInt32(&uq))
274 ubik_PR_SetFieldsEntry(pruclient, 0, id, mask,
275 access, gq, uq, 0, 0);
277 afs_com_err(whoami, code, "on %s %d %x %x %d %d", op, id, mask,
279 } else if (!strcmp(op, "ce")) {
280 char newname[PR_MAXNAMELEN];
282 if (GetInt32(&id) || GetString(newname, sizeof(newname))
283 || GetInt32(&oid) || GetInt32(&newid))
287 ubik_PR_ChangeEntry(pruclient, 0, id, newname, oid,
290 afs_com_err(whoami, code, "on %s %d %s %d %d", op, id, newname,
292 } else if (!strcmp(op, "wh")) {
293 /* scanf("%d",&id); */
297 code = ubik_PR_WhereIsIt(pruclient, 0, id, &pos);
299 printf("%s\n", pr_ErrorMsg(code));
301 printf("location %d\n", pos);
302 } else if (!strcmp(op, "du")) {
303 memset(&entry, 0, sizeof(entry));
304 /* scanf("%d",&pos); */
308 code = ubik_PR_DumpEntry(pruclient, 0, pos, (struct prdebugentry *)&entry);
310 printf("%s\n", pr_ErrorMsg(code));
311 if (code == PRSUCCESS) {
312 PrintEntry(pos, &entry, /*indent */ 0);
314 printf("The contents of the entry for %d are:\n", entry.id);
315 printf("flags %d next %d\n", entry.flags, entry.next);
316 printf("Groups (or members) \n");
317 for (i = 0; i < PRSIZE; i++)
318 printf("%d\n", entry.entries[i]);
319 printf("nextID %d nextname %d name %s\n", entry.nextID,
320 entry.nextName, entry.name);
321 printf("owner %d creator %d\n", entry.owner, entry.creator);
324 } else if (!strcmp(op, "add") || !strcmp(op, "au")) {
325 /* scanf("%d %d",&id,&gid); */
326 if (GetInt32(&id) || GetInt32(&gid))
329 code = ubik_PR_AddToGroup(pruclient, 0, id, gid);
331 afs_com_err(whoami, code, "on %s %d %d", op, id, gid);
332 } else if (!strcmp(op, "iton")) {
333 lid.idlist_val = (afs_int32 *) malloc(20 * sizeof(afs_int32));
334 ptr = lid.idlist_val;
338 while ((lid.idlist_len < 20) && (sscanf(foo, "%d", ptr) != EOF)) {
344 fprintf(stderr, "too many values specified; max is %d\n", 20);
346 lnames.namelist_val = 0;
347 lnames.namelist_len = 0;
348 code = ubik_PR_IDToName(pruclient, 0, &lid, &lnames);
350 printf("%s\n", pr_ErrorMsg(code));
351 if (code == PRSUCCESS) {
352 for (i = 0; i < lnames.namelist_len; i++) {
353 printf("id %d name %s\n", lid.idlist_val[i],
354 lnames.namelist_val[i]);
356 free(lnames.namelist_val);
358 free(lid.idlist_val);
361 } else if (!strcmp(op, "ntoi")) {
362 lnames.namelist_val =
363 (prname *) malloc(PR_MAXLIST * PR_MAXNAMELEN);
364 lnames.namelist_len = 0;
367 for (i = 0; ((lnames.namelist_len < PR_MAXLIST)
368 && (sscanf(foo, "%s", lnames.namelist_val[i]) !=
370 lnames.namelist_len++;
374 fprintf(stderr, "too many values specified; max is %d\n",
379 code = ubik_PR_NameToID(pruclient, 0, &lnames, &lid);
381 printf("%s\n", pr_ErrorMsg(code));
382 if (code == PRSUCCESS) {
383 for (i = 0; i < lid.idlist_len; i++)
384 printf("name %s id %d\n", lnames.namelist_val[i],
386 free(lid.idlist_val);
388 free(lnames.namelist_val);
389 lnames.namelist_val = 0;
390 lnames.namelist_len = 0;
391 } else if (!strcmp(op, "del")) {
392 /* scanf("%d",&id); */
396 code = ubik_PR_Delete(pruclient, 0, id);
398 printf("%s\n", pr_ErrorMsg(code));
399 } else if (!strcmp(op, "dg")) {
400 /* scanf("%d",&id); */
404 code = ubik_PR_Delete(pruclient, 0, id);
406 printf("%s\n", pr_ErrorMsg(code));
407 } else if (!strcmp(op, "rm")) {
408 /* scanf("%d %d",&id,&gid); */
409 if (GetInt32(&id) || GetInt32(&gid))
412 code = ubik_PR_RemoveFromGroup(pruclient, 0, id, gid);
414 printf("%s\n", pr_ErrorMsg(code));
416 #if defined(SUPERGROUPS)
417 else if (!strcmp(op, "lsg")) {
418 alist.prlist_len = 0;
419 alist.prlist_val = 0;
420 /* scanf("%d",&id); */
425 ubik_PR_ListSuperGroups(pruclient, 0, id, &alist,
428 printf("%s\n", pr_ErrorMsg(code));
429 if (code == PRSUCCESS) {
430 ptr = alist.prlist_val;
432 printf("Number of groups greater than PR_MAXGROUPS!\n");
433 printf("Excess of %d.\n", over);
435 for (i = 0; i < alist.prlist_len; i++, ptr++)
436 printf("%d\n", *ptr);
437 free(alist.prlist_val);
438 alist.prlist_len = 0;
439 alist.prlist_val = 0;
442 #endif /* SUPERGROUPS */
443 else if (!strcmp(op, "l")) {
444 alist.prlist_len = 0;
445 alist.prlist_val = 0;
446 /* scanf("%d",&id); */
450 code = ubik_PR_GetCPS(pruclient, 0, id, &alist, &over);
452 printf("%s\n", pr_ErrorMsg(code));
453 if (code == PRSUCCESS) {
454 ptr = alist.prlist_val;
456 printf("Number of groups greater than PR_MAXGROUPS!\n");
457 printf("Excess of %d.\n", over);
459 for (i = 0; i < alist.prlist_len; i++, ptr++)
460 printf("%d\n", *ptr);
461 free(alist.prlist_val);
462 alist.prlist_len = 0;
463 alist.prlist_val = 0;
465 } else if (!strcmp(op, "lh")) {
466 alist.prlist_len = 0;
467 alist.prlist_val = 0;
468 /* scanf("%d",&id); */
469 if (GetString(name, sizeof(name)))
471 else if (!(hostinfo = gethostbyname(name)))
474 hostaddr = (struct in_addr *)hostinfo->h_addr_list[0];
475 id = ntohl(hostaddr->s_addr);
477 ubik_PR_GetHostCPS(pruclient, 0, id, &alist, &over);
480 printf("%s\n", pr_ErrorMsg(code));
481 if (code == PRSUCCESS) {
482 ptr = alist.prlist_val;
484 printf("Number of groups greater than PR_MAXGROUPS!\n");
485 printf("Excess of %d.\n", over);
487 for (i = 0; i < alist.prlist_len; i++, ptr++)
488 printf("%d\n", *ptr);
489 free(alist.prlist_val);
490 alist.prlist_len = 0;
491 alist.prlist_val = 0;
494 #if defined(SUPERGROUPS)
495 else if (!strcmp(op, "m")) {
496 alist.prlist_len = 0;
497 alist.prlist_val = 0;
498 /* scanf("%d",&id); */
503 ubik_PR_ListElements(pruclient, 0, id, &alist,
506 printf("%s\n", pr_ErrorMsg(code));
507 if (code == PRSUCCESS) {
508 ptr = alist.prlist_val;
510 printf("Number of groups greater than PR_MAXGROUPS!\n");
511 printf("Excess of %d.\n", over);
513 for (i = 0; i < alist.prlist_len; i++, ptr++)
514 printf("%d\n", *ptr);
515 free(alist.prlist_val);
516 alist.prlist_len = 0;
517 alist.prlist_val = 0;
520 #endif /* SUPERGROUPS */
521 else if (!strcmp(op, "nu")) {
522 /* scanf("%s",name); */
523 if (GetString(name, sizeof(name)))
526 code = pr_CreateUser(name, &id);
528 printf("%s\n", pr_ErrorMsg(code));
529 if (code == PRSUCCESS)
530 printf("Id is %d.\n", id);
531 } else if (!strcmp(op, "ng")) {
532 /* scanf("%s",name); */
533 if (GetString(name, sizeof(name)))
536 code = ubik_PR_NewEntry(pruclient, 0, name, 1, oid, &id);
538 printf("%s\n", pr_ErrorMsg(code));
539 if (code == PRSUCCESS)
540 printf("Id is %d.\n", id);
541 } else if (!strcmp(op, "lm")) {
542 code = ubik_PR_ListMax(pruclient, 0, &id, &gid);
544 printf("%s\n", pr_ErrorMsg(code));
545 if (code == PRSUCCESS)
546 printf("Max user id is %d, max (really min) group is %d.\n",
548 } else if (!strcmp(op, "smu")) {
549 /* scanf("%d",&id); */
553 code = ubik_PR_SetMax(pruclient, 0, id, 0);
555 printf("%s\n", pr_ErrorMsg(code));
556 } else if (!strcmp(op, "smg")) {
557 /* scanf("%d",&id); */
561 code = ubik_PR_SetMax(pruclient, 0, id, 1);
563 printf("%s\n", pr_ErrorMsg(code));
564 } else if (!strcmp(op, "sin")) {
565 /* scanf("%d",&id); */
569 code = pr_SIdToName(id, name);
571 printf("%s\n", pr_ErrorMsg(code));
572 if (code == PRSUCCESS)
573 printf("id %d name %s\n", id, name);
574 } else if (!strcmp(op, "sni")) {
575 /* scanf("%s",name); */
576 if (GetString(name, sizeof(name)))
579 code = pr_SNameToId(name, &id);
581 printf("%s\n", pr_ErrorMsg(code));
582 if (code == PRSUCCESS)
583 printf("name %s id %d\n", name, id);
584 } else if (!strcmp(op, "fih")) {
586 struct PrUpdateEntry uentry;
587 memset(&uentry, 0, sizeof(uentry));
588 /* scanf("%s",name); */
589 if (GetString(name, sizeof(name))) {
593 code = pr_SNameToId(name, &id);
595 printf("%s\n", pr_ErrorMsg(code));
598 code = pr_SIdToName(id, tname);
599 if (code == PRSUCCESS) {
601 ("Warning: Id hash for %s (id %d) seems correct at the db; rehashing it anyway\n",
605 uentry.Mask = PRUPDATE_IDHASH;
606 code = ubik_PR_UpdateEntry(pruclient, 0, 0, name, &uentry);
608 printf("Failed to update entry %s (err=%d)\n", name, code);
611 } else if (!strcmp(op, "fnh")) {
613 struct PrUpdateEntry uentry;
614 memset(&uentry, 0, sizeof(uentry));
615 /* scanf("%d", &id); */
620 code = pr_SIdToName(id, name);
622 printf("%s\n", pr_ErrorMsg(code));
625 code = pr_SNameToId(name, &tid);
626 if (code == PRSUCCESS) {
628 ("Name hash for %d (name is %s) seems correct at the db; rehashing it anyway\n",
632 uentry.Mask = PRUPDATE_NAMEHASH;
634 ubik_PR_UpdateEntry(pruclient, 0, id, "_foo_", &uentry);
636 printf("Failed to update entry with id %d (err=%d)\n", id,
641 #if defined(SUPERGROUPS)
642 else if (!strcmp(op, "fih")) {
644 struct PrUpdateEntry uentry;
645 memset(&uentry, 0, sizeof(uentry));
646 /* scanf("%s",name); */
647 if (GetString(name, sizeof(name))) {
651 code = pr_SNameToId(name, &id);
653 printf("%s\n", pr_ErrorMsg(code));
656 code = pr_SIdToName(id, tname);
657 if (code == PRSUCCESS) {
659 ("Warning: Id hash for %s (id %d) seems correct at the db; rehashing it anyway\n",
663 uentry.Mask = PRUPDATE_IDHASH;
664 code = ubik_PR_UpdateEntry(pruclient, 0, 0, name, &uentry);
666 printf("Failed to update entry %s (err=%d)\n", name, code);
669 } else if (!strcmp(op, "fnh")) {
671 struct PrUpdateEntry uentry;
672 memset(&uentry, 0, sizeof(uentry));
673 /* scanf("%d", &id); */
678 code = pr_SIdToName(id, name);
680 printf("%s\n", pr_ErrorMsg(code));
683 code = pr_SNameToId(name, &tid);
684 if (code == PRSUCCESS) {
686 ("Name hash for %d (name is %s) seems correct at the db; rehashing it anyway\n",
690 uentry.Mask = PRUPDATE_NAMEHASH;
692 ubik_PR_UpdateEntry(pruclient, 0, id, "_foo_", &uentry);
694 printf("Failed to update entry with id %d (err=%d)\n", id,
699 #endif /* SUPERGROUPS */
700 else if (!strcmp(op, "?"))
702 else if (!strcmp(op, "q"))
705 printf("Unknown op: '%s'! ? for help\n", op);
713 printf("cr name id owner - create entry with name and id.\n");
714 printf("wh id - what is the offset into database for id?\n");
715 printf("du offset - dump the contents of the entry at offset.\n");
716 printf("add uid gid - add user uid to group gid.\n");
717 printf("iton id* - translate the list of id's to names.\n");
718 printf("ntoi name* - translate the list of names to ids.\n");
719 printf("del id - delete the entry for id.\n");
720 printf("dg gid - delete the entry for group gid.\n");
721 printf("rm id gid - remove user id from group gid.\n");
722 printf("l id - get the CPS for id.\n");
723 printf("lh host - get the host CPS for host.\n");
724 #if defined(SUPERGROUPS)
725 printf("lsg id - get the supergroups for id.\n");
726 printf("m id - list elements for id.\n");
728 printf("nu name - create new user with name - returns an id.\n");
729 printf("ng name - create new group with name - returns an id.\n");
730 printf("lm - list max user id and max (really min) group id.\n");
731 printf("smu - set max user id.\n");
732 printf("smg - set max group id.\n");
733 printf("sin id - single iton.\n");
734 printf("sni name - single ntoi.\n");
735 printf("fih name - fix id hash for <name>.\n");
736 printf("fnh id - fix name hash for <id>.\n");
737 printf("q - quit.\n?- this message.\n");
743 while (**s != ' ' && **s != '\0')
748 #endif /* !AFS_PTHREAD_ENV */