146731Skarels /*
246731Skarels * $Source: /mit/kerberos/src/admin/RCS/kdb_edit.c,v $
346731Skarels * $Author: jtkohl $
446731Skarels *
546731Skarels * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
646731Skarels * of Technology.
746731Skarels *
846731Skarels * For copying and distribution information, please see the file
946731Skarels * <mit-copyright.h>.
1046731Skarels *
1146731Skarels * This routine changes the Kerberos encryption keys for principals,
1246731Skarels * i.e., users or services.
1346731Skarels */
1446731Skarels
1546731Skarels /*
1646731Skarels * exit returns 0 ==> success -1 ==> error
1746731Skarels */
1846731Skarels
1946731Skarels #ifndef lint
2046731Skarels static char rcsid_kdb_edit_c[] =
2146731Skarels "$Header: kdb_edit.c,v 4.1 89/03/23 09:58:18 jtkohl Exp $";
2246731Skarels #endif lint
2346731Skarels
2446731Skarels #include <mit-copyright.h>
2546731Skarels
2646731Skarels #include <stdio.h>
2746731Skarels #include <signal.h>
2846731Skarels #include <errno.h>
2946731Skarels #include <strings.h>
3046731Skarels #include <sys/ioctl.h>
3146731Skarels #include <sys/file.h>
3246731Skarels #include "time.h"
3346731Skarels #include <des.h>
3446731Skarels #include <krb.h>
3546731Skarels #include <krb_db.h>
3646731Skarels /* MKEYFILE is now defined in kdc.h */
3746731Skarels #include <kdc.h>
3846731Skarels
3946731Skarels extern char *errmsg();
4046731Skarels extern int errno;
4146731Skarels extern char *strcpy();
4246731Skarels
4346731Skarels void sig_exit();
4446731Skarels
4546731Skarels char prog[32];
4646731Skarels char *progname = prog;
4746731Skarels int nflag = 0;
4846731Skarels int cflag;
4946731Skarels int lflag;
5046731Skarels int uflag;
5146731Skarels int debug;
5246731Skarels extern kerb_debug;
5346731Skarels extern char *sys_errlist[];
5446731Skarels
5546731Skarels Key_schedule KS;
5646731Skarels C_Block new_key;
5746731Skarels unsigned char *input;
5846731Skarels
5946731Skarels unsigned char *ivec;
6046731Skarels int i, j;
6146731Skarels int more;
6246731Skarels
6346731Skarels char *in_ptr;
6446731Skarels char input_name[ANAME_SZ];
6546731Skarels char input_instance[INST_SZ];
6646731Skarels char input_string[ANAME_SZ];
6746731Skarels
6846731Skarels #define MAX_PRINCIPAL 10
6946731Skarels Principal principal_data[MAX_PRINCIPAL];
7046731Skarels
7146731Skarels static Principal old_principal;
7246731Skarels static Principal default_princ;
7346731Skarels
7446731Skarels static C_Block master_key;
7546731Skarels static C_Block session_key;
7646731Skarels static Key_schedule master_key_schedule;
7746731Skarels static char pw_str[255];
7846731Skarels static long master_key_version;
7946731Skarels
80*46735Skarels #define gets(buf) _gets(buf, sizeof(buf)) /* hack */
81*46735Skarels
82*46735Skarels char *
_gets(p,n)83*46735Skarels _gets(p, n)
84*46735Skarels char *p;
85*46735Skarels int n;
86*46735Skarels {
87*46735Skarels char *rv, *fgets();
88*46735Skarels
89*46735Skarels if ((rv = fgets(p, n, stdin)) == NULL)
90*46735Skarels return (rv);
91*46735Skarels if (p = index(p, '\n'))
92*46735Skarels *p = '\0';
93*46735Skarels return (rv);
94*46735Skarels }
95*46735Skarels
main(argc,argv)9646731Skarels main(argc, argv)
9746731Skarels int argc;
9846731Skarels char *argv[];
9946731Skarels
10046731Skarels {
10146731Skarels /* Local Declarations */
10246731Skarels
10346731Skarels long n;
10446731Skarels
10546731Skarels prog[sizeof prog - 1] = '\0'; /* make sure terminated */
10646731Skarels strncpy(prog, argv[0], sizeof prog - 1); /* salt away invoking
10746731Skarels * program */
10846731Skarels
10946731Skarels /* Assume a long is four bytes */
11046731Skarels if (sizeof(long) != 4) {
11146731Skarels fprintf(stdout, "%s: size of long is %d.\n", sizeof(long), prog);
11246731Skarels exit(-1);
11346731Skarels }
11446731Skarels /* Assume <=32 signals */
11546731Skarels if (NSIG > 32) {
11646731Skarels fprintf(stderr, "%s: more than 32 signals defined.\n", prog);
11746731Skarels exit(-1);
11846731Skarels }
11946731Skarels while (--argc > 0 && (*++argv)[0] == '-')
12046731Skarels for (i = 1; argv[0][i] != '\0'; i++) {
12146731Skarels switch (argv[0][i]) {
12246731Skarels
12346731Skarels /* debug flag */
12446731Skarels case 'd':
12546731Skarels debug = 1;
12646731Skarels continue;
12746731Skarels
12846731Skarels /* debug flag */
12946731Skarels case 'l':
13046731Skarels kerb_debug |= 1;
13146731Skarels continue;
13246731Skarels
13346731Skarels case 'n': /* read MKEYFILE for master key */
13446731Skarels nflag = 1;
13546731Skarels continue;
13646731Skarels
13746731Skarels default:
13846731Skarels fprintf(stderr, "%s: illegal flag \"%c\"\n",
13946731Skarels progname, argv[0][i]);
14046731Skarels Usage(); /* Give message and die */
14146731Skarels }
14246731Skarels };
14346731Skarels
14446731Skarels fprintf(stdout, "Opening database...\n");
14546731Skarels fflush(stdout);
14646731Skarels kerb_init();
14746731Skarels if (argc > 0) {
14846731Skarels if (kerb_db_set_name(*argv) != 0) {
14946731Skarels fprintf(stderr, "Could not open altername database name\n");
15046731Skarels exit(1);
15146731Skarels }
15246731Skarels }
15346731Skarels
15446731Skarels #ifdef notdef
15546731Skarels no_core_dumps(); /* diddle signals to avoid core dumps! */
15646731Skarels
15746731Skarels /* ignore whatever is reasonable */
15846731Skarels signal(SIGHUP, SIG_IGN);
15946731Skarels signal(SIGINT, SIG_IGN);
16046731Skarels signal(SIGTSTP, SIG_IGN);
16146731Skarels
16246731Skarels #endif
16346731Skarels
16446731Skarels if (kdb_get_master_key ((nflag == 0),
16546731Skarels master_key, master_key_schedule) != 0) {
16646731Skarels fprintf (stdout, "Couldn't read master key.\n");
16746731Skarels fflush (stdout);
16846731Skarels exit (-1);
16946731Skarels }
17046731Skarels
17146731Skarels if ((master_key_version = kdb_verify_master_key(master_key,
17246731Skarels master_key_schedule,
17346731Skarels stdout)) < 0)
17446731Skarels exit (-1);
17546731Skarels
17646731Skarels /* lookup the default values */
17746731Skarels n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST,
17846731Skarels &default_princ, 1, &more);
17946731Skarels if (n != 1) {
18046731Skarels fprintf(stderr,
18146731Skarels "%s: Kerberos error on default value lookup, %d found.\n",
18246731Skarels progname, n);
18346731Skarels exit(-1);
18446731Skarels }
18546731Skarels fprintf(stdout, "Previous or default values are in [brackets] ,\n");
18646731Skarels fprintf(stdout, "enter return to leave the same, or new value.\n");
18746731Skarels
18846731Skarels while (change_principal()) {
18946731Skarels }
19046731Skarels
19146731Skarels cleanup();
19246731Skarels }
19346731Skarels
change_principal()19446731Skarels change_principal()
19546731Skarels {
19646731Skarels static char temp[255];
19746731Skarels int creating = 0;
19846731Skarels int editpw = 0;
19946731Skarels int changed = 0;
20046731Skarels long temp_long;
20146731Skarels int n;
20246731Skarels struct tm *tp, edate, *localtime();
20346731Skarels long maketime();
20446731Skarels
20546731Skarels fprintf(stdout, "\nPrincipal name: ");
20646731Skarels fflush(stdout);
20746731Skarels if (!gets(input_name) || *input_name == '\0')
20846731Skarels return 0;
20946731Skarels fprintf(stdout, "Instance: ");
21046731Skarels fflush(stdout);
21146731Skarels /* instance can be null */
21246731Skarels gets(input_instance);
21346731Skarels j = kerb_get_principal(input_name, input_instance, principal_data,
21446731Skarels MAX_PRINCIPAL, &more);
21546731Skarels if (!j) {
216*46735Skarels fprintf(stdout, "%s.%s not found, Create [y] ? ", input_name,
217*46735Skarels input_instance);
21846731Skarels gets(temp); /* Default case should work, it didn't */
21946731Skarels if (temp[0] != 'y' && temp[0] != 'Y' && temp[0] != '\0')
22046731Skarels return -1;
22146731Skarels /* make a new principal, fill in defaults */
22246731Skarels j = 1;
22346731Skarels creating = 1;
22446731Skarels strcpy(principal_data[0].name, input_name);
22546731Skarels strcpy(principal_data[0].instance, input_instance);
22646731Skarels principal_data[0].old = NULL;
22746731Skarels principal_data[0].exp_date = default_princ.exp_date;
22846731Skarels principal_data[0].max_life = default_princ.max_life;
22946731Skarels principal_data[0].attributes = default_princ.attributes;
23046731Skarels principal_data[0].kdc_key_ver = (unsigned char) master_key_version;
23146731Skarels principal_data[0].key_version = 0; /* bumped up later */
23246731Skarels }
23346731Skarels tp = localtime(&principal_data[0].exp_date);
23446731Skarels (void) sprintf(principal_data[0].exp_date_txt, "%4d-%02d-%02d",
23546731Skarels tp->tm_year > 1900 ? tp->tm_year : tp->tm_year + 1900,
23646731Skarels tp->tm_mon + 1, tp->tm_mday); /* January is 0, not 1 */
23746731Skarels for (i = 0; i < j; i++) {
23846731Skarels for (;;) {
23946731Skarels fprintf(stdout,
240*46735Skarels "Principal: %s, Instance: %s, kdc_key_ver: %d\n",
24146731Skarels principal_data[i].name, principal_data[i].instance,
24246731Skarels principal_data[i].kdc_key_ver);
24346731Skarels editpw = 1;
24446731Skarels changed = 0;
24546731Skarels if (!creating) {
24646731Skarels /*
24746731Skarels * copy the existing data so we can use the old values
24846731Skarels * for the qualifier clause of the replace
24946731Skarels */
25046731Skarels principal_data[i].old = (char *) &old_principal;
25146731Skarels bcopy(&principal_data[i], &old_principal,
25246731Skarels sizeof(old_principal));
253*46735Skarels printf("Change password [n] ? ");
25446731Skarels gets(temp);
25546731Skarels if (strcmp("y", temp) && strcmp("Y", temp))
25646731Skarels editpw = 0;
25746731Skarels }
25846731Skarels /* password */
25946731Skarels if (editpw) {
26046731Skarels #ifdef NOENCRYPTION
26146731Skarels placebo_read_pw_string(pw_str, sizeof pw_str,
262*46735Skarels "New Password: ", TRUE);
26346731Skarels #else
26446731Skarels des_read_pw_string(pw_str, sizeof pw_str,
265*46735Skarels "New Password: ", TRUE);
26646731Skarels #endif
267*46735Skarels if (pw_str[0] == '\0' || !strcmp(pw_str, "RANDOM")) {
268*46735Skarels printf("Random password [y] ? ");
26946731Skarels gets(temp);
27046731Skarels if (!strcmp("n", temp) || !strcmp("N", temp)) {
27146731Skarels /* no, use literal */
27246731Skarels #ifdef NOENCRYPTION
27346731Skarels bzero(new_key, sizeof(C_Block));
27446731Skarels new_key[0] = 127;
27546731Skarels #else
27646731Skarels string_to_key(pw_str, new_key);
27746731Skarels #endif
27846731Skarels bzero(pw_str, sizeof pw_str); /* "RANDOM" */
27946731Skarels } else {
28046731Skarels #ifdef NOENCRYPTION
28146731Skarels bzero(new_key, sizeof(C_Block));
28246731Skarels new_key[0] = 127;
28346731Skarels #else
28446731Skarels random_key(new_key); /* yes, random */
28546731Skarels #endif
28646731Skarels bzero(pw_str, sizeof pw_str);
28746731Skarels }
28846731Skarels } else if (!strcmp(pw_str, "NULL")) {
28946731Skarels printf("\nNull Key [y] ? ");
29046731Skarels gets(temp);
29146731Skarels if (!strcmp("n", temp) || !strcmp("N", temp)) {
29246731Skarels /* no, use literal */
29346731Skarels #ifdef NOENCRYPTION
29446731Skarels bzero(new_key, sizeof(C_Block));
29546731Skarels new_key[0] = 127;
29646731Skarels #else
29746731Skarels string_to_key(pw_str, new_key);
29846731Skarels #endif
29946731Skarels bzero(pw_str, sizeof pw_str); /* "NULL" */
30046731Skarels } else {
30146731Skarels
30246731Skarels principal_data[i].key_low = 0;
30346731Skarels principal_data[i].key_high = 0;
30446731Skarels goto null_key;
30546731Skarels }
30646731Skarels } else {
30746731Skarels #ifdef NOENCRYPTION
30846731Skarels bzero(new_key, sizeof(C_Block));
30946731Skarels new_key[0] = 127;
31046731Skarels #else
31146731Skarels string_to_key(pw_str, new_key);
31246731Skarels #endif
31346731Skarels bzero(pw_str, sizeof pw_str);
31446731Skarels }
31546731Skarels
31646731Skarels /* seal it under the kerberos master key */
31746731Skarels kdb_encrypt_key (new_key, new_key,
31846731Skarels master_key, master_key_schedule,
31946731Skarels ENCRYPT);
32046731Skarels bcopy(new_key, &principal_data[i].key_low, 4);
32146731Skarels bcopy(((long *) new_key) + 1,
32246731Skarels &principal_data[i].key_high, 4);
32346731Skarels bzero(new_key, sizeof(new_key));
32446731Skarels null_key:
32546731Skarels /* set master key version */
32646731Skarels principal_data[i].kdc_key_ver =
32746731Skarels (unsigned char) master_key_version;
32846731Skarels /* bump key version # */
32946731Skarels principal_data[i].key_version++;
33046731Skarels fprintf(stdout,
33146731Skarels "\nPrincipal's new key version = %d\n",
33246731Skarels principal_data[i].key_version);
33346731Skarels fflush(stdout);
33446731Skarels changed = 1;
33546731Skarels }
33646731Skarels /* expiration date */
33746731Skarels fprintf(stdout, "Expiration date (enter yyyy-mm-dd) [ %s ] ? ",
33846731Skarels principal_data[i].exp_date_txt);
33946731Skarels zaptime(&edate);
34046731Skarels while (gets(temp) && ((n = strlen(temp)) >
34146731Skarels sizeof(principal_data[0].exp_date_txt))) {
34246731Skarels bad_date:
34346731Skarels fprintf(stdout, "\07\07Date Invalid\n");
34446731Skarels fprintf(stdout,
34546731Skarels "Expiration date (enter yyyy-mm-dd) [ %s ] ? ",
34646731Skarels principal_data[i].exp_date_txt);
34746731Skarels zaptime(&edate);
34846731Skarels }
34946731Skarels
35046731Skarels if (*temp) {
35146731Skarels if (sscanf(temp, "%d-%d-%d", &edate.tm_year,
35246731Skarels &edate.tm_mon, &edate.tm_mday) != 3)
35346731Skarels goto bad_date;
35446731Skarels (void) strcpy(principal_data[i].exp_date_txt, temp);
35546731Skarels edate.tm_mon--; /* January is 0, not 1 */
35646731Skarels edate.tm_hour = 23; /* nearly midnight at the end of the */
35746731Skarels edate.tm_min = 59; /* specified day */
35846731Skarels edate.tm_zon = 1; /* local time, not GMT */
35946731Skarels if (!(principal_data[i].exp_date = maketime(&edate)))
36046731Skarels goto bad_date;
36146731Skarels changed = 1;
36246731Skarels }
36346731Skarels
36446731Skarels /* maximum lifetime */
36546731Skarels fprintf(stdout, "Max ticket lifetime (*5 minutes) [ %d ] ? ",
36646731Skarels principal_data[i].max_life);
36746731Skarels while (gets(temp) && *temp) {
36846731Skarels if (sscanf(temp, "%d", &temp_long) != 1)
36946731Skarels goto bad_life;
37046731Skarels if (temp_long > 255 || (temp_long < 0)) {
37146731Skarels bad_life:
37246731Skarels fprintf(stdout, "\07\07Invalid, choose 0-255\n");
37346731Skarels fprintf(stdout,
37446731Skarels "Max ticket lifetime (*5 minutes) [ %d ] ? ",
37546731Skarels principal_data[i].max_life);
37646731Skarels continue;
37746731Skarels }
37846731Skarels changed = 1;
37946731Skarels /* dont clobber */
38046731Skarels principal_data[i].max_life = (unsigned short) temp_long;
38146731Skarels break;
38246731Skarels }
38346731Skarels
38446731Skarels /* attributes */
38546731Skarels fprintf(stdout, "Attributes [ %d ] ? ",
38646731Skarels principal_data[i].attributes);
38746731Skarels while (gets(temp) && *temp) {
38846731Skarels if (sscanf(temp, "%d", &temp_long) != 1)
38946731Skarels goto bad_att;
39046731Skarels if (temp_long > 65535 || (temp_long < 0)) {
39146731Skarels bad_att:
39246731Skarels fprintf(stdout, "\07\07Invalid, choose 0-65535\n");
39346731Skarels fprintf(stdout, "Attributes [ %d ] ? ",
39446731Skarels principal_data[i].attributes);
39546731Skarels continue;
39646731Skarels }
39746731Skarels changed = 1;
39846731Skarels /* dont clobber */
39946731Skarels principal_data[i].attributes =
40046731Skarels (unsigned short) temp_long;
40146731Skarels break;
40246731Skarels }
40346731Skarels
40446731Skarels /*
40546731Skarels * remaining fields -- key versions and mod info, should
40646731Skarels * not be directly manipulated
40746731Skarels */
40846731Skarels if (changed) {
40946731Skarels if (kerb_put_principal(&principal_data[i], 1)) {
41046731Skarels fprintf(stdout,
41146731Skarels "\nError updating Kerberos database");
41246731Skarels } else {
41346731Skarels fprintf(stdout, "Edit O.K.");
41446731Skarels }
41546731Skarels } else {
41646731Skarels fprintf(stdout, "Unchanged");
41746731Skarels }
41846731Skarels
41946731Skarels
42046731Skarels bzero(&principal_data[i].key_low, 4);
42146731Skarels bzero(&principal_data[i].key_high, 4);
42246731Skarels fflush(stdout);
42346731Skarels break;
42446731Skarels }
42546731Skarels }
42646731Skarels if (more) {
42746731Skarels fprintf(stdout, "\nThere were more tuples found ");
42846731Skarels fprintf(stdout, "than there were space for");
42946731Skarels }
43046731Skarels return 1;
43146731Skarels }
43246731Skarels
43346731Skarels
no_core_dumps()43446731Skarels no_core_dumps()
43546731Skarels {
43646731Skarels
43746731Skarels signal(SIGQUIT, sig_exit);
43846731Skarels signal(SIGILL, sig_exit);
43946731Skarels signal(SIGTRAP, sig_exit);
44046731Skarels signal(SIGIOT, sig_exit);
44146731Skarels signal(SIGEMT, sig_exit);
44246731Skarels signal(SIGFPE, sig_exit);
44346731Skarels signal(SIGBUS, sig_exit);
44446731Skarels signal(SIGSEGV, sig_exit);
44546731Skarels signal(SIGSYS, sig_exit);
44646731Skarels }
44746731Skarels
44846731Skarels void
sig_exit(sig,code,scp)44946731Skarels sig_exit(sig, code, scp)
45046731Skarels int sig, code;
45146731Skarels struct sigcontext *scp;
45246731Skarels {
45346731Skarels cleanup();
45446731Skarels fprintf(stderr,
45546731Skarels "\nSignal caught, sig = %d code = %d old pc = 0x%X \nexiting",
45646731Skarels sig, code, scp->sc_pc);
45746731Skarels exit(-1);
45846731Skarels }
45946731Skarels
46046731Skarels
cleanup()46146731Skarels cleanup()
46246731Skarels {
46346731Skarels
46446731Skarels bzero(master_key, sizeof(master_key));
46546731Skarels bzero(session_key, sizeof(session_key));
46646731Skarels bzero(master_key_schedule, sizeof(master_key_schedule));
46746731Skarels bzero(principal_data, sizeof(principal_data));
46846731Skarels bzero(new_key, sizeof(new_key));
46946731Skarels bzero(pw_str, sizeof(pw_str));
47046731Skarels }
Usage()47146731Skarels Usage()
47246731Skarels {
47346731Skarels fprintf(stderr, "Usage: %s [-n]\n", progname);
47446731Skarels exit(1);
47546731Skarels }
47646731Skarels
47746731Skarels /* zaptime code taken from: */
47846731Skarels /*
47946731Skarels * PARTIME parse date/time string into a TM structure
48046731Skarels *
48146731Skarels * Usage:
48246731Skarels * #include "time.h" -- expanded tm structure
48346731Skarels * char *str; struct tm *tp;
48446731Skarels * partime(str,tp);
48546731Skarels * Returns:
48646731Skarels * 0 if parsing failed
48746731Skarels * else time values in specified TM structure (unspecified values
48846731Skarels * set to TMNULL)
48946731Skarels * Notes:
49046731Skarels * This code is quasi-public; it may be used freely in like software.
49146731Skarels * It is not to be sold, nor used in licensed software without
49246731Skarels * permission of the author.
49346731Skarels * For everyone's benefit, please report bugs and improvements!
49446731Skarels * Copyright 1980 by Ken Harrenstien, SRI International.
49546731Skarels * (ARPANET: KLH @ SRI)
49646731Skarels */
49746731Skarels
zaptime(atm)49846731Skarels zaptime(atm)
49946731Skarels register struct tm *atm;
50046731Skarels /* clears atm */
50146731Skarels {
50246731Skarels atm->tm_sec = TMNULL;
50346731Skarels atm->tm_min = TMNULL;
50446731Skarels atm->tm_hour = TMNULL;
50546731Skarels atm->tm_mday = TMNULL;
50646731Skarels atm->tm_mon = TMNULL;
50746731Skarels atm->tm_year = TMNULL;
50846731Skarels atm->tm_wday = TMNULL;
50946731Skarels atm->tm_yday = TMNULL;
51046731Skarels atm->tm_isdst = TMNULL;
51146731Skarels atm->tm_zon = TMNULL;
51246731Skarels atm->tm_ampm = TMNULL;
51346731Skarels }
514