|
|
1.1 root 1: /*
2: * $Source: /mit/kerberos/src/admin/RCS/kdb_edit.c,v $
3: * $Author: jtkohl $
4: *
5: * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
6: * of Technology.
7: *
8: * For copying and distribution information, please see the file
9: * <mit-copyright.h>.
10: *
11: * This routine changes the Kerberos encryption keys for principals,
12: * i.e., users or services.
13: */
14:
15: /*
16: * exit returns 0 ==> success -1 ==> error
17: */
18:
19: #ifndef lint
20: static char rcsid_kdb_edit_c[] =
21: "$Header: kdb_edit.c,v 4.1 89/03/23 09:58:18 jtkohl Exp $";
22: #endif lint
23:
24: #include <mit-copyright.h>
25:
26: #include <stdio.h>
27: #include <signal.h>
28: #include <errno.h>
29: #include <strings.h>
30: #include <sys/ioctl.h>
31: #include <sys/file.h>
32: #include "time.h"
33: #include <des.h>
34: #include <krb.h>
35: #include <krb_db.h>
36: /* MKEYFILE is now defined in kdc.h */
37: #include <kdc.h>
38:
39: extern char *errmsg();
40: extern int errno;
41: extern char *strcpy();
42:
43: void sig_exit();
44:
45: char prog[32];
46: char *progname = prog;
47: int nflag = 0;
48: int cflag;
49: int lflag;
50: int uflag;
51: int debug;
52: extern kerb_debug;
53: extern char *sys_errlist[];
54:
55: Key_schedule KS;
56: C_Block new_key;
57: unsigned char *input;
58:
59: unsigned char *ivec;
60: int i, j;
61: int more;
62:
63: char *in_ptr;
64: char input_name[ANAME_SZ];
65: char input_instance[INST_SZ];
66: char input_string[ANAME_SZ];
67:
68: #define MAX_PRINCIPAL 10
69: Principal principal_data[MAX_PRINCIPAL];
70:
71: static Principal old_principal;
72: static Principal default_princ;
73:
74: static C_Block master_key;
75: static C_Block session_key;
76: static Key_schedule master_key_schedule;
77: static char pw_str[255];
78: static long master_key_version;
79:
80: main(argc, argv)
81: int argc;
82: char *argv[];
83:
84: {
85: /* Local Declarations */
86:
87: long n;
88:
89: prog[sizeof prog - 1] = '\0'; /* make sure terminated */
90: strncpy(prog, argv[0], sizeof prog - 1); /* salt away invoking
91: * program */
92:
93: /* Assume a long is four bytes */
94: if (sizeof(long) != 4) {
95: fprintf(stdout, "%s: size of long is %d.\n", sizeof(long), prog);
96: exit(-1);
97: }
98: /* Assume <=32 signals */
99: if (NSIG > 32) {
100: fprintf(stderr, "%s: more than 32 signals defined.\n", prog);
101: exit(-1);
102: }
103: while (--argc > 0 && (*++argv)[0] == '-')
104: for (i = 1; argv[0][i] != '\0'; i++) {
105: switch (argv[0][i]) {
106:
107: /* debug flag */
108: case 'd':
109: debug = 1;
110: continue;
111:
112: /* debug flag */
113: case 'l':
114: kerb_debug |= 1;
115: continue;
116:
117: case 'n': /* read MKEYFILE for master key */
118: nflag = 1;
119: continue;
120:
121: default:
122: fprintf(stderr, "%s: illegal flag \"%c\"\n",
123: progname, argv[0][i]);
124: Usage(); /* Give message and die */
125: }
126: };
127:
128: fprintf(stdout, "Opening database...\n");
129: fflush(stdout);
130: kerb_init();
131: if (argc > 0) {
132: if (kerb_db_set_name(*argv) != 0) {
133: fprintf(stderr, "Could not open altername database name\n");
134: exit(1);
135: }
136: }
137:
138: #ifdef notdef
139: no_core_dumps(); /* diddle signals to avoid core dumps! */
140:
141: /* ignore whatever is reasonable */
142: signal(SIGHUP, SIG_IGN);
143: signal(SIGINT, SIG_IGN);
144: signal(SIGTSTP, SIG_IGN);
145:
146: #endif
147:
148: if (kdb_get_master_key ((nflag == 0),
149: master_key, master_key_schedule) != 0) {
150: fprintf (stdout, "Couldn't read master key.\n");
151: fflush (stdout);
152: exit (-1);
153: }
154:
155: if ((master_key_version = kdb_verify_master_key(master_key,
156: master_key_schedule,
157: stdout)) < 0)
158: exit (-1);
159:
160: /* lookup the default values */
161: n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST,
162: &default_princ, 1, &more);
163: if (n != 1) {
164: fprintf(stderr,
165: "%s: Kerberos error on default value lookup, %d found.\n",
166: progname, n);
167: exit(-1);
168: }
169: fprintf(stdout, "Previous or default values are in [brackets] ,\n");
170: fprintf(stdout, "enter return to leave the same, or new value.\n");
171:
172: while (change_principal()) {
173: }
174:
175: cleanup();
176: }
177:
178: change_principal()
179: {
180: static char temp[255];
181: int creating = 0;
182: int editpw = 0;
183: int changed = 0;
184: long temp_long;
185: int n;
186: struct tm *tp, edate, *localtime();
187: long maketime();
188:
189: fprintf(stdout, "\nPrincipal name: ");
190: fflush(stdout);
191: if (!gets(input_name) || *input_name == '\0')
192: return 0;
193: fprintf(stdout, "Instance: ");
194: fflush(stdout);
195: /* instance can be null */
196: gets(input_instance);
197: j = kerb_get_principal(input_name, input_instance, principal_data,
198: MAX_PRINCIPAL, &more);
199: if (!j) {
200: fprintf(stdout, "\n\07\07<Not found>, Create [y] ? ");
201: gets(temp); /* Default case should work, it didn't */
202: if (temp[0] != 'y' && temp[0] != 'Y' && temp[0] != '\0')
203: return -1;
204: /* make a new principal, fill in defaults */
205: j = 1;
206: creating = 1;
207: strcpy(principal_data[0].name, input_name);
208: strcpy(principal_data[0].instance, input_instance);
209: principal_data[0].old = NULL;
210: principal_data[0].exp_date = default_princ.exp_date;
211: principal_data[0].max_life = default_princ.max_life;
212: principal_data[0].attributes = default_princ.attributes;
213: principal_data[0].kdc_key_ver = (unsigned char) master_key_version;
214: principal_data[0].key_version = 0; /* bumped up later */
215: }
216: tp = localtime(&principal_data[0].exp_date);
217: (void) sprintf(principal_data[0].exp_date_txt, "%4d-%02d-%02d",
218: tp->tm_year > 1900 ? tp->tm_year : tp->tm_year + 1900,
219: tp->tm_mon + 1, tp->tm_mday); /* January is 0, not 1 */
220: for (i = 0; i < j; i++) {
221: for (;;) {
222: fprintf(stdout,
223: "\nPrincipal: %s, Instance: %s, kdc_key_ver: %d",
224: principal_data[i].name, principal_data[i].instance,
225: principal_data[i].kdc_key_ver);
226: editpw = 1;
227: changed = 0;
228: if (!creating) {
229: /*
230: * copy the existing data so we can use the old values
231: * for the qualifier clause of the replace
232: */
233: principal_data[i].old = (char *) &old_principal;
234: bcopy(&principal_data[i], &old_principal,
235: sizeof(old_principal));
236: printf("\nChange password [n] ? ");
237: gets(temp);
238: if (strcmp("y", temp) && strcmp("Y", temp))
239: editpw = 0;
240: }
241: /* password */
242: if (editpw) {
243: #ifdef NOENCRYPTION
244: placebo_read_pw_string(pw_str, sizeof pw_str,
245: "\nNew Password: ", TRUE);
246: #else
247: des_read_pw_string(pw_str, sizeof pw_str,
248: "\nNew Password: ", TRUE);
249: #endif
250: if (!strcmp(pw_str, "RANDOM")) {
251: printf("\nRandom password [y] ? ");
252: gets(temp);
253: if (!strcmp("n", temp) || !strcmp("N", temp)) {
254: /* no, use literal */
255: #ifdef NOENCRYPTION
256: bzero(new_key, sizeof(C_Block));
257: new_key[0] = 127;
258: #else
259: string_to_key(pw_str, new_key);
260: #endif
261: bzero(pw_str, sizeof pw_str); /* "RANDOM" */
262: } else {
263: #ifdef NOENCRYPTION
264: bzero(new_key, sizeof(C_Block));
265: new_key[0] = 127;
266: #else
267: random_key(new_key); /* yes, random */
268: #endif
269: bzero(pw_str, sizeof pw_str);
270: }
271: } else if (!strcmp(pw_str, "NULL")) {
272: printf("\nNull Key [y] ? ");
273: gets(temp);
274: if (!strcmp("n", temp) || !strcmp("N", temp)) {
275: /* no, use literal */
276: #ifdef NOENCRYPTION
277: bzero(new_key, sizeof(C_Block));
278: new_key[0] = 127;
279: #else
280: string_to_key(pw_str, new_key);
281: #endif
282: bzero(pw_str, sizeof pw_str); /* "NULL" */
283: } else {
284:
285: principal_data[i].key_low = 0;
286: principal_data[i].key_high = 0;
287: goto null_key;
288: }
289: } else {
290: #ifdef NOENCRYPTION
291: bzero(new_key, sizeof(C_Block));
292: new_key[0] = 127;
293: #else
294: string_to_key(pw_str, new_key);
295: #endif
296: bzero(pw_str, sizeof pw_str);
297: }
298:
299: /* seal it under the kerberos master key */
300: kdb_encrypt_key (new_key, new_key,
301: master_key, master_key_schedule,
302: ENCRYPT);
303: bcopy(new_key, &principal_data[i].key_low, 4);
304: bcopy(((long *) new_key) + 1,
305: &principal_data[i].key_high, 4);
306: bzero(new_key, sizeof(new_key));
307: null_key:
308: /* set master key version */
309: principal_data[i].kdc_key_ver =
310: (unsigned char) master_key_version;
311: /* bump key version # */
312: principal_data[i].key_version++;
313: fprintf(stdout,
314: "\nPrincipal's new key version = %d\n",
315: principal_data[i].key_version);
316: fflush(stdout);
317: changed = 1;
318: }
319: /* expiration date */
320: fprintf(stdout, "Expiration date (enter yyyy-mm-dd) [ %s ] ? ",
321: principal_data[i].exp_date_txt);
322: zaptime(&edate);
323: while (gets(temp) && ((n = strlen(temp)) >
324: sizeof(principal_data[0].exp_date_txt))) {
325: bad_date:
326: fprintf(stdout, "\07\07Date Invalid\n");
327: fprintf(stdout,
328: "Expiration date (enter yyyy-mm-dd) [ %s ] ? ",
329: principal_data[i].exp_date_txt);
330: zaptime(&edate);
331: }
332:
333: if (*temp) {
334: if (sscanf(temp, "%d-%d-%d", &edate.tm_year,
335: &edate.tm_mon, &edate.tm_mday) != 3)
336: goto bad_date;
337: (void) strcpy(principal_data[i].exp_date_txt, temp);
338: edate.tm_mon--; /* January is 0, not 1 */
339: edate.tm_hour = 23; /* nearly midnight at the end of the */
340: edate.tm_min = 59; /* specified day */
341: edate.tm_zon = 1; /* local time, not GMT */
342: if (!(principal_data[i].exp_date = maketime(&edate)))
343: goto bad_date;
344: changed = 1;
345: }
346:
347: /* maximum lifetime */
348: fprintf(stdout, "Max ticket lifetime (*5 minutes) [ %d ] ? ",
349: principal_data[i].max_life);
350: while (gets(temp) && *temp) {
351: if (sscanf(temp, "%d", &temp_long) != 1)
352: goto bad_life;
353: if (temp_long > 255 || (temp_long < 0)) {
354: bad_life:
355: fprintf(stdout, "\07\07Invalid, choose 0-255\n");
356: fprintf(stdout,
357: "Max ticket lifetime (*5 minutes) [ %d ] ? ",
358: principal_data[i].max_life);
359: continue;
360: }
361: changed = 1;
362: /* dont clobber */
363: principal_data[i].max_life = (unsigned short) temp_long;
364: break;
365: }
366:
367: /* attributes */
368: fprintf(stdout, "Attributes [ %d ] ? ",
369: principal_data[i].attributes);
370: while (gets(temp) && *temp) {
371: if (sscanf(temp, "%d", &temp_long) != 1)
372: goto bad_att;
373: if (temp_long > 65535 || (temp_long < 0)) {
374: bad_att:
375: fprintf(stdout, "\07\07Invalid, choose 0-65535\n");
376: fprintf(stdout, "Attributes [ %d ] ? ",
377: principal_data[i].attributes);
378: continue;
379: }
380: changed = 1;
381: /* dont clobber */
382: principal_data[i].attributes =
383: (unsigned short) temp_long;
384: break;
385: }
386:
387: /*
388: * remaining fields -- key versions and mod info, should
389: * not be directly manipulated
390: */
391: if (changed) {
392: if (kerb_put_principal(&principal_data[i], 1)) {
393: fprintf(stdout,
394: "\nError updating Kerberos database");
395: } else {
396: fprintf(stdout, "Edit O.K.");
397: }
398: } else {
399: fprintf(stdout, "Unchanged");
400: }
401:
402:
403: bzero(&principal_data[i].key_low, 4);
404: bzero(&principal_data[i].key_high, 4);
405: fflush(stdout);
406: break;
407: }
408: }
409: if (more) {
410: fprintf(stdout, "\nThere were more tuples found ");
411: fprintf(stdout, "than there were space for");
412: }
413: return 1;
414: }
415:
416:
417: no_core_dumps()
418: {
419:
420: signal(SIGQUIT, sig_exit);
421: signal(SIGILL, sig_exit);
422: signal(SIGTRAP, sig_exit);
423: signal(SIGIOT, sig_exit);
424: signal(SIGEMT, sig_exit);
425: signal(SIGFPE, sig_exit);
426: signal(SIGBUS, sig_exit);
427: signal(SIGSEGV, sig_exit);
428: signal(SIGSYS, sig_exit);
429: }
430:
431: void
432: sig_exit(sig, code, scp)
433: int sig, code;
434: struct sigcontext *scp;
435: {
436: cleanup();
437: fprintf(stderr,
438: "\nSignal caught, sig = %d code = %d old pc = 0x%X \nexiting",
439: sig, code, scp->sc_pc);
440: exit(-1);
441: }
442:
443:
444: cleanup()
445: {
446:
447: bzero(master_key, sizeof(master_key));
448: bzero(session_key, sizeof(session_key));
449: bzero(master_key_schedule, sizeof(master_key_schedule));
450: bzero(principal_data, sizeof(principal_data));
451: bzero(new_key, sizeof(new_key));
452: bzero(pw_str, sizeof(pw_str));
453: }
454: Usage()
455: {
456: fprintf(stderr, "Usage: %s [-n]\n", progname);
457: exit(1);
458: }
459:
460: /* zaptime code taken from: */
461: /*
462: * PARTIME parse date/time string into a TM structure
463: *
464: * Usage:
465: * #include "time.h" -- expanded tm structure
466: * char *str; struct tm *tp;
467: * partime(str,tp);
468: * Returns:
469: * 0 if parsing failed
470: * else time values in specified TM structure (unspecified values
471: * set to TMNULL)
472: * Notes:
473: * This code is quasi-public; it may be used freely in like software.
474: * It is not to be sold, nor used in licensed software without
475: * permission of the author.
476: * For everyone's benefit, please report bugs and improvements!
477: * Copyright 1980 by Ken Harrenstien, SRI International.
478: * (ARPANET: KLH @ SRI)
479: */
480:
481: zaptime(atm)
482: register struct tm *atm;
483: /* clears atm */
484: {
485: atm->tm_sec = TMNULL;
486: atm->tm_min = TMNULL;
487: atm->tm_hour = TMNULL;
488: atm->tm_mday = TMNULL;
489: atm->tm_mon = TMNULL;
490: atm->tm_year = TMNULL;
491: atm->tm_wday = TMNULL;
492: atm->tm_yday = TMNULL;
493: atm->tm_isdst = TMNULL;
494: atm->tm_zon = TMNULL;
495: atm->tm_ampm = TMNULL;
496: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.