|
|
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.