cmd: add flags argument to create syntax function
[openafs.git] / src / libadmin / test / kas.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 /*
11  * This file implements the kas related funtions for afscp
12  */
13
14 #include <afsconfig.h>
15 #include <afs/param.h>
16
17 #include <roken.h>
18
19 #include "kas.h"
20
21 /*
22  * Utility functions
23  */
24
25 /*
26  * Generic fuction for converting input string to an integer.  Pass
27  * the error_msg you want displayed if there is an error converting
28  * the string.
29  */
30
31 static int
32 GetIntFromString(const char *int_str, const char *error_msg)
33 {
34     int i;
35     char *bad_char = NULL;
36
37     i = strtoul(int_str, &bad_char, 10);
38     if ((bad_char == NULL) || (*bad_char == 0)) {
39         return i;
40     }
41
42     ERR_EXT(error_msg);
43 }
44
45 int
46 DoKasPrincipalCreate(struct cmd_syndesc *as, void *arock)
47 {
48     enum { PRINCIPAL, INSTANCE,
49         PASSWORD
50     };
51     afs_status_t st = 0;
52     kas_identity_t user;
53     const char *password;
54
55     if (existing_tokens) {
56         ERR_EXT("can't use -usetokens with kas functions");
57     }
58
59     strcpy(user.principal, as->parms[PRINCIPAL].items->data);
60
61     if (as->parms[INSTANCE].items) {
62         strcpy(user.instance, as->parms[INSTANCE].items->data);
63     } else {
64         user.instance[0] = 0;
65     }
66
67     password = as->parms[PASSWORD].items->data;
68
69     if (!kas_PrincipalCreate(cellHandle, 0, &user, password, &st)) {
70         ERR_ST_EXT("kas_PrincipalCreate", st);
71     }
72
73     return 0;
74 }
75
76 int
77 DoKasPrincipalDelete(struct cmd_syndesc *as, void *arock)
78 {
79     enum { PRINCIPAL, INSTANCE };
80     afs_status_t st = 0;
81     kas_identity_t user;
82
83     if (existing_tokens) {
84         ERR_EXT("can't use -usetokens with kas functions");
85     }
86
87     strcpy(user.principal, as->parms[PRINCIPAL].items->data);
88
89     if (as->parms[INSTANCE].items) {
90         strcpy(user.instance, as->parms[PRINCIPAL].items->data);
91     } else {
92         user.instance[0] = 0;
93     }
94
95     if (!kas_PrincipalDelete(cellHandle, 0, &user, &st)) {
96         ERR_ST_EXT("kas_PrincipalDelete", st);
97     }
98
99     return 0;
100 }
101
102 static void
103 Print_kas_principalEntry_p(kas_principalEntry_p principal, const char *prefix)
104 {
105     int i;
106
107     if (principal->adminSetting == KAS_ADMIN) {
108         printf("%sAdmin setting: KAS_ADMIN\n", prefix);
109     } else {
110         printf("%sAdmin setting: NO_KAS_ADMIN\n", prefix);
111     }
112
113     if (principal->tgsSetting == TGS) {
114         printf("%sTGS setting: TGS\n", prefix);
115     } else {
116         printf("%sTGS setting: NO_TGS\n", prefix);
117     }
118
119     if (principal->encSetting == ENCRYPT) {
120         printf("%sEncrypt setting: ENCRYPT\n", prefix);
121     } else {
122         printf("%sEncrypt setting: NO_ENCRYPT\n", prefix);
123     }
124
125     if (principal->cpwSetting == CHANGE_PASSWORD) {
126         printf("%sChange password setting: CHANGE_PASSWORD\n", prefix);
127     } else {
128         printf("%sChange password setting: NO_CHANGE_PASSWORD\n", prefix);
129     }
130
131     if (principal->rpwSetting == REUSE_PASSWORD) {
132         printf("%sReuse password setting: REUSE_PASSWORD\n", prefix);
133     } else {
134         printf("%sReuse password setting: NO_REUSE_PASSWORD\n", prefix);
135     }
136
137     printf("%sExpiration: %u\n", prefix, principal->userExpiration);
138     printf("%sLast modification time %u\n", prefix, principal->lastModTime);
139     printf("%sLast modifying principal %s", prefix,
140            principal->lastModPrincipal.principal);
141     if (principal->lastModPrincipal.instance[0] != 0) {
142         printf(".%s\n", principal->lastModPrincipal.instance);
143     } else {
144         printf("\n");
145     }
146
147     printf("%sLast change password time %u\n", prefix,
148            principal->lastChangePasswordTime);
149     printf("%sMax ticket lifetime %d\n", prefix,
150            principal->maxTicketLifetime);
151     printf("%sKey version number %d\n", prefix, principal->keyVersion);
152
153     printf("%sKey contents :", prefix);
154     for (i = 0; i < KAS_ENCRYPTION_KEY_LEN; i++) {
155         printf("%d ", principal->key.key[i]);
156     }
157     printf("\n");
158
159     printf("%sKey checksum %u\n", prefix, principal->keyCheckSum);
160     printf("%sDays to password expire %d\n", prefix,
161            principal->daysToPasswordExpire);
162     printf("%sFailed login count %d\n", prefix, principal->failLoginCount);
163     printf("%sLock time %d\n", prefix, principal->lockTime);
164 }
165
166 int
167 DoKasPrincipalGet(struct cmd_syndesc *as, void *arock)
168 {
169     enum { PRINCIPAL, INSTANCE };
170     afs_status_t st = 0;
171     kas_identity_t user;
172     kas_principalEntry_t principal;
173
174     if (existing_tokens) {
175         ERR_EXT("can't use -usetokens with kas functions");
176     }
177
178     strcpy(user.principal, as->parms[PRINCIPAL].items->data);
179
180     if (as->parms[INSTANCE].items) {
181         strcpy(user.instance, as->parms[PRINCIPAL].items->data);
182     } else {
183         user.instance[0] = 0;
184     }
185
186     if (!kas_PrincipalGet(cellHandle, 0, &user, &principal, &st)) {
187         ERR_ST_EXT("kas_PrincipalGet", st);
188     }
189
190     Print_kas_principalEntry_p(&principal, "");
191
192     return 0;
193 }
194
195 int
196 DoKasPrincipalList(struct cmd_syndesc *as, void *arock)
197 {
198     afs_status_t st = 0;
199     void *iter;
200     kas_identity_t prin;
201
202     if (existing_tokens) {
203         ERR_EXT("can't use -usetokens with kas functions");
204     }
205
206     if (!kas_PrincipalGetBegin(cellHandle, 0, &iter, &st)) {
207         ERR_ST_EXT("kas_PrincipalGetBegin", st);
208     }
209
210     printf("Listing principals:\n");
211     while (kas_PrincipalGetNext(iter, &prin, &st)) {
212         printf("%s", prin.principal);
213         if (prin.instance[0] != 0) {
214             printf(".%s\n", prin.instance);
215         } else {
216             printf("\n");
217         }
218     }
219
220     if (st != ADMITERATORDONE) {
221         ERR_ST_EXT("kas_PrincipalGetNext", st);
222     }
223
224     if (!kas_PrincipalGetDone(iter, &st)) {
225         ERR_ST_EXT("kas_PrincipalGetDone", st);
226     }
227
228     return 0;
229 }
230
231 int
232 DoKasPrincipalKeySet(struct cmd_syndesc *as, void *arock)
233 {
234     enum { PRINCIPAL, INSTANCE, PASSWORD,
235         KEYVERSION
236     };
237     afs_status_t st = 0;
238     kas_encryptionKey_t key;
239     kas_identity_t user;
240     int key_version;
241     const char *cell;
242     const char *password;
243
244     if (existing_tokens) {
245         ERR_EXT("can't use -usetokens with kas functions");
246     }
247
248     strcpy(user.principal, as->parms[PRINCIPAL].items->data);
249
250     if (as->parms[INSTANCE].items) {
251         strcpy(user.instance, as->parms[INSTANCE].items->data);
252     } else {
253         user.instance[0] = 0;
254     }
255
256     if (!afsclient_CellNameGet(cellHandle, &cell, &st)) {
257         ERR_ST_EXT("afsclient_CellNameGet", st);
258     }
259
260     password = as->parms[PASSWORD].items->data;
261     key_version =
262         GetIntFromString(as->parms[KEYVERSION].items->data,
263                          "invalid key version number");
264     if (!kas_StringToKey(cell, password, &key, &st)) {
265         ERR_ST_EXT("kas_StringToKey", st);
266     }
267
268     if (!kas_PrincipalKeySet(cellHandle, 0, &user, key_version, &key, &st)) {
269         ERR_ST_EXT("kas_PrincipalKeySet", st);
270     }
271
272     return 0;
273 }
274
275 int
276 DoKasPrincipalLockStatusGet(struct cmd_syndesc *as, void *arock)
277 {
278     enum { PRINCIPAL, INSTANCE };
279     afs_status_t st = 0;
280     kas_identity_t user;
281     unsigned int lock_end_time = 0;
282
283     if (existing_tokens) {
284         ERR_EXT("can't use -usetokens with kas functions");
285     }
286
287     strcpy(user.principal, as->parms[PRINCIPAL].items->data);
288
289     if (as->parms[INSTANCE].items) {
290         strcpy(user.instance, as->parms[INSTANCE].items->data);
291     } else {
292         user.instance[0] = 0;
293     }
294
295     if (!kas_PrincipalLockStatusGet
296         (cellHandle, 0, &user, &lock_end_time, &st)) {
297         ERR_ST_EXT("kas_PrincipalLockStatusGet", st);
298     }
299
300     printf("The lock end time is %u\n", lock_end_time);
301
302     return 0;
303 }
304
305 int
306 DoKasPrincipalUnlock(struct cmd_syndesc *as, void *arock)
307 {
308     enum { PRINCIPAL, INSTANCE };
309     afs_status_t st = 0;
310     kas_identity_t user;
311
312     if (existing_tokens) {
313         ERR_EXT("can't use -usetokens with kas functions");
314     }
315
316     strcpy(user.principal, as->parms[PRINCIPAL].items->data);
317
318     if (as->parms[INSTANCE].items) {
319         strcpy(user.instance, as->parms[INSTANCE].items->data);
320     } else {
321         user.instance[0] = 0;
322     }
323
324     if (!kas_PrincipalUnlock(cellHandle, 0, &user, &st)) {
325         ERR_ST_EXT("kas_PrincipalUnlock", st);
326     }
327
328     return 0;
329 }
330
331 int
332 DoKasPrincipalFieldsSet(struct cmd_syndesc *as, void *arock)
333 {
334     enum { PRINCIPAL, INSTANCE, ADMIN, NOADMIN, GRANTTICKET,
335         NOGRANTTICKET, ENCRYPT2, NOENCRYPT, CHANGEPASSWORD,
336         NOCHANGEPASSWORD, REUSEPASSWORD, NOREUSEPASSWORD,
337         EXPIRES, MAXTICKETLIFETIME, PASSWORDEXPIRES,
338         FAILEDPASSWORDATTEMPTS, FAILEDPASSWORDLOCKTIME
339     };
340     afs_status_t st = 0;
341     kas_identity_t user;
342     kas_admin_t admin;
343     kas_admin_p admin_ptr = NULL;
344     int have_admin = 0;
345     kas_tgs_t tgs;
346     kas_tgs_p tgs_ptr = NULL;
347     int have_tgs = 0;
348     kas_enc_t enc;
349     kas_enc_p enc_ptr = NULL;
350     int have_enc = 0;
351     kas_cpw_t cpw;
352     kas_cpw_p cpw_ptr = NULL;
353     int have_cpw = 0;
354     kas_rpw_t reuse;
355     kas_rpw_p reuse_ptr = NULL;
356     int have_reuse = 0;
357     unsigned int expire;
358     unsigned int *expire_ptr = NULL;
359     int have_expire = 0;
360     unsigned int max_ticket;
361     unsigned int *max_ticket_ptr = NULL;
362     int have_max_ticket = 0;
363     unsigned int password_expire;
364     unsigned int *password_expire_ptr = NULL;
365     int have_password_expire = 0;
366     unsigned int failed_password_attempts;
367     unsigned int *failed_password_attempts_ptr = NULL;
368     int have_failed_password_attempts = 0;
369     unsigned int failed_password_lock_time;
370     unsigned int *failed_password_lock_time_ptr = NULL;
371     int have_failed_password_lock_time = 0;
372
373     if (existing_tokens) {
374         ERR_EXT("can't use -usetokens with kas functions");
375     }
376
377     strcpy(user.principal, as->parms[PRINCIPAL].items->data);
378
379     if (as->parms[INSTANCE].items) {
380         strcpy(user.instance, as->parms[INSTANCE].items->data);
381     } else {
382         user.instance[0] = 0;
383     }
384
385     if (as->parms[ADMIN].items) {
386         admin = KAS_ADMIN;
387         admin_ptr = &admin;
388         have_admin = 1;
389     }
390
391     if (as->parms[NOADMIN].items) {
392         admin = NO_KAS_ADMIN;
393         admin_ptr = &admin;
394         if (have_admin) {
395             ERR_EXT("specify either admin or noadmin, not both");
396         }
397         have_admin = 1;
398     }
399
400     if (as->parms[GRANTTICKET].items) {
401         tgs = TGS;
402         tgs_ptr = &tgs;
403         have_tgs = 1;
404     }
405
406     if (as->parms[NOGRANTTICKET].items) {
407         tgs = NO_TGS;
408         tgs_ptr = &tgs;
409         if (have_tgs) {
410             ERR_EXT("specify either grantticket or nograntticket, not both");
411         }
412         have_tgs = 1;
413     }
414
415     if (as->parms[ENCRYPT2].items) {
416         enc = ENCRYPT;
417         enc_ptr = &enc;
418         have_enc = 1;
419     }
420
421     if (as->parms[NOENCRYPT].items) {
422         enc = NO_ENCRYPT;
423         enc_ptr = &enc;
424         if (have_tgs) {
425             ERR_EXT("specify either encrypt or noencrypt, not both");
426         }
427         have_enc = 1;
428     }
429
430     if (as->parms[CHANGEPASSWORD].items) {
431         cpw = CHANGE_PASSWORD;
432         cpw_ptr = &cpw;
433         have_cpw = 1;
434     }
435
436     if (as->parms[NOCHANGEPASSWORD].items) {
437         cpw = NO_CHANGE_PASSWORD;
438         cpw_ptr = &cpw;
439         if (have_tgs) {
440             ERR_EXT("specify either changepassword or "
441                     "nochangepassword, not both");
442         }
443         have_cpw = 1;
444     }
445
446     if (as->parms[REUSEPASSWORD].items) {
447         reuse = REUSE_PASSWORD;
448         reuse_ptr = &reuse;
449         have_reuse = 1;
450     }
451
452     if (as->parms[REUSEPASSWORD].items) {
453         reuse = NO_REUSE_PASSWORD;
454         reuse_ptr = &reuse;
455         if (have_reuse) {
456             ERR_EXT("specify either reusepassword or "
457                     "noreusepassword, not both");
458         }
459         have_reuse = 1;
460     }
461
462     if (as->parms[EXPIRES].items) {
463         expire =
464             GetIntFromString(as->parms[EXPIRES].items->data,
465                              "bad expiration date");
466         expire_ptr = &expire;
467         have_expire = 1;
468     }
469
470     if (as->parms[MAXTICKETLIFETIME].items) {
471         max_ticket =
472             GetIntFromString(as->parms[MAXTICKETLIFETIME].items->data,
473                              "bad max ticket lifetime");
474         max_ticket_ptr = &max_ticket;
475         have_max_ticket = 1;
476     }
477
478     if (as->parms[PASSWORDEXPIRES].items) {
479         password_expire =
480             GetIntFromString(as->parms[PASSWORDEXPIRES].items->data,
481                              "bad expiration date");
482         password_expire_ptr = &password_expire;
483         have_password_expire = 1;
484     }
485
486     if (as->parms[FAILEDPASSWORDATTEMPTS].items) {
487         failed_password_attempts =
488             GetIntFromString(as->parms[FAILEDPASSWORDATTEMPTS].items->data,
489                              "bad expiration date");
490         failed_password_attempts_ptr = &failed_password_attempts;
491         have_failed_password_attempts = 1;
492     }
493
494     if (as->parms[FAILEDPASSWORDLOCKTIME].items) {
495         failed_password_lock_time =
496             GetIntFromString(as->parms[FAILEDPASSWORDLOCKTIME].items->data,
497                              "bad expiration date");
498         failed_password_lock_time_ptr = &failed_password_lock_time;
499         have_failed_password_lock_time = 1;
500     }
501
502     if ((have_admin + have_tgs + have_enc + have_cpw + have_reuse +
503          have_expire + have_max_ticket + have_password_expire +
504          have_failed_password_attempts + have_failed_password_lock_time) ==
505         0) {
506         ERR_EXT("You must specify at least one attribute to change");
507     }
508
509     if (!kas_PrincipalFieldsSet
510         (cellHandle, 0, &user, admin_ptr, tgs_ptr, enc_ptr, cpw_ptr,
511          expire_ptr, max_ticket_ptr, password_expire_ptr, reuse_ptr,
512          failed_password_attempts_ptr, failed_password_lock_time_ptr, &st)) {
513         ERR_ST_EXT("kas_PrincipalFieldsSet", st);
514     }
515
516     return 0;
517 }
518
519 static void
520 Print_kas_serverStats_p(kas_serverStats_p stats, const char *prefix)
521 {
522     time_t stime = stats->serverStartTime;
523
524     printf("%sAllocations %d\n", prefix, stats->allocations);
525     printf("%sFrees %d\n", prefix, stats->frees);
526     printf("%sChange password requests %d\n", prefix,
527            stats->changePasswordRequests);
528     printf("%sAdmin accounts %d\n", prefix, stats->adminAccounts);
529     printf("%sHost %x\n", prefix, stats->host);
530     printf("%sServer start time %s\n", prefix, ctime(&stime));
531     printf("%sUser time %ld secs %ld usec\n", prefix, stats->userTime.tv_sec,
532            (long) stats->userTime.tv_usec);
533     printf("%sSystem time %ld secs %ld usec\n", prefix,
534            stats->systemTime.tv_sec, (long) stats->systemTime.tv_usec);
535     printf("%sData size %d\n", prefix, stats->dataSize);
536     printf("%sStack size %d\n", prefix, stats->stackSize);
537     printf("%sPage faults %d\n", prefix, stats->pageFaults);
538     printf("%sHash table utilization %d\n", prefix,
539            stats->hashTableUtilization);
540     printf("%sAuthentication requests %d aborts %d\n", prefix,
541            stats->authenticate.requests, stats->authenticate.aborts);
542     printf("%sChange password requests %d aborts %d\n", prefix,
543            stats->changePassword.requests, stats->changePassword.aborts);
544     printf("%sGet ticket requests %d aborts %d\n", prefix,
545            stats->getTicket.requests, stats->getTicket.aborts);
546     printf("%sCreate user requests %d aborts %d\n", prefix,
547            stats->createUser.requests, stats->createUser.aborts);
548     printf("%sSet password requests %d aborts %d\n", prefix,
549            stats->setPassword.requests, stats->setPassword.aborts);
550     printf("%sSet fields requests %d aborts %d\n", prefix,
551            stats->setFields.requests, stats->setFields.aborts);
552     printf("%sDelete user requests %d aborts %d\n", prefix,
553            stats->deleteUser.requests, stats->deleteUser.aborts);
554     printf("%sGet entry requests %d aborts %d\n", prefix,
555            stats->getEntry.requests, stats->getEntry.aborts);
556     printf("%sList entry requests %d aborts %d\n", prefix,
557            stats->listEntry.requests, stats->listEntry.aborts);
558     printf("%sGet stats requests %d aborts %d\n", prefix,
559            stats->getStats.requests, stats->getStats.aborts);
560     printf("%sGet password requests %d aborts %d\n", prefix,
561            stats->getPassword.requests, stats->getPassword.aborts);
562     printf("%sGet random key requests %d aborts %d\n", prefix,
563            stats->getRandomKey.requests, stats->getRandomKey.aborts);
564     printf("%sDebug requests %d aborts %d\n", prefix, stats->debug.requests,
565            stats->debug.aborts);
566     printf("%sUDP authenticate requests %d aborts %d\n", prefix,
567            stats->udpAuthenticate.requests, stats->udpAuthenticate.aborts);
568     printf("%sUDP get ticket requests %d aborts %d\n", prefix,
569            stats->udpGetTicket.requests, stats->udpGetTicket.aborts);
570     printf("%sUnlock requests %d aborts %d\n", prefix, stats->unlock.requests,
571            stats->unlock.aborts);
572     printf("%sLock status requests %d aborts %d\n", prefix,
573            stats->lockStatus.requests, stats->lockStatus.aborts);
574     printf("%sString checks %d\n", prefix, stats->stringChecks);
575 }
576
577 int
578 DoKasServerStatsGet(struct cmd_syndesc *as, void *arock)
579 {
580     enum { SERVER };
581     afs_status_t st = 0;
582     const char *server_list[2] = { 0, 0 };
583     void *kas_server = NULL;
584     kas_serverStats_t stats;
585
586     if (existing_tokens) {
587         ERR_EXT("can't use -usetokens with kas functions");
588     }
589
590     if (as->parms[SERVER].items) {
591         server_list[0] = as->parms[SERVER].items->data;
592     }
593
594     if (!kas_ServerOpen(cellHandle, server_list, &kas_server, &st)) {
595         ERR_ST_EXT("kas_ServerOpen", st);
596     }
597
598     if (!kas_ServerStatsGet(0, kas_server, &stats, &st)) {
599         ERR_ST_EXT("kas_ServerStatsGet", st);
600     }
601
602     Print_kas_serverStats_p(&stats, "");
603
604     kas_ServerClose(kas_server, 0);
605
606     return 0;
607 }
608
609 static void
610 Print_kas_serverDebugInfo_p(kas_serverDebugInfo_p debug, const char *prefix)
611 {
612     time_t time;
613     int i;
614
615     printf("%sHost %x\n", prefix, debug->host);
616     time = debug->serverStartTime;
617     printf("%sServer start time %s\n", prefix, ctime(&time));
618     time = debug->currentTime;
619     printf("%sCurrent time %s\n", prefix, ctime(&time));
620     printf("%sNo auth %d\n", prefix, debug->noAuth);
621     time = debug->lastTransaction;
622     printf("%sLast transaction %s\n", prefix, ctime(&time));
623     printf("%sLast operation %s\n", prefix, debug->lastOperation);
624     printf("%sLast principal auth %s\n", prefix, debug->lastPrincipalAuth);
625     printf("%sLast principal UDP auth %s\n", prefix,
626            debug->lastPrincipalUDPAuth);
627     printf("%sLast principal TGS auth %s\n", prefix, debug->lastPrincipalTGS);
628     printf("%sLast principal UDP TGS auth %s\n", prefix,
629            debug->lastPrincipalUDPTGS);
630     printf("%sLast principal admin %s\n", prefix, debug->lastPrincipalAdmin);
631     printf("%sLast server TGS %s\n", prefix, debug->lastServerTGS);
632     printf("%sLast server UDP TGS %s\n", prefix, debug->lastServerUDPTGS);
633     time = debug->nextAutoCheckPointWrite;
634     printf("%sNext auto check point write %s\n", prefix, ctime(&time));
635     printf("%sUpdates remaining before ACPW %d\n", prefix,
636            debug->updatesRemainingBeforeAutoCheckPointWrite);
637     time = debug->dbHeaderRead;
638     printf("%sDatabase header read %s\n", prefix, ctime(&time));
639     printf("%sDatabase version %d\n", prefix, debug->dbVersion);
640     printf("%sDatabase free ptr %d\n", prefix, debug->dbFreePtr);
641     printf("%sDatabase EOF ptr %d\n", prefix, debug->dbEOFPtr);
642     printf("%sDatabase kvno ptr %d\n", prefix, debug->dbKvnoPtr);
643     printf("%sDatabase special keys version%d\n", prefix,
644            debug->dbSpecialKeysVersion);
645     printf("%sDatabase header lock %d\n", prefix, debug->dbHeaderLock);
646     printf("%sKey cache lock %d\n", prefix, debug->keyCacheLock);
647     printf("%sKey cache version %d\n", prefix, debug->keyCacheVersion);
648     printf("%sKey cache size %d\n", prefix, debug->keyCacheSize);
649     printf("%sKey cache used %d\n", prefix, debug->keyCacheUsed);
650
651     printf("%sKey cache\n", prefix);
652
653     for (i = 0; i < debug->keyCacheUsed; i++) {
654         printf("%s\tPrincipal %s\n", prefix, debug->keyCache[i].principal);
655         time = debug->keyCache[i].lastUsed;
656         printf("%s\tLast used %s\n", prefix, ctime(&time));
657         printf("%s\tVersion number %d\n", prefix,
658                debug->keyCache[i].keyVersionNumber);
659         printf("%s\tPrimary %d\n", prefix, debug->keyCache[i].primary);
660         printf("%s\tCheck sum %d\n", prefix, debug->keyCache[i].keyCheckSum);
661         printf("\n");
662     }
663
664 }
665
666 int
667 DoKasServerDebugGet(struct cmd_syndesc *as, void *arock)
668 {
669     enum { SERVER };
670     afs_status_t st = 0;
671     const char *server_list[2] = { 0, 0 };
672     void *kas_server = NULL;
673     kas_serverDebugInfo_t debug;
674
675     if (existing_tokens) {
676         ERR_EXT("can't use -usetokens with kas functions");
677     }
678
679     if (as->parms[SERVER].items) {
680         server_list[0] = as->parms[SERVER].items->data;
681     }
682
683     if (!kas_ServerOpen(cellHandle, server_list, &kas_server, &st)) {
684         ERR_ST_EXT("kas_ServerOpen", st);
685     }
686
687     if (!kas_ServerDebugGet(0, kas_server, &debug, &st)) {
688         ERR_ST_EXT("kas_ServerDebugGet", st);
689     }
690
691     Print_kas_serverDebugInfo_p(&debug, "");
692
693     kas_ServerClose(kas_server, 0);
694
695     return 0;
696 }
697
698 int
699 DoKasServerRandomKeyGet(struct cmd_syndesc *as, void *arock)
700 {
701     afs_status_t st = 0;
702     kas_encryptionKey_t key;
703     int i;
704
705     if (existing_tokens) {
706         ERR_EXT("can't use -usetokens with kas functions");
707     }
708
709     if (!kas_ServerRandomKeyGet(cellHandle, 0, &key, &st)) {
710         ERR_ST_EXT("kas_ServerRandomKeyGet", st);
711     }
712
713     printf("Key: ");
714     for (i = 0; i < KAS_ENCRYPTION_KEY_LEN; i++) {
715         printf("%d ", key.key[i]);
716     }
717     printf("\n");
718
719     return 0;
720 }
721
722 void
723 SetupKasAdminCmd(void)
724 {
725     struct cmd_syndesc *ts;
726
727     ts = cmd_CreateSyntax("KasPrincipalCreate", DoKasPrincipalCreate, NULL, 0,
728                           "create a new principal");
729     cmd_AddParm(ts, "-principal", CMD_SINGLE, CMD_REQUIRED,
730                 "principal to create");
731     cmd_AddParm(ts, "-instance", CMD_SINGLE, CMD_OPTIONAL,
732                 "principal instance");
733     cmd_AddParm(ts, "-password", CMD_SINGLE, CMD_REQUIRED,
734                 "initial principal password");
735     SetupCommonCmdArgs(ts);
736
737     ts = cmd_CreateSyntax("KasPrincipalDelete", DoKasPrincipalDelete, NULL, 0,
738                           "delete a principal");
739     cmd_AddParm(ts, "-principal", CMD_SINGLE, CMD_REQUIRED,
740                 "principal to delete");
741     cmd_AddParm(ts, "-instance", CMD_SINGLE, CMD_OPTIONAL,
742                 "principal instance");
743     SetupCommonCmdArgs(ts);
744
745     ts = cmd_CreateSyntax("KasPrincipalGet", DoKasPrincipalGet, NULL, 0,
746                           "get information about a principal");
747     cmd_AddParm(ts, "-principal", CMD_SINGLE, CMD_REQUIRED,
748                 "principal to get");
749     cmd_AddParm(ts, "-instance", CMD_SINGLE, CMD_OPTIONAL,
750                 "principal instance");
751     SetupCommonCmdArgs(ts);
752
753     ts = cmd_CreateSyntax("KasPrincipalList", DoKasPrincipalList, NULL, 0,
754                           "list all principals");
755     SetupCommonCmdArgs(ts);
756
757     ts = cmd_CreateSyntax("KasPrincipalKeySet", DoKasPrincipalKeySet, NULL, 0,
758                           "set the password for a principal");
759     cmd_AddParm(ts, "-principal", CMD_SINGLE, CMD_REQUIRED,
760                 "principal to modify");
761     cmd_AddParm(ts, "-instance", CMD_SINGLE, CMD_OPTIONAL,
762                 "principal instance");
763     cmd_AddParm(ts, "-password", CMD_SINGLE, CMD_REQUIRED,
764                 "new principal password");
765     cmd_AddParm(ts, "-version", CMD_SINGLE, CMD_REQUIRED,
766                 "password version number");
767     SetupCommonCmdArgs(ts);
768
769     ts = cmd_CreateSyntax("KasPrincipalLockStatusGet",
770                           DoKasPrincipalLockStatusGet, NULL, 0,
771                           "get the lock status of a principal");
772     cmd_AddParm(ts, "-principal", CMD_SINGLE, CMD_REQUIRED,
773                 "principal to query");
774     cmd_AddParm(ts, "-instance", CMD_SINGLE, CMD_OPTIONAL,
775                 "principal instance");
776     SetupCommonCmdArgs(ts);
777
778     ts = cmd_CreateSyntax("KasPrincipalUnlock", DoKasPrincipalUnlock, NULL, 0,
779                           "unlock a principal");
780     cmd_AddParm(ts, "-principal", CMD_SINGLE, CMD_REQUIRED,
781                 "principal to unlock");
782     cmd_AddParm(ts, "-instance", CMD_SINGLE, CMD_OPTIONAL,
783                 "principal instance");
784     SetupCommonCmdArgs(ts);
785
786     ts = cmd_CreateSyntax("KasPrincipalFieldsSet", DoKasPrincipalFieldsSet, NULL, 0,
787                           "modify a principal");
788     cmd_AddParm(ts, "-principal", CMD_SINGLE, CMD_REQUIRED,
789                 "principal to modify");
790     cmd_AddParm(ts, "-instance", CMD_SINGLE, CMD_OPTIONAL,
791                 "principal instance");
792     cmd_AddParm(ts, "-admin", CMD_FLAG, CMD_OPTIONAL,
793                 "make this principal an admin");
794     cmd_AddParm(ts, "-noadmin", CMD_FLAG, CMD_OPTIONAL,
795                 "remove admin from this principal");
796     cmd_AddParm(ts, "-grantticket", CMD_FLAG, CMD_OPTIONAL,
797                 "this principal can grant server tickets");
798     cmd_AddParm(ts, "-nograntticket", CMD_FLAG, CMD_OPTIONAL,
799                 "this principal cannot grant server tickets");
800     cmd_AddParm(ts, "-encrypt", CMD_FLAG, CMD_OPTIONAL,
801                 "this principal can encrypt data");
802     cmd_AddParm(ts, "-noencrypt", CMD_FLAG, CMD_OPTIONAL,
803                 "this principal cannot encrypt data");
804     cmd_AddParm(ts, "-changepassword", CMD_FLAG, CMD_OPTIONAL,
805                 "this principal can change its password");
806     cmd_AddParm(ts, "-nochangepassword", CMD_FLAG, CMD_OPTIONAL,
807                 "this principal cannot change its password");
808     cmd_AddParm(ts, "-reusepassword", CMD_FLAG, CMD_OPTIONAL,
809                 "this principal can reuse its password");
810     cmd_AddParm(ts, "-noreusepassword", CMD_FLAG, CMD_OPTIONAL,
811                 "this principal cannot reuse its password");
812     cmd_AddParm(ts, "-expires", CMD_SINGLE, CMD_OPTIONAL,
813                 "the time at which this principal expires");
814     cmd_AddParm(ts, "-maxticketlifetime", CMD_SINGLE, CMD_OPTIONAL,
815                 "the maximum ticket lifetime this principal can request");
816     cmd_AddParm(ts, "-passwordexpires", CMD_SINGLE, CMD_OPTIONAL,
817                 "the time at which this principal's password expires");
818     cmd_AddParm(ts, "-failedpasswordattempts", CMD_SINGLE, CMD_OPTIONAL,
819                 "the number of failed password attempts this principal "
820                 "can incur before it is locked");
821     cmd_AddParm(ts, "-failedpasswordlocktime", CMD_SINGLE, CMD_OPTIONAL,
822                 "the amount of time this principal will be locked if the "
823                 "maximum failed password attempts is exceeded");
824     SetupCommonCmdArgs(ts);
825
826     ts = cmd_CreateSyntax("KasServerStatsGet", DoKasServerStatsGet, NULL, 0,
827                           "get stats on a kaserver");
828     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED, "server to query");
829     SetupCommonCmdArgs(ts);
830
831     ts = cmd_CreateSyntax("KasServerDebugGet", DoKasServerDebugGet, NULL, 0,
832                           "get debug info from a kaserver");
833     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED, "server to query");
834     SetupCommonCmdArgs(ts);
835
836     ts = cmd_CreateSyntax("KasServerRandomKeyGet", DoKasServerRandomKeyGet, NULL, 0,
837                           "create a random key");
838     SetupCommonCmdArgs(ts);
839
840 }