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>
35 #include <afs/afsutil.h>
38 afs_int32 security = 0;
39 char confdir[AFSDIR_PATH_MAX];
43 #ifndef AFS_PTHREAD_ENV
44 extern struct ubik_client *pruclient;
47 static int ignoreExist = 0;
48 static char line[256];
49 static char *lineProgress;
51 #define WHITESPACE " \t\n"
53 #ifndef AFS_PTHREAD_ENV
57 /* OK, this REALLY sucks bigtime, but I can't tell who is calling
58 * afsconf_CheckAuth easily, and only *SERVERS* should be calling osi_audit
59 * anyway. It's gonna give somebody fits to debug, I know, I know.
63 #endif /* !AFS_PTHREAD_ENV */
66 GetToken(char *format, afs_int32 *l)
71 if (lineProgress == 0)
73 c = sscanf(lineProgress, format, l);
76 /* skip the white space */
77 lineProgress += strspn(lineProgress, WHITESPACE);
78 /* skip to end of token */
79 lineProgress = strpbrk(lineProgress, WHITESPACE);
83 #define GetInt32(l) GetToken ("%d", l)
84 #define GetXInt32(l) GetToken ("%x", l)
87 GetString(char *s, int slen)
93 if (lineProgress == 0)
95 /* skip the white space */
96 lineProgress += strspn(lineProgress, WHITESPACE);
98 /* check for quoted string and find end */
101 l = strcspn(++beg, "\"");
102 if (l == strlen(beg))
103 return -1; /* unbalanced quotes */
104 lineProgress = beg + l + 1;
106 l = strcspn(beg, WHITESPACE);
109 if (l >= slen) { /* don't return too much */
116 s[l] = 0; /* null termination */
121 CodeOk(afs_int32 code)
125 return code && (code != PREXIST) && (code != PRIDEXIST);
129 PrintEntry(afs_int32 ea, struct prentry *e, int indent)
131 /* handle screwed up versions of DumpEntry */
132 if (e->flags & PRCONT) {
133 afs_int32 id = *(afs_int32 *) (e->name);
134 if ((id != PRBADID) && ((id > (1 << 24)) || (id < -(1 << 24)))) {
135 /* assume server incorrectly swapped these bytes... */
137 while (i < sizeof(e->name)) {
140 e->name[i] = e->name[i + 3];
141 e->name[i + 3] = temp;
142 temp = e->name[i + 1];
143 e->name[i + 1] = e->name[i + 2];
144 e->name[i + 2] = temp;
149 return pr_PrintEntry(stdout, /*host order */ 1, ea, e, indent);
152 #ifndef AFS_PTHREAD_ENV
156 #include "AFS_component_version_number.c"
159 main(int argc, char **argv)
161 register afs_int32 code;
163 char name[PR_MAXNAMELEN];
164 afs_int32 id, oid = ANONYMOUSID, gid;
167 struct prentry entry;
171 struct hostent *hostinfo;
172 struct in_addr *hostaddr;
180 * The following signal action for AIX is necessary so that in case of a
181 * crash (i.e. core is generated) we can include the user's data section
182 * in the core dump. Unfortunately, by default, only a partial core is
183 * generated which, in many cases, isn't too useful.
185 struct sigaction nsa;
187 sigemptyset(&nsa.sa_mask);
188 nsa.sa_handler = SIG_DFL;
189 nsa.sa_flags = SA_FULLDUMP;
190 sigaction(SIGSEGV, &nsa, NULL);
194 initialize_PT_error_table();
196 strcpy(confdir, AFSDIR_CLIENT_ETC_DIRPATH);
200 int arglen = strlen(argv[i]);
202 lcstring(arg, argv[i], sizeof(arg));
203 #define IsArg(a) (strncmp (arg,a, arglen) == 0)
204 if (IsArg("-testconfdir"))
205 strncpy(confdir, argv[++i], sizeof(confdir));
206 else if (IsArg("client"))
207 strncpy(confdir, AFSDIR_CLIENT_ETC_DIRPATH, sizeof(confdir));
208 else if (IsArg("server"))
209 strncpy(confdir, AFSDIR_SERVER_ETC_DIRPATH, sizeof(confdir));
210 else if (IsArg("0") || IsArg("1") || IsArg("2"))
211 security = atoi(argv[i]);
212 else if (IsArg("-ignoreexist"))
214 else if (IsArg("-cell"))
218 ("Usage is: 'prclient [-testconfdir <dir> | server | client] [0 | 1 | 2] [-ignoreExist] [-cell <cellname>]\n");
224 printf("Using CellServDB file in %s\n", confdir);
226 printf("Making unauthenticated connection to prserver\n");
228 code = pr_Initialize(security, confdir, cell);
230 afs_com_err(whoami, code, "Couldn't initialize protection library");
238 s = fgets(line, sizeof(line), stdin);
243 code = GetString(op, sizeof(op));
245 afs_com_err(whoami, PRBADARG,
246 "error reading opcode in line '%s', got '%.*s'", line,
251 continue; /* no input */
253 if (!strcmp(op, "cr")) {
254 if (GetString(name, sizeof(name)) || GetInt32(&id)
257 /* use ubik_Call to do the work, finding an up server and handling
258 * the job of finding a sync site, if need be */
260 code = ubik_PR_INewEntry(pruclient, 0, name, id, oid);
262 afs_com_err(whoami, code, "on %s %s %d %d", op, name, id, oid);
263 } else if (!strcmp(op, "sf")) {
264 afs_int32 mask, access, gq, uq;
265 if (GetInt32(&id) || GetXInt32(&mask) || GetXInt32(&access)
266 || GetInt32(&gq) || GetInt32(&uq))
270 ubik_PR_SetFieldsEntry(pruclient, 0, id, mask,
271 access, gq, uq, 0, 0);
273 afs_com_err(whoami, code, "on %s %d %x %x %d %d", op, id, mask,
275 } else if (!strcmp(op, "ce")) {
276 char newname[PR_MAXNAMELEN];
278 if (GetInt32(&id) || GetString(newname, sizeof(newname))
279 || GetInt32(&oid) || GetInt32(&newid))
283 ubik_PR_ChangeEntry(pruclient, 0, id, newname, oid,
286 afs_com_err(whoami, code, "on %s %d %s %d %d", op, id, newname,
288 } else if (!strcmp(op, "wh")) {
289 /* scanf("%d",&id); */
293 code = ubik_PR_WhereIsIt(pruclient, 0, id, &pos);
295 printf("%s\n", pr_ErrorMsg(code));
297 printf("location %d\n", pos);
298 } else if (!strcmp(op, "du")) {
299 memset(&entry, 0, sizeof(entry));
300 /* scanf("%d",&pos); */
304 code = ubik_PR_DumpEntry(pruclient, 0, pos, &entry);
306 printf("%s\n", pr_ErrorMsg(code));
307 if (code == PRSUCCESS) {
308 PrintEntry(pos, &entry, /*indent */ 0);
310 printf("The contents of the entry for %d are:\n", entry.id);
311 printf("flags %d next %d\n", entry.flags, entry.next);
312 printf("Groups (or members) \n");
313 for (i = 0; i < PRSIZE; i++)
314 printf("%d\n", entry.entries[i]);
315 printf("nextID %d nextname %d name %s\n", entry.nextID,
316 entry.nextName, entry.name);
317 printf("owner %d creator %d\n", entry.owner, entry.creator);
320 } else if (!strcmp(op, "add") || !strcmp(op, "au")) {
321 /* scanf("%d %d",&id,&gid); */
322 if (GetInt32(&id) || GetInt32(&gid))
325 code = ubik_PR_AddToGroup(pruclient, 0, id, gid);
327 afs_com_err(whoami, code, "on %s %d %d", op, id, gid);
328 } else if (!strcmp(op, "iton")) {
329 lid.idlist_val = (afs_int32 *) malloc(20 * sizeof(afs_int32));
330 ptr = lid.idlist_val;
334 while ((lid.idlist_len < 20) && (sscanf(foo, "%d", ptr) != EOF)) {
340 fprintf(stderr, "too many values specified; max is %d\n", 20);
342 lnames.namelist_val = 0;
343 lnames.namelist_len = 0;
344 code = ubik_PR_IDToName(pruclient, 0, &lid, &lnames);
346 printf("%s\n", pr_ErrorMsg(code));
347 if (code == PRSUCCESS) {
348 for (i = 0; i < lnames.namelist_len; i++) {
349 printf("id %d name %s\n", lid.idlist_val[i],
350 lnames.namelist_val[i]);
352 free(lnames.namelist_val);
354 free(lid.idlist_val);
357 } else if (!strcmp(op, "ntoi")) {
358 lnames.namelist_val =
359 (prname *) malloc(PR_MAXLIST * PR_MAXNAMELEN);
360 lnames.namelist_len = 0;
363 for (i = 0; ((lnames.namelist_len < PR_MAXLIST)
364 && (sscanf(foo, "%s", lnames.namelist_val[i]) !=
366 lnames.namelist_len++;
370 fprintf(stderr, "too many values specified; max is %d\n",
375 code = ubik_PR_NameToID(pruclient, 0, &lnames, &lid);
377 printf("%s\n", pr_ErrorMsg(code));
378 if (code == PRSUCCESS) {
379 for (i = 0; i < lid.idlist_len; i++)
380 printf("name %s id %d\n", lnames.namelist_val[i],
382 free(lid.idlist_val);
384 free(lnames.namelist_val);
385 lnames.namelist_val = 0;
386 lnames.namelist_len = 0;
387 } else if (!strcmp(op, "del")) {
388 /* scanf("%d",&id); */
392 code = ubik_PR_Delete(pruclient, 0, id);
394 printf("%s\n", pr_ErrorMsg(code));
395 } else if (!strcmp(op, "dg")) {
396 /* scanf("%d",&id); */
400 code = ubik_PR_Delete(pruclient, 0, id);
402 printf("%s\n", pr_ErrorMsg(code));
403 } else if (!strcmp(op, "rm")) {
404 /* scanf("%d %d",&id,&gid); */
405 if (GetInt32(&id) || GetInt32(&gid))
408 code = ubik_PR_RemoveFromGroup(pruclient, 0, id, gid);
410 printf("%s\n", pr_ErrorMsg(code));
412 #if defined(SUPERGROUPS)
413 else if (!strcmp(op, "lsg")) {
414 alist.prlist_len = 0;
415 alist.prlist_val = 0;
416 /* scanf("%d",&id); */
421 ubik_PR_ListSuperGroups(pruclient, 0, id, &alist,
424 printf("%s\n", pr_ErrorMsg(code));
425 if (code == PRSUCCESS) {
426 ptr = alist.prlist_val;
428 printf("Number of groups greater than PR_MAXGROUPS!\n");
429 printf("Excess of %d.\n", over);
431 for (i = 0; i < alist.prlist_len; i++, ptr++)
432 printf("%d\n", *ptr);
433 free(alist.prlist_val);
434 alist.prlist_len = 0;
435 alist.prlist_val = 0;
438 #endif /* SUPERGROUPS */
439 else if (!strcmp(op, "l")) {
440 alist.prlist_len = 0;
441 alist.prlist_val = 0;
442 /* scanf("%d",&id); */
446 code = ubik_PR_GetCPS(pruclient, 0, id, &alist, &over);
448 printf("%s\n", pr_ErrorMsg(code));
449 if (code == PRSUCCESS) {
450 ptr = alist.prlist_val;
452 printf("Number of groups greater than PR_MAXGROUPS!\n");
453 printf("Excess of %d.\n", over);
455 for (i = 0; i < alist.prlist_len; i++, ptr++)
456 printf("%d\n", *ptr);
457 free(alist.prlist_val);
458 alist.prlist_len = 0;
459 alist.prlist_val = 0;
461 } else if (!strcmp(op, "lh")) {
462 alist.prlist_len = 0;
463 alist.prlist_val = 0;
464 /* scanf("%d",&id); */
465 if (GetString(name, sizeof(name)))
467 else if (!(hostinfo = gethostbyname(name)))
470 hostaddr = hostinfo->h_addr_list[0];
471 id = ntohl(hostaddr->s_addr);
473 ubik_PR_GetHostCPS(pruclient, 0, id, &alist, &over);
476 printf("%s\n", pr_ErrorMsg(code));
477 if (code == PRSUCCESS) {
478 ptr = alist.prlist_val;
480 printf("Number of groups greater than PR_MAXGROUPS!\n");
481 printf("Excess of %d.\n", over);
483 for (i = 0; i < alist.prlist_len; i++, ptr++)
484 printf("%d\n", *ptr);
485 free(alist.prlist_val);
486 alist.prlist_len = 0;
487 alist.prlist_val = 0;
490 #if defined(SUPERGROUPS)
491 else if (!strcmp(op, "m")) {
492 alist.prlist_len = 0;
493 alist.prlist_val = 0;
494 /* scanf("%d",&id); */
499 ubik_PR_ListElements(pruclient, 0, id, &alist,
502 printf("%s\n", pr_ErrorMsg(code));
503 if (code == PRSUCCESS) {
504 ptr = alist.prlist_val;
506 printf("Number of groups greater than PR_MAXGROUPS!\n");
507 printf("Excess of %d.\n", over);
509 for (i = 0; i < alist.prlist_len; i++, ptr++)
510 printf("%d\n", *ptr);
511 free(alist.prlist_val);
512 alist.prlist_len = 0;
513 alist.prlist_val = 0;
516 #endif /* SUPERGROUPS */
517 else if (!strcmp(op, "nu")) {
518 /* scanf("%s",name); */
519 if (GetString(name, sizeof(name)))
522 code = pr_CreateUser(name, &id);
524 printf("%s\n", pr_ErrorMsg(code));
525 if (code == PRSUCCESS)
526 printf("Id is %d.\n", id);
527 } else if (!strcmp(op, "ng")) {
528 /* scanf("%s",name); */
529 if (GetString(name, sizeof(name)))
532 code = ubik_PR_NewEntry(pruclient, 0, name, 1, oid, &id);
534 printf("%s\n", pr_ErrorMsg(code));
535 if (code == PRSUCCESS)
536 printf("Id is %d.\n", id);
537 } else if (!strcmp(op, "lm")) {
538 code = ubik_PR_ListMax(pruclient, 0, &id, &gid);
540 printf("%s\n", pr_ErrorMsg(code));
541 if (code == PRSUCCESS)
542 printf("Max user id is %d, max (really min) group is %d.\n",
544 } else if (!strcmp(op, "smu")) {
545 /* scanf("%d",&id); */
549 code = ubik_PR_SetMax(pruclient, 0, id, 0);
551 printf("%s\n", pr_ErrorMsg(code));
552 } else if (!strcmp(op, "smg")) {
553 /* scanf("%d",&id); */
557 code = ubik_PR_SetMax(pruclient, 0, id, 1);
559 printf("%s\n", pr_ErrorMsg(code));
560 } else if (!strcmp(op, "sin")) {
561 /* scanf("%d",&id); */
565 code = pr_SIdToName(id, name);
567 printf("%s\n", pr_ErrorMsg(code));
568 if (code == PRSUCCESS)
569 printf("id %d name %s\n", id, name);
570 } else if (!strcmp(op, "sni")) {
571 /* scanf("%s",name); */
572 if (GetString(name, sizeof(name)))
575 code = pr_SNameToId(name, &id);
577 printf("%s\n", pr_ErrorMsg(code));
578 if (code == PRSUCCESS)
579 printf("name %s id %d\n", name, id);
580 } else if (!strcmp(op, "fih")) {
582 struct PrUpdateEntry uentry;
583 memset(&uentry, 0, sizeof(uentry));
584 /* scanf("%s",name); */
585 if (GetString(name, sizeof(name))) {
589 code = pr_SNameToId(name, &id);
591 printf("%s\n", pr_ErrorMsg(code));
594 code = pr_SIdToName(id, tname);
595 if (code == PRSUCCESS) {
597 ("Warning: Id hash for %s (id %d) seems correct at the db; rehashing it anyway\n",
601 uentry.Mask = PRUPDATE_IDHASH;
602 code = ubik_PR_UpdateEntry(pruclient, 0, 0, name, &uentry);
604 printf("Failed to update entry %s (err=%d)\n", name, code);
607 } else if (!strcmp(op, "fnh")) {
609 struct PrUpdateEntry uentry;
610 memset(&uentry, 0, sizeof(uentry));
611 /* scanf("%d", &id); */
616 code = pr_SIdToName(id, name);
618 printf("%s\n", pr_ErrorMsg(code));
621 code = pr_SNameToId(name, &tid);
622 if (code == PRSUCCESS) {
624 ("Name hash for %d (name is %s) seems correct at the db; rehashing it anyway\n",
628 uentry.Mask = PRUPDATE_NAMEHASH;
630 ubik_PR_UpdateEntry(pruclient, 0, id, "_foo_", &uentry);
632 printf("Failed to update entry with id %d (err=%d)\n", id,
637 #if defined(SUPERGROUPS)
638 else if (!strcmp(op, "fih")) {
640 struct PrUpdateEntry uentry;
641 memset(&uentry, 0, sizeof(uentry));
642 /* scanf("%s",name); */
643 if (GetString(name, sizeof(name))) {
647 code = pr_SNameToId(name, &id);
649 printf("%s\n", pr_ErrorMsg(code));
652 code = pr_SIdToName(id, tname);
653 if (code == PRSUCCESS) {
655 ("Warning: Id hash for %s (id %d) seems correct at the db; rehashing it anyway\n",
659 uentry.Mask = PRUPDATE_IDHASH;
660 code = ubik_PR_UpdateEntry(pruclient, 0, 0, name, &uentry);
662 printf("Failed to update entry %s (err=%d)\n", name, code);
665 } else if (!strcmp(op, "fnh")) {
667 struct PrUpdateEntry uentry;
668 memset(&uentry, 0, sizeof(uentry));
669 /* scanf("%d", &id); */
674 code = pr_SIdToName(id, name);
676 printf("%s\n", pr_ErrorMsg(code));
679 code = pr_SNameToId(name, &tid);
680 if (code == PRSUCCESS) {
682 ("Name hash for %d (name is %s) seems correct at the db; rehashing it anyway\n",
686 uentry.Mask = PRUPDATE_NAMEHASH;
688 ubik_PR_UpdateEntry(pruclient, 0, id, "_foo_", &uentry);
690 printf("Failed to update entry with id %d (err=%d)\n", id,
695 #endif /* SUPERGROUPS */
696 else if (!strcmp(op, "?"))
698 else if (!strcmp(op, "q"))
701 printf("Unknown op: '%s'! ? for help\n", op);
708 printf("cr name id owner - create entry with name and id.\n");
709 printf("wh id - what is the offset into database for id?\n");
710 printf("du offset - dump the contents of the entry at offset.\n");
711 printf("add uid gid - add user uid to group gid.\n");
712 printf("iton id* - translate the list of id's to names.\n");
713 printf("ntoi name* - translate the list of names to ids.\n");
714 printf("del id - delete the entry for id.\n");
715 printf("dg gid - delete the entry for group gid.\n");
716 printf("rm id gid - remove user id from group gid.\n");
717 printf("l id - get the CPS for id.\n");
718 printf("lh host - get the host CPS for host.\n");
719 #if defined(SUPERGROUPS)
720 printf("lsg id - get the supergroups for id.\n");
721 printf("m id - list elements for id.\n");
723 printf("nu name - create new user with name - returns an id.\n");
724 printf("ng name - create new group with name - returns an id.\n");
725 printf("lm - list max user id and max (really min) group id.\n");
726 printf("smu - set max user id.\n");
727 printf("smg - set max group id.\n");
728 printf("sin id - single iton.\n");
729 printf("sni name - single ntoi.\n");
730 printf("fih name - fix id hash for <name>.\n");
731 printf("fnh id - fix name hash for <id>.\n");
732 printf("q - quit.\n?- this message.\n");
739 while (**s != ' ' && **s != '\0')
744 #endif /* !AFS_PTHREAD_ENV */