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 <sys/types.h>
21 #include <WINNT/afsevent.h>
23 #include <netinet/in.h>
31 #include <afs/com_err.h>
32 #include <afs/cellconfig.h>
37 #include <afs/afsutil.h>
40 afs_int32 security = 0;
41 char confdir[AFSDIR_PATH_MAX];
45 #ifndef AFS_PTHREAD_ENV
46 extern struct ubik_client *pruclient;
47 static void skip(char **);
48 static void PrintHelp(void);
51 static int ignoreExist = 0;
52 static char line[256];
53 static char *lineProgress;
55 #define WHITESPACE " \t\n"
57 #ifndef AFS_PTHREAD_ENV
61 /* OK, this REALLY sucks bigtime, but I can't tell who is calling
62 * afsconf_CheckAuth easily, and only *SERVERS* should be calling osi_audit
63 * anyway. It's gonna give somebody fits to debug, I know, I know.
67 #endif /* !AFS_PTHREAD_ENV */
70 GetToken(char *format, afs_int32 *l)
75 if (lineProgress == 0)
77 c = sscanf(lineProgress, format, l);
80 /* skip the white space */
81 lineProgress += strspn(lineProgress, WHITESPACE);
82 /* skip to end of token */
83 lineProgress = strpbrk(lineProgress, WHITESPACE);
87 #define GetInt32(l) GetToken ("%d", l)
88 #define GetXInt32(l) GetToken ("%x", l)
91 GetString(char *s, int slen)
97 if (lineProgress == 0)
99 /* skip the white space */
100 lineProgress += strspn(lineProgress, WHITESPACE);
102 /* check for quoted string and find end */
105 l = strcspn(++beg, "\"");
106 if (l == strlen(beg))
107 return -1; /* unbalanced quotes */
108 lineProgress = beg + l + 1;
110 l = strcspn(beg, WHITESPACE);
113 if (l >= slen) { /* don't return too much */
120 s[l] = 0; /* null termination */
125 CodeOk(afs_int32 code)
129 return code && (code != PREXIST) && (code != PRIDEXIST);
133 PrintEntry(afs_int32 ea, struct prentry *e, int indent)
135 /* handle screwed up versions of DumpEntry */
136 if (e->flags & PRCONT) {
139 memcpy(&id, e->name, sizeof(id));
140 if ((id != PRBADID) && ((id > (1 << 24)) || (id < -(1 << 24)))) {
141 /* assume server incorrectly swapped these bytes... */
143 while (i < sizeof(e->name)) {
146 e->name[i] = e->name[i + 3];
147 e->name[i + 3] = temp;
148 temp = e->name[i + 1];
149 e->name[i + 1] = e->name[i + 2];
150 e->name[i + 2] = temp;
155 return pr_PrintEntry(stdout, /*host order */ 1, ea, e, indent);
158 #ifndef AFS_PTHREAD_ENV
162 #include "AFS_component_version_number.c"
165 main(int argc, char **argv)
169 char name[PR_MAXNAMELEN];
170 afs_int32 id, oid = ANONYMOUSID, gid;
174 struct prentry entry;
178 struct hostent *hostinfo;
179 struct in_addr *hostaddr;
187 * The following signal action for AIX is necessary so that in case of a
188 * crash (i.e. core is generated) we can include the user's data section
189 * in the core dump. Unfortunately, by default, only a partial core is
190 * generated which, in many cases, isn't too useful.
192 struct sigaction nsa;
194 sigemptyset(&nsa.sa_mask);
195 nsa.sa_handler = SIG_DFL;
196 nsa.sa_flags = SA_FULLDUMP;
197 sigaction(SIGSEGV, &nsa, NULL);
201 initialize_PT_error_table();
203 strcpy(confdir, AFSDIR_CLIENT_ETC_DIRPATH);
207 int arglen = strlen(argv[n]);
209 lcstring(arg, argv[n], sizeof(arg));
210 #define IsArg(a) (strncmp (arg,a, arglen) == 0)
211 if (IsArg("-testconfdir"))
212 strncpy(confdir, argv[++n], sizeof(confdir));
213 else if (IsArg("client"))
214 strncpy(confdir, AFSDIR_CLIENT_ETC_DIRPATH, sizeof(confdir));
215 else if (IsArg("server"))
216 strncpy(confdir, AFSDIR_SERVER_ETC_DIRPATH, sizeof(confdir));
217 else if (IsArg("0") || IsArg("1") || IsArg("2"))
218 security = atoi(argv[n]);
219 else if (IsArg("-ignoreexist"))
221 else if (IsArg("-cell"))
225 ("Usage is: 'prclient [-testconfdir <dir> | server | client] [0 | 1 | 2] [-ignoreExist] [-cell <cellname>]\n");
231 printf("Using CellServDB file in %s\n", confdir);
233 printf("Making unauthenticated connection to prserver\n");
235 code = pr_Initialize(security, confdir, cell);
237 afs_com_err(whoami, code, "Couldn't initialize protection library");
245 s = fgets(line, sizeof(line), stdin);
250 code = GetString(op, sizeof(op));
252 afs_com_err(whoami, PRBADARG,
253 "error reading opcode in line '%s', got '%.*s'", line,
258 continue; /* no input */
260 if (!strcmp(op, "cr")) {
261 if (GetString(name, sizeof(name)) || GetInt32(&id)
264 /* use ubik_Call to do the work, finding an up server and handling
265 * the job of finding a sync site, if need be */
267 code = ubik_PR_INewEntry(pruclient, 0, name, id, oid);
269 afs_com_err(whoami, code, "on %s %s %d %d", op, name, id, oid);
270 } else if (!strcmp(op, "sf")) {
271 afs_int32 mask, access, gq, uq;
272 if (GetInt32(&id) || GetXInt32(&mask) || GetXInt32(&access)
273 || GetInt32(&gq) || GetInt32(&uq))
277 ubik_PR_SetFieldsEntry(pruclient, 0, id, mask,
278 access, gq, uq, 0, 0);
280 afs_com_err(whoami, code, "on %s %d %x %x %d %d", op, id, mask,
282 } else if (!strcmp(op, "ce")) {
283 char newname[PR_MAXNAMELEN];
285 if (GetInt32(&id) || GetString(newname, sizeof(newname))
286 || GetInt32(&oid) || GetInt32(&newid))
290 ubik_PR_ChangeEntry(pruclient, 0, id, newname, oid,
293 afs_com_err(whoami, code, "on %s %d %s %d %d", op, id, newname,
295 } else if (!strcmp(op, "wh")) {
296 /* scanf("%d",&id); */
300 code = ubik_PR_WhereIsIt(pruclient, 0, id, &pos);
302 printf("%s\n", pr_ErrorMsg(code));
304 printf("location %d\n", pos);
305 } else if (!strcmp(op, "du")) {
306 memset(&entry, 0, sizeof(entry));
307 /* scanf("%d",&pos); */
311 code = ubik_PR_DumpEntry(pruclient, 0, pos, (struct prdebugentry *)&entry);
313 printf("%s\n", pr_ErrorMsg(code));
314 if (code == PRSUCCESS) {
315 PrintEntry(pos, &entry, /*indent */ 0);
317 printf("The contents of the entry for %d are:\n", entry.id);
318 printf("flags %d next %d\n", entry.flags, entry.next);
319 printf("Groups (or members) \n");
320 for (i = 0; i < PRSIZE; i++)
321 printf("%d\n", entry.entries[i]);
322 printf("nextID %d nextname %d name %s\n", entry.nextID,
323 entry.nextName, entry.name);
324 printf("owner %d creator %d\n", entry.owner, entry.creator);
327 } else if (!strcmp(op, "add") || !strcmp(op, "au")) {
328 /* scanf("%d %d",&id,&gid); */
329 if (GetInt32(&id) || GetInt32(&gid))
332 code = ubik_PR_AddToGroup(pruclient, 0, id, gid);
334 afs_com_err(whoami, code, "on %s %d %d", op, id, gid);
335 } else if (!strcmp(op, "iton")) {
336 lid.idlist_val = (afs_int32 *) malloc(20 * sizeof(afs_int32));
337 ptr = lid.idlist_val;
341 while ((lid.idlist_len < 20) && (sscanf(foo, "%d", ptr) != EOF)) {
347 fprintf(stderr, "too many values specified; max is %d\n", 20);
349 lnames.namelist_val = 0;
350 lnames.namelist_len = 0;
351 code = ubik_PR_IDToName(pruclient, 0, &lid, &lnames);
353 printf("%s\n", pr_ErrorMsg(code));
354 if (code == PRSUCCESS) {
355 for (i = 0; i < lnames.namelist_len; i++) {
356 printf("id %d name %s\n", lid.idlist_val[i],
357 lnames.namelist_val[i]);
359 free(lnames.namelist_val);
361 free(lid.idlist_val);
364 } else if (!strcmp(op, "ntoi")) {
365 lnames.namelist_val =
366 (prname *) malloc(PR_MAXLIST * PR_MAXNAMELEN);
367 lnames.namelist_len = 0;
370 for (i = 0; ((lnames.namelist_len < PR_MAXLIST)
371 && (sscanf(foo, "%s", lnames.namelist_val[i]) !=
373 lnames.namelist_len++;
377 fprintf(stderr, "too many values specified; max is %d\n",
382 code = ubik_PR_NameToID(pruclient, 0, &lnames, &lid);
384 printf("%s\n", pr_ErrorMsg(code));
385 if (code == PRSUCCESS) {
386 for (i = 0; i < lid.idlist_len; i++)
387 printf("name %s id %d\n", lnames.namelist_val[i],
389 free(lid.idlist_val);
391 free(lnames.namelist_val);
392 lnames.namelist_val = 0;
393 lnames.namelist_len = 0;
394 } else if (!strcmp(op, "del")) {
395 /* scanf("%d",&id); */
399 code = ubik_PR_Delete(pruclient, 0, id);
401 printf("%s\n", pr_ErrorMsg(code));
402 } else if (!strcmp(op, "dg")) {
403 /* scanf("%d",&id); */
407 code = ubik_PR_Delete(pruclient, 0, id);
409 printf("%s\n", pr_ErrorMsg(code));
410 } else if (!strcmp(op, "rm")) {
411 /* scanf("%d %d",&id,&gid); */
412 if (GetInt32(&id) || GetInt32(&gid))
415 code = ubik_PR_RemoveFromGroup(pruclient, 0, id, gid);
417 printf("%s\n", pr_ErrorMsg(code));
419 #if defined(SUPERGROUPS)
420 else if (!strcmp(op, "lsg")) {
421 alist.prlist_len = 0;
422 alist.prlist_val = 0;
423 /* scanf("%d",&id); */
428 ubik_PR_ListSuperGroups(pruclient, 0, id, &alist,
431 printf("%s\n", pr_ErrorMsg(code));
432 if (code == PRSUCCESS) {
433 ptr = alist.prlist_val;
435 printf("Number of groups greater than PR_MAXGROUPS!\n");
436 printf("Excess of %d.\n", over);
438 for (i = 0; i < alist.prlist_len; i++, ptr++)
439 printf("%d\n", *ptr);
440 free(alist.prlist_val);
441 alist.prlist_len = 0;
442 alist.prlist_val = 0;
445 #endif /* SUPERGROUPS */
446 else if (!strcmp(op, "l")) {
447 alist.prlist_len = 0;
448 alist.prlist_val = 0;
449 /* scanf("%d",&id); */
453 code = ubik_PR_GetCPS(pruclient, 0, id, &alist, &over);
455 printf("%s\n", pr_ErrorMsg(code));
456 if (code == PRSUCCESS) {
457 ptr = alist.prlist_val;
459 printf("Number of groups greater than PR_MAXGROUPS!\n");
460 printf("Excess of %d.\n", over);
462 for (i = 0; i < alist.prlist_len; i++, ptr++)
463 printf("%d\n", *ptr);
464 free(alist.prlist_val);
465 alist.prlist_len = 0;
466 alist.prlist_val = 0;
468 } else if (!strcmp(op, "lh")) {
469 alist.prlist_len = 0;
470 alist.prlist_val = 0;
471 /* scanf("%d",&id); */
472 if (GetString(name, sizeof(name)))
474 else if (!(hostinfo = gethostbyname(name)))
477 hostaddr = (struct in_addr *)hostinfo->h_addr_list[0];
478 id = ntohl(hostaddr->s_addr);
480 ubik_PR_GetHostCPS(pruclient, 0, id, &alist, &over);
483 printf("%s\n", pr_ErrorMsg(code));
484 if (code == PRSUCCESS) {
485 ptr = alist.prlist_val;
487 printf("Number of groups greater than PR_MAXGROUPS!\n");
488 printf("Excess of %d.\n", over);
490 for (i = 0; i < alist.prlist_len; i++, ptr++)
491 printf("%d\n", *ptr);
492 free(alist.prlist_val);
493 alist.prlist_len = 0;
494 alist.prlist_val = 0;
497 #if defined(SUPERGROUPS)
498 else if (!strcmp(op, "m")) {
499 alist.prlist_len = 0;
500 alist.prlist_val = 0;
501 /* scanf("%d",&id); */
506 ubik_PR_ListElements(pruclient, 0, id, &alist,
509 printf("%s\n", pr_ErrorMsg(code));
510 if (code == PRSUCCESS) {
511 ptr = alist.prlist_val;
513 printf("Number of groups greater than PR_MAXGROUPS!\n");
514 printf("Excess of %d.\n", over);
516 for (i = 0; i < alist.prlist_len; i++, ptr++)
517 printf("%d\n", *ptr);
518 free(alist.prlist_val);
519 alist.prlist_len = 0;
520 alist.prlist_val = 0;
523 #endif /* SUPERGROUPS */
524 else if (!strcmp(op, "nu")) {
525 /* scanf("%s",name); */
526 if (GetString(name, sizeof(name)))
529 code = pr_CreateUser(name, &id);
531 printf("%s\n", pr_ErrorMsg(code));
532 if (code == PRSUCCESS)
533 printf("Id is %d.\n", id);
534 } else if (!strcmp(op, "ng")) {
535 /* scanf("%s",name); */
536 if (GetString(name, sizeof(name)))
539 code = ubik_PR_NewEntry(pruclient, 0, name, 1, oid, &id);
541 printf("%s\n", pr_ErrorMsg(code));
542 if (code == PRSUCCESS)
543 printf("Id is %d.\n", id);
544 } else if (!strcmp(op, "lm")) {
545 code = ubik_PR_ListMax(pruclient, 0, &id, &gid);
547 printf("%s\n", pr_ErrorMsg(code));
548 if (code == PRSUCCESS)
549 printf("Max user id is %d, max (really min) group is %d.\n",
551 } else if (!strcmp(op, "smu")) {
552 /* scanf("%d",&id); */
556 code = ubik_PR_SetMax(pruclient, 0, id, 0);
558 printf("%s\n", pr_ErrorMsg(code));
559 } else if (!strcmp(op, "smg")) {
560 /* scanf("%d",&id); */
564 code = ubik_PR_SetMax(pruclient, 0, id, 1);
566 printf("%s\n", pr_ErrorMsg(code));
567 } else if (!strcmp(op, "sin")) {
568 /* scanf("%d",&id); */
572 code = pr_SIdToName(id, name);
574 printf("%s\n", pr_ErrorMsg(code));
575 if (code == PRSUCCESS)
576 printf("id %d name %s\n", id, name);
577 } else if (!strcmp(op, "sni")) {
578 /* scanf("%s",name); */
579 if (GetString(name, sizeof(name)))
582 code = pr_SNameToId(name, &id);
584 printf("%s\n", pr_ErrorMsg(code));
585 if (code == PRSUCCESS)
586 printf("name %s id %d\n", name, id);
587 } else if (!strcmp(op, "fih")) {
589 struct PrUpdateEntry uentry;
590 memset(&uentry, 0, sizeof(uentry));
591 /* scanf("%s",name); */
592 if (GetString(name, sizeof(name))) {
596 code = pr_SNameToId(name, &id);
598 printf("%s\n", pr_ErrorMsg(code));
601 code = pr_SIdToName(id, tname);
602 if (code == PRSUCCESS) {
604 ("Warning: Id hash for %s (id %d) seems correct at the db; rehashing it anyway\n",
608 uentry.Mask = PRUPDATE_IDHASH;
609 code = ubik_PR_UpdateEntry(pruclient, 0, 0, name, &uentry);
611 printf("Failed to update entry %s (err=%d)\n", name, code);
614 } else if (!strcmp(op, "fnh")) {
616 struct PrUpdateEntry uentry;
617 memset(&uentry, 0, sizeof(uentry));
618 /* scanf("%d", &id); */
623 code = pr_SIdToName(id, name);
625 printf("%s\n", pr_ErrorMsg(code));
628 code = pr_SNameToId(name, &tid);
629 if (code == PRSUCCESS) {
631 ("Name hash for %d (name is %s) seems correct at the db; rehashing it anyway\n",
635 uentry.Mask = PRUPDATE_NAMEHASH;
637 ubik_PR_UpdateEntry(pruclient, 0, id, "_foo_", &uentry);
639 printf("Failed to update entry with id %d (err=%d)\n", id,
644 #if defined(SUPERGROUPS)
645 else if (!strcmp(op, "fih")) {
647 struct PrUpdateEntry uentry;
648 memset(&uentry, 0, sizeof(uentry));
649 /* scanf("%s",name); */
650 if (GetString(name, sizeof(name))) {
654 code = pr_SNameToId(name, &id);
656 printf("%s\n", pr_ErrorMsg(code));
659 code = pr_SIdToName(id, tname);
660 if (code == PRSUCCESS) {
662 ("Warning: Id hash for %s (id %d) seems correct at the db; rehashing it anyway\n",
666 uentry.Mask = PRUPDATE_IDHASH;
667 code = ubik_PR_UpdateEntry(pruclient, 0, 0, name, &uentry);
669 printf("Failed to update entry %s (err=%d)\n", name, code);
672 } else if (!strcmp(op, "fnh")) {
674 struct PrUpdateEntry uentry;
675 memset(&uentry, 0, sizeof(uentry));
676 /* scanf("%d", &id); */
681 code = pr_SIdToName(id, name);
683 printf("%s\n", pr_ErrorMsg(code));
686 code = pr_SNameToId(name, &tid);
687 if (code == PRSUCCESS) {
689 ("Name hash for %d (name is %s) seems correct at the db; rehashing it anyway\n",
693 uentry.Mask = PRUPDATE_NAMEHASH;
695 ubik_PR_UpdateEntry(pruclient, 0, id, "_foo_", &uentry);
697 printf("Failed to update entry with id %d (err=%d)\n", id,
702 #endif /* SUPERGROUPS */
703 else if (!strcmp(op, "?"))
705 else if (!strcmp(op, "q"))
708 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");
746 while (**s != ' ' && **s != '\0')
751 #endif /* !AFS_PTHREAD_ENV */