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 /* These routines provide administrative tools for managing the AuthServer.
11 There is an interactive routine that can be used to examine the database and
12 make small changes as well as subroutines to permit specialized programs to
13 update the database, change the server passwords, etc. */
15 #include <afsconfig.h>
16 #include <afs/param.h>
19 #ifdef IGNORE_SOME_GCC_WARNINGS
20 # pragma GCC diagnostic warning "-Wstrict-prototypes"
25 #include <afs/opr_assert.h>
29 #include <hcrypto/des.h>
30 #include <hcrypto/ui.h>
35 #include <rx/rxkad_convert.h>
37 #define UBIK_LEGACY_CALLITER 1
40 #include <afs/cellconfig.h>
42 #include <afs/com_err.h>
43 #include <afs/afsutil.h>
46 #include "kauth_internal.h"
51 #define CMD_PARSER_AMBIG_FIX 1 /* allow ambiguous aliases */
53 #define KA_SIXHOURS (6*3600)
55 static struct ubik_client
*conn
;
56 static char cell
[MAXKTCREALMLEN
] = "";
57 static char whoami
[32];
58 static char passwd
[BUFSIZ
];
59 static char myName
[510]; /* almost like whoami save with path and without : */
63 static char **zero_argv
;
64 afs_uint32
ka_islocked(char *, char *, afs_uint32
*);
73 code
= ka_ExpandCell(0, cell
, 0 /*local */ );
75 afs_com_err(whoami
, code
, "Can't expand cell name");
80 /* These are the command operation procedures. */
83 DumpUser(char *user
, char *arock
, int showadmin
, int showkey
, char *inst
)
85 char name
[MAXKTCNAMELEN
];
86 char instance
[MAXKTCNAMELEN
];
89 char bob
[KA_TIMESTR_LEN
];
91 struct kaentryinfo tentry
;
93 code
= ka_ParseLoginName(user
, name
, instance
, 0);
95 afs_com_err(whoami
, code
, "parsing user's name '%s'", user
);
102 ubik_KAM_GetEntry(conn
, 0, name
, inst
, KAMAJORVERSION
, &tentry
);
104 afs_com_err(whoami
, code
, "getting information for %s.%s", name
, inst
);
107 if (tentry
.minor_version
!= KAMINORVERSION
)
108 printf("Minor version number mismatch: got %d, expected %d\n",
109 tentry
.minor_version
, KAMINORVERSION
);
110 if (showadmin
&& !(tentry
.flags
& KAFADMIN
))
112 ka_PrintUserID("\nUser data for ", name
, inst
, "");
115 #define NEWPREFIX "+"
116 if (tentry
.flags
& KAFADMIN
) {
117 printf("%sADMIN", prefix
);
120 if (tentry
.flags
& KAFNOTGS
) {
121 printf("%sNOTGS", prefix
);
124 if (tentry
.flags
& KAFNOCPW
) {
125 printf("%sNOCPW", prefix
);
128 if (tentry
.flags
& KAFNOSEAL
) {
129 printf("%sNOSEAL", prefix
);
132 if (tentry
.flags
& KAFNEWASSOC
) {
133 printf("%sNEWASSOC", prefix
);
136 if (tentry
.flags
& KAFASSOCROOT
) {
137 printf("%sASSOCROOT", prefix
);
140 if (tentry
.flags
& KAFASSOC
) {
141 printf("%sASSOC", prefix
);
144 if (tentry
.user_expiration
<= now
) {
145 printf("%sexpired", prefix
);
148 if (strcmp(prefix
, NEWPREFIX
) == 0)
153 if ((!ka_KeyIsZero((char *)&tentry
.key
, sizeof(tentry
.key
))) && (showkey
)) {
154 printf(" key (%d):", tentry
.key_version
);
155 ka_PrintBytes((char *)&tentry
.key
, sizeof(tentry
.key
));
157 if (tentry
.keyCheckSum
== 0)
158 printf(" key version is %d", tentry
.key_version
);
160 printf(" key (%d) cksum is %u", tentry
.key_version
,
163 ka_timestr(tentry
.change_password_time
, bob
, KA_TIMESTR_LEN
);
164 printf(", last cpw: %s\n", bob
);
165 if (!tentry
.misc_auth_bytes
) {
166 printf(" password will never expire.\n");
168 (" An unlimited number of unsuccessful authentications is permitted.\n");
170 unsigned char misc_stuff
[4];
173 temp
= tentry
.misc_auth_bytes
;
175 temp = ntohl(tentry.misc_auth_bytes);
177 unpack_long(temp
, misc_stuff
);
179 if (!misc_stuff
[0]) {
180 printf(" password will never expire.\n");
182 ka_timestr((tentry
.change_password_time
+
183 misc_stuff
[0] * 24 * 60 * 60), bob
, KA_TIMESTR_LEN
);
184 printf(" password will expire: %s\n", bob
);
189 (" An unlimited number of unsuccessful authentications is permitted.\n");
192 (" %d consecutive unsuccessful authentications are permitted.\n",
196 printf(" The lock time for this user is not limited.\n");
198 printf(" The lock time for this user is %4.1f minutes.\n",
199 (float)((unsigned int)misc_stuff
[3] << 9) / 60.0);
201 if (!(misc_stuff
[1] & KA_ISLOCKED
)
202 || !ka_islocked(name
, instance
, &temp
))
203 printf(" User is not locked.\n");
204 else if (temp
== (afs_uint32
) (-1L))
205 printf(" User is locked forever.\n");
207 ka_timestr(temp
, bob
, KA_TIMESTR_LEN
);
208 printf(" User is locked until %s\n", bob
);
214 char exp
[KA_TIMESTR_LEN
];
215 ka_timestr(tentry
.user_expiration
, exp
, KA_TIMESTR_LEN
);
216 if (tentry
.user_expiration
< now
)
217 printf(" DISABLED entry at %s.", exp
);
218 else if (tentry
.user_expiration
== NEVERDATE
)
219 printf(" entry never expires.");
221 printf(" entry expires on %s.", exp
);
223 printf(" Max ticket lifetime %.2f hours.\n",
224 tentry
.max_ticket_lifetime
/ 3600.0);
225 ka_timestr(tentry
.modification_time
, bob
, KA_TIMESTR_LEN
);
226 printf(" last mod on %s by ", bob
);
227 ka_PrintUserID("", tentry
.modification_user
.name
,
228 tentry
.modification_user
.instance
, "\n");
229 if ((tentry
.reserved3
& 0xffff0000) == 0x12340000) {
230 int short reused
= (short)tentry
.reserved3
;
232 printf(" permit password reuse\n");
234 printf(" don't permit password reuse\n");
241 ListUsers(struct cmd_syndesc
*as
, void *arock
)
246 afs_int32 next_index
;
247 int code
, all
= 0, showa
= 0;
248 int showkey
= (as
->parms
[2].items
!= NULL
);
250 if (as
->parms
[0].items
)
252 if (as
->parms
[1].items
) {
256 for (index
= 0; 1; index
= next_index
) {
258 ubik_KAM_ListEntry(conn
, 0, index
, &next_index
, &count
,
261 afs_com_err(whoami
, code
, "calling KAM_ListEntry");
267 printf("next_index (%d) is negative: ", next_index
);
268 if (strlen(name
.name
) == 0)
269 printf("name is zero length: ");
271 DumpUser(name
.name
, NULL
, showa
, showkey
, name
.instance
);
273 ka_PrintUserID("", name
.name
, name
.instance
, "\n");
280 ExamineUser(struct cmd_syndesc
*as
, void *arock
)
282 int showkey
= (as
->parms
[1].items
!= NULL
);
283 return DumpUser(as
->parms
[0].items
->data
, arock
, 0, showkey
, NULL
);
293 handle_errors(int code
, /* error code to handle */
294 struct OKerrors OKlist
[], /* list of errors & messages that should be ignored */
296 { /* set this if we should retry, clear otherwise */
299 for (i
= 0; OKlist
[i
].code
; i
++) {
300 if (OKlist
[i
].code
== code
) {
301 printf("%s\n", OKlist
[i
].msg
);
302 *persist
= 0; /* we're done */
307 printf(" : [%s] %s", afs_error_table_name(code
), afs_error_message(code
));
310 printf(", wait one second\n");
314 case RX_CALL_TIMEOUT
:
315 printf(" (retrying)\n");
320 *persist
= 0; /* don't retry these errors */
325 CreateUser(struct cmd_syndesc
*as
, void *arock
)
328 char name
[MAXKTCNAMELEN
];
329 char instance
[MAXKTCNAMELEN
];
330 struct ktc_encryptionKey key
;
333 struct OKerrors OKlist
[2];
336 code
= ka_ParseLoginName(as
->parms
[0].items
->data
, name
, instance
, 0);
338 afs_com_err(whoami
, code
, "parsing user's name '%s'",
339 as
->parms
[0].items
->data
);
342 ka_StringToKey(as
->parms
[1].items
->data
, cell
, &key
);
345 code
= ubik_KAM_CreateUser(conn
, 0, name
, instance
,
346 *ktc_to_EncryptionKey(&key
));
349 ka_PrintUserID("Creating user ", name
, instance
, " ");
350 code
= handle_errors(code
, OKlist
, &persist
);
356 DeleteUser(struct cmd_syndesc
*as
, void *arock
)
359 char name
[MAXKTCNAMELEN
];
360 char instance
[MAXKTCNAMELEN
];
363 struct OKerrors OKlist
[2];
365 code
= ka_ParseLoginName(as
->parms
[0].items
->data
, name
, instance
, 0);
367 afs_com_err(whoami
, code
, "parsing user's name '%s'",
368 as
->parms
[0].items
->data
);
373 code
= ubik_KAM_DeleteUser(conn
, 0, name
, instance
);
376 ka_PrintUserID("Deleting user ", name
, instance
, " ");
377 code
= handle_errors(code
, OKlist
, &persist
);
383 read_time_interval(char *str
, afs_int32
* seconds
)
389 str
= strncpy(buf
, str
, sizeof(buf
));
390 s
= strchr(str
, ':');
394 *s
++ = '\0'; /* separate hours and minutes */
395 sec
= atoi(str
) * 3600 + atoi(s
) * 60;
402 parse_flags(char *name
, char *inst
, char *str
, afs_int32
* flags
)
404 struct kaentryinfo tentry
;
410 int addop
; /* 1=add bit; 0=remove bit */
414 str
= lcstring(bitspec
, str
, sizeof(bitspec
));
416 if (strncmp(str
, "0x", 2) == 0) /* 0x => hex */
417 sscanf(str
, "0x%lx", (long unsigned int *) &f
);
418 else if (*str
== '0') /* assume octal */
419 sscanf(str
, "%lo", (long unsigned int *) &f
);
420 else /* just assume hex */
421 sscanf(str
, "%lx", (long unsigned int *) &f
);
428 if (strchr("+-", *str
))
429 addop
= (*str
++ == '+');
430 else if (*str
== '_') {
436 ubik_KAM_GetEntry(conn
, 0, name
, inst
, KAMAJORVERSION
,
439 afs_com_err(whoami
, code
,
440 "could get current flag value for %s.%s", name
, inst
);
457 if (strcmp(bit
, "admin") == 0)
459 else if (strcmp(bit
, "noadmin") == 0)
460 flag
= KAFADMIN
, addop
= !addop
;
461 else if (strcmp(bit
, "notgs") == 0)
463 else if (strcmp(bit
, "tgs") == 0)
464 flag
= KAFNOTGS
, addop
= !addop
;
465 else if (strcmp(bit
, "noseal") == 0)
467 else if (strcmp(bit
, "seal") == 0)
468 flag
= KAFNOSEAL
, addop
= !addop
;
469 else if (strcmp(bit
, "nocpw") == 0)
471 else if (strcmp(bit
, "cpw") == 0)
472 flag
= KAFNOCPW
, addop
= !addop
;
473 else if (strcmp(bit
, "newassoc") == 0)
475 else if (strcmp(bit
, "nonewassoc") == 0)
476 flag
= KAFNEWASSOC
, addop
= !addop
;
479 ("Illegal bit name: %s; choices are: [no]admin, [no]tgs, [no]seal, [no]cpw\n",
492 addop
= 1; /* get next op */
493 else if ((*str
== '-') || (*str
== '_'))
496 printf("Illegal combination operator: %c\n", *str
);
502 *flags
= (f
& KAF_SETTABLE_FLAGS
) | KAFNORMAL
;
506 #define seriouserror(code) ((code <0) || ((code != UNOSERVERS) && (code != UNOQUORUM) && code != UNOTSYNC))
508 /* return MAXLONG if locked forever */
510 ka_islocked(char *name
, char *instance
, afs_uint32
* when
)
520 ubik_CallIter(KAM_LockStatus
, conn
, UPUBIKONLY
, &count
, (long) name
,
521 (long) instance
, (long) &tempwhen
, 0, 0, 0,
522 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
524 if (seriouserror(code
))
525 afs_com_err(whoami
, code
, NULL
);
526 } else if (tempwhen
) { /* user is locked */
527 if (!*when
|| tempwhen
< *when
) {
531 } else /* ! tempwhen ==> user is not locked */
534 } while (code
!= UNOSERVERS
);
540 Unlock(struct cmd_syndesc
*as
, void *arock
)
542 afs_int32 code
, rcode
= 0;
545 char name
[MAXKTCNAMELEN
];
546 char instance
[MAXKTCNAMELEN
];
548 code
= ka_ParseLoginName(as
->parms
[0].items
->data
, name
, instance
, 0);
550 afs_com_err(whoami
, code
, "parsing user's name '%s'",
551 as
->parms
[0].items
->data
);
557 code
= ubik_CallIter(KAM_Unlock
, conn
, 0, &count
, (long) name
, (long) instance
,
558 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
559 if (code
&& (code
!= UNOSERVERS
)) {
561 if (conn
&& conn
->conns
[count
- 1]
562 && rx_PeerOf(conn
->conns
[count
- 1])) {
563 server
= rx_HostOf(rx_PeerOf(conn
->conns
[count
- 1]));
565 afs_com_err(whoami
, code
,
566 "so %s.%s may still be locked (on server %d.%d.%d.%d)",
567 name
, instance
, ((server
>> 24) & 0xFF),
568 ((server
>> 16) & 0xFF), ((server
>> 8) & 0xFF),
575 } while (code
!= UNOSERVERS
);
581 SetFields(struct cmd_syndesc
*as
, void *arock
)
584 char name
[MAXKTCNAMELEN
];
585 char instance
[MAXKTCNAMELEN
];
588 afs_int32 expiration
= 0;
589 afs_int32 lifetime
= 0;
590 afs_int32 maxAssociates
= -1;
591 afs_int32 pwexpiry
= 0;
592 afs_int32 was_spare
= 0;
593 char misc_auth_bytes
[4];
596 code
= ka_ParseLoginName(as
->parms
[0].items
->data
, name
, instance
, 0);
598 afs_com_err(whoami
, code
, "parsing user's name '%s'",
599 as
->parms
[0].items
->data
);
603 if (as
->parms
[1].items
) {
604 code
= parse_flags(name
, instance
, as
->parms
[1].items
->data
, &flags
);
607 ("Illegal flag specification: %s, should be of the form <'='|'+'|'-'|'_'>bitname{<'+'|'-'>bitname}*\n",
608 as
->parms
[1].items
->data
);
612 if (as
->parms
[2].items
) {
614 char *s
= strncpy(buf
, as
->parms
[2].items
->data
, sizeof(buf
));
615 code
= ktime_DateToInt32(s
, &expiration
);
617 printf("Illegal time format %s: %s\n", as
->parms
[2].items
->data
,
618 ktime_GetDateUsage());
621 if (expiration
== 0) {
622 fprintf(stderr
, "Expiration time must be after (about) 1970.\n");
625 if (expiration
< time(0)) {
627 "Warning: expiration being set into the past, account will be disabled.\n");
633 if (as
->parms
[3].items
) {
634 code
= read_time_interval(as
->parms
[3].items
->data
, &lifetime
);
639 /* no point in doing this any sooner than necessary */
640 for (i
= 0; i
< 4; misc_auth_bytes
[i
++] = 0);
642 if (as
->parms
[4].items
) {
643 pwexpiry
= strtol(as
->parms
[4].items
->data
, &end
, 10);
646 "Password lifetime specified must be a non-negative decimal integer.\n");
649 if (pwexpiry
< 0 || pwexpiry
> 254) {
651 "Password lifetime range must be [0..254] days.\n");
652 fprintf(stderr
, "Zero represents an unlimited lifetime.\n");
656 misc_auth_bytes
[0] = pwexpiry
+ 1;
659 if (as
->parms
[5].items
) {
661 reuse
= (as
->parms
[5].items
->data
);
663 if (!strcmp(reuse
, "yes")) {
664 misc_auth_bytes
[1] = KA_REUSEPW
;
665 } else if (strcmp(reuse
, "no")) {
667 "must specify \"yes\" or \"no\": \"yes\" assumed\n");
668 misc_auth_bytes
[1] = KA_REUSEPW
;
670 misc_auth_bytes
[1] = KA_NOREUSEPW
;
674 if (as
->parms
[6].items
) {
677 nfailures
= strtol(as
->parms
[6].items
->data
, &end
, 10);
679 if (*end
!= '\0' || nfailures
< 0 || nfailures
> 254) {
680 fprintf(stderr
, "Failure limit must be in [0..254].\n");
681 fprintf(stderr
, "Zero represents unlimited login attempts.\n");
684 misc_auth_bytes
[2] = nfailures
+ 1;
687 if (as
->parms
[7].items
) {
688 int locktime
, hrs
, mins
;
692 s
= as
->parms
[7].items
->data
;
694 sscanf(s
, "%d:%d", &hrs
, &mins
);
696 sscanf(s
, "%d", &mins
);
698 locktime
= hrs
* 60 + mins
;
699 if (hrs
< 0 || hrs
> 36 || mins
< 0) {
701 "Lockout times must be either minutes or hh:mm.\n");
702 fprintf(stderr
, "Lockout times must be less than 36 hours.\n");
704 } else if (locktime
> 36 * 60) {
706 "Lockout times must be either minutes or hh:mm.\n");
707 fprintf(stderr
, "Lockout times must be less than 36 hours.\n");
709 "Continuing with lock time of exactly 36 hours...\n");
712 locktime
= (locktime
* 60 + 511) >> 9; /* ceil(l*60/512) */
713 misc_auth_bytes
[3] = locktime
+ 1; /* will be 1 if user said 0 */
716 if (as
->parms
[8].items
) {
717 maxAssociates
= atoi(as
->parms
[6].items
->data
);
718 if (maxAssociates
< 0) {
719 printf("Illegal maximum number of associates\n");
724 was_spare
= pack_long(misc_auth_bytes
);
726 if (was_spare
|| flags
|| expiration
|| lifetime
|| (maxAssociates
>= 0))
728 ubik_KAM_SetFields(conn
, 0, name
, instance
, flags
,
729 expiration
, lifetime
, maxAssociates
, was_spare
,
732 printf("Must specify one of the optional parameters\n");
736 afs_com_err(whoami
, code
, "calling KAM_SetFields for %s.%s", name
,
742 StringToKey(struct cmd_syndesc
*as
, void *arock
)
745 char realm
[MAXKTCREALMLEN
];
746 struct ktc_encryptionKey key
;
748 if (as
->parms
[1].items
) {
749 code
= ka_ExpandCell(as
->parms
[1].items
->data
, realm
, 0 /*local */ );
751 afs_com_err(whoami
, code
,
752 "expanding %s as cell name, attempting to continue",
753 as
->parms
[1].items
->data
);
755 ucstring(realm
, realm
, sizeof(realm
));
757 if ((code
= DefaultCell()))
759 ucstring(realm
, cell
, sizeof(realm
));
761 ka_StringToKey(as
->parms
[0].items
->data
, realm
, &key
);
763 printf("Converting %s in realm '%s' yields key='",
764 as
->parms
[0].items
->data
, realm
);
765 ka_PrintBytes((char *)&key
, sizeof(key
));
768 DES_string_to_key(as
->parms
[0].items
->data
, ktc_to_cblockptr(&key
));
770 printf("Converting %s with the DES string to key yields key='",
771 as
->parms
[0].items
->data
);
772 ka_PrintBytes((char *)&key
, sizeof(key
));
779 SetPassword(struct cmd_syndesc
*as
, void *arock
)
782 char name
[MAXKTCNAMELEN
];
783 char instance
[MAXKTCNAMELEN
];
784 char realm
[MAXKTCREALMLEN
];
785 struct ktc_encryptionKey key
;
788 code
= ka_ParseLoginName(as
->parms
[0].items
->data
, name
, instance
, realm
);
790 afs_com_err(whoami
, code
, "parsing user's name '%s'",
791 as
->parms
[0].items
->data
);
795 if (strlen(realm
) == 0)
796 ucstring(realm
, cell
, sizeof(realm
));
798 if (as
->parms
[1].items
&& as
->parms
[2].items
) {
799 printf("Can't specify both a password and a key\n");
801 } else if (as
->parms
[1].items
) {
802 (void)init_child(myName
);
803 (void)give_to_child(passwd
); /* old password */
804 code
= password_bad(as
->parms
[1].items
->data
);
805 (void)terminate_child();
808 ka_StringToKey(as
->parms
[1].items
->data
, realm
, &key
);
809 } else if (as
->parms
[2].items
) {
810 if (ka_ReadBytes(as
->parms
[2].items
->data
, (char *)&key
, sizeof(key
))
812 printf("Key must be 8 bytes: '%s' was too long\n",
813 as
->parms
[2].items
->data
);
817 printf("Must specify new password or key\n");
822 if (as
->parms
[3].items
)
823 sscanf(as
->parms
[3].items
->data
, "%d", &kvno
);
825 code
= ubik_KAM_SetPassword(conn
, 0, name
, instance
, kvno
,
826 *ktc_to_EncryptionKey(&key
));
828 afs_com_err(whoami
, code
, "so can't set password for %s.%s", name
,
833 #define PrintPrincipal(p,n,l) \
834 PrintName((p)->name, (p)->instance, (p)->cell, l, n)
837 PrintName(char *name
, char *inst
, char *acell
, int buflen
, char *buf
)
840 int left
; /* if ConvertBytes stops early */
849 left
= ka_ConvertBytes(buf
, buflen
, name
, strlen(name
));
853 afs_com_err(whoami
, code
, "PrintName: principal name was '%s'.'%s'@'%s'",
860 if (nlen
+ len
+ 1 >= buflen
)
863 left
= ka_ConvertBytes(buf
+ nlen
, buflen
- nlen
, inst
, len
);
871 char *lcell
= ka_LocalCell();
874 if (strcmp(acell
, lcell
) != 0) {
875 /* only append cell if not the local cell */
876 if (nlen
+ len
+ 1 >= buflen
)
879 left
= ka_ConvertBytes(buf
+ nlen
, buflen
- nlen
, acell
, len
);
887 #define PrintedPrincipal(p) PrintedName ((p)->name, (p)->instance, (p)->cell)
889 /* PrintedName - returned a pointer to a static string in which the formated
890 * name has been stored. */
893 PrintedName(char *name
, char *inst
, char *cell
)
895 static char printedName
[128];
897 code
= PrintName(name
, inst
, cell
, sizeof(printedName
), printedName
);
901 strncpy(printedName
, name
, sizeof(printedName
));
902 printedName
[sizeof(printedName
) - 8] = 0;
903 strcat(printedName
, "<error>");
909 ListTicket(struct ktc_principal
*server
, int verbose
)
912 struct ktc_token token
; /* the token we're printing */
913 struct ktc_principal client
;
914 char UserName
[sizeof(struct ktc_principal
)];
915 char ServerName
[sizeof(struct ktc_principal
)];
916 afs_int32 now
= time(0);
917 char bob
[KA_TIMESTR_LEN
];
919 /* get the ticket info itself */
920 code
= ktc_GetToken(server
, &token
, sizeof(token
), &client
);
922 afs_com_err(whoami
, code
, "failed to get token info for server %s",
923 PrintedPrincipal(server
));
926 code
= PrintPrincipal(&client
, UserName
, sizeof(UserName
));
929 /* spaces are printed as "\040" */
930 if (UserName
[0] == 0)
932 else if (strncmp(UserName
, "AFS\\040ID\\040", 13) == 0) {
933 printf("User's (AFS ID %s) tokens", UserName
+ 13);
934 } else if (strncmp(UserName
, "Unix\\040UID\\040", 15) == 0) {
937 printf("User %s's tokens", UserName
);
939 code
= PrintPrincipal(server
, ServerName
, sizeof(ServerName
));
942 printf(" for %s ", ServerName
);
944 if (token
.startTime
> now
) {
945 ka_timestr(token
.startTime
, bob
, KA_TIMESTR_LEN
);
946 printf("[>> POSTDATED 'till %s <<]", bob
);
949 if (token
.endTime
<= now
)
950 printf("[>> Expired <<]\n");
952 ka_timestr(token
.endTime
, bob
, KA_TIMESTR_LEN
);
953 printf("[Expires %s]\n", bob
);
956 printf("SessionKey: ");
957 ka_PrintBytes((char *)&token
.sessionKey
, sizeof(token
.sessionKey
));
958 printf("\nTicket (kvno = %d, len = %d): ", token
.kvno
,
960 ka_PrintBytes((char *)token
.ticket
, token
.ticketLen
);
967 GetTicket(struct cmd_syndesc
*as
, void *arock
)
970 struct ktc_principal server
;
971 struct ktc_token token
;
972 afs_int32 life
= KA_SIXHOURS
;
974 if (as
->parms
[1].items
) {
975 code
= read_time_interval(as
->parms
[1].items
->data
, &life
);
980 ka_ParseLoginName(as
->parms
[0].items
->data
, server
.name
,
981 server
.instance
, server
.cell
);
983 afs_com_err(whoami
, code
, "parsing user's name '%s'",
984 as
->parms
[0].items
->data
);
987 if (server
.cell
[0] == 0) {
988 if ((code
= DefaultCell()))
990 strcpy(server
.cell
, cell
);
992 code
= ka_ExpandCell(server
.cell
, server
.cell
, 0 /*local */ );
994 afs_com_err(whoami
, code
, "Can't expand cell name");
999 token
.ticketLen
= 0; /* in case there are no tokens */
1001 ka_GetServerToken(server
.name
, server
.instance
, server
.cell
, life
,
1002 &token
, /*new */ 1, /*dosetpag */ 0);
1004 afs_com_err(whoami
, code
, "getting ticket for %s",
1005 PrintedPrincipal(&server
));
1007 code
= ListTicket(&server
, /*verbose */ 1);
1013 GetPassword(struct cmd_syndesc
*as
, void *arock
)
1016 char name
[MAXKTCNAMELEN
];
1017 struct ktc_encryptionKey key
;
1018 static struct ubik_client
*lpbkConn
= 0;
1020 /* no instance allowed */
1021 code
= ka_ParseLoginName(as
->parms
[0].items
->data
, name
, 0, 0);
1024 afs_com_err(whoami
, code
,
1025 "getting %s's password via loopback connection to GetPassword",
1027 /* if we got a timeout, print a clarification, too */
1030 "%s: please note that this command must be run locally on a database server machine.\n",
1035 if (lpbkConn
== 0) {
1036 struct rx_connection
*conns
[2];
1037 struct rx_securityClass
*sc
;
1038 int si
; /* security class index */
1043 sc
= rxnull_NewClientSecurityObject();
1044 si
= RX_SECIDX_NULL
;
1046 rx_NewConnection(htonl(INADDR_LOOPBACK
), htons(AFSCONF_KAUTHPORT
),
1047 KA_MAINTENANCE_SERVICE
, sc
, si
);
1049 code
= ubik_ClientInit(conns
, &lpbkConn
);
1053 code
= ubik_KAM_GetPassword(lpbkConn
, 0, name
,
1054 ktc_to_EncryptionKey(&key
));
1055 /* Lets close down the ubik_Client connection now */
1056 ubik_ClientDestroy(lpbkConn
);
1060 ka_PrintBytes((char *)&key
, sizeof(key
));
1066 GetRandomKey(struct cmd_syndesc
*as
, void *arock
)
1069 struct ktc_encryptionKey key
;
1071 code
= ubik_KAM_GetRandomKey(conn
, 0, ktc_to_EncryptionKey(&key
));
1073 afs_com_err(whoami
, code
, "so can't get random key");
1077 ka_PrintBytes((char *)&key
, sizeof(key
));
1079 for (i
= 0; i
< sizeof(key
); i
++) {
1080 printf("%.2x", ((char *)&key
)[i
] & 0xff);
1092 Statistics(struct cmd_syndesc
*as
, void *arock
)
1098 char bob
[KA_TIMESTR_LEN
];
1101 ubik_KAM_GetStats(conn
, 0, KAMAJORVERSION
, &admins
, &statics
,
1104 printf("call to GetStats failed: %s\n", ka_ErrorString(code
));
1107 if (statics
.minor_version
!= KAMINORVERSION
)
1108 printf("Minor version number mismatch: got %d, expected %d\n",
1109 statics
.minor_version
, KAMINORVERSION
);
1110 printf("%d allocs, %d frees, %d password changes\n", statics
.allocs
,
1111 statics
.frees
, statics
.cpws
);
1112 printf("Hash table utilization = %f%%\n",
1113 (double)dynamics
.hashTableUtilization
/ 100.0);
1114 ka_timestr(dynamics
.start_time
, bob
, KA_TIMESTR_LEN
);
1115 printf("From host %lx started at %s:\n",
1116 afs_printable_uint32_lu(dynamics
.host
), bob
);
1118 #define print_stat(name) if (dynamics.name.requests) printf (" of %d requests for %s, %d were aborted.\n", dynamics.name.requests, # name, dynamics.name.aborts)
1119 print_stat(Authenticate
);
1120 print_stat(ChangePassword
);
1121 print_stat(GetTicket
);
1122 print_stat(CreateUser
);
1123 print_stat(SetPassword
);
1124 print_stat(SetFields
);
1125 print_stat(DeleteUser
);
1126 print_stat(GetEntry
);
1127 print_stat(ListEntry
);
1128 print_stat(GetStats
);
1129 print_stat(GetPassword
);
1130 print_stat(GetRandomKey
);
1132 print_stat(UAuthenticate
);
1133 print_stat(UGetTicket
);
1135 #if (KAMAJORVERSION>5)
1136 print cpu stats
printf("%d string checks\n", dynamics
.string_checks
);
1138 printf("Used %.3f seconds of CPU time.\n",
1139 dynamics
.string_checks
/ 1000.0);
1141 printf("%d admin accounts\n", admins
);
1146 DebugInfo(struct cmd_syndesc
*as
, void *arock
)
1149 struct ka_debugInfo info
;
1153 char bob
[KA_TIMESTR_LEN
];
1156 if (as
->parms
[0].items
) {
1157 struct ubik_client
*iConn
;
1159 ka_SingleServerConn(cell
, as
->parms
[0].items
->data
,
1160 KA_MAINTENANCE_SERVICE
, 0, &iConn
);
1162 struct afsconf_cell cellinfo
;
1164 afs_com_err(whoami
, code
, "couldn't find host %s in cell %s",
1165 as
->parms
[0].items
->data
, cell
);
1166 code
= ka_GetServers(cell
, &cellinfo
);
1168 afs_com_err(whoami
, code
, "getting servers in cell %s", cell
);
1170 printf("Servers in cell %s, are:\n", cell
);
1171 for (i
= 0; i
< cellinfo
.numServers
; i
++)
1172 printf(" %s\n", cellinfo
.hostName
[i
]);
1176 code
= ubik_KAM_Debug(iConn
, 0, KAMAJORVERSION
, 0, &info
);
1177 ubik_ClientDestroy(iConn
);
1179 code
= ubik_KAM_Debug(conn
, 0, KAMAJORVERSION
, 0, &info
);
1182 afs_com_err(whoami
, code
, "call to Debug failed");
1187 if (info
.minorVersion
!= KAMINORVERSION
)
1188 printf("Minor version number mismatch: got %d, expected %d\n",
1189 info
.minorVersion
, KAMINORVERSION
);
1192 #if (KAMAJORVERSION>5)
1199 timeOffset
= -timeOffset
;
1200 if (timeOffset
> 60) {
1202 ("WARNING: Large server client clock skew: %d seconds. Call itself took %d seconds.\n",
1203 timeOffset
, now
- start
);
1205 ka_timestr(info
.startTime
, bob
, KA_TIMESTR_LEN
);
1206 printf("From host %lx started %sat %s:\n",
1207 afs_printable_uint32_lu(info
.host
),
1208 (info
.noAuth
? "w/o authorization " : ""), bob
);
1209 ka_timestr(info
.lastTrans
, bob
, KA_TIMESTR_LEN
);
1210 printf("Last trans was %s at %s\n", info
.lastOperation
, bob
);
1211 ka_timestr(info
.dbHeaderRead
, bob
, KA_TIMESTR_LEN
);
1212 printf("Header last read %s.\n", bob
);
1213 printf("db version=%d, keyVersion=%d, key cache version=%d\n",
1214 info
.dbVersion
, info
.dbSpecialKeysVersion
, info
.kcVersion
);
1215 printf("db ptrs: free %d, eof %d, kvno %d.\n", info
.dbFreePtr
,
1216 info
.dbEofPtr
, info
.dbKvnoPtr
);
1217 ka_timestr(info
.nextAutoCPW
, bob
, KA_TIMESTR_LEN
);
1218 printf("Next autoCPW at %s or in %d updates.\n", bob
,
1219 info
.updatesRemaining
);
1220 if (info
.cheader_lock
|| info
.keycache_lock
)
1221 printf("locks: cheader %08lx, keycache %08lx\n",
1222 afs_printable_uint32_lu(info
.cheader_lock
),
1223 afs_printable_uint32_lu(info
.keycache_lock
));
1224 printf("Last authentication for %s, last admin user was %s\n",
1225 info
.lastAuth
, info
.lastAdmin
);
1226 printf("Last TGS op was a %s ticket was for %s\n", info
.lastTGSServer
,
1228 printf("Last UDP TGS was a %s ticket for %s. UDP Authenticate for %s\n",
1229 info
.lastUTGSServer
, info
.lastUTGS
, info
.lastUAuth
);
1230 printf("key cache size %d, used %d.\n", info
.kcSize
, info
.kcUsed
);
1231 if (info
.kcUsed
> KADEBUGKCINFOSIZE
) {
1232 printf("insufficient room to return all key cache entries!\n");
1233 info
.kcUsed
= KADEBUGKCINFOSIZE
;
1235 for (i
= 0; i
< info
.kcUsed
; i
++)
1236 ka_timestr(info
.kcInfo
[i
].used
, bob
, KA_TIMESTR_LEN
);
1237 printf("%32s %c %2x(%2x) used %s\n", info
.kcInfo
[i
].principal
,
1238 (info
.kcInfo
[i
].primary
? '*' : ' '), info
.kcInfo
[i
].kvno
,
1239 info
.kcInfo
[i
].keycksum
, bob
);
1244 Interactive(struct cmd_syndesc
*as
, void *arock
)
1251 Quit(struct cmd_syndesc
*as
, void *arock
)
1258 MyAfterProc(struct cmd_syndesc
*as
, void *arock
)
1260 if (!strcmp(as
->name
, "help"))
1263 /* Determine if we need to destory the ubik connection.
1264 * Closing it avoids resends of packets.
1267 ubik_ClientDestroy(conn
);
1274 int init
= 0, noauth
;
1275 char name
[MAXKTCNAMELEN
];
1276 char instance
[MAXKTCNAMELEN
];
1277 char newCell
[MAXKTCREALMLEN
];
1278 afs_uint32 serverList
[MAXSERVERS
];
1281 NoAuth(struct cmd_syndesc
*as
, void *arock
)
1288 MyBeforeProc(struct cmd_syndesc
*as
, void *arock
)
1290 struct ktc_encryptionKey key
;
1291 struct ktc_principal auth_server
, client
;
1292 struct ktc_token auth_token
;
1293 char realm
[MAXKTCREALMLEN
];
1295 struct ktc_token token
, *pToken
;
1296 int i
, acode
, code
= 0;
1299 char *ws
= strrchr(as
->a0name
, '/');
1301 ws
++; /* skip everything before the "/" */
1304 if (strlen(ws
) > 0) {
1305 strncpy(whoami
, ws
, sizeof(whoami
));
1306 if (strlen(whoami
) + 1 >= sizeof(whoami
))
1307 strcpy(whoami
, "kas:");
1309 strcat(whoami
, ":");
1312 /* append sub-command name */
1313 strncat(whoami
, as
->name
, sizeof(whoami
) - strlen(whoami
) - 1);
1316 if (as
->parms
[12].name
== 0)
1319 assert(as
->parms
[13].name
&& as
->parms
[14].name
&& as
->parms
[15].name
1320 && as
->parms
[16].name
);
1322 /* MyAfterProc() destroys the conn, but just to be sure */
1324 ubik_ClientDestroy(conn
);
1328 if (!init
|| as
->parms
[12].items
|| as
->parms
[13].items
1329 || as
->parms
[14].items
|| as
->parms
[15].items
1330 || as
->parms
[16].items
) {
1331 strcpy(instance
, "");
1332 strcpy(newCell
, "");
1334 if (as
->parms
[12].items
) { /* -admin_username */
1336 ka_ParseLoginName(as
->parms
[12].items
->data
, name
, instance
,
1339 afs_com_err(whoami
, code
, "parsing user's name '%s'",
1340 as
->parms
[12].items
->data
);
1345 DWORD len
= MAXKTCNAMELEN
;
1346 if (!GetUserName((LPTSTR
) name
, &len
)) {
1347 printf("Can't get user name \n");
1351 /* No explicit name provided: use Unix uid. */
1352 struct passwd
*pw
= getpwuid(getuid());
1354 printf("Can't figure out your name from your user id.\n");
1357 strncpy(name
, pw
->pw_name
, sizeof(name
));
1361 if (as
->parms
[14].items
) { /* -cell */
1362 if (strlen(newCell
) > 0) {
1363 printf("Duplicate cell specification not allowed\n");
1365 strncpy(newCell
, as
->parms
[14].items
->data
, sizeof(newCell
));
1368 code
= ka_ExpandCell(newCell
, newCell
, 0 /*local */ );
1370 afs_com_err(whoami
, code
, "Can't expand cell name");
1373 strcpy(cell
, newCell
);
1375 if (as
->parms
[15].items
) { /* -servers */
1376 struct cmd_item
*ip
;
1377 char *ap
[MAXSERVERS
+ 2];
1381 for (ip
= as
->parms
[15].items
, i
= 2; ip
; ip
= ip
->next
, i
++)
1383 code
= ubik_ParseClientList(i
, ap
, serverList
);
1385 afs_com_err(whoami
, code
, "could not parse server list");
1388 ka_ExplicitCell(cell
, serverList
);
1391 noauth
= (as
->parms
[16].items
? 1 : 0); /* -noauth */
1396 token
.ticketLen
= 0; /* in case there are no tokens */
1397 if (!noauth
) { /* Will prompt for a password */
1398 /* first see if there's already an admin ticket */
1400 ka_GetAdminToken(0, 0, cell
, 0, KA_SIXHOURS
, &token
,
1402 if (code
) { /* if not then get key and try again */
1403 if (as
->parms
[13].items
) { /* if password specified */
1404 strncpy(passwd
, as
->parms
[13].items
->data
, sizeof(passwd
));
1405 memset(as
->parms
[13].items
->data
, 0,
1406 strlen(as
->parms
[13].items
->data
));
1408 char msg
[MAXKTCNAMELEN
+ 50];
1409 if (as
->parms
[12].items
)
1410 sprintf(msg
, "Administrator's (%s) Password: ", name
);
1412 sprintf(msg
, "Password for %s: ", name
);
1413 code
= UI_UTIL_read_pw_string(passwd
, sizeof(passwd
), msg
, 0);
1416 else if (strlen(passwd
) == 0)
1417 code
= KANULLPASSWORD
;
1419 afs_com_err(whoami
, code
, "reading password");
1423 ka_StringToKey(passwd
, cell
, &key
);
1425 ka_GetAdminToken(name
, instance
, cell
, &key
, KA_SIXHOURS
,
1426 &token
, 0 /* !new */ );
1427 if (code
== KABADREQUEST
) {
1428 DES_string_to_key(passwd
, ktc_to_cblockptr(&key
));
1430 ka_GetAdminToken(name
, instance
, cell
, &key
, KA_SIXHOURS
,
1431 &token
, 0 /* !new */ );
1433 if ((code
== KABADREQUEST
) && (strlen(passwd
) > 8)) {
1434 /* try with only the first 8 characters incase they set
1435 * their password with an old style passwd program. */
1437 ka_StringToKey(passwd
, cell
, &key
);
1439 ka_GetAdminToken(name
, instance
, cell
, &key
, KA_SIXHOURS
,
1440 &token
, 0 /* !new */ );
1443 "Warning: you have typed a password longer than 8 characters, but only the\n");
1445 "first 8 characters were actually significant. If you change your password\n");
1447 "again this warning message will go away.\n");
1454 reason
= "password was incorrect";
1457 reason
= "Authentication Server was unavailable";
1460 reason
= (char *)afs_error_message(code
);
1463 "%s: Auth. as %s to AuthServer failed: %s\nProceeding w/o authentication\n",
1464 whoami
, PrintedName(name
, instance
, cell
), reason
);
1466 /* get an Authentication token while were at it. */
1467 if (ka_CellToRealm(cell
, realm
, 0) != 0)
1469 strcpy(auth_server
.name
, KA_TGS_NAME
);
1470 strcpy(auth_server
.instance
, realm
);
1471 strcpy(auth_server
.cell
, cell
);
1473 (&auth_server
, &auth_token
, sizeof(struct ktc_token
),
1476 ka_GetAuthToken(name
, instance
, cell
, &key
,
1477 MAXKTCTICKETLIFETIME
, (afs_int32
*) 0
1478 /*Don't need pwd expiration info here */
1480 if (acode
&& (acode
!= code
)) /* codes are usually the same */
1481 afs_com_err(whoami
, code
,
1482 "getting Authentication token for %s",
1483 PrintedName(name
, instance
, cell
));
1485 memset(&key
, 0, sizeof(key
));
1489 pToken
= ((token
.ticketLen
== 0) ? 0 : &token
);
1490 code
= ka_AuthServerConn(cell
, KA_MAINTENANCE_SERVICE
, pToken
, &conn
);
1491 if (code
&& pToken
) {
1492 afs_com_err(whoami
, code
,
1493 "connecting to AuthServer: now trying w/o authentication");
1494 code
= ka_AuthServerConn(cell
, KA_MAINTENANCE_SERVICE
, 0, &conn
);
1496 afs_com_err(whoami
, code
,
1497 "making unauthenticated connection to AuthServer");
1500 afs_com_err(whoami
, code
,
1501 "Couldn't establish connection to Authentication Server");
1505 /* now default unspecified password by prompting from terminal */
1506 if (as
->nParms
>= 12)
1507 for (i
= 0; i
< 12; i
++)
1508 if (as
->parms
[i
].name
&& (as
->parms
[i
].items
== 0)) {
1509 char *p
= as
->parms
[i
].name
; /* parameter name */
1510 int l
= strlen(p
); /* length of name */
1511 /* does parameter end in "password" */
1512 if (strcmp(p
+ (l
- 8), "password") == 0) {
1514 char password
[BUFSIZ
];
1515 struct cmd_item
*ip
;
1519 code
= UI_UTIL_read_pw_string(password
, sizeof(password
), msg
, 1);
1522 else if (strlen(password
) == 0)
1523 code
= KANULLPASSWORD
;
1525 afs_com_err(whoami
, code
, "prompting for %s", p
+ 1);
1528 ip
= malloc(sizeof(struct cmd_item
));
1529 ip
->data
= strdup(password
);
1531 as
->parms
[i
].items
= ip
;
1534 if (!conn
) { /* if all else fails... */
1535 code
= NoAuth(0, 0); /* get unauthenticated conn */
1542 /* These are some helpful command that deal with the cache managers tokens. */
1545 ForgetTicket(struct cmd_syndesc
*as
, void *arock
)
1550 struct ktc_principal server
;
1552 if (as
->parms
[0].items
) {
1553 char *name
= as
->parms
[0].items
->data
;
1555 ka_ParseLoginName(name
, server
.name
, server
.instance
,
1558 afs_com_err(whoami
, code
, "couldn't interpret name '%s'", name
);
1561 if (server
.cell
[0] == 0) {
1562 if (code
= DefaultCell())
1564 strcpy(server
.cell
, cell
);
1566 code
= ka_ExpandCell(server
.cell
, server
.cell
, 0 /*local */ );
1568 afs_com_err(whoami
, code
, "Can't expand cell name");
1572 code
= ktc_ForgetToken(&server
);
1574 afs_com_err(whoami
, code
, "couldn't remove tokens for %s",
1575 PrintedPrincipal(&server
));
1579 if (!as
->parms
[1].items
) {
1580 fprintf(stderr
, "Must specify server name or -all\n");
1583 code
= ktc_ForgetAllTokens();
1585 afs_com_err(whoami
, code
, "couldn't delete all tokens");
1590 code
= ktc_ForgetAllTokens();
1592 afs_com_err(whoami
, code
, "couldn't delete all tokens");
1599 ListTickets(struct cmd_syndesc
*as
, void *arock
)
1602 int index
, newIndex
;
1603 struct ktc_principal server
;
1606 if (as
->parms
[1].items
)
1608 if (as
->parms
[0].items
) {
1609 char *name
= as
->parms
[0].items
->data
;
1611 ka_ParseLoginName(name
, server
.name
, server
.instance
,
1614 afs_com_err(whoami
, code
, "couldn't interpret name '%s'", name
);
1617 if (server
.cell
[0] == 0) {
1618 if ((code
= DefaultCell()))
1620 strcpy(server
.cell
, cell
);
1622 code
= ka_ExpandCell(server
.cell
, server
.cell
, 0 /*local */ );
1624 afs_com_err(whoami
, code
, "Can't expand cell name");
1628 code
= ListTicket(&server
, verbose
);
1630 for (index
= 0;; index
= newIndex
) {
1631 code
= ktc_ListTokens(index
, &newIndex
, &server
);
1633 if (code
== KTC_NOENT
)
1634 code
= 0; /* end of list */
1637 code
= ListTicket(&server
, verbose
);
1643 add_std_args(struct cmd_syndesc
*ts
)
1646 /* 12 */ cmd_AddParm(ts
, "-admin_username", CMD_SINGLE
, CMD_OPTIONAL
,
1647 "admin principal to use for authentication");
1648 /* 13 */ cmd_AddParm(ts
, "-password_for_admin", CMD_SINGLE
, CMD_OPTIONAL
,
1650 /* 14 */ cmd_AddParm(ts
, "-cell", CMD_SINGLE
, CMD_OPTIONAL
, "cell name");
1651 /* 15 */ cmd_AddParm(ts
, "-servers", CMD_LIST
, CMD_OPTIONAL
,
1652 "explicit list of authentication servers");
1653 /* 16 */ cmd_AddParm(ts
, "-noauth", CMD_FLAG
, CMD_OPTIONAL
,
1654 "don't authenticate");
1658 ka_AdminInteractive(int cmd_argc
, char *cmd_argv
[])
1661 struct cmd_syndesc
*ts
;
1667 strncpy(myName
, *cmd_argv
, 509);
1669 cmd_SetBeforeProc(MyBeforeProc
, NULL
);
1670 cmd_SetAfterProc(MyAfterProc
, NULL
);
1672 ts
= cmd_CreateSyntax("interactive", Interactive
, NULL
, 0,
1673 "enter interactive mode");
1676 cmd_CreateSyntax("noauthentication", NoAuth
, NULL
, 0,
1677 "connect to AuthServer w/o using token");
1679 ts
= cmd_CreateSyntax("list", ListUsers
, NULL
, 0,
1680 "list all users in database");
1681 cmd_AddParm(ts
, "-long", CMD_FLAG
, CMD_OPTIONAL
,
1682 "show detailed info about each user");
1683 cmd_AddParm(ts
, "-showadmin", CMD_FLAG
, CMD_OPTIONAL
,
1684 "show all cell administrators");
1685 cmd_AddParm(ts
, "-showkey", CMD_FLAG
, CMD_OPTIONAL
,
1686 "show the user's actual key rather than the checksum");
1688 cmd_CreateAlias(ts
, "ls");
1690 ts
= cmd_CreateSyntax("examine", ExamineUser
, NULL
, 0,
1691 "examine the entry for a user");
1692 cmd_AddParm(ts
, "-name", CMD_SINGLE
, 0, "name of user");
1693 cmd_AddParm(ts
, "-showkey", CMD_FLAG
, CMD_OPTIONAL
,
1694 "show the user's actual key rather than the checksum");
1697 ts
= cmd_CreateSyntax("create", CreateUser
, NULL
, 0,
1698 "create an entry for a user");
1699 cmd_AddParm(ts
, "-name", CMD_SINGLE
, 0, "name of user");
1700 cmd_AddParm(ts
, "-initial_password", CMD_SINGLE
, CMD_OPTIONAL
,
1701 "initial password");
1704 ts
= cmd_CreateSyntax("delete", DeleteUser
, NULL
, 0, "delete a user");
1705 cmd_AddParm(ts
, "-name", CMD_SINGLE
, 0, "name of user");
1707 cmd_CreateAlias(ts
, "rm");
1709 ts
= cmd_CreateSyntax("setfields", SetFields
, NULL
, 0,
1710 "set various fields in a user's entry");
1711 cmd_AddParm(ts
, "-name", CMD_SINGLE
, 0, "name of user");
1712 cmd_AddParm(ts
, "-flags", CMD_SINGLE
, CMD_OPTIONAL
,
1713 "hex flag value or flag name expression");
1714 cmd_AddParm(ts
, "-expiration", CMD_SINGLE
, CMD_OPTIONAL
,
1715 "date of account expiration");
1716 cmd_AddParm(ts
, "-lifetime", CMD_SINGLE
, CMD_OPTIONAL
,
1717 "maximum ticket lifetime");
1718 cmd_AddParm(ts
, "-pwexpires", CMD_SINGLE
, CMD_OPTIONAL
,
1719 "number days password is valid ([0..254])");
1720 cmd_AddParm(ts
, "-reuse", CMD_SINGLE
, CMD_OPTIONAL
,
1721 "permit password reuse (yes/no)");
1722 cmd_AddParm(ts
, "-attempts", CMD_SINGLE
, CMD_OPTIONAL
,
1723 "maximum successive failed login tries ([0..254])");
1724 cmd_AddParm(ts
, "-locktime", CMD_SINGLE
, CMD_OPTIONAL
,
1725 "failure penalty [hh:mm or minutes]");
1727 cmd_AddParm(ts
, "-associates", CMD_SINGLE
, CMD_OPTIONAL
,
1728 "maximum associate instances");
1731 cmd_CreateAlias(ts
, "sf");
1734 ts
= cmd_CreateSyntax("unlock", Unlock
, NULL
, 0,
1735 "Enable authentication ID after max failed attempts exceeded");
1736 cmd_AddParm(ts
, "-name", CMD_SINGLE
, 0, "authentication ID");
1740 ts
= cmd_CreateSyntax("stringtokey", StringToKey
, NULL
, 0,
1741 "convert a string to a key");
1742 cmd_AddParm(ts
, "-string", CMD_SINGLE
, 0, "password string");
1743 cmd_AddParm(ts
, "-cell", CMD_SINGLE
, CMD_OPTIONAL
, "cell name");
1745 ts
= cmd_CreateSyntax("setpassword", SetPassword
, NULL
, 0,
1746 "set a user's password");
1747 cmd_AddParm(ts
, "-name", CMD_SINGLE
, 0, "name of user");
1748 cmd_AddParm(ts
, "-new_password", CMD_SINGLE
, CMD_OPTIONAL
,
1751 cmd_AddParm(ts
, "-kvno", CMD_SINGLE
, CMD_OPTIONAL
, "key version number");
1753 cmd_CreateAlias(ts
, "sp");
1754 #ifdef CMD_PARSER_AMBIG_FIX
1755 cmd_CreateAlias(ts
, "setpasswd");
1758 ts
= cmd_CreateSyntax("setkey", SetPassword
, NULL
, CMD_HIDDEN
, "set a user's key");
1759 cmd_AddParm(ts
, "-name", CMD_SINGLE
, 0, "name of user");
1761 cmd_AddParm(ts
, "-new_key", CMD_SINGLE
, 0, "eight byte new key");
1763 cmd_AddParm(ts
, "-kvno", CMD_SINGLE
, CMD_OPTIONAL
, "key version number");
1766 ts
= cmd_CreateSyntax("getpassword", GetPassword
, NULL
, CMD_HIDDEN
, "get a user's password");
1767 cmd_AddParm(ts
, "-name", CMD_SINGLE
, 0, "name of user");
1768 /* don't take standard args */
1769 /* add_std_args (ts); */
1770 #ifdef CMD_PARSER_AMBIG_FIX
1771 cmd_CreateAlias(ts
, "getpasswd");
1774 ts
= cmd_CreateSyntax("getrandomkey", GetRandomKey
, NULL
, CMD_HIDDEN
, "get a random key");
1777 ts
= cmd_CreateSyntax("getticket", GetTicket
, NULL
, CMD_HIDDEN
, "get a ticket for a specific server");
1778 cmd_AddParm(ts
, "-name", CMD_SINGLE
, 0, "name of server");
1779 cmd_AddParm(ts
, "-lifetime", CMD_SINGLE
, CMD_OPTIONAL
, "ticket lifetime");
1782 ts
= cmd_CreateSyntax("statistics", Statistics
, NULL
, 0,
1783 "show statistics for AuthServer");
1786 ts
= cmd_CreateSyntax("debuginfo", DebugInfo
, NULL
, CMD_HIDDEN
, "show debugging info from AuthServer");
1787 cmd_AddParm(ts
, "-hostname", CMD_SINGLE
, CMD_OPTIONAL
,
1788 "authentication server host name");
1791 ts
= cmd_CreateSyntax("forgetticket", ForgetTicket
, NULL
, 0,
1792 "delete user's tickets");
1794 cmd_AddParm(ts
, "-name", CMD_SINGLE
, (CMD_OPTIONAL
| CMD_HIDE
),
1797 cmd_AddParm(ts
, "-all", CMD_FLAG
, CMD_OPTIONAL
, "delete all tickets");
1799 ts
= cmd_CreateSyntax("listtickets", ListTickets
, NULL
, 0,
1800 "show all cache manager tickets");
1801 cmd_AddParm(ts
, "-name", CMD_SINGLE
, CMD_OPTIONAL
, "name of server");
1802 cmd_AddParm(ts
, "-long", CMD_FLAG
, CMD_OPTIONAL
,
1803 "show session key and ticket");
1805 cmd_CreateSyntax("quit", Quit
, NULL
, 0, "exit program");
1808 conn
= 0; /* no connection yet */
1809 zero_argc
= cmd_argc
;
1810 zero_argv
= cmd_argv
;
1812 strcpy(whoami
, "kas");
1814 if ((code
= cmd_Dispatch(cmd_argc
, cmd_argv
))) {
1823 s
= fgets(line
, sizeof(line
), stdin
);
1825 return 0; /* EOF on input */
1826 for (i
= strlen(line
) - 1; i
>= 0 && isspace(line
[i
]); i
--)
1829 continue; /* blank line */
1832 cmd_ParseLine(line
, argv
, &argc
, sizeof(argv
) / sizeof(argv
[0]));
1834 afs_com_err(whoami
, code
, "parsing line: '%s'", line
);
1837 code
= cmd_Dispatch(argc
, argv
);