Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / kauth / test / test_interim_ktc.c
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
4 *
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
8 */
9
10 /* Test ktc related calls as well as some file access stuff. */
11
12 #include <afsconfig.h>
13 #include <afs/param.h>
14
15 #include <sys/types.h>
16 #include <errno.h>
17 #include <stdio.h>
18 #include <sys/file.h>
19 #include <arpa/inet.h>
20 #include <afs/prs_fs.h>
21
22 #include <afs/stds.h>
23 #include <afs/com_err.h>
24 #include <afs/cellconfig.h>
25 #include <afs/auth.h>
26 #include <afs/afs_consts.h>
27 #include "kautils.h"
28
29
30 extern int errno;
31
32 static char *whoami = "test_interim_ktc";
33 static verbose = 1;
34 #define CELLSTOKEEP 50
35 static char cell[MAXKTCREALMLEN];
36 static char cellNameList[CELLSTOKEEP][MAXKTCREALMLEN];
37 static int nCells = 0;
38 static int unusedCell;
39 static char tester[MAXKTCNAMELEN];
40 static char testerPassword[32];
41 static long testerId;
42 static char remoteTester[MAXKTCNAMELEN];
43 static char remoteTesterPassword[32];
44 static long remoteTesterId;
45
46 static void
47 PrintPrincipal(stream, p)
48 FILE *stream;
49 struct ktc_principal *p;
50 {
51 if (!verbose)
52 return;
53 fprintf(stream, "%s", p->name);
54 if (strlen(p->instance))
55 fprintf(stream, ".%s", p->instance);
56 if (strlen(p->cell) && (strcmp(p->cell, ka_LocalCell()) != 0))
57 fprintf(stream, "@%s", p->cell);
58 }
59
60 static void
61 PrintAuthentication(stream, s, t, c)
62 FILE *stream;
63 struct ktc_principal *s, *c;
64 struct ktc_token *t;
65 {
66 long lifetime;
67 unsigned long now = time(0);
68 char bob[KA_TIMESTR_LEN];
69
70 lifetime = (unsigned long)t->endTime - (unsigned long)t->startTime;
71
72 fprintf(stream, "Ticket for '");
73 PrintPrincipal(stream, s);
74 fprintf(stream, "'\n");
75 ka_timestr(t->endTime, bob, KA_TIMESTR_LEN);
76 fprintf(stream, " good for %d seconds till %s", lifetime, bob);
77
78 /* Allow one second grace, so the even/odd lifetime doesn't appear as an
79 * error. If it is way off complain loudly. */
80 if (now + KTC_TIME_UNCERTAINTY < t->startTime)
81 fprintf(stream, " [FUTURE]\n");
82 else if (now + 1 < t->startTime)
83 fprintf(stream, " [ahead]\n");
84 else if (now >= t->endTime + KTC_TIME_UNCERTAINTY)
85 fprintf(stream, " [EXPIRED]\n");
86 else if (now >= t->endTime)
87 fprintf(stream, " [behind]\n");
88 else
89 fprintf(stream, "\n");
90 fprintf(stream, " for user '");
91 PrintPrincipal(stream, c);
92 fprintf(stream, "'\n");
93 fprintf(stream, " session key='");
94 ka_PrintBytes(&t->sessionKey, sizeof(t->sessionKey));
95 fprintf(stream, "'\n");
96 fprintf(stream, " kvno=%d, ticket is %d bytes long.\n", t->kvno,
97 t->ticketLen);
98 if (lifetime & 1) {
99 fprintf(stream, "from %d to %d is %d seconds\n", t->startTime,
100 t->endTime, lifetime);
101 fprintf(stream, "Lifetime is odd\n");
102 }
103 }
104
105 static int
106 CheckUnixUID(server, token, client)
107 struct ktc_principal *server;
108 struct ktc_token *token;
109 struct ktc_principal *client;
110 {
111 long code;
112 struct ktc_token ntoken;
113 struct ktc_principal nclient;
114 long lifetime;
115 char name_buf[24];
116
117 code = ktc_SetToken(server, token, client, 0);
118 if (code) {
119 afs_com_err(whoami, code, "using SetToken to set vice id");
120 return 1;
121 }
122 sprintf(name_buf, "Unix UID %d", getuid());
123
124 code = ktc_GetToken(server, &ntoken, sizeof(ntoken), &nclient);
125 if (code || (strcmp(nclient.name, name_buf) != 0)
126 || strlen(nclient.instance)) {
127 fprintf(stderr, "GetToken returned bad client: '");
128 PrintPrincipal(stderr, &nclient);
129 fprintf(stderr, "'\n");
130 afs_com_err(whoami, code, "should have gotten '%s'", name_buf);
131 return 1;
132 }
133 lifetime =
134 (unsigned long)ntoken.endTime - (unsigned long)ntoken.startTime;
135 if ((lifetime & 1) == 1) {
136 afs_com_err(whoami, code, "GetToken returned even lifetime (%d)",
137 lifetime);
138 return 1;
139 }
140 return 0;
141 }
142
143 static int
144 CheckAFSId(server, token, client)
145 struct ktc_principal *server;
146 struct ktc_token *token;
147 struct ktc_principal *client;
148 {
149 long code;
150 struct ktc_token ntoken;
151 struct ktc_principal nclient;
152 long lifetime;
153 char name_buf[24];
154 long viceId;
155
156 viceId = atoi((client->name) + 7);
157 code = ktc_SetToken(server, token, client, 0);
158 if (code) {
159 afs_com_err(whoami, code, "using SetToken to set vice id to %d", viceId);
160 return 1;
161 }
162 code = ktc_GetToken(server, &ntoken, sizeof(ntoken), &nclient);
163 if ((strncmp(nclient.name, "AFS ID ", 7) != 0)
164 || (strlen(nclient.name) < 8) || (atoi(nclient.name + 7) != viceId)
165 || strlen(nclient.instance)) {
166 fprintf(stderr, "GetToken returned bad client: '");
167 PrintPrincipal(stderr, &nclient);
168 fprintf(stderr, "' should have gotten '");
169 PrintPrincipal(stderr, client);
170 fprintf(stderr, "'\n");
171 afs_com_err(whoami, code, "didn't preserve AFS ID");
172 return 1;
173 }
174 lifetime =
175 (unsigned long)ntoken.endTime - (unsigned long)ntoken.startTime;
176 if ((lifetime & 1) == 0) {
177 afs_com_err(whoami, code, "GetToken returned even lifetime (%d)",
178 lifetime);
179 return 1;
180 }
181 return 0;
182 }
183
184 #include <afs/venus.h>
185
186 /* Stolen from auth/comktc.c: U_CellSetLocalTokens */
187 /* Try various Auth2 style pioctl calls with kvno == 999 */
188
189 static int
190 CheckAuth2(server)
191 struct ktc_principal *server;
192 {
193 long code;
194 int i;
195 struct ViceIoctl buffer; /*pioctl() communication block */
196 struct ktc_principal client;
197 struct ktc_token token;
198 long lifetime;
199
200 struct EncryptedSecretToken {
201 char data[56];
202 };
203 typedef struct EncryptedSecretToken EncryptedSecretToken;
204
205 struct ClearToken {
206 long AuthHandle;
207 struct ktc_encryptionKey HandShakeKey;
208 long ViceId;
209 long BeginTimestamp;
210 long EndTimestamp;
211 };
212 typedef struct ClearToken ClearToken;
213
214 /* venus buffer for using the new interface to set/get venus tokens */
215 typedef struct {
216 int sTokenSize; /*Size in bytes of secret token */
217 EncryptedSecretToken stoken; /*Secret token */
218 int cTokenSize; /*Size in bytes of clear token */
219 ClearToken ctoken; /*Clear token */
220 int isPrimary; /*Is this the primary ID? */
221 char cellName[64]; /*Cell in which tokens are valid */
222 } venusbuff;
223 venusbuff inbuff;
224 ClearToken cToken;
225 EncryptedSecretToken sToken;
226 char *cellID;
227 int primaryFlag;
228
229 cellID = server->cell;
230 primaryFlag = 0;
231
232 /* First build a plausible clear token (code from old auth(2) server */
233 cToken.AuthHandle = -1; /* not in use right now */
234 for (i = 0; i < sizeof(struct ktc_encryptionKey); i++)
235 cToken.HandShakeKey.data[i] = random() & 0xff;
236 cToken.BeginTimestamp = 0;
237 cToken.EndTimestamp = time(0) + 60 * 60 * 25; /* valid for 25 hours */
238 cToken.ViceId = 123;
239
240 /* Then invent secret token */
241 for (i = 0; i < sizeof(sToken); i++)
242 sToken.data[i] = random() & 0xff;
243
244
245 /*Copy in the sizes and bodies of the secret and clear tokens */
246 inbuff.sTokenSize = sizeof(EncryptedSecretToken);
247 memcpy((char *)&inbuff.stoken, &sToken, sizeof(EncryptedSecretToken));
248 inbuff.cTokenSize = sizeof(ClearToken);
249 memcpy((char *)&inbuff.ctoken, &cToken, sizeof(ClearToken));
250
251 /* Copy in the Primary ID flag and the cell name */
252 #if DB_CELLS
253 fprintf(stderr,
254 "U_CellSetLocalTokens: using isPrimary=%d, cellName='%s'\n",
255 primaryFlag, cellID);
256 #endif /* DB_CELLS */
257 inbuff.isPrimary = primaryFlag;
258 strcpy(inbuff.cellName, cellID);
259
260 /* Place our inbuff in the standard PIOCTL buffer and go for it. */
261 buffer.in = (char *)&inbuff;
262 buffer.out = 0;
263 buffer.in_size = sizeof(inbuff);
264 buffer.out_size = 0;
265 code = pioctl(0, _VICEIOCTL(3), &buffer, 1);
266 if (code) {
267 afs_com_err(whoami, errno, "setting old-style token");
268 return 1;
269 }
270
271 /* now get it back and see if it's OK */
272 code = ktc_GetToken(server, &token, sizeof(token), &client);
273 if ((strcmp(client.name, "AFS ID 123") != 0) || strlen(client.instance)
274 || (strcmp(client.cell, cellID) != 0)) {
275 fprintf(stderr, "GetToken returned bad client: '");
276 PrintPrincipal(stderr, &client);
277 fprintf(stderr, "'\n");
278 return 1;
279 }
280 if ((token.kvno != 999) || (token.startTime != 0)
281 || (token.endTime != cToken.EndTimestamp)
282 || (token.ticketLen != sizeof(sToken))
283 ||
284 (memcmp
285 (&cToken.HandShakeKey, &token.sessionKey,
286 sizeof(struct ktc_encryptionKey)) != 0)
287 || (memcmp(&sToken, token.ticket, sizeof(sToken)) != 0)) {
288 fprintf(stdout, "Auth2 token was bad\n");
289 PrintAuthentication(stdout, server, &token, &client);
290 return 1;
291 }
292
293 return 0;
294
295 }
296
297 /* Stolen from the "fs" command. */
298
299 #define MAXNAME 100
300
301 static void
302 ListCellsCmd()
303 {
304 long code;
305 long i, j;
306 char *tcp;
307 long clear;
308 char space[AFS_PIOCTL_MAXSIZE];
309 struct ViceIoctl blob;
310
311 for (i = 0; i < 1000; i++) {
312 char *cellname;
313 blob.out_size = AFS_PIOCTL_MAXSIZE;
314 blob.in_size = sizeof(long);
315 blob.in = space;
316 blob.out = space;
317 memcpy(space, &i, sizeof(long));
318 code = pioctl(0, VIOCGETCELL, &blob, 1);
319 if (code < 0) {
320 if (errno == EDOM)
321 break; /* done with the list */
322 else {
323 afs_com_err(whoami, code, "getting cell list");
324 exit(1);
325 }
326 }
327 cellname = space + 8 * sizeof(long);
328 if (verbose > 1) {
329 printf("Cell %s on hosts", cellname);
330 for (j = 0; j < 8; j++) {
331 memcpy(&clear, space + j * sizeof(long), sizeof(long));
332 if (clear == 0)
333 break;
334 #if SLOW
335 tcp = hostutil_GetNameByINet(clear);
336 #else
337 tcp = inet_ntoa(clear);
338 #endif
339 printf(" %s", tcp);
340 }
341 printf(".\n");
342 }
343 if (nCells < CELLSTOKEEP) {
344 strncpy(cellNameList[nCells++], cellname, MAXKTCREALMLEN);
345 }
346 }
347 return;
348 }
349
350 /* Stolen from the fs command */
351
352 struct Acl {
353 int nplus;
354 int nminus;
355 struct AclEntry *pluslist;
356 struct AclEntry *minuslist;
357 };
358
359 struct AclEntry {
360 struct AclEntry *next;
361 char name[MAXNAME];
362 long rights;
363 };
364
365 char *
366 AclToString(acl)
367 struct Acl *acl;
368 {
369 static char mydata[AFS_PIOCTL_MAXSIZE];
370 char tstring[AFS_PIOCTL_MAXSIZE];
371 struct AclEntry *tp;
372 sprintf(mydata, "%d\n%d\n", acl->nplus, acl->nminus);
373 for (tp = acl->pluslist; tp; tp = tp->next) {
374 sprintf(tstring, "%s %d\n", tp->name, tp->rights);
375 strcat(mydata, tstring);
376 }
377 for (tp = acl->minuslist; tp; tp = tp->next) {
378 sprintf(tstring, "%s %d\n", tp->name, tp->rights);
379 strcat(mydata, tstring);
380 }
381 return mydata;
382 }
383
384 char *
385 SkipLine(astr)
386 char *astr;
387 {
388 while (*astr != '\n')
389 astr++;
390 astr++;
391 return astr;
392 }
393
394 struct Acl *
395 ParseAcl(astr)
396 char *astr;
397 {
398 int nplus, nminus, i, trights;
399 char tname[MAXNAME];
400 struct AclEntry *first, *last, *tl;
401 struct Acl *ta;
402 sscanf(astr, "%d", &nplus);
403 astr = SkipLine(astr);
404 sscanf(astr, "%d", &nminus);
405 astr = SkipLine(astr);
406
407 ta = malloc(sizeof(struct Acl));
408 ta->nplus = nplus;
409 ta->nminus = nminus;
410
411 last = 0;
412 first = 0;
413 for (i = 0; i < nplus; i++) {
414 sscanf(astr, "%100s %d", tname, &trights);
415 astr = SkipLine(astr);
416 tl = malloc(sizeof(struct AclEntry));
417 if (!first)
418 first = tl;
419 strcpy(tl->name, tname);
420 tl->rights = trights;
421 tl->next = 0;
422 if (last)
423 last->next = tl;
424 last = tl;
425 }
426 ta->pluslist = first;
427
428 last = 0;
429 first = 0;
430 for (i = 0; i < nminus; i++) {
431 sscanf(astr, "%100s %d", tname, &trights);
432 astr = SkipLine(astr);
433 tl = malloc(sizeof(struct AclEntry));
434 if (!first)
435 first = tl;
436 strcpy(tl->name, tname);
437 tl->rights = trights;
438 tl->next = 0;
439 if (last)
440 last->next = tl;
441 last = tl;
442 }
443 ta->minuslist = first;
444
445 return ta;
446 }
447
448 ZapList(alist)
449 struct AclEntry *alist;
450 {
451 struct AclEntry *tp, *np;
452 for (tp = alist; tp; tp = np) {
453 np = tp->next;
454 free(tp);
455 }
456 }
457
458 int
459 PruneList(ae)
460 struct AclEntry **ae;
461 {
462 struct AclEntry **lp;
463 struct AclEntry *te, *ne;
464 long ctr;
465 ctr = 0;
466 lp = ae;
467 for (te = *ae; te; te = ne) {
468 if (te->rights == 0) {
469 *lp = te->next;
470 ne = te->next;
471 free(te);
472 ctr++;
473 } else {
474 ne = te->next;
475 lp = &te->next;
476 }
477 }
478 return ctr;
479 }
480
481 static int
482 AddTester(pathname)
483 char *pathname;
484 {
485 long code;
486 struct ViceIoctl blob;
487 struct Acl *al;
488 char space[AFS_PIOCTL_MAXSIZE];
489
490 blob.out_size = AFS_PIOCTL_MAXSIZE;
491 blob.in_size = 0;
492 blob.out = space;
493 code = pioctl(pathname, VIOCGETAL, &blob, 1);
494 if (code) {
495 afs_com_err(whoami, errno, "getting acl for %s", pathname);
496 return 1;
497 }
498 if (verbose > 1)
499 printf("old acl for %s is %s\n", pathname, space);
500 al = ParseAcl(space);
501
502 {
503 struct AclEntry *tlist;
504 struct AclEntry *ae;
505 /* clean acl up a bit */
506 ZapList(al->minuslist);
507 al->minuslist = 0;
508 al->nminus = 0;
509 for (ae = al->pluslist; ae; ae = ae->next) {
510 if ((strcmp(ae->name, tester) == 0) ||
511 /* punt useless entries (like system:anyuser) */
512 !(ae->
513 rights & (PRSFS_INSERT | PRSFS_DELETE | PRSFS_WRITE |
514 PRSFS_LOCK | PRSFS_ADMINISTER)))
515 ae->rights = 0;
516 }
517 al->nplus -= PruneList(&al->pluslist);
518
519 tlist = malloc(sizeof(struct AclEntry));
520 tlist->rights = 9;
521 strcpy(tlist->name, tester);
522 tlist->next = al->pluslist;
523 al->pluslist = tlist;
524 al->nplus++;
525 }
526
527 if (verbose > 1) {
528 char tmp[100];
529 printf("before:\n");
530 sprintf(tmp, "fs la %s", pathname);
531 system(tmp);
532 }
533
534 blob.in = AclToString(al);
535 blob.out_size = 0;
536 blob.in_size = 1 + strlen(blob.in);
537 code = pioctl(pathname, VIOCSETAL, &blob, 1);
538 if (code) {
539 afs_com_err(whoami, errno, "setting acl on %s to %s", pathname, blob.in);
540 return 1;
541 }
542 if (verbose > 1) {
543 char tmp[100];
544 printf("after:\n");
545 sprintf(tmp, "fs la %s", pathname);
546 system(tmp);
547 }
548 return 0;
549 }
550
551 /* Free this cell for reuse */
552 static void
553 FreeUnusedCell()
554 {
555 struct ktc_principal client, server;
556 struct ktc_token token;
557 long code;
558
559 strcpy(server.name, "afs");
560 strcpy(server.instance, "");
561 strcpy(server.cell, cellNameList[unusedCell]);
562
563 token.ticketLen = MINKTCTICKETLEN;
564 token.endTime = 0;
565 code = ktc_SetToken(&server, &token, &client, 0);
566 if (code) {
567 afs_com_err(whoami, code, "freeing cell");
568 exit(1);
569 }
570 }
571
572 static int
573 TryAuthenticating(name, password, viceId, cell)
574 char *name;
575 char *password;
576 long viceId;
577 char *cell;
578 {
579 long code;
580 char *reason;
581 struct ktc_principal server, client;
582 struct ktc_token token;
583 long lifetime;
584 unsigned long now = time(0);
585
586 code = ka_UserAuthenticate(name, "", cell, password, 0, &reason);
587 if (code) {
588 fprintf(stderr, "unable to authenticate as %s because %s\n", name,
589 reason);
590 return 1;
591 }
592 strcpy(server.name, "afs");
593 strcpy(server.instance, "");
594 strcpy(server.cell, cell);
595 code = ktc_GetToken(&server, &token, sizeof(token), &client);
596 if (code) {
597 afs_com_err(whoami, code, "so couldn't get %s's afs token in %s", name,
598 cell);
599 return code;
600 }
601 if (code = tkt_CheckTimes(token.startTime, token.endTime, now) != 2) {
602 fprintf(stdout, "Bad times on afs ticket\n");
603 PrintAuthentication(stdout, &server, &token, &client);
604 return code;
605 }
606
607 lifetime = token.endTime - token.startTime;
608 if ((lifetime & 1) == 0) {
609 fprintf(stderr, "*** Old style KTC (in cell %s) ***\n", cell);
610 } else {
611 char tmp[24];
612 sprintf(tmp, "AFS ID %d", viceId);
613 if ((strcmp(client.name, tmp) != 0) || strlen(client.instance)) {
614 fprintf(stderr, "GetToken returned bad client: '");
615 PrintPrincipal(stderr, &client);
616 fprintf(stderr, "' should have gotten AFS ID %d for %s@%s\n",
617 viceId, name, cell);
618 return 1;
619 }
620 }
621 if (verbose) {
622 fprintf(stdout, "%s@%s using ", name, cell);
623 PrintAuthentication(stdout, &server, &token, &client);
624 }
625 return 0;
626 }
627
628 static long
629 CheckAFSTickets()
630 {
631 long code;
632 struct ktc_principal client, server;
633 struct ktc_token token;
634 struct ktc_principal nclient;
635 struct ktc_token ntoken;
636 long lifetime;
637 long exitCode = 0;
638 char *reason;
639 char *tdpath = "./tester_dir";
640 char *tfpath = "./tester_dir/touch";
641 int fd;
642 unsigned long now = time(0);
643
644 strcpy(server.name, "afs");
645 strcpy(server.instance, "");
646 strcpy(server.cell, ka_LocalCell());
647 code = ktc_GetToken(&server, &token, sizeof(token), &client);
648 if (code) {
649 afs_com_err(whoami, code, "so couldn't get afs token");
650 return code;
651 }
652
653 code = mkdir(tdpath, 0777);
654 if (code && (errno != EEXIST)) {
655 afs_com_err(whoami, errno, "making test dir %s", tdpath);
656 return code;
657 }
658 fd = open(tfpath, O_WRONLY + O_CREAT + O_TRUNC, 0777);
659 if (fd == -1) {
660 afs_com_err(whoami, errno, "making test file %s", tfpath);
661 goto failed;
662 }
663 code = close(fd);
664 if (code) {
665 afs_com_err(whoami, errno, "failed to close %s after create", tfpath);
666 goto failed;
667 }
668
669 code = AddTester(tdpath);
670 if (code)
671 goto failed;
672
673 setpag();
674
675 if (TryAuthenticating(tester, testerPassword, testerId, server.cell))
676 goto failed;
677 code = ktc_GetToken(&server, &ntoken, sizeof(ntoken), &nclient);
678 if (code) {
679 afs_com_err(whoami, code, "getting new local afs token");
680 goto failed;
681 }
682
683 if (remoteTesterId) { /* make sure remote cells work also */
684 if (TryAuthenticating
685 (remoteTester, remoteTesterPassword, remoteTesterId, cell))
686 goto failed;
687 }
688
689 ktc_ForgetToken(&server); /* switch to unauthenticated */
690
691 /* check to see if remote ticket disappears also. */
692 {
693 struct ktc_principal remote;
694 strcpy(remote.name, "afs");
695 strcpy(remote.instance, "");
696 strcpy(remote.cell, cell);
697 code = ktc_GetToken(&remote, 0, 0, 0);
698 if (code == KTC_NOENT)
699 fprintf(stdout, "*** Using interim KTC ***\n");
700 else
701 fprintf(stdout, "Using kernel ticket cache\n");
702 }
703
704 code = open(tfpath, O_RDONLY, 0); /* check for read access */
705 if (!((code == -1) && ((errno == ENOENT) || (errno == EACCES)))) {
706 afs_com_err(whoami, errno, "didn't fail to open %s for read", tfpath);
707 goto failed;
708 }
709
710 /* as tester we should have read but not write */
711 code = ktc_SetToken(&server, &ntoken, &nclient, 0);
712 if (code) {
713 afs_com_err(whoami, code, "restoring new local afs token");
714 goto failed;
715 }
716 code = open(tfpath, O_RDWR + O_TRUNC, 0);
717 if ((code != -1) || (errno != EACCES)) {
718 afs_com_err(whoami, errno, "didn't fail to open %s for write", tfpath);
719 goto failed;
720 }
721 fd = open(tfpath, O_RDONLY, 0);
722 if (fd == -1) {
723 afs_com_err(whoami, errno, "failed to open %s for read", tfpath);
724 goto failed;
725 }
726 code = close(fd);
727 if (code) {
728 afs_com_err(whoami, errno, "failed to close %s after open", tfpath);
729 goto failed;
730 }
731
732 finish:
733 /* go back to original privileges */
734 code = ktc_SetToken(&server, &token, &client, 0);
735 if (code) {
736 afs_com_err(whoami, code, "so couldn't set afs token in new pag");
737 exit(1);
738 }
739 if (unlink(tfpath) || rmdir(tdpath)) {
740 afs_com_err(whoami, errno, "removing test dir %s", tdpath);
741 return 1;
742 }
743 return exitCode;
744
745 failed:
746 exitCode = 1;
747 goto finish;
748 }
749
750 main(argc, argv)
751 int argc;
752 char *argv[];
753 {
754 int i;
755 long code;
756 struct ktc_principal client, server;
757 struct ktc_token token;
758 struct ktc_principal nclient, nnclient;
759 struct ktc_token ntoken;
760 long lifetime;
761 long viceId;
762 int printToken = 0; /* just print afs @ remoteCell */
763
764 srandom(1);
765
766 /* Initialize afs_com_err error code hacking */
767 initialize_U_error_table();
768 initialize_KA_error_table();
769 initialize_RXK_error_table();
770 initialize_KTC_error_table();
771 initialize_ACFG_error_table();
772
773 /* set defaults */
774 strcpy(cell, "");
775 strcpy(tester, "tester");
776 strcpy(testerPassword, "xxx");
777 testerId = 1031;
778 remoteTesterId = 0; /* don't try this */
779
780 /* parse arguments */
781 i = 1;
782 while (i < argc) {
783 int arglen = strlen(argv[i]);
784 char arg[256];
785 lcstring(arg, argv[i], sizeof(arg));
786 #define IsArg(a) (strncmp (arg,a, arglen) == 0)
787 if (IsArg("-quiet"))
788 verbose--;
789 else if (IsArg("-verbose"))
790 verbose++;
791 else if (IsArg("-printtoken"))
792 printToken++;
793 else if (IsArg("-remotecell"))
794 strncpy(cell, argv[++i], sizeof(cell));
795 else if (IsArg("-testid"))
796 testerId = atoi(argv[++i]);
797 else if (IsArg("-tester"))
798 strncpy(tester, argv[++i], sizeof(tester));
799 else if (IsArg("-testpassword"))
800 strncpy(testerPassword, argv[++i], sizeof(testerPassword));
801 else if (IsArg("-remotetestid"))
802 remoteTesterId = atoi(argv[++i]);
803 else if (IsArg("-remotetester"))
804 strncpy(remoteTester, argv[++i], sizeof(tester));
805 else if (IsArg("-remotetestpassword"))
806 strncpy(remoteTesterPassword, argv[++i],
807 sizeof(remoteTesterPassword));
808 else {
809 fprintf(stderr, "unexpected arg '%s'\n", arg);
810 usage:
811 fprintf(stderr,
812 "Usage is: '%s [-quiet] [-verbose] [-remotecell <cellname>] [-testid <AFS ID>] [-tester <name>] -testpassword <pass> [-remotetestid <AFS ID> -remotetester <name> -remotetestpassword <pass>]\n",
813 whoami);
814 exit(1);
815 }
816 i++;
817 }
818
819 /* get list of cells */
820 ListCellsCmd();
821
822 /* expand requested cell name */
823 code = ka_CellConfig(AFSCONF_CLIENTNAME);
824 if (code)
825 afs_com_err(whoami, code, "calling cell config");
826 code = ka_ExpandCell(cell, cell, 0);
827 if (code) {
828 afs_com_err(whoami, code, "expanding cell %s", cell);
829 exit(1);
830 }
831
832 strcpy(server.name, "afs");
833 strcpy(server.instance, "");
834 strcpy(server.cell, cell);
835 if (printToken) {
836 code = ktc_GetToken(&server, &token, sizeof(token), &client);
837 if (code) {
838 afs_com_err(whoami, code, "so couldn't get afs token");
839 exit(1);
840 }
841 PrintAuthentication(stdout, &server, &token, &client);
842 } else { /* dummy up a token */
843 token.startTime = time(0);
844 token.endTime = token.startTime + 3600;
845 token.kvno = 1;
846 token.ticketLen = 48;
847 }
848
849 /* find a cell w/o tokens */
850 for (i = 0; i < nCells; i++) {
851 strcpy(server.cell, cellNameList[i]);
852 code = ktc_GetToken(&server, &ntoken, sizeof(ntoken), &nclient);
853 if ((code == KTC_NOENT) || ((code == 0) && (ntoken.endTime == 0)))
854 goto unused_cell_found;
855 }
856 fprintf(stderr, "All cells have tokens\n");
857 unused_cell_found:
858 unusedCell = i;
859 if (verbose)
860 printf("Using unused cell %s\n", cellNameList[unusedCell]);
861
862 /* First check for various pathological cases */
863
864 strcpy(server.cell, "foo.bar.baz");
865 memcpy(&ntoken, &token, sizeof(ntoken));
866 code = ktc_SetToken(&server, &ntoken, &client, 0);
867 if (code != KTC_NOCELL) {
868 afs_com_err(whoami, code,
869 "should have gotten bad pioctl error calling SetToken with bogus cell name");
870 goto failed;
871 }
872 strcpy(server.cell, cellNameList[unusedCell]);
873
874 ntoken.ticketLen = 0;
875 code = ktc_SetToken(&server, &ntoken, &client, 0);
876 if ((code != KTC_TOOBIG) && (code != KTC_PIOCTLFAIL)) {
877 afs_com_err(whoami, code,
878 "should have gotten error calling SetToken with zero ticket length");
879 goto failed;
880 }
881 ntoken.ticketLen = token.ticketLen;
882 ntoken.endTime = 0;
883 code = ktc_SetToken(&server, &ntoken, &client, 0);
884 if (code) {
885 afs_com_err(whoami, code, "calling SetToken with zero expiration time");
886 goto failed;
887 }
888 strcpy(nclient.name, "foo");
889 strcpy(nclient.instance, "bar");
890 strcpy(nclient.cell, "foo.bar.baz");
891 code = ktc_SetToken(&server, &ntoken, &nclient, 0);
892 if (code) {
893 afs_com_err(whoami, code, "calling SetToken with bogus client cell");
894 goto failed;
895 }
896 memcpy(&ntoken, &token, sizeof(ntoken));
897 if (token.kvno == 999)
898 ntoken.kvno = 99;
899
900 /* Now check out SetToken parsing of specially formed names */
901
902 strcpy(nclient.instance, "");
903 /* cell is uniformly ignored */
904 viceId = 123;
905 sprintf(nclient.name, "AFS ID %d", viceId);
906 if (CheckAFSId(&server, &ntoken, &nclient))
907 goto failed;
908 ntoken.endTime--;
909 if (CheckAFSId(&server, &ntoken, &nclient))
910 goto failed;
911 sprintf(nclient.name, "AFS ID 0%d", viceId);
912 if (CheckAFSId(&server, &ntoken, &nclient))
913 goto failed;
914 #if 1
915 sprintf(nclient.name, "AFS ID %d", -44444);
916 if (CheckAFSId(&server, &ntoken, &nclient))
917 goto failed;
918 #endif
919 sprintf(nclient.name, "AFS ID %d", 0x7fffffff);
920 if (CheckAFSId(&server, &ntoken, &nclient))
921 goto failed;
922
923 sprintf(nclient.name, "AFS ID ");
924 if (CheckUnixUID(&server, &ntoken, &nclient))
925 goto failed;
926 sprintf(nclient.name, "AFS ID 10x");
927 if (CheckUnixUID(&server, &ntoken, &nclient))
928 goto failed;
929 sprintf(nclient.name, "foobar");
930 if (CheckUnixUID(&server, &ntoken, &nclient))
931 goto failed;
932 ntoken.endTime--;
933 if (CheckUnixUID(&server, &ntoken, &nclient))
934 goto failed;
935
936 /* make sure simulated auth2 tokens still does something reasonable */
937 if (CheckAuth2(&server))
938 goto failed;
939
940 FreeUnusedCell();
941
942 code = CheckAFSTickets(); /* returns in new PAG */
943 if (code)
944 exit(1);
945
946 rx_Finalize();
947
948 printf("All OK\n");
949 exit(0);
950
951 failed:
952 FreeUnusedCell();
953 exit(1);
954 }