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>
34 #include <afs/afsutil.h>
37 afs_int32 security = 0;
38 char confdir[AFSDIR_PATH_MAX];
42 #ifndef AFS_PTHREAD_ENV
43 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 */
65 GetToken(char *format, afs_int32 *l)
70 if (lineProgress == 0)
72 c = sscanf(lineProgress, format, l);
75 /* skip the white space */
76 lineProgress += strspn(lineProgress, WHITESPACE);
77 /* skip to end of token */
78 lineProgress = strpbrk(lineProgress, WHITESPACE);
82 #define GetInt32(l) GetToken ("%d", l)
83 #define GetXInt32(l) GetToken ("%x", l)
86 GetString(char *s, int slen)
92 if (lineProgress == 0)
94 /* skip the white space */
95 lineProgress += strspn(lineProgress, WHITESPACE);
97 /* check for quoted string and find end */
100 l = strcspn(++beg, "\"");
101 if (l == strlen(beg))
102 return -1; /* unbalanced quotes */
103 lineProgress = beg + l + 1;
105 l = strcspn(beg, WHITESPACE);
108 if (l >= slen) { /* don't return too much */
115 s[l] = 0; /* null termination */
120 CodeOk(afs_int32 code)
124 return code && (code != PREXIST) && (code != PRIDEXIST);
128 PrintEntry(afs_int32 ea, struct prentry *e, int indent)
130 /* handle screwed up versions of DumpEntry */
131 if (e->flags & PRCONT) {
132 afs_int32 id = *(afs_int32 *) (e->name);
133 if ((id != PRBADID) && ((id > (1 << 24)) || (id < -(1 << 24)))) {
134 /* assume server incorrectly swapped these bytes... */
136 while (i < sizeof(e->name)) {
139 e->name[i] = e->name[i + 3];
140 e->name[i + 3] = temp;
141 temp = e->name[i + 1];
142 e->name[i + 1] = e->name[i + 2];
143 e->name[i + 2] = temp;
148 return pr_PrintEntry(stdout, /*host order */ 1, ea, e, indent);
151 #ifndef AFS_PTHREAD_ENV
155 #include "AFS_component_version_number.c"
158 main(int argc, char **argv)
160 register afs_int32 code;
162 char name[PR_MAXNAMELEN];
163 afs_int32 id, oid = ANONYMOUSID, gid;
166 struct prentry entry;
170 struct hostent *hostinfo;
171 struct in_addr *hostaddr;
179 * The following signal action for AIX is necessary so that in case of a
180 * crash (i.e. core is generated) we can include the user's data section
181 * in the core dump. Unfortunately, by default, only a partial core is
182 * generated which, in many cases, isn't too useful.
184 struct sigaction nsa;
186 sigemptyset(&nsa.sa_mask);
187 nsa.sa_handler = SIG_DFL;
188 nsa.sa_flags = SA_FULLDUMP;
189 sigaction(SIGSEGV, &nsa, NULL);
193 initialize_PT_error_table();
195 strcpy(confdir, AFSDIR_CLIENT_ETC_DIRPATH);
199 int arglen = strlen(argv[i]);
201 lcstring(arg, argv[i], sizeof(arg));
202 #define IsArg(a) (strncmp (arg,a, arglen) == 0)
203 if (IsArg("-testconfdir"))
204 strncpy(confdir, argv[++i], sizeof(confdir));
205 else if (IsArg("client"))
206 strncpy(confdir, AFSDIR_CLIENT_ETC_DIRPATH, sizeof(confdir));
207 else if (IsArg("server"))
208 strncpy(confdir, AFSDIR_SERVER_ETC_DIRPATH, sizeof(confdir));
209 else if (IsArg("0") || IsArg("1") || IsArg("2"))
210 security = atoi(argv[i]);
211 else if (IsArg("-ignoreexist"))
213 else if (IsArg("-cell"))
217 ("Usage is: 'prclient [-testconfdir <dir> | server | client] [0 | 1 | 2] [-ignoreExist] [-cell <cellname>]\n");
223 printf("Using CellServDB file in %s\n", confdir);
225 printf("Making unauthenticated connection to prserver\n");
227 code = pr_Initialize(security, confdir, cell);
229 afs_com_err(whoami, code, "Couldn't initialize protection library");
237 s = fgets(line, sizeof(line), stdin);
242 code = GetString(op, sizeof(op));
244 afs_com_err(whoami, PRBADARG,
245 "error reading opcode in line '%s', got '%.*s'", line,
250 continue; /* no input */
252 if (!strcmp(op, "cr")) {
253 if (GetString(name, sizeof(name)) || GetInt32(&id)
256 /* use ubik_Call to do the work, finding an up server and handling
257 * the job of finding a sync site, if need be */
259 code = ubik_PR_INewEntry(pruclient, 0, name, id, oid);
261 afs_com_err(whoami, code, "on %s %s %d %d", op, name, id, oid);
262 } else if (!strcmp(op, "sf")) {
263 afs_int32 mask, access, gq, uq;
264 if (GetInt32(&id) || GetXInt32(&mask) || GetXInt32(&access)
265 || GetInt32(&gq) || GetInt32(&uq))
269 ubik_PR_SetFieldsEntry(pruclient, 0, id, mask,
270 access, gq, uq, 0, 0);
272 afs_com_err(whoami, code, "on %s %d %x %x %d %d", op, id, mask,
274 } else if (!strcmp(op, "ce")) {
275 char newname[PR_MAXNAMELEN];
277 if (GetInt32(&id) || GetString(newname, sizeof(newname))
278 || GetInt32(&oid) || GetInt32(&newid))
282 ubik_PR_ChangeEntry(pruclient, 0, id, newname, oid,
285 afs_com_err(whoami, code, "on %s %d %s %d %d", op, id, newname,
287 } else if (!strcmp(op, "wh")) {
288 /* scanf("%d",&id); */
292 code = ubik_PR_WhereIsIt(pruclient, 0, id, &pos);
294 printf("%s\n", pr_ErrorMsg(code));
296 printf("location %d\n", pos);
297 } else if (!strcmp(op, "du")) {
298 memset(&entry, 0, sizeof(entry));
299 /* scanf("%d",&pos); */
303 code = ubik_PR_DumpEntry(pruclient, 0, pos, &entry);
305 printf("%s\n", pr_ErrorMsg(code));
306 if (code == PRSUCCESS) {
307 PrintEntry(pos, &entry, /*indent */ 0);
309 printf("The contents of the entry for %d are:\n", entry.id);
310 printf("flags %d next %d\n", entry.flags, entry.next);
311 printf("Groups (or members) \n");
312 for (i = 0; i < PRSIZE; i++)
313 printf("%d\n", entry.entries[i]);
314 printf("nextID %d nextname %d name %s\n", entry.nextID,
315 entry.nextName, entry.name);
316 printf("owner %d creator %d\n", entry.owner, entry.creator);
319 } else if (!strcmp(op, "add") || !strcmp(op, "au")) {
320 /* scanf("%d %d",&id,&gid); */
321 if (GetInt32(&id) || GetInt32(&gid))
324 code = ubik_PR_AddToGroup(pruclient, 0, id, gid);
326 afs_com_err(whoami, code, "on %s %d %d", op, id, gid);
327 } else if (!strcmp(op, "iton")) {
328 lid.idlist_val = (afs_int32 *) malloc(20 * sizeof(afs_int32));
329 ptr = lid.idlist_val;
333 while ((lid.idlist_len < 20) && (sscanf(foo, "%d", ptr) != EOF)) {
339 fprintf(stderr, "too many values specified; max is %d\n", 20);
341 lnames.namelist_val = 0;
342 lnames.namelist_len = 0;
343 code = ubik_PR_IDToName(pruclient, 0, &lid, &lnames);
345 printf("%s\n", pr_ErrorMsg(code));
346 if (code == PRSUCCESS) {
347 for (i = 0; i < lnames.namelist_len; i++) {
348 printf("id %d name %s\n", lid.idlist_val[i],
349 lnames.namelist_val[i]);
351 free(lnames.namelist_val);
353 free(lid.idlist_val);
356 } else if (!strcmp(op, "ntoi")) {
357 lnames.namelist_val =
358 (prname *) malloc(PR_MAXLIST * PR_MAXNAMELEN);
359 lnames.namelist_len = 0;
362 for (i = 0; ((lnames.namelist_len < PR_MAXLIST)
363 && (sscanf(foo, "%s", lnames.namelist_val[i]) !=
365 lnames.namelist_len++;
369 fprintf(stderr, "too many values specified; max is %d\n",
374 code = ubik_PR_NameToID(pruclient, 0, &lnames, &lid);
376 printf("%s\n", pr_ErrorMsg(code));
377 if (code == PRSUCCESS) {
378 for (i = 0; i < lid.idlist_len; i++)
379 printf("name %s id %d\n", lnames.namelist_val[i],
381 free(lid.idlist_val);
383 free(lnames.namelist_val);
384 lnames.namelist_val = 0;
385 lnames.namelist_len = 0;
386 } else if (!strcmp(op, "del")) {
387 /* scanf("%d",&id); */
391 code = ubik_PR_Delete(pruclient, 0, id);
393 printf("%s\n", pr_ErrorMsg(code));
394 } else if (!strcmp(op, "dg")) {
395 /* scanf("%d",&id); */
399 code = ubik_PR_Delete(pruclient, 0, id);
401 printf("%s\n", pr_ErrorMsg(code));
402 } else if (!strcmp(op, "rm")) {
403 /* scanf("%d %d",&id,&gid); */
404 if (GetInt32(&id) || GetInt32(&gid))
407 code = ubik_PR_RemoveFromGroup(pruclient, 0, id, gid);
409 printf("%s\n", pr_ErrorMsg(code));
411 #if defined(SUPERGROUPS)
412 else if (!strcmp(op, "lsg")) {
413 alist.prlist_len = 0;
414 alist.prlist_val = 0;
415 /* scanf("%d",&id); */
420 ubik_PR_ListSuperGroups(pruclient, 0, id, &alist,
423 printf("%s\n", pr_ErrorMsg(code));
424 if (code == PRSUCCESS) {
425 ptr = alist.prlist_val;
427 printf("Number of groups greater than PR_MAXGROUPS!\n");
428 printf("Excess of %d.\n", over);
430 for (i = 0; i < alist.prlist_len; i++, ptr++)
431 printf("%d\n", *ptr);
432 free(alist.prlist_val);
433 alist.prlist_len = 0;
434 alist.prlist_val = 0;
437 #endif /* SUPERGROUPS */
438 else if (!strcmp(op, "l")) {
439 alist.prlist_len = 0;
440 alist.prlist_val = 0;
441 /* scanf("%d",&id); */
445 code = ubik_PR_GetCPS(pruclient, 0, id, &alist, &over);
447 printf("%s\n", pr_ErrorMsg(code));
448 if (code == PRSUCCESS) {
449 ptr = alist.prlist_val;
451 printf("Number of groups greater than PR_MAXGROUPS!\n");
452 printf("Excess of %d.\n", over);
454 for (i = 0; i < alist.prlist_len; i++, ptr++)
455 printf("%d\n", *ptr);
456 free(alist.prlist_val);
457 alist.prlist_len = 0;
458 alist.prlist_val = 0;
460 } else if (!strcmp(op, "lh")) {
461 alist.prlist_len = 0;
462 alist.prlist_val = 0;
463 /* scanf("%d",&id); */
464 if (GetString(name, sizeof(name)))
466 else if (!(hostinfo = gethostbyname(name)))
469 hostaddr = hostinfo->h_addr_list[0];
470 id = ntohl(hostaddr->s_addr);
472 ubik_PR_GetHostCPS(pruclient, 0, id, &alist, &over);
475 printf("%s\n", pr_ErrorMsg(code));
476 if (code == PRSUCCESS) {
477 ptr = alist.prlist_val;
479 printf("Number of groups greater than PR_MAXGROUPS!\n");
480 printf("Excess of %d.\n", over);
482 for (i = 0; i < alist.prlist_len; i++, ptr++)
483 printf("%d\n", *ptr);
484 free(alist.prlist_val);
485 alist.prlist_len = 0;
486 alist.prlist_val = 0;
489 #if defined(SUPERGROUPS)
490 else if (!strcmp(op, "m")) {
491 alist.prlist_len = 0;
492 alist.prlist_val = 0;
493 /* scanf("%d",&id); */
498 ubik_PR_ListElements(pruclient, 0, id, &alist,
501 printf("%s\n", pr_ErrorMsg(code));
502 if (code == PRSUCCESS) {
503 ptr = alist.prlist_val;
505 printf("Number of groups greater than PR_MAXGROUPS!\n");
506 printf("Excess of %d.\n", over);
508 for (i = 0; i < alist.prlist_len; i++, ptr++)
509 printf("%d\n", *ptr);
510 free(alist.prlist_val);
511 alist.prlist_len = 0;
512 alist.prlist_val = 0;
515 #endif /* SUPERGROUPS */
516 else if (!strcmp(op, "nu")) {
517 /* scanf("%s",name); */
518 if (GetString(name, sizeof(name)))
521 code = pr_CreateUser(name, &id);
523 printf("%s\n", pr_ErrorMsg(code));
524 if (code == PRSUCCESS)
525 printf("Id is %d.\n", id);
526 } else if (!strcmp(op, "ng")) {
527 /* scanf("%s",name); */
528 if (GetString(name, sizeof(name)))
531 code = ubik_PR_NewEntry(pruclient, 0, name, 1, oid, &id);
533 printf("%s\n", pr_ErrorMsg(code));
534 if (code == PRSUCCESS)
535 printf("Id is %d.\n", id);
536 } else if (!strcmp(op, "lm")) {
537 code = ubik_PR_ListMax(pruclient, 0, &id, &gid);
539 printf("%s\n", pr_ErrorMsg(code));
540 if (code == PRSUCCESS)
541 printf("Max user id is %d, max (really min) group is %d.\n",
543 } else if (!strcmp(op, "smu")) {
544 /* scanf("%d",&id); */
548 code = ubik_PR_SetMax(pruclient, 0, id, 0);
550 printf("%s\n", pr_ErrorMsg(code));
551 } else if (!strcmp(op, "smg")) {
552 /* scanf("%d",&id); */
556 code = ubik_PR_SetMax(pruclient, 0, id, 1);
558 printf("%s\n", pr_ErrorMsg(code));
559 } else if (!strcmp(op, "sin")) {
560 /* scanf("%d",&id); */
564 code = pr_SIdToName(id, name);
566 printf("%s\n", pr_ErrorMsg(code));
567 if (code == PRSUCCESS)
568 printf("id %d name %s\n", id, name);
569 } else if (!strcmp(op, "sni")) {
570 /* scanf("%s",name); */
571 if (GetString(name, sizeof(name)))
574 code = pr_SNameToId(name, &id);
576 printf("%s\n", pr_ErrorMsg(code));
577 if (code == PRSUCCESS)
578 printf("name %s id %d\n", name, id);
579 } else if (!strcmp(op, "fih")) {
581 struct PrUpdateEntry uentry;
582 memset(&uentry, 0, sizeof(uentry));
583 /* scanf("%s",name); */
584 if (GetString(name, sizeof(name))) {
588 code = pr_SNameToId(name, &id);
590 printf("%s\n", pr_ErrorMsg(code));
593 code = pr_SIdToName(id, tname);
594 if (code == PRSUCCESS) {
596 ("Warning: Id hash for %s (id %d) seems correct at the db; rehashing it anyway\n",
600 uentry.Mask = PRUPDATE_IDHASH;
601 code = ubik_PR_UpdateEntry(pruclient, 0, 0, name, &uentry);
603 printf("Failed to update entry %s (err=%d)\n", name, code);
606 } else if (!strcmp(op, "fnh")) {
608 struct PrUpdateEntry uentry;
609 memset(&uentry, 0, sizeof(uentry));
610 /* scanf("%d", &id); */
615 code = pr_SIdToName(id, name);
617 printf("%s\n", pr_ErrorMsg(code));
620 code = pr_SNameToId(name, &tid);
621 if (code == PRSUCCESS) {
623 ("Name hash for %d (name is %s) seems correct at the db; rehashing it anyway\n",
627 uentry.Mask = PRUPDATE_NAMEHASH;
629 ubik_PR_UpdateEntry(pruclient, 0, id, "_foo_", &uentry);
631 printf("Failed to update entry with id %d (err=%d)\n", id,
636 #if defined(SUPERGROUPS)
637 else if (!strcmp(op, "fih")) {
639 struct PrUpdateEntry uentry;
640 memset(&uentry, 0, sizeof(uentry));
641 /* scanf("%s",name); */
642 if (GetString(name, sizeof(name))) {
646 code = pr_SNameToId(name, &id);
648 printf("%s\n", pr_ErrorMsg(code));
651 code = pr_SIdToName(id, tname);
652 if (code == PRSUCCESS) {
654 ("Warning: Id hash for %s (id %d) seems correct at the db; rehashing it anyway\n",
658 uentry.Mask = PRUPDATE_IDHASH;
659 code = ubik_PR_UpdateEntry(pruclient, 0, 0, name, &uentry);
661 printf("Failed to update entry %s (err=%d)\n", name, code);
664 } else if (!strcmp(op, "fnh")) {
666 struct PrUpdateEntry uentry;
667 memset(&uentry, 0, sizeof(uentry));
668 /* scanf("%d", &id); */
673 code = pr_SIdToName(id, name);
675 printf("%s\n", pr_ErrorMsg(code));
678 code = pr_SNameToId(name, &tid);
679 if (code == PRSUCCESS) {
681 ("Name hash for %d (name is %s) seems correct at the db; rehashing it anyway\n",
685 uentry.Mask = PRUPDATE_NAMEHASH;
687 ubik_PR_UpdateEntry(pruclient, 0, id, "_foo_", &uentry);
689 printf("Failed to update entry with id %d (err=%d)\n", id,
694 #endif /* SUPERGROUPS */
695 else if (!strcmp(op, "?"))
697 else if (!strcmp(op, "q"))
700 printf("Unknown op: '%s'! ? for help\n", op);
707 printf("cr name id owner - create entry with name and id.\n");
708 printf("wh id - what is the offset into database for id?\n");
709 printf("du offset - dump the contents of the entry at offset.\n");
710 printf("add uid gid - add user uid to group gid.\n");
711 printf("iton id* - translate the list of id's to names.\n");
712 printf("ntoi name* - translate the list of names to ids.\n");
713 printf("del id - delete the entry for id.\n");
714 printf("dg gid - delete the entry for group gid.\n");
715 printf("rm id gid - remove user id from group gid.\n");
716 printf("l id - get the CPS for id.\n");
717 printf("lh host - get the host CPS for host.\n");
718 #if defined(SUPERGROUPS)
719 printf("lsg id - get the supergroups for id.\n");
720 printf("m id - list elements for id.\n");
722 printf("nu name - create new user with name - returns an id.\n");
723 printf("ng name - create new group with name - returns an id.\n");
724 printf("lm - list max user id and max (really min) group id.\n");
725 printf("smu - set max user id.\n");
726 printf("smg - set max group id.\n");
727 printf("sin id - single iton.\n");
728 printf("sni name - single ntoi.\n");
729 printf("fih name - fix id hash for <name>.\n");
730 printf("fnh id - fix name hash for <id>.\n");
731 printf("q - quit.\n?- this message.\n");
738 while (**s != ' ' && **s != '\0')
743 #endif /* !AFS_PTHREAD_ENV */