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 #ifndef AFS_PTHREAD_ENV
38 extern struct ubik_client
*pruclient
;
39 static void skip(char **);
40 static void PrintHelp(void);
43 static int ignoreExist
= 0;
44 static char line
[256];
45 static char *lineProgress
;
47 #define WHITESPACE " \t\n"
49 #ifndef AFS_PTHREAD_ENV
53 /* OK, this REALLY sucks bigtime, but I can't tell who is calling
54 * afsconf_CheckAuth easily, and only *SERVERS* should be calling osi_audit
55 * anyway. It's gonna give somebody fits to debug, I know, I know.
59 #endif /* !AFS_PTHREAD_ENV */
62 GetToken(char *format
, afs_int32
*l
)
67 if (lineProgress
== 0)
69 c
= sscanf(lineProgress
, format
, l
);
72 /* skip the white space */
73 lineProgress
+= strspn(lineProgress
, WHITESPACE
);
74 /* skip to end of token */
75 lineProgress
= strpbrk(lineProgress
, WHITESPACE
);
79 #define GetInt32(l) GetToken ("%d", l)
80 #define GetXInt32(l) GetToken ("%x", l)
83 GetString(char *s
, int slen
)
89 if (lineProgress
== 0)
91 /* skip the white space */
92 lineProgress
+= strspn(lineProgress
, WHITESPACE
);
94 /* check for quoted string and find end */
97 l
= strcspn(++beg
, "\"");
99 return -1; /* unbalanced quotes */
100 lineProgress
= beg
+ l
+ 1;
102 l
= strcspn(beg
, WHITESPACE
);
105 if (l
>= slen
) { /* don't return too much */
112 s
[l
] = 0; /* null termination */
117 CodeOk(afs_int32 code
)
121 return code
&& (code
!= PREXIST
) && (code
!= PRIDEXIST
);
125 PrintEntry(afs_int32 ea
, struct prentry
*e
, int indent
)
127 /* handle screwed up versions of DumpEntry */
128 if (e
->flags
& PRCONT
) {
131 memcpy(&id
, e
->name
, sizeof(id
));
132 if ((id
!= PRBADID
) && ((id
> (1 << 24)) || (id
< -(1 << 24)))) {
133 /* assume server incorrectly swapped these bytes... */
135 while (i
< sizeof(e
->name
)) {
138 e
->name
[i
] = e
->name
[i
+ 3];
139 e
->name
[i
+ 3] = temp
;
140 temp
= e
->name
[i
+ 1];
141 e
->name
[i
+ 1] = e
->name
[i
+ 2];
142 e
->name
[i
+ 2] = temp
;
147 return pr_PrintEntry(stdout
, /*host order */ 1, ea
, e
, indent
);
150 #ifndef AFS_PTHREAD_ENV
154 #include "AFS_component_version_number.c"
157 main(int argc
, char **argv
)
161 char name
[PR_MAXNAMELEN
];
162 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
[n
]);
201 lcstring(arg
, argv
[n
], sizeof(arg
));
202 #define IsArg(a) (strncmp (arg,a, arglen) == 0)
203 if (IsArg("-testconfdir"))
204 strncpy(confdir
, argv
[++n
], 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
[n
]);
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
,
246 (int) sizeof(op
), op
);
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
, (struct prdebugentry
*)&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
= 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
= malloc(PR_MAXLIST
* PR_MAXNAMELEN
);
358 lnames
.namelist_len
= 0;
361 for (i
= 0; ((lnames
.namelist_len
< PR_MAXLIST
)
362 && (sscanf(foo
, "%63s", lnames
.namelist_val
[i
]) !=
364 lnames
.namelist_len
++;
368 fprintf(stderr
, "too many values specified; max is %d\n",
373 code
= ubik_PR_NameToID(pruclient
, 0, &lnames
, &lid
);
375 printf("%s\n", pr_ErrorMsg(code
));
376 if (code
== PRSUCCESS
) {
377 for (i
= 0; i
< lid
.idlist_len
; i
++)
378 printf("name %s id %d\n", lnames
.namelist_val
[i
],
380 free(lid
.idlist_val
);
382 free(lnames
.namelist_val
);
383 lnames
.namelist_val
= 0;
384 lnames
.namelist_len
= 0;
385 } else if (!strcmp(op
, "del")) {
386 /* scanf("%d",&id); */
390 code
= ubik_PR_Delete(pruclient
, 0, id
);
392 printf("%s\n", pr_ErrorMsg(code
));
393 } else if (!strcmp(op
, "dg")) {
394 /* scanf("%d",&id); */
398 code
= ubik_PR_Delete(pruclient
, 0, id
);
400 printf("%s\n", pr_ErrorMsg(code
));
401 } else if (!strcmp(op
, "rm")) {
402 /* scanf("%d %d",&id,&gid); */
403 if (GetInt32(&id
) || GetInt32(&gid
))
406 code
= ubik_PR_RemoveFromGroup(pruclient
, 0, id
, gid
);
408 printf("%s\n", pr_ErrorMsg(code
));
410 #if defined(SUPERGROUPS)
411 else if (!strcmp(op
, "lsg")) {
412 alist
.prlist_len
= 0;
413 alist
.prlist_val
= 0;
414 /* scanf("%d",&id); */
419 ubik_PR_ListSuperGroups(pruclient
, 0, id
, &alist
,
422 printf("%s\n", pr_ErrorMsg(code
));
423 if (code
== PRSUCCESS
) {
424 ptr
= alist
.prlist_val
;
426 printf("Number of groups greater than PR_MAXGROUPS!\n");
427 printf("Excess of %d.\n", over
);
429 for (i
= 0; i
< alist
.prlist_len
; i
++, ptr
++)
430 printf("%d\n", *ptr
);
431 free(alist
.prlist_val
);
432 alist
.prlist_len
= 0;
433 alist
.prlist_val
= 0;
436 #endif /* SUPERGROUPS */
437 else if (!strcmp(op
, "l")) {
438 alist
.prlist_len
= 0;
439 alist
.prlist_val
= 0;
440 /* scanf("%d",&id); */
444 code
= ubik_PR_GetCPS(pruclient
, 0, id
, &alist
, &over
);
446 printf("%s\n", pr_ErrorMsg(code
));
447 if (code
== PRSUCCESS
) {
448 ptr
= alist
.prlist_val
;
450 printf("Number of groups greater than PR_MAXGROUPS!\n");
451 printf("Excess of %d.\n", over
);
453 for (i
= 0; i
< alist
.prlist_len
; i
++, ptr
++)
454 printf("%d\n", *ptr
);
455 free(alist
.prlist_val
);
456 alist
.prlist_len
= 0;
457 alist
.prlist_val
= 0;
459 } else if (!strcmp(op
, "lh")) {
460 alist
.prlist_len
= 0;
461 alist
.prlist_val
= 0;
462 /* scanf("%d",&id); */
463 if (GetString(name
, sizeof(name
)))
465 else if (!(hostinfo
= gethostbyname(name
)))
468 hostaddr
= (struct in_addr
*)hostinfo
->h_addr_list
[0];
469 id
= ntohl(hostaddr
->s_addr
);
471 ubik_PR_GetHostCPS(pruclient
, 0, id
, &alist
, &over
);
474 printf("%s\n", pr_ErrorMsg(code
));
475 if (code
== PRSUCCESS
) {
476 ptr
= alist
.prlist_val
;
478 printf("Number of groups greater than PR_MAXGROUPS!\n");
479 printf("Excess of %d.\n", over
);
481 for (i
= 0; i
< alist
.prlist_len
; i
++, ptr
++)
482 printf("%d\n", *ptr
);
483 free(alist
.prlist_val
);
484 alist
.prlist_len
= 0;
485 alist
.prlist_val
= 0;
488 #if defined(SUPERGROUPS)
489 else if (!strcmp(op
, "m")) {
490 alist
.prlist_len
= 0;
491 alist
.prlist_val
= 0;
492 /* scanf("%d",&id); */
497 ubik_PR_ListElements(pruclient
, 0, id
, &alist
,
500 printf("%s\n", pr_ErrorMsg(code
));
501 if (code
== PRSUCCESS
) {
502 ptr
= alist
.prlist_val
;
504 printf("Number of groups greater than PR_MAXGROUPS!\n");
505 printf("Excess of %d.\n", over
);
507 for (i
= 0; i
< alist
.prlist_len
; i
++, ptr
++)
508 printf("%d\n", *ptr
);
509 free(alist
.prlist_val
);
510 alist
.prlist_len
= 0;
511 alist
.prlist_val
= 0;
514 #endif /* SUPERGROUPS */
515 else if (!strcmp(op
, "nu")) {
516 /* scanf("%s",name); */
517 if (GetString(name
, sizeof(name
)))
520 code
= pr_CreateUser(name
, &id
);
522 printf("%s\n", pr_ErrorMsg(code
));
523 if (code
== PRSUCCESS
)
524 printf("Id is %d.\n", id
);
525 } else if (!strcmp(op
, "ng")) {
526 /* scanf("%s",name); */
527 if (GetString(name
, sizeof(name
)))
530 code
= ubik_PR_NewEntry(pruclient
, 0, name
, 1, oid
, &id
);
532 printf("%s\n", pr_ErrorMsg(code
));
533 if (code
== PRSUCCESS
)
534 printf("Id is %d.\n", id
);
535 } else if (!strcmp(op
, "lm")) {
536 code
= ubik_PR_ListMax(pruclient
, 0, &id
, &gid
);
538 printf("%s\n", pr_ErrorMsg(code
));
539 if (code
== PRSUCCESS
)
540 printf("Max user id is %d, max (really min) group is %d.\n",
542 } else if (!strcmp(op
, "smu")) {
543 /* scanf("%d",&id); */
547 code
= ubik_PR_SetMax(pruclient
, 0, id
, 0);
549 printf("%s\n", pr_ErrorMsg(code
));
550 } else if (!strcmp(op
, "smg")) {
551 /* scanf("%d",&id); */
555 code
= ubik_PR_SetMax(pruclient
, 0, id
, 1);
557 printf("%s\n", pr_ErrorMsg(code
));
558 } else if (!strcmp(op
, "sin")) {
559 /* scanf("%d",&id); */
563 code
= pr_SIdToName(id
, name
);
565 printf("%s\n", pr_ErrorMsg(code
));
566 if (code
== PRSUCCESS
)
567 printf("id %d name %s\n", id
, name
);
568 } else if (!strcmp(op
, "sni")) {
569 /* scanf("%s",name); */
570 if (GetString(name
, sizeof(name
)))
573 code
= pr_SNameToId(name
, &id
);
575 printf("%s\n", pr_ErrorMsg(code
));
576 if (code
== PRSUCCESS
)
577 printf("name %s id %d\n", name
, id
);
578 } else if (!strcmp(op
, "fih")) {
580 struct PrUpdateEntry uentry
;
581 memset(&uentry
, 0, sizeof(uentry
));
582 /* scanf("%s",name); */
583 if (GetString(name
, sizeof(name
))) {
587 code
= pr_SNameToId(name
, &id
);
589 printf("%s\n", pr_ErrorMsg(code
));
592 code
= pr_SIdToName(id
, tname
);
593 if (code
== PRSUCCESS
) {
595 ("Warning: Id hash for %s (id %d) seems correct at the db; rehashing it anyway\n",
599 uentry
.Mask
= PRUPDATE_IDHASH
;
600 code
= ubik_PR_UpdateEntry(pruclient
, 0, 0, name
, &uentry
);
602 printf("Failed to update entry %s (err=%d)\n", name
, code
);
605 } else if (!strcmp(op
, "fnh")) {
607 struct PrUpdateEntry uentry
;
608 memset(&uentry
, 0, sizeof(uentry
));
609 /* scanf("%d", &id); */
614 code
= pr_SIdToName(id
, name
);
616 printf("%s\n", pr_ErrorMsg(code
));
619 code
= pr_SNameToId(name
, &tid
);
620 if (code
== PRSUCCESS
) {
622 ("Name hash for %d (name is %s) seems correct at the db; rehashing it anyway\n",
626 uentry
.Mask
= PRUPDATE_NAMEHASH
;
628 ubik_PR_UpdateEntry(pruclient
, 0, id
, "_foo_", &uentry
);
630 printf("Failed to update entry with id %d (err=%d)\n", id
,
635 #if defined(SUPERGROUPS)
636 else if (!strcmp(op
, "fih")) {
638 struct PrUpdateEntry uentry
;
639 memset(&uentry
, 0, sizeof(uentry
));
640 /* scanf("%s",name); */
641 if (GetString(name
, sizeof(name
))) {
645 code
= pr_SNameToId(name
, &id
);
647 printf("%s\n", pr_ErrorMsg(code
));
650 code
= pr_SIdToName(id
, tname
);
651 if (code
== PRSUCCESS
) {
653 ("Warning: Id hash for %s (id %d) seems correct at the db; rehashing it anyway\n",
657 uentry
.Mask
= PRUPDATE_IDHASH
;
658 code
= ubik_PR_UpdateEntry(pruclient
, 0, 0, name
, &uentry
);
660 printf("Failed to update entry %s (err=%d)\n", name
, code
);
663 } else if (!strcmp(op
, "fnh")) {
665 struct PrUpdateEntry uentry
;
666 memset(&uentry
, 0, sizeof(uentry
));
667 /* scanf("%d", &id); */
672 code
= pr_SIdToName(id
, name
);
674 printf("%s\n", pr_ErrorMsg(code
));
677 code
= pr_SNameToId(name
, &tid
);
678 if (code
== PRSUCCESS
) {
680 ("Name hash for %d (name is %s) seems correct at the db; rehashing it anyway\n",
684 uentry
.Mask
= PRUPDATE_NAMEHASH
;
686 ubik_PR_UpdateEntry(pruclient
, 0, id
, "_foo_", &uentry
);
688 printf("Failed to update entry with id %d (err=%d)\n", id
,
693 #endif /* SUPERGROUPS */
694 else if (!strcmp(op
, "?"))
696 else if (!strcmp(op
, "q"))
699 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");
738 while (**s
!= ' ' && **s
!= '\0')
743 #endif /* !AFS_PTHREAD_ENV */