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>
16 #include <sys/types.h>
18 #include <sys/resource.h>
20 #include <netinet/in.h>
26 #include <afs/cellconfig.h>
28 #include <afs/com_err.h>
29 #include <afs/debug.h>
35 static char *whoami = "test_rxkad_free";
36 static char realm[MAXKTCREALMLEN];
38 static char *admin_user;
40 static struct ktc_principal afs;
41 static struct ktc_token oldAFSToken;
42 static struct ktc_principal oldClient;
44 static void Crash (line)
48 if (oldAFSToken.endTime > 0) {
49 code = ktc_SetToken (&afs, &oldAFSToken, &oldClient, 0);
50 printf ("%s original AFS token\n",
51 (code == 0 ? "Restoring" : "Failed to restore"));
53 if (line) printf ("Crashing at line %d\n", line);
56 #define CRASH() Crash (__LINE__)
57 #define EXIT() Crash (0)
59 static void PrintRxkadStats()
61 printf ("New Objects client %d, server %d. Destroyed objects %d.\n",
62 rxkad_stats_clientObjects, rxkad_stats_serverObjects,
63 rxkad_stats.destroyObject);
64 printf ("client conns: %d %d %d, destroyed client %d.\n",
65 rxkad_stats.connections[0], rxkad_stats.connections[1],
66 rxkad_stats.connections[2], rxkad_stats.destroyClient);
67 printf ("server challenges %d, responses %d %d %d\n",
68 rxkad_stats.challengesSent, rxkad_stats.responses[0],
69 rxkad_stats.responses[1], rxkad_stats.responses[2]);
70 printf ("server conns %d %d %d unused %d, unauth %d\n",
71 rxkad_stats.destroyConn[0], rxkad_stats.destroyConn[1],
72 rxkad_stats.destroyConn[2],
73 rxkad_stats.destroyUnused, rxkad_stats.destroyUnauth);
76 static void SetFields (conn, name, flags, expiration, lifetime)
77 IN struct ubik_client *conn;
89 if (strcmp (name, KA_TGS_NAME) == 0) instance = realm;
94 if (flags & KAFNOSEAL)
95 what = "NOTGS+NOSEAL";
97 else if (flags & KAFNOSEAL)
101 if (strcmp (name, admin_user) == 0) flags |= KAFADMIN;
103 else if (expiration) {
104 which = "expiration";
105 sprintf (buf, "now + %.1f hours",
106 (double)(expiration-time(0)) / 3600.0);
111 sprintf (buf, "%.1f hours", (double)lifetime / 3600.0);
115 printf ("Setting %s of ", which);
116 ka_PrintUserID ("", name, instance, "");
117 printf (" to %s\n", what);
118 code = ubik_Call (KAM_SetFields, conn, 0,
119 name, instance, flags, expiration, lifetime, -1,
122 com_err (whoami, code, "calling set fields on %s", name);
126 #define SetLife(c,n,l) SetFields (c,n,0,0,l);
127 #define SetExp(c,n,e) SetFields (c,n,0,e,0);
128 #define SetFlags(c,n,f) SetFields (c,n,f,0,0);
131 #define KERBEROS 0x2a
133 static void CheckLife (tokenEnd, start, expectedLife, match)
138 char bob[KA_TIMESTR_LEN];
139 printf ("Expecting %s match with lifetime of %.1f hours\n",
140 (match == EXACT ? "exact" : "kerberos"),
141 (double)expectedLife / 3600.0);
142 expectedEnd = expectedLife + start;
143 if (match == EXACT) {
144 if (abs(expectedEnd - tokenEnd) <= 2) return;
146 if (match == KERBEROS) {
147 unsigned char kerberosV4Life;
149 kerberosV4Life = time_to_life (start, expectedEnd);
150 kend = life_to_time (start, kerberosV4Life);
151 if (abs(kend - tokenEnd) <= 1) return;
152 kerberosV4Life = time_to_life (start, expectedEnd-2);
153 kend = life_to_time (start, kerberosV4Life);
154 if (abs(kend - tokenEnd) <= 1) return;
156 ka_timestr(tokenEnd,bob,KA_TIMESTR_LEN);
157 printf ("End doesn't match: token was %s", bob);
158 ka_timestr(expectedEnd,bob,KA_TIMESTR_LEN);
159 printf (", but expected %s\n", bob);
163 static void GetTokenLife (name, passwd, expectedLife, match)
166 IN long expectedLife;
167 IN long match; /* or expected error code */
173 code = ka_UserAuthenticateLife (0, name, "", cell, passwd, 0, &reason);
174 if (!((match == EXACT) || (match == KERBEROS))) { /* must be error code */
176 printf ("Received expected error code\n");
181 fprintf (stderr, "Unable to authenticate to AFS because %s.\n",
185 code = ktc_GetToken (&afs, &t, sizeof(t), 0);
187 com_err (whoami, code, "getting afs token from ktc");
190 CheckLife (t.endTime, t.startTime, expectedLife, match);
193 static long Main (as, arock)
194 IN struct cmd_syndesc *as;
198 char name[MAXKTCNAMELEN];
199 char instance[MAXKTCNAMELEN];
200 char newCell[MAXKTCREALMLEN];
202 long serverList[MAXSERVERS];
203 extern struct passwd *getpwuid();
206 struct ktc_encryptionKey key;
213 unsigned long startTime;
214 unsigned long deadTime;
218 int patient = (as->parms[0].items != 0);
223 if (as->parms[12].items) { /* if username specified */
224 code = ka_ParseLoginName (as->parms[12].items->data,
225 name, instance, newCell);
227 com_err (whoami, code, "parsing user's name '%s'",
228 as->parms[12].items->data);
231 if (strlen(newCell) > 0) cellSpecified = 1;
234 /* No explicit name provided: use Unix uid. */
235 pw = getpwuid(getuid());
237 printf ("Can't figure out your name from your user id.\n");
240 strncpy (name, pw->pw_name, sizeof(name));
241 strcpy (instance, "");
242 strcpy (newCell, "");
244 admin_user = name; /* this guy should keep admin bit */
246 if (strcmp(as->parms[14].name, "-cell") == 0) {
247 if (as->parms[14].items) { /* if cell specified */
249 printf ("Duplicate cell specification not allowed\n");
250 else strncpy (newCell, as->parms[14].items->data,
255 code = ka_ExpandCell (newCell, newCell, 0/*local*/);
257 com_err (whoami, code, "Can't expand cell name");
261 code = ka_CellToRealm (cell, realm, 0);
263 com_err (whoami, code, "Can't get realm from cell name");
267 if (as->parms[13].items) { /* if password specified */
268 strncpy (passwd, as->parms[13].items->data, sizeof(passwd));
269 bzero (as->parms[13].items->data, strlen (as->parms[13].items->data));
271 char msg[sizeof(name)+15];
272 if (as->parms[12].items) strcpy (msg, "Admin Password: ");
273 else sprintf (msg, "Password for %s: ", name);
274 code = read_pw_string (passwd, sizeof(passwd), msg, 0);
275 if (code) code = KAREADPW;
276 else if (strlen(passwd) == 0) code = KANULLPASSWORD;
278 com_err (whoami, code, "reading password");
282 if (as->parms[15].items) {
284 char *ap[MAXSERVERS+2];
286 for (ip = as->parms[15].items, i=2; ip; ip=ip->next, i++)
290 code = ubik_ParseClientList(i, ap, serverList);
292 com_err (whoami, code, "could not parse server list");
295 ka_ExplicitCell (cell, serverList);
298 ka_StringToKey (passwd, cell, &key);
300 strcpy (afs.name, AUTH_SUPERUSER);
301 strcpy (afs.instance, "");
302 strcpy (afs.cell, cell);
303 code = ktc_GetToken (&afs, &oldAFSToken, sizeof(oldAFSToken), &oldClient);
305 com_err (whoami, code, "saving existing afs token");
311 struct ktc_token token;
312 struct ktc_token *pToken;
313 struct ubik_client *ubikConn;
314 struct kaentryinfo tentry;
315 struct ktc_principal tgs_server;
316 struct ktc_token tgs_token;
317 struct ktc_principal tgs_client;
320 code = ka_GetAdminToken (name, instance, cell, &key, 3600,
323 com_err (whoami, code, "getting admin token");
327 if (token.ticketLen == 0) {
328 fprintf ("Can't get admin token\n");
332 code = ka_AuthServerConn (cell, KA_MAINTENANCE_SERVICE, pToken,
335 com_err (whoami, code, "Getting AuthServer ubik conn");
339 SetFlags (ubikConn, AUTH_SUPERUSER, KAFNORMAL);
340 SetFlags (ubikConn, name, KAFNORMAL);
341 SetLife (ubikConn, KA_TGS_NAME, MAXKTCTICKETLIFETIME);
342 SetLife (ubikConn, AUTH_SUPERUSER, MAXKTCTICKETLIFETIME);
343 SetLife (ubikConn, name, 3600);
344 deadTime = startTime + 365*24*3600;
345 SetExp (ubikConn, KA_TGS_NAME, deadTime);
346 SetExp (ubikConn, AUTH_SUPERUSER, deadTime);
347 SetExp (ubikConn, name, deadTime);
349 GetTokenLife (name, passwd, 3600, EXACT);
351 /* get TGS ticket for proper realm */
352 strcpy (tgs_server.name, KA_TGS_NAME);
353 strcpy (tgs_server.instance, realm);
354 strcpy (tgs_server.cell, cell);
355 /* save this for future use */
356 code = ktc_GetToken (&tgs_server, &tgs_token, sizeof(tgs_token),
359 com_err (whoami, code, "saving tgs token");
363 SetLife (ubikConn, name, MAXKTCTICKETLIFETIME);
365 GetTokenLife (name, passwd, MAXKTCTICKETLIFETIME, EXACT);
367 SetLife (ubikConn, AUTH_SUPERUSER, 4000);
369 GetTokenLife (name, passwd, 4000, KERBEROS);
370 SetLife (ubikConn, AUTH_SUPERUSER, MAXKTCTICKETLIFETIME);
372 SetLife (ubikConn, KA_TGS_NAME, 5000);
374 GetTokenLife (name, passwd, 5000, KERBEROS);
375 SetLife (ubikConn, KA_TGS_NAME, MAXKTCTICKETLIFETIME);
378 SetExp (ubikConn, KA_TGS_NAME, now+6000);
379 GetTokenLife (name, passwd, 6000, KERBEROS);
380 SetExp (ubikConn, KA_TGS_NAME, deadTime);
383 SetExp (ubikConn, AUTH_SUPERUSER, now+7000);
384 GetTokenLife (name, passwd, 7000, KERBEROS);
385 SetExp (ubikConn, AUTH_SUPERUSER, deadTime);
388 SetExp (ubikConn, name, now+8000);
389 GetTokenLife (name, passwd, 8000, KERBEROS);
391 /* since the rest should be errors, restore good AFS ticket */
392 code = ktc_SetToken (&afs, &oldAFSToken, &oldClient, 0);
394 com_err (whoami, code, "restoring old afs token");
398 SetExp (ubikConn, name, now-1000);
399 GetTokenLife (name, passwd, 8000, KABADUSER);
400 SetExp (ubikConn, name, deadTime);
402 SetExp (ubikConn, AUTH_SUPERUSER, now-1000);
403 GetTokenLife (name, passwd, 8000, KABADSERVER);
404 SetExp (ubikConn, AUTH_SUPERUSER, deadTime);
406 SetFlags (ubikConn, AUTH_SUPERUSER, KAFNORMAL+KAFNOSEAL);
407 GetTokenLife (name, passwd, 8000, KABADSERVER);
408 SetFlags (ubikConn, AUTH_SUPERUSER, KAFNORMAL);
410 SetFlags (ubikConn, name, KAFNORMAL+KAFNOTGS);
411 GetTokenLife (name, passwd, 8000, KABADUSER);
412 /* restore old tgs, since GetTicket are prohibited too. */
413 code = ktc_SetToken (&tgs_server, &tgs_token, &tgs_client, 0);
415 com_err (whoami, code, "restoring old tgs token");
418 printf ("Restoring TGT obtained before NOTGS set\n");
419 code = ka_GetServerToken (AUTH_SUPERUSER, "", cell, 100, 0, 1);
420 if (code != KABADUSER) {
421 com_err (whoami, code, "expected BADUSER error, getting AFS token w/ old tgs token but with NOTGS set");
423 } else printf ("Received expected error code\n");
424 SetFlags (ubikConn, name, KAFNORMAL);
426 if (patient) { /* this requires waiting too long */
427 struct ktc_token afsToken;
428 code = ktc_SetToken (&afs, &oldAFSToken, &oldClient, 0);
430 com_err (whoami, code, "restoring old afs token");
433 fprintf (stdout, "Waiting for TGS ticket to age (about 5 min)...");
435 while (((now = time(0))-tgs_token.startTime) < 5*60) {
436 if (((now - tgs_token.startTime) % 60) == 0) {
438 "%d seconds to go...", (now-tgs_token.startTime));
441 IOMGR_Sleep (1); /* with afs token restored... */
443 /* restore old tgs */
444 code = ktc_SetToken (&tgs_server, &tgs_token, &tgs_client, 0);
446 com_err (whoami, code, "restoring old tgs token");
449 code = ka_GetServerToken (AUTH_SUPERUSER, "", cell,
450 MAXKTCTICKETLIFETIME, &afsToken, 1);
452 com_err (whoami, code, "getting AFS token w/ old tgs token");
455 CheckLife (afsToken.endTime, afsToken.startTime,
458 ubik_ClientDestroy (ubikConn);
461 printf ("calling finalize\n");
464 printf ("All Okay\n");
472 register struct cmd_syndesc *ts;
475 initialize_u_error_table();
476 initialize_cmd_error_table();
477 initialize_rxk_error_table();
478 initialize_ktc_error_table();
479 initialize_acfg_error_table();
480 initialize_ka_error_table();
482 ts = cmd_CreateSyntax (0, Main, 0, "Main program");
483 /* 0 */ cmd_AddParm (ts, "-patient", CMD_FLAG, CMD_OPTIONAL,
484 "wait for TGS ticket to age");
486 /* 12 */ cmd_AddParm (ts, "-admin_username", CMD_SINGLE, CMD_OPTIONAL,
487 "admin principal to use for authentication");
488 /* 13 */ cmd_AddParm (ts, "-password_for_admin", CMD_SINGLE, CMD_OPTIONAL,
490 /* 14 */ cmd_AddParm (ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");
491 /* 15 */ cmd_AddParm (ts, "-servers", CMD_LIST, CMD_OPTIONAL,
492 "explicit list of authentication servers");
493 code = cmd_Dispatch(argc, argv);