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>
18 #include <WINNT/afsevent.h>
23 #include <afs/com_err.h>
24 #include <afs/cellconfig.h>
25 #include <afs/afsutil.h>
32 afs_int32 security = 0;
33 char confdir[AFSDIR_PATH_MAX];
37 extern struct ubik_client *pruclient;
38 static void skip(char **);
39 static void PrintHelp(void);
41 static int ignoreExist = 0;
42 static char line[256];
43 static char *lineProgress;
45 #define WHITESPACE " \t\n"
50 /* OK, this REALLY sucks bigtime, but I can't tell who is calling
51 * afsconf_CheckAuth easily, and only *SERVERS* should be calling osi_audit
52 * anyway. It's gonna give somebody fits to debug, I know, I know.
58 GetToken(char *format, afs_int32 *l)
63 if (lineProgress == 0)
65 c = sscanf(lineProgress, format, l);
68 /* skip the white space */
69 lineProgress += strspn(lineProgress, WHITESPACE);
70 /* skip to end of token */
71 lineProgress = strpbrk(lineProgress, WHITESPACE);
75 #define GetInt32(l) GetToken ("%d", l)
76 #define GetXInt32(l) GetToken ("%x", l)
79 GetString(char *s, int slen)
85 if (lineProgress == 0)
87 /* skip the white space */
88 lineProgress += strspn(lineProgress, WHITESPACE);
90 /* check for quoted string and find end */
93 l = strcspn(++beg, "\"");
95 return -1; /* unbalanced quotes */
96 lineProgress = beg + l + 1;
98 l = strcspn(beg, WHITESPACE);
101 if (l >= slen) { /* don't return too much */
108 s[l] = 0; /* null termination */
113 CodeOk(afs_int32 code)
117 return code && (code != PREXIST) && (code != PRIDEXIST);
121 PrintEntry(afs_int32 ea, struct prentry *e, int indent)
123 /* handle screwed up versions of DumpEntry */
124 if (e->flags & PRCONT) {
127 memcpy(&id, e->name, sizeof(id));
128 if ((id != PRBADID) && ((id > (1 << 24)) || (id < -(1 << 24)))) {
129 /* assume server incorrectly swapped these bytes... */
131 while (i < sizeof(e->name)) {
134 e->name[i] = e->name[i + 3];
135 e->name[i + 3] = temp;
136 temp = e->name[i + 1];
137 e->name[i + 1] = e->name[i + 2];
138 e->name[i + 2] = temp;
143 return pr_PrintEntry(stdout, /*host order */ 1, ea, e, indent);
149 #include "AFS_component_version_number.c"
152 main(int argc, char **argv)
156 char name[PR_MAXNAMELEN];
157 afs_int32 id, oid = ANONYMOUSID, gid;
161 struct prentry entry;
165 struct hostent *hostinfo;
166 struct in_addr *hostaddr;
174 * The following signal action for AIX is necessary so that in case of a
175 * crash (i.e. core is generated) we can include the user's data section
176 * in the core dump. Unfortunately, by default, only a partial core is
177 * generated which, in many cases, isn't too useful.
179 struct sigaction nsa;
181 sigemptyset(&nsa.sa_mask);
182 nsa.sa_handler = SIG_DFL;
183 nsa.sa_flags = SA_FULLDUMP;
184 sigaction(SIGSEGV, &nsa, NULL);
188 initialize_PT_error_table();
190 strcpy(confdir, AFSDIR_CLIENT_ETC_DIRPATH);
194 int arglen = strlen(argv[n]);
196 lcstring(arg, argv[n], sizeof(arg));
197 #define IsArg(a) (strncmp (arg,a, arglen) == 0)
198 if (IsArg("-testconfdir"))
199 strncpy(confdir, argv[++n], sizeof(confdir));
200 else if (IsArg("client"))
201 strncpy(confdir, AFSDIR_CLIENT_ETC_DIRPATH, sizeof(confdir));
202 else if (IsArg("server"))
203 strncpy(confdir, AFSDIR_SERVER_ETC_DIRPATH, sizeof(confdir));
204 else if (IsArg("0") || IsArg("1") || IsArg("2"))
205 security = atoi(argv[n]);
206 else if (IsArg("-ignoreexist"))
208 else if (IsArg("-cell"))
212 ("Usage is: 'prclient [-testconfdir <dir> | server | client] [0 | 1 | 2] [-ignoreExist] [-cell <cellname>]\n");
218 printf("Using CellServDB file in %s\n", confdir);
220 printf("Making unauthenticated connection to prserver\n");
222 code = pr_Initialize(security, confdir, cell);
224 afs_com_err(whoami, code, "Couldn't initialize protection library");
232 s = fgets(line, sizeof(line), stdin);
237 code = GetString(op, sizeof(op));
239 afs_com_err(whoami, PRBADARG,
240 "error reading opcode in line '%s', got '%.*s'", line,
241 (int) sizeof(op), op);
245 continue; /* no input */
247 if (!strcmp(op, "cr")) {
248 if (GetString(name, sizeof(name)) || GetInt32(&id)
251 /* use ubik_Call to do the work, finding an up server and handling
252 * the job of finding a sync site, if need be */
254 code = ubik_PR_INewEntry(pruclient, 0, name, id, oid);
256 afs_com_err(whoami, code, "on %s %s %d %d", op, name, id, oid);
257 } else if (!strcmp(op, "sf")) {
258 afs_int32 mask, access, gq, uq;
259 if (GetInt32(&id) || GetXInt32(&mask) || GetXInt32(&access)
260 || GetInt32(&gq) || GetInt32(&uq))
264 ubik_PR_SetFieldsEntry(pruclient, 0, id, mask,
265 access, gq, uq, 0, 0);
267 afs_com_err(whoami, code, "on %s %d %x %x %d %d", op, id, mask,
269 } else if (!strcmp(op, "ce")) {
270 char newname[PR_MAXNAMELEN];
272 if (GetInt32(&id) || GetString(newname, sizeof(newname))
273 || GetInt32(&oid) || GetInt32(&newid))
277 ubik_PR_ChangeEntry(pruclient, 0, id, newname, oid,
280 afs_com_err(whoami, code, "on %s %d %s %d %d", op, id, newname,
282 } else if (!strcmp(op, "wh")) {
283 /* scanf("%d",&id); */
287 code = ubik_PR_WhereIsIt(pruclient, 0, id, &pos);
289 printf("%s\n", pr_ErrorMsg(code));
291 printf("location %d\n", pos);
292 } else if (!strcmp(op, "du")) {
293 memset(&entry, 0, sizeof(entry));
294 /* scanf("%d",&pos); */
298 code = ubik_PR_DumpEntry(pruclient, 0, pos, (struct prdebugentry *)&entry);
300 printf("%s\n", pr_ErrorMsg(code));
301 if (code == PRSUCCESS) {
302 PrintEntry(pos, &entry, /*indent */ 0);
304 printf("The contents of the entry for %d are:\n", entry.id);
305 printf("flags %d next %d\n", entry.flags, entry.next);
306 printf("Groups (or members) \n");
307 for (i = 0; i < PRSIZE; i++)
308 printf("%d\n", entry.entries[i]);
309 printf("nextID %d nextname %d name %s\n", entry.nextID,
310 entry.nextName, entry.name);
311 printf("owner %d creator %d\n", entry.owner, entry.creator);
314 } else if (!strcmp(op, "add") || !strcmp(op, "au")) {
315 /* scanf("%d %d",&id,&gid); */
316 if (GetInt32(&id) || GetInt32(&gid))
319 code = ubik_PR_AddToGroup(pruclient, 0, id, gid);
321 afs_com_err(whoami, code, "on %s %d %d", op, id, gid);
322 } else if (!strcmp(op, "iton")) {
323 lid.idlist_val = malloc(20 * sizeof(afs_int32));
324 ptr = lid.idlist_val;
328 while ((lid.idlist_len < 20) && (sscanf(foo, "%d", ptr) != EOF)) {
334 fprintf(stderr, "too many values specified; max is %d\n", 20);
336 lnames.namelist_val = 0;
337 lnames.namelist_len = 0;
338 code = ubik_PR_IDToName(pruclient, 0, &lid, &lnames);
340 printf("%s\n", pr_ErrorMsg(code));
341 if (code == PRSUCCESS) {
342 for (i = 0; i < lnames.namelist_len; i++) {
343 printf("id %d name %s\n", lid.idlist_val[i],
344 lnames.namelist_val[i]);
346 free(lnames.namelist_val);
348 free(lid.idlist_val);
351 } else if (!strcmp(op, "ntoi")) {
352 lnames.namelist_val = malloc(PR_MAXLIST * PR_MAXNAMELEN);
353 lnames.namelist_len = 0;
356 for (i = 0; ((lnames.namelist_len < PR_MAXLIST)
357 && (sscanf(foo, "%63s", lnames.namelist_val[i]) !=
359 lnames.namelist_len++;
363 fprintf(stderr, "too many values specified; max is %d\n",
368 code = ubik_PR_NameToID(pruclient, 0, &lnames, &lid);
370 printf("%s\n", pr_ErrorMsg(code));
371 if (code == PRSUCCESS) {
372 for (i = 0; i < lid.idlist_len; i++)
373 printf("name %s id %d\n", lnames.namelist_val[i],
375 free(lid.idlist_val);
377 free(lnames.namelist_val);
378 lnames.namelist_val = 0;
379 lnames.namelist_len = 0;
380 } else if (!strcmp(op, "del")) {
381 /* scanf("%d",&id); */
385 code = ubik_PR_Delete(pruclient, 0, id);
387 printf("%s\n", pr_ErrorMsg(code));
388 } else if (!strcmp(op, "dg")) {
389 /* scanf("%d",&id); */
393 code = ubik_PR_Delete(pruclient, 0, id);
395 printf("%s\n", pr_ErrorMsg(code));
396 } else if (!strcmp(op, "rm")) {
397 /* scanf("%d %d",&id,&gid); */
398 if (GetInt32(&id) || GetInt32(&gid))
401 code = ubik_PR_RemoveFromGroup(pruclient, 0, id, gid);
403 printf("%s\n", pr_ErrorMsg(code));
405 #if defined(SUPERGROUPS)
406 else if (!strcmp(op, "lsg")) {
407 alist.prlist_len = 0;
408 alist.prlist_val = 0;
409 /* scanf("%d",&id); */
414 ubik_PR_ListSuperGroups(pruclient, 0, id, &alist,
417 printf("%s\n", pr_ErrorMsg(code));
418 if (code == PRSUCCESS) {
419 ptr = alist.prlist_val;
421 printf("Number of groups greater than PR_MAXGROUPS!\n");
422 printf("Excess of %d.\n", over);
424 for (i = 0; i < alist.prlist_len; i++, ptr++)
425 printf("%d\n", *ptr);
426 free(alist.prlist_val);
427 alist.prlist_len = 0;
428 alist.prlist_val = 0;
431 #endif /* SUPERGROUPS */
432 else if (!strcmp(op, "l")) {
433 alist.prlist_len = 0;
434 alist.prlist_val = 0;
435 /* scanf("%d",&id); */
439 code = ubik_PR_GetCPS(pruclient, 0, id, &alist, &over);
441 printf("%s\n", pr_ErrorMsg(code));
442 if (code == PRSUCCESS) {
443 ptr = alist.prlist_val;
445 printf("Number of groups greater than PR_MAXGROUPS!\n");
446 printf("Excess of %d.\n", over);
448 for (i = 0; i < alist.prlist_len; i++, ptr++)
449 printf("%d\n", *ptr);
450 free(alist.prlist_val);
451 alist.prlist_len = 0;
452 alist.prlist_val = 0;
454 } else if (!strcmp(op, "lh")) {
455 alist.prlist_len = 0;
456 alist.prlist_val = 0;
457 /* scanf("%d",&id); */
458 if (GetString(name, sizeof(name)))
460 else if (!(hostinfo = gethostbyname(name)))
463 hostaddr = (struct in_addr *)hostinfo->h_addr_list[0];
464 id = ntohl(hostaddr->s_addr);
466 ubik_PR_GetHostCPS(pruclient, 0, id, &alist, &over);
469 printf("%s\n", pr_ErrorMsg(code));
470 if (code == PRSUCCESS) {
471 ptr = alist.prlist_val;
473 printf("Number of groups greater than PR_MAXGROUPS!\n");
474 printf("Excess of %d.\n", over);
476 for (i = 0; i < alist.prlist_len; i++, ptr++)
477 printf("%d\n", *ptr);
478 free(alist.prlist_val);
479 alist.prlist_len = 0;
480 alist.prlist_val = 0;
483 #if defined(SUPERGROUPS)
484 else if (!strcmp(op, "m")) {
485 alist.prlist_len = 0;
486 alist.prlist_val = 0;
487 /* scanf("%d",&id); */
492 ubik_PR_ListElements(pruclient, 0, id, &alist,
495 printf("%s\n", pr_ErrorMsg(code));
496 if (code == PRSUCCESS) {
497 ptr = alist.prlist_val;
499 printf("Number of groups greater than PR_MAXGROUPS!\n");
500 printf("Excess of %d.\n", over);
502 for (i = 0; i < alist.prlist_len; i++, ptr++)
503 printf("%d\n", *ptr);
504 free(alist.prlist_val);
505 alist.prlist_len = 0;
506 alist.prlist_val = 0;
509 #endif /* SUPERGROUPS */
510 else if (!strcmp(op, "nu")) {
511 /* scanf("%s",name); */
512 if (GetString(name, sizeof(name)))
515 code = pr_CreateUser(name, &id);
517 printf("%s\n", pr_ErrorMsg(code));
518 if (code == PRSUCCESS)
519 printf("Id is %d.\n", id);
520 } else if (!strcmp(op, "ng")) {
521 /* scanf("%s",name); */
522 if (GetString(name, sizeof(name)))
525 code = ubik_PR_NewEntry(pruclient, 0, name, 1, oid, &id);
527 printf("%s\n", pr_ErrorMsg(code));
528 if (code == PRSUCCESS)
529 printf("Id is %d.\n", id);
530 } else if (!strcmp(op, "lm")) {
531 code = ubik_PR_ListMax(pruclient, 0, &id, &gid);
533 printf("%s\n", pr_ErrorMsg(code));
534 if (code == PRSUCCESS)
535 printf("Max user id is %d, max (really min) group is %d.\n",
537 } else if (!strcmp(op, "smu")) {
538 /* scanf("%d",&id); */
542 code = ubik_PR_SetMax(pruclient, 0, id, 0);
544 printf("%s\n", pr_ErrorMsg(code));
545 } else if (!strcmp(op, "smg")) {
546 /* scanf("%d",&id); */
550 code = ubik_PR_SetMax(pruclient, 0, id, 1);
552 printf("%s\n", pr_ErrorMsg(code));
553 } else if (!strcmp(op, "sin")) {
554 /* scanf("%d",&id); */
558 code = pr_SIdToName(id, name);
560 printf("%s\n", pr_ErrorMsg(code));
561 if (code == PRSUCCESS)
562 printf("id %d name %s\n", id, name);
563 } else if (!strcmp(op, "sni")) {
564 /* scanf("%s",name); */
565 if (GetString(name, sizeof(name)))
568 code = pr_SNameToId(name, &id);
570 printf("%s\n", pr_ErrorMsg(code));
571 if (code == PRSUCCESS)
572 printf("name %s id %d\n", name, id);
573 } else if (!strcmp(op, "fih")) {
575 struct PrUpdateEntry uentry;
576 memset(&uentry, 0, sizeof(uentry));
577 /* scanf("%s",name); */
578 if (GetString(name, sizeof(name))) {
582 code = pr_SNameToId(name, &id);
584 printf("%s\n", pr_ErrorMsg(code));
587 code = pr_SIdToName(id, tname);
588 if (code == PRSUCCESS) {
590 ("Warning: Id hash for %s (id %d) seems correct at the db; rehashing it anyway\n",
594 uentry.Mask = PRUPDATE_IDHASH;
595 code = ubik_PR_UpdateEntry(pruclient, 0, 0, name, &uentry);
597 printf("Failed to update entry %s (err=%d)\n", name, code);
600 } else if (!strcmp(op, "fnh")) {
602 struct PrUpdateEntry uentry;
603 memset(&uentry, 0, sizeof(uentry));
604 /* scanf("%d", &id); */
609 code = pr_SIdToName(id, name);
611 printf("%s\n", pr_ErrorMsg(code));
614 code = pr_SNameToId(name, &tid);
615 if (code == PRSUCCESS) {
617 ("Name hash for %d (name is %s) seems correct at the db; rehashing it anyway\n",
621 uentry.Mask = PRUPDATE_NAMEHASH;
623 ubik_PR_UpdateEntry(pruclient, 0, id, "_foo_", &uentry);
625 printf("Failed to update entry with id %d (err=%d)\n", id,
630 #if defined(SUPERGROUPS)
631 else if (!strcmp(op, "fih")) {
633 struct PrUpdateEntry uentry;
634 memset(&uentry, 0, sizeof(uentry));
635 /* scanf("%s",name); */
636 if (GetString(name, sizeof(name))) {
640 code = pr_SNameToId(name, &id);
642 printf("%s\n", pr_ErrorMsg(code));
645 code = pr_SIdToName(id, tname);
646 if (code == PRSUCCESS) {
648 ("Warning: Id hash for %s (id %d) seems correct at the db; rehashing it anyway\n",
652 uentry.Mask = PRUPDATE_IDHASH;
653 code = ubik_PR_UpdateEntry(pruclient, 0, 0, name, &uentry);
655 printf("Failed to update entry %s (err=%d)\n", name, code);
658 } else if (!strcmp(op, "fnh")) {
660 struct PrUpdateEntry uentry;
661 memset(&uentry, 0, sizeof(uentry));
662 /* scanf("%d", &id); */
667 code = pr_SIdToName(id, name);
669 printf("%s\n", pr_ErrorMsg(code));
672 code = pr_SNameToId(name, &tid);
673 if (code == PRSUCCESS) {
675 ("Name hash for %d (name is %s) seems correct at the db; rehashing it anyway\n",
679 uentry.Mask = PRUPDATE_NAMEHASH;
681 ubik_PR_UpdateEntry(pruclient, 0, id, "_foo_", &uentry);
683 printf("Failed to update entry with id %d (err=%d)\n", id,
688 #endif /* SUPERGROUPS */
689 else if (!strcmp(op, "?"))
691 else if (!strcmp(op, "q"))
694 printf("Unknown op: '%s'! ? for help\n", op);
703 printf("cr name id owner - create entry with name and id.\n");
704 printf("wh id - what is the offset into database for id?\n");
705 printf("du offset - dump the contents of the entry at offset.\n");
706 printf("add uid gid - add user uid to group gid.\n");
707 printf("iton id* - translate the list of id's to names.\n");
708 printf("ntoi name* - translate the list of names to ids.\n");
709 printf("del id - delete the entry for id.\n");
710 printf("dg gid - delete the entry for group gid.\n");
711 printf("rm id gid - remove user id from group gid.\n");
712 printf("l id - get the CPS for id.\n");
713 printf("lh host - get the host CPS for host.\n");
714 #if defined(SUPERGROUPS)
715 printf("lsg id - get the supergroups for id.\n");
716 printf("m id - list elements for id.\n");
718 printf("nu name - create new user with name - returns an id.\n");
719 printf("ng name - create new group with name - returns an id.\n");
720 printf("lm - list max user id and max (really min) group id.\n");
721 printf("smu - set max user id.\n");
722 printf("smg - set max group id.\n");
723 printf("sin id - single iton.\n");
724 printf("sni name - single ntoi.\n");
725 printf("fih name - fix id hash for <name>.\n");
726 printf("fnh id - fix name hash for <id>.\n");
727 printf("q - quit.\n?- this message.\n");
733 while (**s != ' ' && **s != '\0')