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>
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 extern struct ubik_client *pruclient;
44 static int ignoreExist = 0;
45 static char line[256];
46 static char *lineProgress;
48 #define WHITESPACE " \t\n"
50 #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 */
61 int GetToken (format, l)
68 if (lineProgress == 0) lineProgress = line;
69 c = sscanf (lineProgress, format, l);
70 if (c != 1) return -1;
71 /* skip the white space */
72 lineProgress += strspn (lineProgress, WHITESPACE);
73 /* skip to end of token */
74 lineProgress = strpbrk (lineProgress, WHITESPACE);
78 #define GetInt32(l) GetToken ("%d", l)
79 #define GetXInt32(l) GetToken ("%x", l)
81 int GetString (s, slen)
89 if (lineProgress == 0) lineProgress = line;
90 /* skip the white space */
91 lineProgress += strspn (lineProgress, WHITESPACE);
93 /* check for quoted string and find end */
96 l = strcspn (++beg, "\"");
97 if (l == strlen(beg)) return -1; /* unbalanced quotes */
98 lineProgress = beg+l+1;
100 l = strcspn (beg, WHITESPACE);
103 if (l >= slen) { /* don't return too much */
109 s[l] = 0; /* null termination */
116 if (!ignoreExist) return code;
117 return code && (code != PREXIST) && (code != PRIDEXIST);
120 int PrintEntry (ea, e, indent)
125 /* handle screwed up versions of DumpEntry */
126 if (e->flags & PRCONT) {
127 afs_int32 id = *(afs_int32 *)(e->name);
128 if ((id != PRBADID) && ((id > (1<<24)) || (id < -(1<<24)))) {
129 /* assume server incorrectly swapped these bytes... */
131 while (i<sizeof(e->name)) {
134 e->name[i] = e->name[i+3];
137 e->name[i+1] = e->name[i+2];
143 return pr_PrintEntry (stdout, /*host order*/1, ea, e, indent);
146 #ifndef AFS_PTHREAD_ENV
150 #include "AFS_component_version_number.c"
156 register afs_int32 code;
158 char name[PR_MAXNAMELEN];
159 afs_int32 id, oid, gid;
162 struct prentry entry;
173 * The following signal action for AIX is necessary so that in case of a
174 * crash (i.e. core is generated) we can include the user's data section
175 * in the core dump. Unfortunately, by default, only a partial core is
176 * generated which, in many cases, isn't too useful.
178 struct sigaction nsa;
180 sigemptyset(&nsa.sa_mask);
181 nsa.sa_handler = SIG_DFL;
182 nsa.sa_flags = SA_FULLDUMP;
183 sigaction(SIGSEGV, &nsa, NULL);
187 initialize_pt_error_table();
189 strcpy(confdir, AFSDIR_CLIENT_ETC_DIRPATH);
193 int arglen = strlen(argv[i]);
195 lcstring (arg, argv[i], sizeof(arg));
196 #define IsArg(a) (strncmp (arg,a, arglen) == 0)
197 if (IsArg("-testconfdir"))
198 strncpy (confdir, argv[++i], sizeof(confdir));
199 else if (IsArg("client"))
200 strncpy(confdir, AFSDIR_CLIENT_ETC_DIRPATH, sizeof(confdir));
201 else if (IsArg("server"))
202 strncpy(confdir, AFSDIR_SERVER_ETC_DIRPATH, sizeof(confdir));
203 else if (IsArg("0") || IsArg("1") || IsArg("2"))
204 security = atoi(argv[i]);
205 else if (IsArg("-ignoreexist"))
207 else if (IsArg("-cell"))
210 printf ("Usage is: 'prclient [-testconfdir <dir> | server | client] [0 | 1 | 2] [-ignoreExist] [-cell <cellname>]\n");
216 printf ("Using CellServDB file in %s\n", confdir);
218 printf ("Making unauthenticated connection to prserver\n");
220 code = pr_Initialize (security, confdir, cell);
222 com_err (whoami, code, "Couldn't initialize protection library");
230 s = fgets(line, sizeof(line), stdin);
231 if (s == NULL) break;
234 code = GetString (op, sizeof(op));
236 com_err (whoami, PRBADARG,
237 "error reading opcode in line '%s', got '%.*s'",
238 line, sizeof(op), op);
241 if (strlen(op) == 0) continue; /* no input */
243 if (!strcmp(op, "cr")) {
244 if (GetString (name, sizeof(name)) ||
246 GetInt32 (&oid)) code = PRBADARG;
247 /* use ubik_Call to do the work, finding an up server and handling
248 the job of finding a sync site, if need be */
249 else code = ubik_Call(PR_INewEntry, pruclient,0, name, id, oid);
251 com_err (whoami, code, "on %s %s %d %d", op, name, id, oid);
253 else if (!strcmp(op, "sf")) {
254 afs_int32 mask, access, gq, uq;
255 if (GetInt32 (&id) ||
257 GetXInt32 (&access) ||
259 GetInt32 (&uq)) code = PRBADARG;
260 else code = ubik_Call(PR_SetFieldsEntry, pruclient,0,
261 id, mask, access, gq, uq, 0,0);
263 com_err (whoami, code, "on %s %d %x %x %d %d",
264 op, id, mask, access, gq, uq);
266 else if (!strcmp(op, "ce")) {
267 char newname[PR_MAXNAMELEN];
269 if (GetInt32 (&id) ||
270 GetString (newname, sizeof(newname)) ||
272 GetInt32 (&newid)) code = PRBADARG;
273 else code = ubik_Call(PR_ChangeEntry, pruclient,0,
274 id, newname, oid, newid);
276 com_err (whoami, code, "on %s %d %s %d %d",
277 op, id, newname, oid, newid);
279 else if (!strcmp(op,"wh")) {
280 /* scanf("%d",&id); */
281 if (GetInt32 (&id)) code = PRBADARG;
282 else code = ubik_Call(PR_WhereIsIt, pruclient, 0, id, &pos);
283 if (CodeOk(code)) printf("%s\n",pr_ErrorMsg(code));
284 else printf("location %d\n",pos);
286 else if (!strcmp(op,"du")) {
287 bzero(&entry,sizeof(entry));
288 /* scanf("%d",&pos); */
289 if (GetInt32 (&pos)) code = PRBADARG;
290 else code = ubik_Call(PR_DumpEntry, pruclient, 0, pos, &entry);
291 if (CodeOk(code)) printf("%s\n",pr_ErrorMsg(code));
292 if (code == PRSUCCESS) {
293 PrintEntry (pos, &entry, /*indent*/0);
295 printf("The contents of the entry for %d are:\n",entry.id);
296 printf("flags %d next %d\n",entry.flags,entry.next);
297 printf("Groups (or members) \n");
298 for (i=0;i<PRSIZE;i++)
299 printf("%d\n",entry.entries[i]);
300 printf("nextID %d nextname %d name %s\n",entry.nextID,entry.nextName,entry.name);
301 printf("owner %d creator %d\n",entry.owner, entry.creator);
305 else if (!strcmp(op,"add") || !strcmp(op,"au")) {
306 /* scanf("%d %d",&id,&gid); */
307 if (GetInt32 (&id) ||
308 GetInt32 (&gid)) code = PRBADARG;
309 else code = ubik_Call(PR_AddToGroup,pruclient,0,id,gid);
311 com_err (whoami, code, "on %s %d %d", op, id, gid);
313 else if (!strcmp(op,"iton")) {
314 lid.idlist_val = (afs_int32 *)malloc(20*sizeof(afs_int32));
315 ptr = lid.idlist_val;
319 while ((lid.idlist_len < 20) && (sscanf(foo,"%d",ptr) != EOF)) {
325 fprintf (stderr, "too many values specified; max is %d\n", 20);
327 lnames.namelist_val = 0;
328 lnames.namelist_len = 0;
329 code = ubik_Call(PR_IDToName,pruclient,0,&lid,&lnames);
330 if (CodeOk(code)) printf("%s\n",pr_ErrorMsg(code));
331 if (code == PRSUCCESS) {
332 for (i=0;i<lnames.namelist_len;i++) {
333 printf("id %d name %s\n",lid.idlist_val[i],lnames.namelist_val[i]);
335 free(lnames.namelist_val);
337 free(lid.idlist_val);
341 else if (!strcmp(op,"ntoi")) {
342 lnames.namelist_val = (prname *)malloc(PR_MAXLIST*PR_MAXNAMELEN);
343 lnames.namelist_len = 0;
346 for (i=0; ((lnames.namelist_len < PR_MAXLIST) &&
347 (sscanf(foo,"%s",lnames.namelist_val[i]) != EOF));
349 lnames.namelist_len++;
353 fprintf (stderr, "too many values specified; max is %d\n", PR_MAXLIST);
357 code = ubik_Call(PR_NameToID,pruclient,0,&lnames,&lid);
358 if (CodeOk(code)) printf("%s\n",pr_ErrorMsg(code));
359 if (code == PRSUCCESS) {
360 for (i=0;i<lid.idlist_len;i++)
361 printf("name %s id %d\n",lnames.namelist_val[i],lid.idlist_val[i]);
362 free(lid.idlist_val);
364 free(lnames.namelist_val);
365 lnames.namelist_val = 0;
366 lnames.namelist_len = 0;
368 else if (!strcmp(op,"del")) {
369 /* scanf("%d",&id); */
370 if (GetInt32 (&id)) code = PRBADARG;
371 else code = ubik_Call(PR_Delete, pruclient,0,id);
372 if (CodeOk(code)) printf("%s\n",pr_ErrorMsg(code));
374 else if (!strcmp(op,"dg")) {
375 /* scanf("%d",&id); */
376 if (GetInt32 (&id)) code = PRBADARG;
377 else code = ubik_Call(PR_Delete,pruclient,0,id);
378 if (CodeOk(code)) printf("%s\n",pr_ErrorMsg(code));
380 else if (!strcmp(op,"rm")) {
381 /* scanf("%d %d",&id,&gid); */
382 if (GetInt32 (&id) ||
383 GetInt32 (&gid)) code = PRBADARG;
384 else code = ubik_Call(PR_RemoveFromGroup,pruclient,0,id,gid);
385 if (CodeOk(code)) printf("%s\n",pr_ErrorMsg(code));
387 else if (!strcmp(op,"l")) {
388 alist.prlist_len = 0;
389 alist.prlist_val = 0;
390 /* scanf("%d",&id); */
391 if (GetInt32 (&id)) code = PRBADARG;
392 else code = ubik_Call(PR_GetCPS,pruclient,0,id, &alist, &over);
393 if (CodeOk(code)) printf("%s\n",pr_ErrorMsg(code));
394 if (code == PRSUCCESS) {
395 ptr = alist.prlist_val;
397 printf("Number of groups greater than PR_MAXGROUPS!\n");
398 printf("Excess of %d.\n",over);
400 for (i=0;i<alist.prlist_len;i++,ptr++)
402 free(alist.prlist_val);
403 alist.prlist_len = 0;
404 alist.prlist_val = 0;
407 else if (!strcmp(op,"nu")) {
408 /* scanf("%s",name); */
409 if (GetString (name, sizeof(name))) code = PRBADARG;
410 else code = pr_CreateUser(name,&id);
411 if (CodeOk(code)) printf("%s\n",pr_ErrorMsg(code));
412 if (code == PRSUCCESS)
413 printf("Id is %d.\n",id);
415 else if (!strcmp(op,"ng")) {
416 /* scanf("%s",name); */
417 if (GetString (name, sizeof(name))) code = PRBADARG;
418 else code = ubik_Call(PR_NewEntry,pruclient,0,name,1,&id);
419 if (CodeOk(code)) printf("%s\n",pr_ErrorMsg(code));
420 if (code == PRSUCCESS)
421 printf("Id is %d.\n",id);
423 else if (!strcmp(op,"lm")) {
424 code = ubik_Call(PR_ListMax,pruclient,0,&id,&gid);
425 if (CodeOk(code)) printf("%s\n",pr_ErrorMsg(code));
426 if (code == PRSUCCESS)
427 printf("Max user id is %d, max (really min) group is %d.\n",
430 else if (!strcmp(op,"smu")) {
431 /* scanf("%d",&id); */
432 if (GetInt32 (&id)) code = PRBADARG;
433 else code = ubik_Call(PR_SetMax, pruclient, 0,id,0);
434 if (CodeOk(code)) printf("%s\n",pr_ErrorMsg(code));
436 else if (!strcmp(op,"smg")) {
437 /* scanf("%d",&id); */
438 if (GetInt32 (&id)) code = PRBADARG;
439 else code = ubik_Call(PR_SetMax, pruclient, 0,id,1);
440 if (CodeOk(code)) printf("%s\n",pr_ErrorMsg(code));
442 else if (!strcmp(op,"sin")) {
443 /* scanf("%d",&id); */
444 if (GetInt32 (&id)) code = PRBADARG;
445 else code = pr_SIdToName(id,name);
446 if (CodeOk(code)) printf("%s\n",pr_ErrorMsg(code));
447 if (code == PRSUCCESS)
448 printf("id %d name %s\n",id,name);
450 else if (!strcmp(op,"sni")) {
451 /* scanf("%s",name); */
452 if (GetString (name, sizeof(name))) code = PRBADARG;
453 else code = pr_SNameToId(name,&id);
454 if (CodeOk(code)) printf("%s\n",pr_ErrorMsg(code));
455 if (code == PRSUCCESS)
456 printf("name %s id %d\n",name,id);
458 else if (!strcmp(op,"fih")) {
460 struct PrUpdateEntry uentry;
461 bzero(&uentry, sizeof(uentry));
462 /* scanf("%s",name); */
463 if (GetString (name, sizeof(name))) {
467 code = pr_SNameToId(name,&id);
469 printf("%s\n",pr_ErrorMsg(code));
472 code = pr_SIdToName(id, tname);
473 if (code == PRSUCCESS) {
474 printf("Warning: Id hash for %s (id %d) seems correct at the db; rehashing it anyway\n", name, id);
477 uentry.Mask = PRUPDATE_IDHASH;
478 code = ubik_Call(PR_UpdateEntry, pruclient, 0,0,name,&uentry);
480 printf("Failed to update entry %s (err=%d)\n", name, code);
484 else if (!strcmp(op,"fnh")) {
486 struct PrUpdateEntry uentry;
487 bzero(&uentry, sizeof(uentry));
488 /* scanf("%d", &id); */
489 if (GetInt32 (&id)) {
493 code = pr_SIdToName(id, name);
495 printf("%s\n",pr_ErrorMsg(code));
498 code = pr_SNameToId(name, &tid);
499 if (code == PRSUCCESS) {
500 printf("Name hash for %d (name is %s) seems correct at the db; rehashing it anyway\n", id, name);
503 uentry.Mask = PRUPDATE_NAMEHASH;
504 code = ubik_Call(PR_UpdateEntry, pruclient, 0,id,"_foo_",&uentry);
506 printf("Failed to update entry with id %d (err=%d)\n", id, code);
510 else if (!strcmp(op,"?"))
512 else if (!strcmp(op,"q")) exit(0);
513 else printf("Unknown op: '%s'! ? for help\n", op);
520 printf("cr name id owner - create entry with name and id.\n");
521 printf("wh id - what is the offset into database for id?\n");
522 printf("du offset - dump the contents of the entry at offset.\n");
523 printf("add uid gid - add user uid to group gid.\n");
524 printf("iton id* - translate the list of id's to names.\n");
525 printf("ntoi name* - translate the list of names to ids.\n");
526 printf("del id - delete the entry for id.\n");
527 printf("dg gid - delete the entry for group gid.\n");
528 printf("rm id gid - remove user id from group gid.\n");
529 printf("l id - get the CPS for id.\n");
530 printf("nu name - create new user with name - returns an id.\n");
531 printf("ng name - create new group with name - returns an id.\n");
532 printf("lm - list max user id and max (really min) group id.\n");
533 printf("smu - set max user id.\n");
534 printf("smg - set max group id.\n");
535 printf("sin id - single iton.\n");
536 printf("sni name - single ntoi.\n");
537 printf("fih name - fix id hash for <name>.\n");
538 printf("fnh id - fix name hash for <id>.\n");
539 printf("q - quit.\n?- this message.\n");
546 while (**s != ' ' && **s != '\0') (*s)++;
547 while (**s == ' ') (*s)++;
549 #endif /* !AFS_PTHREAD_ENV */