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 extern struct ubik_client *pruclient;
46 static int ignoreExist = 0;
47 static char line[256];
48 static char *lineProgress;
50 #define WHITESPACE " \t\n"
52 #ifndef AFS_PTHREAD_ENV
56 /* OK, this REALLY sucks bigtime, but I can't tell who is calling
57 * afsconf_CheckAuth easily, and only *SERVERS* should be calling osi_audit
58 * anyway. It's gonna give somebody fits to debug, I know, I know.
62 #endif /* !AFS_PTHREAD_ENV */
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, 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 com_err(whoami, code, "Couldn't initialize protection library");
246 s = fgets(line, sizeof(line), stdin);
251 code = GetString(op, sizeof(op));
253 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_Call(PR_INewEntry, pruclient, 0, name, id, oid);
270 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_Call(PR_SetFieldsEntry, pruclient, 0, id, mask,
279 access, gq, uq, 0, 0);
281 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_Call(PR_ChangeEntry, pruclient, 0, id, newname, oid,
294 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_Call(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_Call(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_Call(PR_AddToGroup, pruclient, 0, id, gid);
335 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_Call(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;
372 ((lnames.namelist_len < PR_MAXLIST)
373 && (sscanf(foo, "%s", lnames.namelist_val[i]) != EOF));
375 lnames.namelist_len++;
379 fprintf(stderr, "too many values specified; max is %d\n",
384 code = ubik_Call(PR_NameToID, pruclient, 0, &lnames, &lid);
386 printf("%s\n", pr_ErrorMsg(code));
387 if (code == PRSUCCESS) {
388 for (i = 0; i < lid.idlist_len; i++)
389 printf("name %s id %d\n", lnames.namelist_val[i],
391 free(lid.idlist_val);
393 free(lnames.namelist_val);
394 lnames.namelist_val = 0;
395 lnames.namelist_len = 0;
396 } else if (!strcmp(op, "del")) {
397 /* scanf("%d",&id); */
401 code = ubik_Call(PR_Delete, pruclient, 0, id);
403 printf("%s\n", pr_ErrorMsg(code));
404 } else if (!strcmp(op, "dg")) {
405 /* scanf("%d",&id); */
409 code = ubik_Call(PR_Delete, pruclient, 0, id);
411 printf("%s\n", pr_ErrorMsg(code));
412 } else if (!strcmp(op, "rm")) {
413 /* scanf("%d %d",&id,&gid); */
414 if (GetInt32(&id) || GetInt32(&gid))
417 code = ubik_Call(PR_RemoveFromGroup, pruclient, 0, id, gid);
419 printf("%s\n", pr_ErrorMsg(code));
421 #if defined(SUPERGROUPS)
422 else if (!strcmp(op, "lsg")) {
423 alist.prlist_len = 0;
424 alist.prlist_val = 0;
425 /* scanf("%d",&id); */
430 ubik_Call(PR_ListSuperGroups, pruclient, 0, id, &alist,
433 printf("%s\n", pr_ErrorMsg(code));
434 if (code == PRSUCCESS) {
435 ptr = alist.prlist_val;
437 printf("Number of groups greater than PR_MAXGROUPS!\n");
438 printf("Excess of %d.\n", over);
440 for (i = 0; i < alist.prlist_len; i++, ptr++)
441 printf("%d\n", *ptr);
442 free(alist.prlist_val);
443 alist.prlist_len = 0;
444 alist.prlist_val = 0;
447 #endif /* SUPERGROUPS */
448 else if (!strcmp(op, "l")) {
449 alist.prlist_len = 0;
450 alist.prlist_val = 0;
451 /* scanf("%d",&id); */
455 code = ubik_Call(PR_GetCPS, pruclient, 0, id, &alist, &over);
457 printf("%s\n", pr_ErrorMsg(code));
458 if (code == PRSUCCESS) {
459 ptr = alist.prlist_val;
461 printf("Number of groups greater than PR_MAXGROUPS!\n");
462 printf("Excess of %d.\n", over);
464 for (i = 0; i < alist.prlist_len; i++, ptr++)
465 printf("%d\n", *ptr);
466 free(alist.prlist_val);
467 alist.prlist_len = 0;
468 alist.prlist_val = 0;
470 } else if (!strcmp(op, "lh")) {
471 alist.prlist_len = 0;
472 alist.prlist_val = 0;
473 /* scanf("%d",&id); */
474 if (GetString(name, sizeof(name)))
476 else if (!(hostinfo = gethostbyname(name)))
479 hostaddr = hostinfo->h_addr_list[0];
480 id = ntohl(hostaddr->s_addr);
482 ubik_Call(PR_GetHostCPS, pruclient, 0, id, &alist, &over);
485 printf("%s\n", pr_ErrorMsg(code));
486 if (code == PRSUCCESS) {
487 ptr = alist.prlist_val;
489 printf("Number of groups greater than PR_MAXGROUPS!\n");
490 printf("Excess of %d.\n", over);
492 for (i = 0; i < alist.prlist_len; i++, ptr++)
493 printf("%d\n", *ptr);
494 free(alist.prlist_val);
495 alist.prlist_len = 0;
496 alist.prlist_val = 0;
499 #if defined(SUPERGROUPS)
500 else if (!strcmp(op, "m")) {
501 alist.prlist_len = 0;
502 alist.prlist_val = 0;
503 /* scanf("%d",&id); */
508 ubik_Call(PR_ListElements, pruclient, 0, id, &alist,
511 printf("%s\n", pr_ErrorMsg(code));
512 if (code == PRSUCCESS) {
513 ptr = alist.prlist_val;
515 printf("Number of groups greater than PR_MAXGROUPS!\n");
516 printf("Excess of %d.\n", over);
518 for (i = 0; i < alist.prlist_len; i++, ptr++)
519 printf("%d\n", *ptr);
520 free(alist.prlist_val);
521 alist.prlist_len = 0;
522 alist.prlist_val = 0;
525 #endif /* SUPERGROUPS */
526 else if (!strcmp(op, "nu")) {
527 /* scanf("%s",name); */
528 if (GetString(name, sizeof(name)))
531 code = pr_CreateUser(name, &id);
533 printf("%s\n", pr_ErrorMsg(code));
534 if (code == PRSUCCESS)
535 printf("Id is %d.\n", id);
536 } else if (!strcmp(op, "ng")) {
537 /* scanf("%s",name); */
538 if (GetString(name, sizeof(name)))
541 code = ubik_Call(PR_NewEntry, pruclient, 0, name, 1, &id);
543 printf("%s\n", pr_ErrorMsg(code));
544 if (code == PRSUCCESS)
545 printf("Id is %d.\n", id);
546 } else if (!strcmp(op, "lm")) {
547 code = ubik_Call(PR_ListMax, pruclient, 0, &id, &gid);
549 printf("%s\n", pr_ErrorMsg(code));
550 if (code == PRSUCCESS)
551 printf("Max user id is %d, max (really min) group is %d.\n",
553 } else if (!strcmp(op, "smu")) {
554 /* scanf("%d",&id); */
558 code = ubik_Call(PR_SetMax, pruclient, 0, id, 0);
560 printf("%s\n", pr_ErrorMsg(code));
561 } else if (!strcmp(op, "smg")) {
562 /* scanf("%d",&id); */
566 code = ubik_Call(PR_SetMax, pruclient, 0, id, 1);
568 printf("%s\n", pr_ErrorMsg(code));
569 } else if (!strcmp(op, "sin")) {
570 /* scanf("%d",&id); */
574 code = pr_SIdToName(id, name);
576 printf("%s\n", pr_ErrorMsg(code));
577 if (code == PRSUCCESS)
578 printf("id %d name %s\n", id, name);
579 } else if (!strcmp(op, "sni")) {
580 /* scanf("%s",name); */
581 if (GetString(name, sizeof(name)))
584 code = pr_SNameToId(name, &id);
586 printf("%s\n", pr_ErrorMsg(code));
587 if (code == PRSUCCESS)
588 printf("name %s id %d\n", name, id);
589 } else if (!strcmp(op, "fih")) {
591 struct PrUpdateEntry uentry;
592 memset(&uentry, 0, sizeof(uentry));
593 /* scanf("%s",name); */
594 if (GetString(name, sizeof(name))) {
598 code = pr_SNameToId(name, &id);
600 printf("%s\n", pr_ErrorMsg(code));
603 code = pr_SIdToName(id, tname);
604 if (code == PRSUCCESS) {
606 ("Warning: Id hash for %s (id %d) seems correct at the db; rehashing it anyway\n",
610 uentry.Mask = PRUPDATE_IDHASH;
611 code = ubik_Call(PR_UpdateEntry, pruclient, 0, 0, name, &uentry);
613 printf("Failed to update entry %s (err=%d)\n", name, code);
616 } else if (!strcmp(op, "fnh")) {
618 struct PrUpdateEntry uentry;
619 memset(&uentry, 0, sizeof(uentry));
620 /* scanf("%d", &id); */
625 code = pr_SIdToName(id, name);
627 printf("%s\n", pr_ErrorMsg(code));
630 code = pr_SNameToId(name, &tid);
631 if (code == PRSUCCESS) {
633 ("Name hash for %d (name is %s) seems correct at the db; rehashing it anyway\n",
637 uentry.Mask = PRUPDATE_NAMEHASH;
639 ubik_Call(PR_UpdateEntry, pruclient, 0, id, "_foo_", &uentry);
641 printf("Failed to update entry with id %d (err=%d)\n", id,
646 #if defined(SUPERGROUPS)
647 else if (!strcmp(op, "fih")) {
649 struct PrUpdateEntry uentry;
650 bzero(&uentry, sizeof(uentry));
651 /* scanf("%s",name); */
652 if (GetString(name, sizeof(name))) {
656 code = pr_SNameToId(name, &id);
658 printf("%s\n", pr_ErrorMsg(code));
661 code = pr_SIdToName(id, tname);
662 if (code == PRSUCCESS) {
664 ("Warning: Id hash for %s (id %d) seems correct at the db; rehashing it anyway\n",
668 uentry.Mask = PRUPDATE_IDHASH;
669 code = ubik_Call(PR_UpdateEntry, pruclient, 0, 0, name, &uentry);
671 printf("Failed to update entry %s (err=%d)\n", name, code);
674 } else if (!strcmp(op, "fnh")) {
676 struct PrUpdateEntry uentry;
677 bzero(&uentry, sizeof(uentry));
678 /* scanf("%d", &id); */
683 code = pr_SIdToName(id, name);
685 printf("%s\n", pr_ErrorMsg(code));
688 code = pr_SNameToId(name, &tid);
689 if (code == PRSUCCESS) {
691 ("Name hash for %d (name is %s) seems correct at the db; rehashing it anyway\n",
695 uentry.Mask = PRUPDATE_NAMEHASH;
697 ubik_Call(PR_UpdateEntry, pruclient, 0, id, "_foo_", &uentry);
699 printf("Failed to update entry with id %d (err=%d)\n", id,
704 #endif /* SUPERGROUPS */
705 else if (!strcmp(op, "?"))
707 else if (!strcmp(op, "q"))
710 printf("Unknown op: '%s'! ? for help\n", op);
717 printf("cr name id owner - create entry with name and id.\n");
718 printf("wh id - what is the offset into database for id?\n");
719 printf("du offset - dump the contents of the entry at offset.\n");
720 printf("add uid gid - add user uid to group gid.\n");
721 printf("iton id* - translate the list of id's to names.\n");
722 printf("ntoi name* - translate the list of names to ids.\n");
723 printf("del id - delete the entry for id.\n");
724 printf("dg gid - delete the entry for group gid.\n");
725 printf("rm id gid - remove user id from group gid.\n");
726 printf("l id - get the CPS for id.\n");
727 printf("lh host - get the host CPS for host.\n");
728 #if defined(SUPERGROUPS)
729 printf("lsg id - get the supergroups for id.\n");
730 printf("m id - list elements for id.\n");
732 printf("nu name - create new user with name - returns an id.\n");
733 printf("ng name - create new group with name - returns an id.\n");
734 printf("lm - list max user id and max (really min) group id.\n");
735 printf("smu - set max user id.\n");
736 printf("smg - set max group id.\n");
737 printf("sin id - single iton.\n");
738 printf("sni name - single ntoi.\n");
739 printf("fih name - fix id hash for <name>.\n");
740 printf("fnh id - fix name hash for <id>.\n");
741 printf("q - quit.\n?- this message.\n");
748 while (**s != ' ' && **s != '\0')
753 #endif /* !AFS_PTHREAD_ENV */