Annotation of 43BSDReno/kerberosIV/kdb_util/kdb_util.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * $Source: /usr/src/kerberosIV/kdb_util/RCS/kdb_util.c,v $
        !             3:  * $Author: kfall $
        !             4:  *
        !             5:  * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
        !             6:  * 
        !             7:  * For copying and distribution information, please see the file
        !             8:  * <mit-copyright.h>.
        !             9:  *
        !            10:  * Kerberos database manipulation utility. This program allows you to
        !            11:  * dump a kerberos database to an ascii readable file and load this
        !            12:  * file into the database. Read locking of the database is done during a
        !            13:  * dump operation. NO LOCKING is done during a load operation. Loads
        !            14:  * should happen with other processes shutdown. 
        !            15:  *
        !            16:  * Written July 9, 1987 by Jeffrey I. Schiller
        !            17:  */
        !            18: 
        !            19: #ifndef        lint
        !            20: static char rcsid_kdb_util_c[] =
        !            21: "$Id: kdb_util.c,v 4.5 90/06/25 22:12:42 kfall Exp $";
        !            22: #endif lint
        !            23: 
        !            24: #include <mit-copyright.h>
        !            25: #include <sys/types.h>
        !            26: #include <sys/file.h>
        !            27: #include <netinet/in.h>
        !            28: #include <string.h>
        !            29: #include <stdio.h>
        !            30: #include "time.h"
        !            31: #include <des.h>
        !            32: #include <krb.h>
        !            33: #include <krb_db.h>
        !            34: 
        !            35: #define TRUE 1
        !            36: 
        !            37: Principal aprinc;
        !            38: 
        !            39: static des_cblock master_key, new_master_key;
        !            40: static des_key_schedule master_key_schedule, new_master_key_schedule;
        !            41: 
        !            42: #define zaptime(foo) bzero((char *)(foo), sizeof(*(foo)))
        !            43: 
        !            44: extern long kdb_get_master_key(), kdb_verify_master_key();
        !            45: extern char *malloc();
        !            46: extern int errno;
        !            47: 
        !            48: char *progname;
        !            49: 
        !            50: main(argc, argv)
        !            51:     int     argc;
        !            52:     char  **argv;
        !            53: {
        !            54:     FILE   *file;
        !            55:     enum {
        !            56:        OP_LOAD,
        !            57:        OP_DUMP,
        !            58:        OP_SLAVE_DUMP,
        !            59:        OP_NEW_MASTER,
        !            60:        OP_CONVERT_OLD_DB,
        !            61:     }       op;
        !            62:     char *file_name;
        !            63:     char *prog = argv[0];
        !            64:     char *db_name;
        !            65:     
        !            66:     progname = prog;   /* required by libkdb (yuck!) */
        !            67: 
        !            68:     if (argc != 3 && argc != 4) {
        !            69:        fprintf(stderr, "Usage: %s operation file-name [database name].\n",
        !            70:                argv[0]);
        !            71:        exit(1);
        !            72:     }
        !            73:     if (argc == 3)
        !            74:        db_name = DBM_FILE;
        !            75:     else
        !            76:        db_name = argv[3];
        !            77: 
        !            78:     if (kerb_db_set_name (db_name) != 0) {
        !            79:        perror("Can't open database");
        !            80:        exit(1);
        !            81:     }
        !            82:     
        !            83:     if (!strcmp(argv[1], "load"))
        !            84:        op = OP_LOAD;
        !            85:     else if (!strcmp(argv[1], "dump"))
        !            86:        op = OP_DUMP;
        !            87:     else if (!strcmp(argv[1], "slave_dump"))
        !            88:         op = OP_SLAVE_DUMP;
        !            89:     else if (!strcmp(argv[1], "new_master_key"))
        !            90:         op = OP_NEW_MASTER;
        !            91:     else if (!strcmp(argv[1], "convert_old_db"))
        !            92:         op = OP_CONVERT_OLD_DB;
        !            93:     else {
        !            94:        fprintf(stderr,
        !            95:            "%s: %s is an invalid operation.\n", prog, argv[1]);
        !            96:        fprintf(stderr,
        !            97:            "%s: Valid operations are \"dump\", \"slave_dump\",", argv[0]);
        !            98:        fprintf(stderr,
        !            99:                "\"load\", \"new_master_key\", and \"convert_old_db\".\n");
        !           100:        exit(1);
        !           101:     }
        !           102: 
        !           103:     file_name = argv[2];
        !           104:     file = fopen(file_name, op == OP_LOAD ? "r" : "w");
        !           105:     if (file == NULL) {
        !           106:        fprintf(stderr, "%s: Unable to open %s\n", prog, argv[2]);
        !           107:        (void) fflush(stderr);
        !           108:        perror("open");
        !           109:        exit(1);
        !           110:     }
        !           111: 
        !           112:     switch (op) {
        !           113:     case OP_DUMP:
        !           114:       if ((dump_db (db_name, file, (void (*)()) 0) == EOF) ||
        !           115:          (fclose(file) == EOF)) {
        !           116:          fprintf(stderr, "error on file %s:", file_name);
        !           117:          perror("");
        !           118:          exit(1);
        !           119:       }
        !           120:       break;
        !           121:     case OP_SLAVE_DUMP:
        !           122:       if ((dump_db (db_name, file, (void (*)()) 0) == EOF) ||
        !           123:          (fclose(file) == EOF)) {
        !           124:          fprintf(stderr, "error on file %s:", file_name);
        !           125:          perror("");
        !           126:          exit(1);
        !           127:       }
        !           128:       update_ok_file (file_name);
        !           129:       break;
        !           130:     case OP_LOAD:
        !           131:       load_db (db_name, file);
        !           132:       break;
        !           133:     case OP_NEW_MASTER:
        !           134:       convert_new_master_key (db_name, file);
        !           135:       printf("Don't forget to do a `kdb_util load %s' to reload the database!\n", file_name);
        !           136:       break;
        !           137:     case OP_CONVERT_OLD_DB:
        !           138:       convert_old_format_db (db_name, file);
        !           139:       printf("Don't forget to do a `kdb_util load %s' to reload the database!\n", file_name);      
        !           140:       break;
        !           141:     }
        !           142:     exit(0);
        !           143:   }
        !           144: 
        !           145: clear_secrets ()
        !           146: {
        !           147:   bzero((char *)master_key, sizeof (des_cblock));
        !           148:   bzero((char *)master_key_schedule, sizeof (Key_schedule));
        !           149:   bzero((char *)new_master_key, sizeof (des_cblock));
        !           150:   bzero((char *)new_master_key_schedule, sizeof (Key_schedule));
        !           151: }
        !           152: 
        !           153: /* cv_key is a procedure which takes a principle and changes its key, 
        !           154:    either for a new method of encrypting the keys, or a new master key.
        !           155:    if cv_key is null no transformation of key is done (other than net byte
        !           156:    order). */
        !           157: 
        !           158: struct callback_args {
        !           159:     void (*cv_key)();
        !           160:     FILE *output_file;
        !           161: };
        !           162: 
        !           163: static int dump_db_1(arg, principal)
        !           164:     char *arg;
        !           165:     Principal *principal;
        !           166: {          /* replace null strings with "*" */
        !           167:     struct callback_args *a = (struct callback_args *)arg;
        !           168:     
        !           169:     if (principal->instance[0] == '\0') {
        !           170:        principal->instance[0] = '*';
        !           171:        principal->instance[1] = '\0';
        !           172:     }
        !           173:     if (principal->mod_name[0] == '\0') {
        !           174:        principal->mod_name[0] = '*';
        !           175:        principal->mod_name[1] = '\0';
        !           176:     }
        !           177:     if (principal->mod_instance[0] == '\0') {
        !           178:        principal->mod_instance[0] = '*';
        !           179:        principal->mod_instance[1] = '\0';
        !           180:     }
        !           181:     if (a->cv_key != NULL) {
        !           182:        (*a->cv_key) (principal);
        !           183:     }
        !           184:     fprintf(a->output_file, "%s %s %d %d %d %d %x %x",
        !           185:            principal->name,
        !           186:            principal->instance,
        !           187:            principal->max_life,
        !           188:            principal->kdc_key_ver,
        !           189:            principal->key_version,
        !           190:            principal->attributes,
        !           191:            htonl (principal->key_low),
        !           192:            htonl (principal->key_high));
        !           193:     print_time(a->output_file, principal->exp_date);
        !           194:     print_time(a->output_file, principal->mod_date);
        !           195:     fprintf(a->output_file, " %s %s\n",
        !           196:            principal->mod_name,
        !           197:            principal->mod_instance);
        !           198:     return 0;
        !           199: }
        !           200: 
        !           201: dump_db (db_file, output_file, cv_key)
        !           202:      char *db_file;
        !           203:      FILE *output_file;
        !           204:      void (*cv_key)();
        !           205: {
        !           206:     struct callback_args a;
        !           207: 
        !           208:     a.cv_key = cv_key;
        !           209:     a.output_file = output_file;
        !           210:     
        !           211:     kerb_db_iterate (dump_db_1, (char *)&a);
        !           212:     return fflush(output_file);
        !           213: }
        !           214: 
        !           215: load_db (db_file, input_file)
        !           216:      char *db_file;
        !           217:      FILE *input_file;
        !           218: {
        !           219:     char    exp_date_str[50];
        !           220:     char    mod_date_str[50];
        !           221:     int     temp1, temp2, temp3;
        !           222:     long time_explode();
        !           223:     int code;
        !           224:     extern char *sys_errlist[];
        !           225:     char *temp_db_file;
        !           226:     temp1 = strlen(db_file+2);
        !           227:     temp_db_file = malloc (temp1);
        !           228:     strcpy(temp_db_file, db_file);
        !           229:     strcat(temp_db_file, "~");
        !           230: 
        !           231:     /* Create the database */
        !           232:     if ((code = kerb_db_create(temp_db_file)) != 0) {
        !           233:        fprintf(stderr, "Couldn't create temp database %s: %s\n",
        !           234:                temp_db_file, sys_errlist[code]);
        !           235:        exit(1);
        !           236:     }
        !           237:     kerb_db_set_name(temp_db_file);
        !           238:     for (;;) {                 /* explicit break on eof from fscanf */
        !           239:        bzero((char *)&aprinc, sizeof(aprinc));
        !           240:        if (fscanf(input_file,
        !           241:                   "%s %s %d %d %d %hd %x %x %s %s %s %s\n",
        !           242:                   aprinc.name,
        !           243:                   aprinc.instance,
        !           244:                   &temp1,
        !           245:                   &temp2,
        !           246:                   &temp3,
        !           247:                   &aprinc.attributes,
        !           248:                   &aprinc.key_low,
        !           249:                   &aprinc.key_high,
        !           250:                   exp_date_str,
        !           251:                   mod_date_str,
        !           252:                   aprinc.mod_name,
        !           253:                   aprinc.mod_instance) == EOF)
        !           254:            break;
        !           255:        aprinc.key_low = ntohl (aprinc.key_low);
        !           256:        aprinc.key_high = ntohl (aprinc.key_high);
        !           257:        aprinc.max_life = (unsigned char) temp1;
        !           258:        aprinc.kdc_key_ver = (unsigned char) temp2;
        !           259:        aprinc.key_version = (unsigned char) temp3;
        !           260:        aprinc.exp_date = time_explode(exp_date_str);
        !           261:        aprinc.mod_date = time_explode(mod_date_str);
        !           262:        if (aprinc.instance[0] == '*')
        !           263:            aprinc.instance[0] = '\0';
        !           264:        if (aprinc.mod_name[0] == '*')
        !           265:            aprinc.mod_name[0] = '\0';
        !           266:        if (aprinc.mod_instance[0] == '*')
        !           267:            aprinc.mod_instance[0] = '\0';
        !           268:        if (kerb_db_put_principal(&aprinc, 1) != 1) {
        !           269:            fprintf(stderr, "Couldn't store %s.%s: %s; load aborted\n",
        !           270:                    aprinc.name, aprinc.instance,
        !           271:                    sys_errlist[errno]);
        !           272:            exit(1);
        !           273:        };
        !           274:     }
        !           275:     if ((code = kerb_db_rename(temp_db_file, db_file)) != 0)
        !           276:        perror("database rename failed");
        !           277:     (void) fclose(input_file);
        !           278:     free(temp_db_file);
        !           279: }
        !           280: 
        !           281: print_time(file, timeval)
        !           282:     FILE   *file;
        !           283:     unsigned long timeval;
        !           284: {
        !           285:     struct tm *tm;
        !           286:     struct tm *gmtime();
        !           287:     tm = gmtime((long *)&timeval);
        !           288:     fprintf(file, " %04d%02d%02d%02d%02d",
        !           289:             tm->tm_year < 1900 ? tm->tm_year + 1900: tm->tm_year,
        !           290:             tm->tm_mon + 1,
        !           291:             tm->tm_mday,
        !           292:             tm->tm_hour,
        !           293:             tm->tm_min);
        !           294: }
        !           295: 
        !           296: /*ARGSUSED*/
        !           297: update_ok_file (file_name)
        !           298:      char *file_name;
        !           299: {
        !           300:     /* handle slave locking/failure stuff */
        !           301:     char *file_ok;
        !           302:     int fd;
        !           303:     static char ok[]=".dump_ok";
        !           304: 
        !           305:     if ((file_ok = (char *)malloc(strlen(file_name) + strlen(ok) + 1))
        !           306:        == NULL) {
        !           307:        fprintf(stderr, "kdb_util: out of memory.\n");
        !           308:        (void) fflush (stderr);
        !           309:        perror ("malloc");
        !           310:        exit (1);
        !           311:     }
        !           312:     strcpy(file_ok, file_name);
        !           313:     strcat(file_ok, ok);
        !           314:     if ((fd = open(file_ok, O_WRONLY|O_CREAT|O_TRUNC, 0400)) < 0) {
        !           315:        fprintf(stderr, "Error creating 'ok' file, '%s'", file_ok);
        !           316:        perror("");
        !           317:        (void) fflush (stderr);
        !           318:        exit (1);
        !           319:     }
        !           320:     free(file_ok);
        !           321:     close(fd);
        !           322: }
        !           323: 
        !           324: void
        !           325: convert_key_new_master (p)
        !           326:      Principal *p;
        !           327: {
        !           328:   des_cblock key;
        !           329: 
        !           330:   /* leave null keys alone */
        !           331:   if ((p->key_low == 0) && (p->key_high == 0)) return;
        !           332: 
        !           333:   /* move current key to des_cblock for encryption, special case master key
        !           334:      since that's changing */
        !           335:   if ((strncmp (p->name, KERB_M_NAME, ANAME_SZ) == 0) &&
        !           336:       (strncmp (p->instance, KERB_M_INST, INST_SZ) == 0)) {
        !           337:     bcopy((char *)new_master_key, (char *) key, sizeof (des_cblock));
        !           338:     (p->key_version)++;
        !           339:   } else {
        !           340:     bcopy((char *)&(p->key_low), (char *)key, 4);
        !           341:     bcopy((char *)&(p->key_high), (char *) (((long *) key) + 1), 4);
        !           342:     kdb_encrypt_key (key, key, master_key, master_key_schedule, DECRYPT);
        !           343:   }
        !           344: 
        !           345:   kdb_encrypt_key (key, key, new_master_key, new_master_key_schedule, ENCRYPT);
        !           346: 
        !           347:   bcopy((char *)key, (char *)&(p->key_low), 4);
        !           348:   bcopy((char *)(((long *) key) + 1), (char *)&(p->key_high), 4);
        !           349:   bzero((char *)key, sizeof (key));  /* a little paranoia ... */
        !           350: 
        !           351:   (p->kdc_key_ver)++;
        !           352: }
        !           353: 
        !           354: convert_new_master_key (db_file, out)
        !           355:      char *db_file;
        !           356:      FILE *out;
        !           357: {
        !           358: 
        !           359:   printf ("\n\nEnter the CURRENT master key.");
        !           360:   if (kdb_get_master_key (TRUE, master_key, master_key_schedule) != 0) {
        !           361:     fprintf (stderr, "%s: Couldn't get master key.\n");
        !           362:     clear_secrets ();
        !           363:     exit (-1);
        !           364:   }
        !           365: 
        !           366:   if (kdb_verify_master_key (master_key, master_key_schedule, stderr) < 0) {
        !           367:     clear_secrets ();
        !           368:     exit (-1);
        !           369:   }
        !           370: 
        !           371:   printf ("\n\nNow enter the NEW master key.  Do not forget it!!");
        !           372:   if (kdb_get_master_key (TRUE, new_master_key, new_master_key_schedule) != 0) {
        !           373:     fprintf (stderr, "%s: Couldn't get new master key.\n");
        !           374:     clear_secrets ();
        !           375:     exit (-1);
        !           376:   }
        !           377: 
        !           378:   dump_db (db_file, out, convert_key_new_master);
        !           379: }
        !           380: 
        !           381: void
        !           382: convert_key_old_db (p)
        !           383:      Principal *p;
        !           384: {
        !           385:   des_cblock key;
        !           386: 
        !           387:  /* leave null keys alone */
        !           388:   if ((p->key_low == 0) && (p->key_high == 0)) return;
        !           389: 
        !           390:   bcopy((char *)&(p->key_low), (char *)key, 4);
        !           391:   bcopy((char *)&(p->key_high), (char *)(((long *) key) + 1), 4);
        !           392: 
        !           393: #ifndef NOENCRYPTION
        !           394:   /* get clear key, old style */
        !           395:   (void) des_pcbc_encrypt ((des_cblock *) key, (des_cblock *) key,
        !           396:                (long) sizeof(des_cblock), 
        !           397:                master_key_schedule, (des_cblock *)master_key_schedule,
        !           398:                DECRYPT);
        !           399: #endif
        !           400: 
        !           401:   /* make new key, new style */
        !           402:   kdb_encrypt_key (key, key, master_key, master_key_schedule, ENCRYPT);
        !           403: 
        !           404:   bcopy((char *)key, (char *)&(p->key_low), 4);
        !           405:   bcopy((char *)(((long *) key) + 1), (char *)&(p->key_high), 4);
        !           406:   bzero((char *)key, sizeof (key));  /* a little paranoia ... */
        !           407: }
        !           408: 
        !           409: convert_old_format_db (db_file, out)
        !           410:      char *db_file;
        !           411:      FILE *out;
        !           412: {
        !           413:   des_cblock key_from_db;
        !           414:   Principal principal_data[1];
        !           415:   int n, more;
        !           416: 
        !           417:   if (kdb_get_master_key (TRUE, master_key, master_key_schedule) != 0L) {
        !           418:     fprintf (stderr, "%s: Couldn't get master key.\n");
        !           419:     clear_secrets();
        !           420:     exit (-1);
        !           421:   }
        !           422: 
        !           423:   /* can't call kdb_verify_master_key because this is an old style db */
        !           424:   /* lookup the master key version */
        !           425:   n = kerb_get_principal(KERB_M_NAME, KERB_M_INST, principal_data,
        !           426:                         1 /* only one please */, &more);
        !           427:   if ((n != 1) || more) {
        !           428:     fprintf(stderr, "verify_master_key: ",
        !           429:            "Kerberos error on master key lookup, %d found.\n",
        !           430:            n);
        !           431:     exit (-1);
        !           432:   }
        !           433: 
        !           434:   /* set up the master key */
        !           435:   fprintf(stderr, "Current Kerberos master key version is %d.\n",
        !           436:          principal_data[0].kdc_key_ver);
        !           437: 
        !           438:   /*
        !           439:    * now use the master key to decrypt (old style) the key in the db, had better
        !           440:    * be the same! 
        !           441:    */
        !           442:   bcopy((char *)&principal_data[0].key_low, (char *)key_from_db, 4);
        !           443:   bcopy((char *)&principal_data[0].key_high,
        !           444:        (char *)(((long *) key_from_db) + 1), 4);
        !           445: #ifndef NOENCRYPTION
        !           446:   (void) des_pcbc_encrypt (key_from_db, key_from_db,
        !           447:                           (long) sizeof(key_from_db),
        !           448:                           master_key_schedule,
        !           449:                           (des_cblock *) master_key_schedule, DECRYPT);
        !           450: #endif
        !           451:   /* the decrypted database key had better equal the master key */
        !           452:   n = bcmp((char *) master_key, (char *) key_from_db,
        !           453:           sizeof(master_key));
        !           454:   bzero((char *)key_from_db, sizeof(key_from_db));
        !           455: 
        !           456:   if (n) {
        !           457:     fprintf(stderr, "\n\07\07%verify_master_key: Invalid master key, ");
        !           458:     fprintf(stderr, "does not match database.\n");
        !           459:     exit (-1);
        !           460:   }
        !           461:     
        !           462:   fprintf(stderr, "Master key verified.\n");
        !           463:   (void) fflush(stderr);
        !           464: 
        !           465:   dump_db (db_file, out, convert_key_old_db);
        !           466: }
        !           467: 
        !           468: long
        !           469: time_explode(cp)
        !           470: register char *cp;
        !           471: {
        !           472:     char wbuf[5];
        !           473:     struct tm tp;
        !           474:     long maketime();
        !           475:     int local;
        !           476: 
        !           477:     zaptime(&tp);                      /* clear out the struct */
        !           478:     
        !           479:     if (strlen(cp) > 10) {             /* new format */
        !           480:        (void) strncpy(wbuf, cp, 4);
        !           481:        wbuf[4] = 0;
        !           482:        tp.tm_year = atoi(wbuf);
        !           483:        cp += 4;                        /* step over the year */
        !           484:        local = 0;                      /* GMT */
        !           485:     } else {                           /* old format: local time, 
        !           486:                                           year is 2 digits, assuming 19xx */
        !           487:        wbuf[0] = *cp++;
        !           488:        wbuf[1] = *cp++;
        !           489:        wbuf[2] = 0;
        !           490:        tp.tm_year = 1900 + atoi(wbuf);
        !           491:        local = 1;                      /* local */
        !           492:     }
        !           493: 
        !           494:     wbuf[0] = *cp++;
        !           495:     wbuf[1] = *cp++;
        !           496:     wbuf[2] = 0;
        !           497:     tp.tm_mon = atoi(wbuf)-1;
        !           498: 
        !           499:     wbuf[0] = *cp++;
        !           500:     wbuf[1] = *cp++;
        !           501:     tp.tm_mday = atoi(wbuf);
        !           502:     
        !           503:     wbuf[0] = *cp++;
        !           504:     wbuf[1] = *cp++;
        !           505:     tp.tm_hour = atoi(wbuf);
        !           506:     
        !           507:     wbuf[0] = *cp++;
        !           508:     wbuf[1] = *cp++;
        !           509:     tp.tm_min = atoi(wbuf);
        !           510: 
        !           511: 
        !           512:     return(maketime(&tp, local));
        !           513: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.