⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kdb_util.c

📁 早期freebsd实现
💻 C
字号:
/* * $Source: /usr/src/kerberosIV/kdb_util/RCS/kdb_util.c,v $ * $Author: bostic $ * * Copyright 1987, 1988 by the Massachusetts Institute of Technology. *  * For copying and distribution information, please see the file * <mit-copyright.h>. * * Kerberos database manipulation utility. This program allows you to * dump a kerberos database to an ascii readable file and load this * file into the database. Read locking of the database is done during a * dump operation. NO LOCKING is done during a load operation. Loads * should happen with other processes shutdown.  * * Written July 9, 1987 by Jeffrey I. Schiller */#ifndef	lintstatic char rcsid_kdb_util_c[] ="$Id: kdb_util.c,v 4.7 93/05/21 08:56:29 bostic Exp $";#endif	lint#include <mit-copyright.h>#include <sys/types.h>#include <sys/file.h>#include <netinet/in.h>#include <string.h>#include <stdio.h>#include "time.h"#include <des.h>#include <krb.h>#include <krb_db.h>#define TRUE 1Principal aprinc;static des_cblock master_key, new_master_key;static des_key_schedule master_key_schedule, new_master_key_schedule;#define zaptime(foo) bzero((char *)(foo), sizeof(*(foo)))extern long kdb_get_master_key(), kdb_verify_master_key();extern char *malloc();extern int errno;char *progname;main(argc, argv)    int     argc;    char  **argv;{    FILE   *file;    enum {	OP_LOAD,	OP_DUMP,	OP_SLAVE_DUMP,	OP_NEW_MASTER,	OP_CONVERT_OLD_DB,    }       op;    char *file_name;    char *prog = argv[0];    char *db_name;        progname = prog;	/* required by libkdb (yuck!) */    if (argc != 3 && argc != 4) {	fprintf(stderr, "Usage: %s operation file-name [database name].\n",		argv[0]);	exit(1);    }    if (argc == 3)	db_name = DBM_FILE;    else	db_name = argv[3];    if (kerb_db_set_name (db_name) != 0) {	perror("Can't open database");	exit(1);    }        if (!strcmp(argv[1], "load"))	op = OP_LOAD;    else if (!strcmp(argv[1], "dump"))	op = OP_DUMP;    else if (!strcmp(argv[1], "slave_dump"))        op = OP_SLAVE_DUMP;    else if (!strcmp(argv[1], "new_master_key"))        op = OP_NEW_MASTER;    else if (!strcmp(argv[1], "convert_old_db"))        op = OP_CONVERT_OLD_DB;    else {	fprintf(stderr,	    "%s: %s is an invalid operation.\n", prog, argv[1]);	fprintf(stderr,	    "%s: Valid operations are \"dump\", \"slave_dump\",", argv[0]);	fprintf(stderr,		"\"load\", \"new_master_key\", and \"convert_old_db\".\n");	exit(1);    }    file_name = argv[2];    file = fopen(file_name, op == OP_LOAD ? "r" : "w");    if (file == NULL) {	fprintf(stderr, "%s: Unable to open %s\n", prog, argv[2]);	(void) fflush(stderr);	perror("open");	exit(1);    }    switch (op) {    case OP_DUMP:      if ((dump_db (db_name, file, (void (*)()) 0) == EOF) ||	  (fclose(file) == EOF)) {	  fprintf(stderr, "error on file %s:", file_name);	  perror("");	  exit(1);      }      break;    case OP_SLAVE_DUMP:      if ((dump_db (db_name, file, (void (*)()) 0) == EOF) ||	  (fclose(file) == EOF)) {	  fprintf(stderr, "error on file %s:", file_name);	  perror("");	  exit(1);      }      update_ok_file (file_name);      break;    case OP_LOAD:      load_db (db_name, file);      break;    case OP_NEW_MASTER:      convert_new_master_key (db_name, file);      printf("Don't forget to do a `kdb_util load %s' to reload the database!\n", file_name);      break;    case OP_CONVERT_OLD_DB:      convert_old_format_db (db_name, file);      printf("Don't forget to do a `kdb_util load %s' to reload the database!\n", file_name);            break;    }    exit(0);  }clear_secrets (){  bzero((char *)master_key, sizeof (des_cblock));  bzero((char *)master_key_schedule, sizeof (Key_schedule));  bzero((char *)new_master_key, sizeof (des_cblock));  bzero((char *)new_master_key_schedule, sizeof (Key_schedule));}/* cv_key is a procedure which takes a principle and changes its key,    either for a new method of encrypting the keys, or a new master key.   if cv_key is null no transformation of key is done (other than net byte   order). */struct callback_args {    void (*cv_key)();    FILE *output_file;};static int dump_db_1(arg, principal)    char *arg;    Principal *principal;{	    /* replace null strings with "*" */    struct callback_args *a = (struct callback_args *)arg;        if (principal->instance[0] == '\0') {	principal->instance[0] = '*';	principal->instance[1] = '\0';    }    if (principal->mod_name[0] == '\0') {	principal->mod_name[0] = '*';	principal->mod_name[1] = '\0';    }    if (principal->mod_instance[0] == '\0') {	principal->mod_instance[0] = '*';	principal->mod_instance[1] = '\0';    }    if (a->cv_key != NULL) {	(*a->cv_key) (principal);    }    fprintf(a->output_file, "%s %s %d %d %d %d %x %x",	    principal->name,	    principal->instance,	    principal->max_life,	    principal->kdc_key_ver,	    principal->key_version,	    principal->attributes,	    htonl (principal->key_low),	    htonl (principal->key_high));    print_time(a->output_file, principal->exp_date);    print_time(a->output_file, principal->mod_date);    fprintf(a->output_file, " %s %s\n",	    principal->mod_name,	    principal->mod_instance);    return 0;}dump_db (db_file, output_file, cv_key)     char *db_file;     FILE *output_file;     void (*cv_key)();{    struct callback_args a;    a.cv_key = cv_key;    a.output_file = output_file;        kerb_db_iterate (dump_db_1, (char *)&a);    return fflush(output_file);}load_db (db_file, input_file)     char *db_file;     FILE *input_file;{    char    exp_date_str[50];    char    mod_date_str[50];    int     temp1, temp2, temp3;    long time_explode();    int code;    char *temp_db_file;    temp1 = strlen(db_file) + 2;    temp_db_file = malloc (temp1);    strcpy(temp_db_file, db_file);    strcat(temp_db_file, "~");    /* Create the database */    if ((code = kerb_db_create(temp_db_file)) != 0) {	fprintf(stderr, "Couldn't create temp database %s: %s\n",		temp_db_file, sys_errlist[code]);	exit(1);    }    kerb_db_set_name(temp_db_file);    for (;;) {			/* explicit break on eof from fscanf */	bzero((char *)&aprinc, sizeof(aprinc));	if (fscanf(input_file,		   "%s %s %d %d %d %hd %x %x %s %s %s %s\n",		   aprinc.name,		   aprinc.instance,		   &temp1,		   &temp2,		   &temp3,		   &aprinc.attributes,		   &aprinc.key_low,		   &aprinc.key_high,		   exp_date_str,		   mod_date_str,		   aprinc.mod_name,		   aprinc.mod_instance) == EOF)	    break;	aprinc.key_low = ntohl (aprinc.key_low);	aprinc.key_high = ntohl (aprinc.key_high);	aprinc.max_life = (unsigned char) temp1;	aprinc.kdc_key_ver = (unsigned char) temp2;	aprinc.key_version = (unsigned char) temp3;	aprinc.exp_date = time_explode(exp_date_str);	aprinc.mod_date = time_explode(mod_date_str);	if (aprinc.instance[0] == '*')	    aprinc.instance[0] = '\0';	if (aprinc.mod_name[0] == '*')	    aprinc.mod_name[0] = '\0';	if (aprinc.mod_instance[0] == '*')	    aprinc.mod_instance[0] = '\0';	if (kerb_db_put_principal(&aprinc, 1) != 1) {	    fprintf(stderr, "Couldn't store %s.%s: %s; load aborted\n",		    aprinc.name, aprinc.instance,		    sys_errlist[errno]);	    exit(1);	};    }    if ((code = kerb_db_rename(temp_db_file, db_file)) != 0)	perror("database rename failed");    (void) fclose(input_file);    free(temp_db_file);}print_time(file, timeval)    FILE   *file;    unsigned long timeval;{    struct tm *tm;    struct tm *gmtime();    tm = gmtime((long *)&timeval);    fprintf(file, " %04d%02d%02d%02d%02d",            tm->tm_year < 1900 ? tm->tm_year + 1900: tm->tm_year,            tm->tm_mon + 1,            tm->tm_mday,            tm->tm_hour,            tm->tm_min);}/*ARGSUSED*/update_ok_file (file_name)     char *file_name;{    /* handle slave locking/failure stuff */    char *file_ok;    int fd;    static char ok[]=".dump_ok";    if ((file_ok = (char *)malloc(strlen(file_name) + strlen(ok) + 1))	== NULL) {	fprintf(stderr, "kdb_util: out of memory.\n");	(void) fflush (stderr);	perror ("malloc");	exit (1);    }    strcpy(file_ok, file_name);    strcat(file_ok, ok);    if ((fd = open(file_ok, O_WRONLY|O_CREAT|O_TRUNC, 0400)) < 0) {	fprintf(stderr, "Error creating 'ok' file, '%s'", file_ok);	perror("");	(void) fflush (stderr);	exit (1);    }    free(file_ok);    close(fd);}voidconvert_key_new_master (p)     Principal *p;{  des_cblock key;  /* leave null keys alone */  if ((p->key_low == 0) && (p->key_high == 0)) return;  /* move current key to des_cblock for encryption, special case master key     since that's changing */  if ((strncmp (p->name, KERB_M_NAME, ANAME_SZ) == 0) &&      (strncmp (p->instance, KERB_M_INST, INST_SZ) == 0)) {    bcopy((char *)new_master_key, (char *) key, sizeof (des_cblock));    (p->key_version)++;  } else {    bcopy((char *)&(p->key_low), (char *)key, 4);    bcopy((char *)&(p->key_high), (char *) (((long *) key) + 1), 4);    kdb_encrypt_key (key, key, master_key, master_key_schedule, DECRYPT);  }  kdb_encrypt_key (key, key, new_master_key, new_master_key_schedule, ENCRYPT);  bcopy((char *)key, (char *)&(p->key_low), 4);  bcopy((char *)(((long *) key) + 1), (char *)&(p->key_high), 4);  bzero((char *)key, sizeof (key));  /* a little paranoia ... */  (p->kdc_key_ver)++;}convert_new_master_key (db_file, out)     char *db_file;     FILE *out;{  printf ("\n\nEnter the CURRENT master key.");  if (kdb_get_master_key (TRUE, master_key, master_key_schedule) != 0) {    fprintf (stderr, "%s: Couldn't get master key.\n");    clear_secrets ();    exit (-1);  }  if (kdb_verify_master_key (master_key, master_key_schedule, stderr) < 0) {    clear_secrets ();    exit (-1);  }  printf ("\n\nNow enter the NEW master key.  Do not forget it!!");  if (kdb_get_master_key (TRUE, new_master_key, new_master_key_schedule) != 0) {    fprintf (stderr, "%s: Couldn't get new master key.\n");    clear_secrets ();    exit (-1);  }  dump_db (db_file, out, convert_key_new_master);}voidconvert_key_old_db (p)     Principal *p;{  des_cblock key; /* leave null keys alone */  if ((p->key_low == 0) && (p->key_high == 0)) return;  bcopy((char *)&(p->key_low), (char *)key, 4);  bcopy((char *)&(p->key_high), (char *)(((long *) key) + 1), 4);#ifndef NOENCRYPTION  /* get clear key, old style */  (void) des_pcbc_encrypt ((des_cblock *) key, (des_cblock *) key,		(long) sizeof(des_cblock), 		master_key_schedule, (des_cblock *)master_key_schedule,		DECRYPT);#endif  /* make new key, new style */  kdb_encrypt_key (key, key, master_key, master_key_schedule, ENCRYPT);  bcopy((char *)key, (char *)&(p->key_low), 4);  bcopy((char *)(((long *) key) + 1), (char *)&(p->key_high), 4);  bzero((char *)key, sizeof (key));  /* a little paranoia ... */}convert_old_format_db (db_file, out)     char *db_file;     FILE *out;{  des_cblock key_from_db;  Principal principal_data[1];  int n, more;  if (kdb_get_master_key (TRUE, master_key, master_key_schedule) != 0L) {    fprintf (stderr, "%s: Couldn't get master key.\n");    clear_secrets();    exit (-1);  }  /* can't call kdb_verify_master_key because this is an old style db */  /* lookup the master key version */  n = kerb_get_principal(KERB_M_NAME, KERB_M_INST, principal_data,			 1 /* only one please */, &more);  if ((n != 1) || more) {    fprintf(stderr, "verify_master_key: ",	    "Kerberos error on master key lookup, %d found.\n",	    n);    exit (-1);  }  /* set up the master key */  fprintf(stderr, "Current Kerberos master key version is %d.\n",	  principal_data[0].kdc_key_ver);  /*   * now use the master key to decrypt (old style) the key in the db, had better   * be the same!    */  bcopy((char *)&principal_data[0].key_low, (char *)key_from_db, 4);  bcopy((char *)&principal_data[0].key_high,	(char *)(((long *) key_from_db) + 1), 4);#ifndef NOENCRYPTION  (void) des_pcbc_encrypt (key_from_db, key_from_db,			   (long) sizeof(key_from_db),			   master_key_schedule,			   (des_cblock *) master_key_schedule, DECRYPT);#endif  /* the decrypted database key had better equal the master key */  n = bcmp((char *) master_key, (char *) key_from_db,	   sizeof(master_key));  bzero((char *)key_from_db, sizeof(key_from_db));  if (n) {    fprintf(stderr, "\n\07\07%verify_master_key: Invalid master key, ");    fprintf(stderr, "does not match database.\n");    exit (-1);  }      fprintf(stderr, "Master key verified.\n");  (void) fflush(stderr);  dump_db (db_file, out, convert_key_old_db);}longtime_explode(cp)register char *cp;{    char wbuf[5];    struct tm tp;    long maketime();    int local;    zaptime(&tp);			/* clear out the struct */        if (strlen(cp) > 10) {		/* new format */	(void) strncpy(wbuf, cp, 4);	wbuf[4] = 0;	tp.tm_year = atoi(wbuf);	cp += 4;			/* step over the year */	local = 0;			/* GMT */    } else {				/* old format: local time, 					   year is 2 digits, assuming 19xx */	wbuf[0] = *cp++;	wbuf[1] = *cp++;	wbuf[2] = 0;	tp.tm_year = 1900 + atoi(wbuf);	local = 1;			/* local */    }    wbuf[0] = *cp++;    wbuf[1] = *cp++;    wbuf[2] = 0;    tp.tm_mon = atoi(wbuf)-1;    wbuf[0] = *cp++;    wbuf[1] = *cp++;    tp.tm_mday = atoi(wbuf);        wbuf[0] = *cp++;    wbuf[1] = *cp++;    tp.tm_hour = atoi(wbuf);        wbuf[0] = *cp++;    wbuf[1] = *cp++;    tp.tm_min = atoi(wbuf);    return(maketime(&tp, local));}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -